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)) ( 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): 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): 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 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)
from hvm.vm.computation import (BaseComputation) from hvm.exceptions import ( OutOfGas, InsufficientFunds, StackDepthLimit, ReceivableTransactionNotFound, ) from .constants import EIP170_CODE_SIZE_LIMIT from .opcodes import HELIOS_TESTNET_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, } 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, }, ) HELIOS_TESTNET_PRECOMPILES = BYZANTIUM_PRECOMPILES
def selfdestruct(computation): beneficiary = force_bytes_to_address( computation.stack_pop(type_hint=constants.BYTES)) _selfdestruct(computation, beneficiary) raise Halt('SELFDESTRUCT')
from eth_utils import to_set from hvm import constants from hvm.utils.address import ( force_bytes_to_address, ) THREE = force_bytes_to_address(b'\x03') @to_set def collect_touched_accounts(computation): """ 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 """ 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: yield beneficiary continue else: yield beneficiary if computation.msg.to != constants.CREATE_CONTRACT_ADDRESS: if computation.is_error and computation.is_origin_computation:
from hvm.exceptions import ( OutOfGas, InsufficientFunds, StackDepthLimit, ) from hvm.utils.address import ( force_bytes_to_address, ) from hvm.utils.hexadecimal import ( encode_hex, ) 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:`~hvm.vm.computation.BaseComputation` """ # Override opcodes = FRONTIER_OPCODES _precompiles = FRONTIER_PRECOMPILES
import pytest from hvm.estimators.gas import binary_gas_search_1000_tolerance from hvm.utils.address import force_bytes_to_address from tests.core.helpers import ( fill_block, new_transaction, ) ADDRESS_2 = b'\0' * 19 + b'\x02' ADDR_1010 = force_bytes_to_address(b'\x10\x10') @pytest.fixture def chain(chain_without_block_validation): return chain_without_block_validation @pytest.mark.parametrize( 'should_sign_tx', (True, False), ) @pytest.mark.parametrize( 'data, gas_estimator, to, on_pending, expected', ( (b'', None, ADDR_1010, True, 21000), (b'', None, ADDR_1010, False, 21000), (b'\xff' * 10, None, ADDR_1010, True, 21680), (b'\xff' * 10, None, ADDR_1010, False, 21680),
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)
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)
from cytoolz import ( merge, ) from hvm import precompiles from hvm.utils.address import ( force_bytes_to_address, ) from hvm.vm.forks.frontier.computation import FRONTIER_PRECOMPILES from hvm.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:`~hvm.vm.forks.spurious_dragon.computation.SpuriousDragonComputation` """ # Override opcodes = BYZANTIUM_OPCODES _precompiles = BYZANTIUM_PRECOMPILES