def get_call_params(self, computation): gas = computation.stack_pop(type_hint=constants.UINT256) code_address = 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) to = computation.msg.storage_address sender = computation.msg.sender value = computation.msg.value return ( gas, value, to, sender, code_address, memory_input_start_position, memory_input_size, memory_output_start_position, memory_output_size, False, # should_transfer_value, computation.msg.is_static, )
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 )
def extcodecopy(computation): account = force_bytes_to_address( computation.stack_pop(type_hint=constants.BYTES)) ( mem_start_position, code_start_position, size, ) = computation.stack_pop(num_items=3, type_hint=constants.UINT256) computation.extend_memory(mem_start_position, size) word_count = ceil32(size) // 32 copy_gas_cost = constants.GAS_COPY * word_count computation.consume_gas( copy_gas_cost, reason='EXTCODECOPY: word gas cost', ) code = computation.state.account_db.get_code(account) code_bytes = code[code_start_position:code_start_position + size] padded_code_bytes = code_bytes.ljust(size, b'\x00') computation.memory_write(mem_start_position, size, padded_code_bytes)
def get_call_params(self, computation: BaseComputation) -> CallParams: gas = computation.stack_pop(type_hint=constants.UINT256) to = force_bytes_to_address( computation.stack_pop(type_hint=constants.BYTES)) ( value, memory_input_start_position, memory_input_size, memory_output_start_position, memory_output_size, ) = computation.stack_pop(num_items=5, type_hint=constants.UINT256) return ( gas, value, to, None, # sender None, # code_address memory_input_start_position, memory_input_size, memory_output_start_position, memory_output_size, True, # should_transfer_value, computation.msg.is_static, )
def selfdestruct_eip150(computation: BaseComputation) -> None: beneficiary = force_bytes_to_address( computation.stack_pop(type_hint=constants.BYTES)) if not computation.state.account_db.account_exists(beneficiary): computation.consume_gas( constants.GAS_SELFDESTRUCT_NEWACCOUNT, reason=mnemonics.SELFDESTRUCT, ) _selfdestruct(computation, beneficiary)
def create_random_tx(chain, is_valid=True): return chain.create_unsigned_transaction( nonce=0, gas_price=1, gas=2100000000000 if is_valid else 0, # For simplicity, both peers create tx with the same private key. # We rely on unique data to create truly unique txs data=uuid.uuid4().bytes, to=force_bytes_to_address(b'\x10\x10'), value=1, ).as_signed_transaction(funded_address_private_key())
def selfdestruct_eip161(computation: BaseComputation) -> None: beneficiary = force_bytes_to_address( computation.stack_pop(type_hint=constants.BYTES)) is_dead = (not computation.state.account_db.account_exists(beneficiary) or computation.state.account_db.account_is_empty(beneficiary)) if is_dead and computation.state.account_db.get_balance( computation.msg.storage_address): computation.consume_gas( constants.GAS_SELFDESTRUCT_NEWACCOUNT, reason=mnemonics.SELFDESTRUCT, ) _selfdestruct(computation, beneficiary)
def extcodehash(computation): """ Return the code hash for a given address. EIP: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1052.md """ account = force_bytes_to_address( computation.stack_pop(type_hint=constants.BYTES)) account_db = computation.state.account_db if not account_db.account_exists(account): computation.stack_push(constants.NULL_BYTE) else: computation.stack_push(account_db.get_code_hash(account))
import pytest from eth.chains.base import MiningChain from eth.utils.address import force_bytes_to_address from tests.core.helpers import ( new_transaction, ) ADDRESS_1010 = force_bytes_to_address(b'\x10\x10') @pytest.fixture def chain(chain_without_block_validation): if not isinstance(chain_without_block_validation, MiningChain): pytest.skip("these tests require a mining chain implementation") else: return chain_without_block_validation def test_building_block_incrementally_with_single_transaction( chain, funded_address, funded_address_private_key): head_hash = chain.get_canonical_head().hash tx = new_transaction( chain.get_vm(), from_=funded_address, to=ADDRESS_1010, private_key=funded_address_private_key, ) _, _, computation = chain.apply_transaction(tx) assert computation.is_success
def extcodesize(computation): account = force_bytes_to_address( computation.stack_pop(type_hint=constants.BYTES)) code_size = len(computation.state.account_db.get_code(account)) computation.stack_push(code_size)
def balance(computation): addr = force_bytes_to_address( computation.stack_pop(type_hint=constants.BYTES)) balance = computation.state.account_db.get_balance(addr) computation.stack_push(balance)
InsufficientFunds, StackDepthLimit, ) from eth.utils.address import ( force_bytes_to_address, ) from eth.utils.hexadecimal import ( encode_hex, ) from eth.vm.computation import ( BaseComputation, ) from .opcodes import FRONTIER_OPCODES FRONTIER_PRECOMPILES = { force_bytes_to_address(b'\x01'): precompiles.ecrecover, force_bytes_to_address(b'\x02'): precompiles.sha256, force_bytes_to_address(b'\x03'): precompiles.ripemd160, force_bytes_to_address(b'\x04'): precompiles.identity, } class FrontierComputation(BaseComputation): """ A class for all execution computations in the ``Frontier`` fork. Inherits from :class:`~eth.vm.computation.BaseComputation` """ # Override opcodes = FRONTIER_OPCODES _precompiles = FRONTIER_PRECOMPILES
from typing import Iterable from eth_utils import to_set from eth import constants from eth.utils.address import ( force_bytes_to_address, ) from eth.vm.computation import BaseComputation THREE = force_bytes_to_address(b'\x03') @to_set def collect_touched_accounts(computation: BaseComputation) -> Iterable[bytes]: """ Collect all of the accounts that *may* need to be deleted based on EIP161: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-161.md also see: https://github.com/ethereum/EIPs/issues/716 """ if computation.is_origin_computation and computation.transaction_context.gas_price == 0: yield computation.state.coinbase for beneficiary in sorted(set(computation.accounts_to_delete.values())): if computation.is_error and computation.is_origin_computation: # Special case to account for geth+parity bug # https://github.com/ethereum/EIPs/issues/716 if beneficiary == THREE:
def selfdestruct(computation: BaseComputation) -> None: beneficiary = force_bytes_to_address( computation.stack_pop(type_hint=constants.BYTES)) _selfdestruct(computation, beneficiary) raise Halt('SELFDESTRUCT')
from cytoolz import ( merge, ) from eth import precompiles from eth.utils.address import ( force_bytes_to_address, ) from eth.vm.forks.frontier.computation import FRONTIER_PRECOMPILES from eth.vm.forks.spurious_dragon.computation import SpuriousDragonComputation from .opcodes import BYZANTIUM_OPCODES BYZANTIUM_PRECOMPILES = merge( FRONTIER_PRECOMPILES, { force_bytes_to_address(b'\x05'): precompiles.modexp, force_bytes_to_address(b'\x06'): precompiles.ecadd, force_bytes_to_address(b'\x07'): precompiles.ecmul, force_bytes_to_address(b'\x08'): precompiles.ecpairing, }, ) class ByzantiumComputation(SpuriousDragonComputation): """ A class for all execution computations in the ``Byzantium`` fork. Inherits from :class:`~eth.vm.forks.spurious_dragon.computation.SpuriousDragonComputation` """ # Override opcodes = BYZANTIUM_OPCODES _precompiles = BYZANTIUM_PRECOMPILES