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 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 extcodesize(computation): account = force_bytes_to_address( computation.stack.pop(type_hint=constants.BYTES)) with computation.vm_state.state_db(read_only=True) as state_db: code_size = len(state_db.get_code(account)) computation.stack.push(code_size)
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 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 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.gas_meter.consume_gas( copy_gas_cost, reason='EXTCODECOPY: word gas cost', ) with computation.vm_state.state_db(read_only=True) as state_db: code = state_db.get_code(account) code_bytes = code[code_start_position:code_start_position + size] padded_code_bytes = pad_right(code_bytes, size, b'\x00') computation.memory.write(mem_start_position, size, padded_code_bytes)
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 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 suicide_eip150(computation): beneficiary = force_bytes_to_address( computation.stack.pop(type_hint=constants.BYTES)) with computation.vm.state_db(read_only=True) as state_db: if not state_db.account_exists(beneficiary): computation.gas_meter.consume_gas(constants.GAS_SUICIDE_NEWACCOUNT, reason=mnemonics.SUICIDE) _suicide(computation, beneficiary)
def selfdestruct_eip150(computation): beneficiary = force_bytes_to_address(computation.stack.pop(type_hint=constants.BYTES)) with computation.vm_state.state_db(read_only=True) as state_db: if not state_db.account_exists(beneficiary): computation.gas_meter.consume_gas( constants.GAS_SELFDESTRUCT_NEWACCOUNT, reason=mnemonics.SELFDESTRUCT, ) _selfdestruct(computation, beneficiary)
def selfdestruct_eip150(computation): beneficiary = force_bytes_to_address( computation.stack.pop(type_hint=constants.BYTES)) with computation.vm_state.state_db(read_only=True) as state_db: if not state_db.account_exists(beneficiary): computation.gas_meter.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)) with computation.state_db(read_only=True) as state_db: is_dead = (not state_db.account_exists(beneficiary) or state_db.account_is_empty(beneficiary)) if is_dead and state_db.get_balance(computation.msg.storage_address): computation.consume_gas( constants.GAS_SELFDESTRUCT_NEWACCOUNT, reason=mnemonics.SELFDESTRUCT, ) _selfdestruct(computation, beneficiary)
def selfdestruct_eip161(computation): beneficiary = force_bytes_to_address(computation.stack.pop(type_hint=constants.BYTES)) with computation.vm_state.state_db(read_only=True) as state_db: is_dead = ( not state_db.account_exists(beneficiary) or state_db.account_is_empty(beneficiary) ) if is_dead and state_db.get_balance(computation.msg.storage_address): computation.gas_meter.consume_gas( constants.GAS_SELFDESTRUCT_NEWACCOUNT, reason=mnemonics.SELFDESTRUCT, ) _selfdestruct(computation, beneficiary)
def suicide(computation): beneficiary = force_bytes_to_address(computation.stack.pop(type_hint=constants.BYTES)) local_balance = computation.evm.block.state_db.get_balance(computation.msg.storage_address) beneficiary_balance = computation.evm.block.state_db.get_balance(beneficiary) # 1st: Transfer to beneficiary computation.evm.block.state_db.set_balance( beneficiary, local_balance + beneficiary_balance, ) # 2nd: Zero the balance of the address being deleted (must come after # sending to beneficiary in case the contract named itself as the # beneficiary. computation.evm.block.state_db.set_balance(computation.msg.storage_address, 0) # 3rd: Register the account to be deleted computation.register_account_for_deletion(computation.msg.storage_address)
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.gas_meter.consume_gas( copy_gas_cost, reason='EXTCODECOPY: word gas cost', ) with computation.vm_state.state_db(read_only=True) as state_db: code = state_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 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 evm import constants from evm.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 """ 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: yield beneficiary continue else: yield beneficiary
from evm import precompiles from evm.vm.computation import (BaseComputation) from evm.exceptions import ( OutOfGas, InsufficientFunds, StackDepthLimit, ) from evm.utils.address import ( force_bytes_to_address, ) from evm.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): # Override opcodes = FRONTIER_OPCODES _precompiles = FRONTIER_PRECOMPILES def apply_message(self): snapshot = self.state.snapshot() if self.msg.depth > constants.STACK_DEPTH_LIMIT:
def selfdestruct(computation): beneficiary = force_bytes_to_address( computation.stack_pop(type_hint=constants.BYTES)) _selfdestruct(computation, beneficiary) raise Halt('SELFDESTRUCT')
def balance(computation): addr = force_bytes_to_address( computation.stack.pop(type_hint=constants.BYTES)) with computation.vm_state.state_db(read_only=True) as state_db: balance = state_db.get_balance(addr) computation.stack.push(balance)
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.evm.block.state_db.get_code(account)) computation.stack.push(code_size)
from eth_utils import to_set from evm import constants from evm.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 """ if computation.is_origin_computation and computation.transaction_context.gas_price == 0: yield computation.vm_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: yield beneficiary continue else:
import pytest from evm.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): 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
from ..frontier import FRONTIER_PRECOMPILES from ..spurious_dragon import SpuriousDragonVM from .constants import EIP649_BLOCK_REWARD from .headers import ( create_byzantium_header_from_parent, configure_byzantium_header, ) from .opcodes import BYZANTIUM_OPCODES from .blocks import ByzantiumBlock 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, }, ) def _byzantium_get_block_reward(block_number): return EIP649_BLOCK_REWARD def _byzantium_get_uncle_reward(block_number, uncle): validate_lte(uncle.block_number, MAX_UNCLE_DEPTH) block_number_delta = block_number - uncle.block_number return (8 - block_number_delta) * EIP649_BLOCK_REWARD // 8
def precompile_identity(computation): word_count = ceil32(len(computation.msg.data)) // 32 gas_fee = constants.GAS_IDENTITY + word_count * constants.GAS_IDENTITYWORD computation.gas_meter.consume_gas(gas_fee, reason="Identity Precompile") computation.output = computation.msg.data return computation def precompile_ripemd160(computation): word_count = ceil32(len(computation.msg.data)) // 32 gas_fee = constants.GAS_RIPEMD160 + word_count * constants.GAS_RIPEMD160WORD computation.gas_meter.consume_gas(gas_fee, reason="RIPEMD160 Precompile") # TODO: this only works if openssl is installed. hash = hashlib.new('ripemd160', computation.msg.data).digest() padded_hash = pad32(hash) computation.output = padded_hash return computation PRECOMPILES = { force_bytes_to_address(b'\x01'): precompile_ecrecover, force_bytes_to_address(b'\x02'): precompiled_sha256, force_bytes_to_address(b'\x03'): precompile_ripemd160, force_bytes_to_address(b'\x04'): precompile_identity, }
def balance(computation): addr = force_bytes_to_address( computation.stack.pop(type_hint=constants.BYTES)) balance = computation.vm_state.read_only_state_db.get_balance(addr) computation.stack.push(balance)
def extcodesize(computation): account = force_bytes_to_address(computation.stack.pop(type_hint=constants.BYTES)) with computation.vm_state.state_db(read_only=True) as state_db: code_size = len(state_db.get_code(account)) computation.stack.push(code_size)
def balance(computation): addr = force_bytes_to_address(computation.stack.pop(type_hint=constants.BYTES)) with computation.vm_state.state_db(read_only=True) as state_db: balance = state_db.get_balance(addr) computation.stack.push(balance)
def suicide(computation): beneficiary = force_bytes_to_address( computation.stack.pop(type_hint=constants.BYTES)) _suicide(computation, beneficiary)