value
of ether
tokens
between accounts:
<address>.send
<address>.transfer
<address>.call{value}
via the CALL opcode
Since 2019, it has been recommended to avoid using
<address>.send
and <address>.transfer
, because these forward a fixed 2300
gas (and gas costs for common operations periodically change, forcing backwards incompatibility).<address>
, enabling
reentrancy
and
Denial of service (DoS)
attack vectors if a developer is not cautious.
Historically, this has led to billions of
dollars of smart contract exploits.
EIP-5920 introduces a new opcode,
PAY
, that takes two stack parameters, addr
and val
, transferring val
wei
into addr
, without calling any of its functions. In this way, developers
can easily transfer ether without transferring execution context.
EIP Specification
Constants
Constant | Definition |
---|---|
WARM_STORAGE_READ_COST | EIP-2929 |
COLD_ACCOUNT_ACCESS_COST | EIP-2929 |
GAS_NEW_ACCOUNT | EELS |
GAS_CALL_VALUE | EELS |
Behavior
A new opcode is introduced:PAY
(0xf9
), which:
- Pops two values from the stack:
addr
thenval
- Transfers
val
wei from the current target address to the addressaddr
- Marks
addr
as warm (addingaddr
toaccessed_addresses
)
Gas Cost
The gas cost forPAY
is the sum of the following:
- Is
addr
inaccessed_addresses
?- If yes,
WARM_STORAGE_READ_COST
; - Otherwise,
COLD_ACCOUNT_ACCESS_COST
.
- If yes,
- Does
addr
exist or isval
zero?- If yes to either, zero;
- Otherwise,
GAS_NEW_ACCOUNT
.
- Is
val
zero?- If yes, zero;
- Otherwise,
GAS_CALL_VALUE
.
PAY
cannot be implemented on networks with empty accounts (see
EIP-7523).