EIP-5920
Adds a new PAY
opcode to send ether without transferring execution context.
Today, when using Solidity to write smart contracts
for the EVM, there are three ways to transfer some value
of ether
tokens
between accounts:
<address>.send
<address>.transfer
<address>.call{value}
via the CALL opcode
<address>.send
and <address>.transfer
, because these forward a fixed 2300
gas (and gas costs for common operations periodically change, forcing backwards incompatibility).Across all three methods, execution context and control flow is passed to
<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 for PAY
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).