Skip to content

Commit

Permalink
futzing with STATICCALL
Browse files Browse the repository at this point in the history
  • Loading branch information
pipermerriam committed Oct 19, 2017
1 parent fefaf31 commit a0ffd53
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 29 deletions.
71 changes: 42 additions & 29 deletions evm/logic/call.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from evm.exceptions import (
OutOfGas,
WriteProtection,
)
from evm.opcode import (
Opcode,
Expand Down Expand Up @@ -229,35 +230,6 @@ def get_call_params(self, computation):
False, # should_transfer_value,
computation.msg.is_static, # is_static
)


class StaticCall(Call):
def get_call_params(self, computation):
gas = computation.stack.pop(type_hint=constants.UINT256)
to = force_bytes_to_address(computation.stack.pop(type_hint=constants.BYTES))

(
memory_input_start_position,
memory_input_size,
memory_output_start_position,
memory_output_size,
) = computation.stack.pop(num_items=4, type_hint=constants.UINT256)

return (
gas,
0, # value
to,
None, # sender
None, # code_address
memory_input_start_position,
memory_input_size,
memory_output_start_position,
memory_output_size,
False, # should_transfer_value,
True, # is_static
)


#
# EIP150
#
Expand Down Expand Up @@ -319,3 +291,44 @@ def compute_msg_extra_gas(self, computation, gas, to, value):
transfer_gas_fee = constants.GAS_CALLVALUE if value else 0
create_gas_fee = constants.GAS_NEWACCOUNT if (account_is_dead and value) else 0
return transfer_gas_fee + create_gas_fee


#
# Byzantium
#
class StaticCall(CallEIP161):
def get_call_params(self, computation):
gas = computation.stack.pop(type_hint=constants.UINT256)
to = force_bytes_to_address(computation.stack.pop(type_hint=constants.BYTES))

(
memory_input_start_position,
memory_input_size,
memory_output_start_position,
memory_output_size,
) = computation.stack.pop(num_items=4, type_hint=constants.UINT256)

return (
gas,
0, # value
to,
None, # sender
None, # code_address
memory_input_start_position,
memory_input_size,
memory_output_start_position,
memory_output_size,
False, # should_transfer_value,
True, # is_static
)


class CallByzantium(CallEIP161):
def get_call_params(self, computation):
call_params = super(CallByzantium, self).get_call_params(computation)
value = call_params[1]
if computation.msg.is_static and value != 0:
raise WriteProtection("Cannot modify state while inside of a STATICCALL context")
return call_params


8 changes: 8 additions & 0 deletions evm/vm/forks/byzantium/opcodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,19 @@ def inner(computation):
mnemonic=mnemonics.REVERT,
gas_cost=constants.GAS_ZERO,
),
#
# Call
#
opcode_values.STATICCALL: call.StaticCall.configure(
name='opcode:STATICCALL',
mnemonic=mnemonics.STATICCALL,
gas_cost=constants.GAS_CALL_EIP150,
)(),
opcode_values.CALL: call.CallByzantium.configure(
name='opcode:CALL',
mnemonic=mnemonics.CALL,
gas_cost=constants.GAS_CALL_EIP150,
)(),
#
# Logging
#
Expand Down

0 comments on commit a0ffd53

Please sign in to comment.