Skip to content

Commit 99e3a93

Browse files
committed
Implement EIP-5920
1 parent aa8f57c commit 99e3a93

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

src/ethereum/osaka/vm/instructions/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ class Ops(enum.Enum):
252252
EXTDELEGATECALL = 0xF9
253253
STATICCALL = 0xFA
254254
EXTSTATICCALL = 0xFB
255+
PAY = 0xFC
255256
REVERT = 0xFD
256257
INVALID = 0xFE
257258
SELFDESTRUCT = 0xFF
@@ -427,6 +428,7 @@ class Ops(enum.Enum):
427428
Ops.EXTCALL: system_instructions.ext_call,
428429
Ops.EXTDELEGATECALL: system_instructions.ext_delegatecall,
429430
Ops.EXTSTATICCALL: system_instructions.ext_staticcall,
431+
Ops.PAY: system_instructions.pay,
430432
}
431433

432434

@@ -659,6 +661,7 @@ class Ops(enum.Enum):
659661
Ops.EXTCALL: OpcodeStackItemCount(inputs=4, outputs=1),
660662
Ops.EXTDELEGATECALL: OpcodeStackItemCount(inputs=3, outputs=1),
661663
Ops.EXTSTATICCALL: OpcodeStackItemCount(inputs=3, outputs=1),
664+
Ops.PAY: OpcodeStackItemCount(inputs=2, outputs=1),
662665
}
663666

664667

src/ethereum/osaka/vm/instructions/system.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,3 +1379,58 @@ def return_contract(evm: Evm) -> None:
13791379

13801380
# PROGRAM COUNTER
13811381
evm.running = False
1382+
1383+
1384+
def pay(evm: Evm) -> None:
1385+
"""
1386+
Transfer ether to an account.
1387+
1388+
Parameters
1389+
----------
1390+
evm :
1391+
The current EVM frame.
1392+
"""
1393+
# STACK
1394+
try:
1395+
to = to_address_without_mask(pop(evm.stack))
1396+
except ValueError as e:
1397+
raise ExceptionalHalt from e
1398+
value = pop(evm.stack)
1399+
1400+
# GAS
1401+
if to in evm.accessed_addresses:
1402+
access_gas_cost = GAS_WARM_ACCESS
1403+
else:
1404+
evm.accessed_addresses.add(to)
1405+
access_gas_cost = GAS_COLD_ACCOUNT_ACCESS
1406+
1407+
create_gas_cost = (
1408+
Uint(0)
1409+
if is_account_alive(evm.message.block_env.state, to) or value == 0
1410+
else GAS_NEW_ACCOUNT
1411+
)
1412+
1413+
transfer_gas_cost = Uint(0) if value == U256(0) else GAS_CALL_VALUE
1414+
1415+
charge_gas(evm, access_gas_cost + create_gas_cost + transfer_gas_cost)
1416+
1417+
# OPERATION
1418+
if value > U256(0):
1419+
try:
1420+
move_ether(
1421+
evm.message.block_env.state,
1422+
evm.message.current_target,
1423+
to,
1424+
value,
1425+
)
1426+
push(evm.stack, U256(1))
1427+
except AssertionError:
1428+
# TODO: This behavior has not been
1429+
# finalized yet and is simply based on
1430+
# ongoing discussions. The final update
1431+
# needs to be made to this based on the
1432+
# agreed upon spec.
1433+
push(evm.stack, U256(0))
1434+
1435+
# PROGRAM COUNTER
1436+
evm.pc += Uint(1)

0 commit comments

Comments
 (0)