예제 #1
0
def setup_computation(vm_class, create_address, code):

    message = Message(
        to=CANONICAL_ADDRESS_A,
        sender=CANONICAL_ADDRESS_B,
        create_address=create_address,
        value=0,
        data=b'',
        code=code,
        gas=1000000,
    )

    tx_context = vm_class._state_class.transaction_context_class(
        gas_price=1,
        origin=CANONICAL_ADDRESS_B,
    )

    vm = vm_class(GENESIS_HEADER, ChainDB(AtomicDB()))

    computation = vm_class._state_class.computation_class(
        state=vm.state,
        message=message,
        transaction_context=tx_context,
    )

    return computation
예제 #2
0
def prepare_computation(vm_class):

    message = Message(
        to=CANONICAL_ADDRESS_A,
        sender=CANONICAL_ADDRESS_B,
        value=100,
        data=b'',
        code=b'',
        gas=800,
    )

    tx_context = vm_class._state_class.transaction_context_class(
        gas_price=1,
        origin=CANONICAL_ADDRESS_B,
    )

    vm = vm_class(GENESIS_HEADER, ChainDB(MemoryDB()))

    computation = vm_class._state_class.computation_class(
        state=vm.state,
        message=message,
        transaction_context=tx_context,
    )

    computation.state.account_db.touch_account(
        decode_hex(EMPTY_ADDRESS_IN_STATE))
    computation.state.account_db.set_code(decode_hex(ADDRESS_WITH_CODE[0]),
                                          ADDRESS_WITH_CODE[1])

    return computation
예제 #3
0
def setup_computation(VM, code):
  CANONICAL_ADDRESS_A = to_canonical_address("0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6")
  CANONICAL_ADDRESS_B = to_canonical_address("0xcd1722f3947def4cf144679da39c4c32bdc35681")
  message = Message(
    to=CANONICAL_ADDRESS_A,
    sender=CANONICAL_ADDRESS_B,
    create_address=CANONICAL_ADDRESS_B,
    value=0,
    data=b'',
    code=code,
    gas=1000000,
  )

  tx_context = VM._state_class.transaction_context_class(
      gas_price=1,
      origin=CANONICAL_ADDRESS_B,
  )

  computation =VM._state_class.computation_class(
      state=VM.state,
      message=message,
      transaction_context=tx_context,
  )

  return computation
예제 #4
0
파일: state.py 프로젝트: marcgarreau/py-evm
    def build_evm_message(self, transaction: SignedTransactionAPI) -> MessageAPI:
        # Use vm_state.get_gas_price instead of transaction_context.gas_price so
        #   that we can run get_transaction_result (aka~ eth_call) and estimate_gas.
        #   Both work better if the GASPRICE opcode returns the original real price,
        #   but the sender's balance doesn't actually deduct the gas. This get_gas_price()
        #   will return 0 for eth_call, but transaction_context.gas_price will return
        #   the same value as the GASPRICE opcode.
        gas_fee = transaction.gas * self.vm_state.get_gas_price(transaction)

        # Buy Gas
        self.vm_state.delta_balance(transaction.sender, -1 * gas_fee)

        # Increment Nonce
        self.vm_state.increment_nonce(transaction.sender)

        # Setup VM Message
        message_gas = transaction.gas - transaction.intrinsic_gas

        if transaction.to == CREATE_CONTRACT_ADDRESS:
            contract_address = generate_contract_address(
                transaction.sender,
                self.vm_state.get_nonce(transaction.sender) - 1,
            )
            data = b''
            code = transaction.data
        else:
            contract_address = None
            data = transaction.data
            code = self.vm_state.get_code(transaction.to)

        self.vm_state.logger.debug2(
            (
                "TRANSACTION: sender: %s | to: %s | value: %s | gas: %s | "
                "gas-price: %s | s: %s | r: %s | y_parity: %s | data-hash: %s"
            ),
            encode_hex(transaction.sender),
            encode_hex(transaction.to),
            transaction.value,
            transaction.gas,
            transaction.gas_price,
            transaction.s,
            transaction.r,
            transaction.y_parity,
            encode_hex(keccak(transaction.data)),
        )

        message = Message(
            gas=message_gas,
            to=transaction.to,
            sender=transaction.sender,
            value=transaction.value,
            data=data,
            code=code,
            create_address=contract_address,
        )
        return message
def message():
    message = Message(
        to=CANONICAL_ADDRESS_A,
        sender=CANONICAL_ADDRESS_B,
        value=100,
        data=b'',
        code=b'',
        gas=100,
    )
    return message
예제 #6
0
def message(canonical_address_a, canonical_address_b):
    message = Message(
        to=canonical_address_a,
        sender=canonical_address_b,
        value=100,
        data=b'',
        code=b'',
        gas=100,
    )
    return message
예제 #7
0
파일: state.py 프로젝트: ggs134/py-evm
    def build_delegation_evm_message(self, transaction: SignedTransactionAPI) -> MessageAPI:

        ### DAEJUN changed ###
        # gas_fee = transaction.gas * transaction.gas_price
        gas_fee = 0

        ### DAEJUN changed ###
        # Buy Gas
        self.vm_state.delta_balance(transaction.sender, -1 * gas_fee)

        # Increment Nonce
        self.vm_state.increment_nonce(transaction.sender)

        # Setup VM Message
        # VM에 최초로 전달하는 가스량. 그냥 두면 된다.
        message_gas = transaction.gas - transaction.intrinsic_gas

        if transaction.to == CREATE_CONTRACT_ADDRESS:
            contract_address = generate_contract_address(
                transaction.sender,
                self.vm_state.get_nonce(transaction.sender) - 1,
            )
            data = b''
            code = transaction.data
        else:
            contract_address = None
            data = transaction.data
            code = self.vm_state.get_code(transaction.to)

        self.vm_state.logger.debug2(
            (
                "TRANSACTION: sender: %s | to: %s | value: %s | gas: %s | "
                "gas-price: %s | s: %s | r: %s | y_parity: %s | data-hash: %s"
            ),
            encode_hex(transaction.sender),
            encode_hex(transaction.to),
            transaction.value,
            transaction.gas,
            transaction.gas_price,
            transaction.s,
            transaction.r,
            transaction.y_parity,
            encode_hex(keccak(transaction.data)),
        )

        message = Message(
            gas=message_gas,
            to=transaction.to,
            sender=transaction.sender,
            value=transaction.value,
            data=data,
            code=code,
            create_address=contract_address,
        )
        return message
예제 #8
0
    def prepare_child_message(self, gas: int, to: Address, value: int,
                              data: BytesOrView, code: bytes,
                              **kwargs: Any) -> MessageAPI:
        kwargs.setdefault('sender', self.msg.storage_address)

        child_message = Message(gas=gas,
                                to=to,
                                value=value,
                                data=data,
                                code=code,
                                depth=self.msg.depth + 1,
                                **kwargs)
        return child_message
예제 #9
0
    def build_evm_message(self,
                          transaction: BaseOrSpoofTransaction) -> Message:

        gas_fee = transaction.gas * transaction.gas_price

        # Buy Gas
        self.vm_state.account_db.delta_balance(transaction.sender,
                                               -1 * gas_fee)

        # Increment Nonce
        self.vm_state.account_db.increment_nonce(transaction.sender)

        # Setup VM Message
        message_gas = transaction.gas - transaction.intrinsic_gas

        if transaction.to == CREATE_CONTRACT_ADDRESS:
            contract_address = generate_contract_address(
                transaction.sender,
                self.vm_state.account_db.get_nonce(transaction.sender) - 1,
            )
            data = b''
            code = transaction.data
        else:
            contract_address = None
            data = transaction.data
            code = self.vm_state.account_db.get_code(transaction.to)

        self.vm_state.logger.debug2(
            ("TRANSACTION: sender: %s | to: %s | value: %s | gas: %s | "
             "gas-price: %s | s: %s | r: %s | v: %s | data-hash: %s"),
            encode_hex(transaction.sender),
            encode_hex(transaction.to),
            transaction.value,
            transaction.gas,
            transaction.gas_price,
            transaction.s,
            transaction.r,
            transaction.v,
            encode_hex(keccak(transaction.data)),
        )

        message = Message(
            gas=message_gas,
            to=transaction.to,
            sender=transaction.sender,
            value=transaction.value,
            data=data,
            code=code,
            create_address=contract_address,
        )
        return message
예제 #10
0
def _create_message(gas=1,
                    to=ADDRESS_A,
                    sender=ADDRESS_B,
                    value=0,
                    data=b"",
                    code=b"",
                    **kwargs):
    return Message(gas=gas,
                   to=to,
                   sender=sender,
                   value=value,
                   data=data,
                   code=code,
                   **kwargs)
예제 #11
0
    def prepare_child_message(self, gas: int, to: Address, value: int,
                              data: BytesOrView, code: bytes,
                              **kwargs: Any) -> Message:
        """
        Helper method for creating a child computation.
        """
        kwargs.setdefault('sender', self.msg.storage_address)

        child_message = Message(gas=gas,
                                to=to,
                                value=value,
                                data=data,
                                code=code,
                                depth=self.msg.depth + 1,
                                **kwargs)
        return child_message
예제 #12
0
def test_is_origin_computation(computation, transaction_context):
    assert computation.is_origin_computation
    message2 = Message(
        to=CANONICAL_ADDRESS_A,
        # Different sender than the tx context origin
        sender=CANONICAL_ADDRESS_A,
        value=100,
        data=b'',
        code=b'',
        gas=100,
    )
    computation2 = DummyComputation(
        state=None,
        message=message2,
        transaction_context=transaction_context,
    )
    assert not computation2.is_origin_computation
예제 #13
0
def test_is_origin_computation(computation, transaction_context,
                               canonical_address_a):
    assert computation.is_origin_computation
    message2 = Message(
        to=canonical_address_a,
        # Different sender than the tx context origin
        sender=canonical_address_a,
        value=100,
        data=b'',
        code=b'',
        gas=100,
    )
    computation2 = DummyComputation(
        state=None,
        message=message2,
        transaction_context=transaction_context,
    )
    assert not computation2.is_origin_computation
예제 #14
0
def fixture_to_computation(fixture, code, vm):
    message = Message(
        to=fixture['exec']['address'],
        sender=fixture['exec']['caller'],
        value=fixture['exec']['value'],
        data=fixture['exec']['data'],
        code=code,
        gas=fixture['exec']['gas'],
    )
    transaction_context = BaseTransactionContext(
        origin=fixture['exec']['origin'],
        gas_price=fixture['exec']['gasPrice'],
    )
    return vm.state.get_computation(message, transaction_context).apply_computation(
        vm.state,
        message,
        transaction_context,
    )
예제 #15
0
def gen_context(chain):
    CANONICAL_ADDRESS_A = to_canonical_address(
        "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6")
    CANONICAL_ADDRESS_B = to_canonical_address(
        "0xcd1722f3947def4cf144679da39c4c32bdc35681")
    state = chain.get_vm().state
    message = Message(
        to=CANONICAL_ADDRESS_A,
        sender=CANONICAL_ADDRESS_B,
        create_address=None,
        value=0,
        data=b'',
        code=b'',
        gas=1000000,
    )
    tx_context = chain.get_vm()._state_class.transaction_context_class(
        gas_price=1, origin=CANONICAL_ADDRESS_B)
    return state, message, tx_context
예제 #16
0
def run_computation(vm,
                    create_address,
                    code,
                    gas=1000000,
                    to=CANONICAL_ADDRESS_A,
                    transaction_sender=b'\x11' * 20,
                    data=b'',
                    access_list=None):
    executor = vm.state.get_transaction_executor()

    message = Message(
        to=to,
        sender=CANONICAL_ADDRESS_B,
        create_address=create_address,
        value=0,
        data=data,
        code=code,
        gas=gas,
    )
    if access_list is not None:
        txn_builder = vm.get_transaction_builder()
        unsigned_transaction = txn_builder.new_unsigned_access_list_transaction(
            vm.chain_context.chain_id,
            nonce=2,
            gas_price=1,
            gas=gas,
            to=to,
            value=3,
            data=data,
            access_list=access_list,
        )
    else:
        unsigned_transaction = vm.create_unsigned_transaction(
            nonce=2,
            gas_price=1,
            gas=gas,
            to=to,
            value=3,
            data=data,
        )
    transaction = SpoofTransaction(unsigned_transaction,
                                   from_=transaction_sender)

    return executor.build_computation(message, transaction)
예제 #17
0
파일: base.py 프로젝트: Kong-F/EVMFuzzer
    def execute_bytecode(
        self,
        origin,
        gas_price,
        gas,
        to,
        sender,
        value,
        data,
        code,
        code_address=None,
    ):
        """
        Execute raw bytecode in the context of the current state of
        the virtual machine.
        """
        if origin is None:
            origin = sender

        # Construct a message
        message = Message(
            gas=gas,
            to=to,
            sender=sender,
            value=value,
            data=data,
            code=code,
            code_address=code_address,
        )

        # Construction a tx context
        transaction_context = self.state.get_transaction_context_class()(
            gas_price=gas_price,
            origin=origin,
        )

        # Execute it in the VM
        return self.state.get_computation(
            message, transaction_context).apply_computation(
                self.state,
                message,
                transaction_context,
            )
예제 #18
0
    def execute_bytecode(
        self,
        origin: Address,
        gas_price: int,
        gas: int,
        to: Address,
        sender: Address,
        value: int,
        data: bytes,
        code: bytes,
        code_address: Address = None,
    ) -> ComputationAPI:
        if origin is None:
            origin = sender

        # Construct a message
        message = Message(
            gas=gas,
            to=to,
            sender=sender,
            value=value,
            data=data,
            code=code,
            code_address=code_address,
        )

        # Construction a tx context
        transaction_context = self.state.get_transaction_context_class()(
            gas_price=gas_price,
            origin=origin,
        )

        # Execute it in the VM
        return self.state.get_computation(
            message, transaction_context).apply_computation(
                self.state,
                message,
                transaction_context,
            )
예제 #19
0
def prepare_computation(vm_class):

    message = Message(
        to=CANONICAL_ADDRESS_A,
        sender=CANONICAL_ADDRESS_B,
        value=100,
        data=b'',
        code=b'',
        gas=800,
    )

    tx_context = vm_class._state_class.transaction_context_class(
        gas_price=1,
        origin=CANONICAL_ADDRESS_B,
    )

    computation = vm_class._state_class.computation_class(
        state=None,
        message=message,
        transaction_context=tx_context,
    )
    return computation
예제 #20
0
def setup_computation(vm_class,
                      create_address,
                      code,
                      chain_id=None,
                      gas=1000000,
                      to=CANONICAL_ADDRESS_A,
                      data=b''):

    message = Message(
        to=to,
        sender=CANONICAL_ADDRESS_B,
        create_address=create_address,
        value=0,
        data=data,
        code=code,
        gas=gas,
    )

    chain_context = ChainContext(chain_id)

    tx_context = vm_class._state_class.transaction_context_class(
        gas_price=1,
        origin=CANONICAL_ADDRESS_B,
    )

    db = AtomicDB()
    vm = vm_class(GENESIS_HEADER, ChainDB(db), chain_context,
                  ConsensusContext(db))

    computation = vm_class._state_class.computation_class(
        state=vm.state,
        message=message,
        transaction_context=tx_context,
    )

    return computation
예제 #21
0
    
    vm = chain.get_vm()
    geometry_options = {
        "landscape": True,
        "margin": "0.5in",
        "headheight": "20pt",
        "headsep": "10pt",
        "includeheadfoot": True
    }
    doc = ""
    message = Message(
            supergas,
            MOCK_ADDRESS,
            MOCK_ADDRESS,
            0,
            b'',
            bytecode,
            create_address=MOCK_ADDRESS,
            code_address=MOCK_ADDRESS,
            should_transfer_value=False
            )
    vm.get_state_class()
    doc, comp = apply_latex_computation(vm,message)
    md = markdown.markdown(doc,extensions=['mdx_math','markdown.extensions.extra'],output_format="html5")
    md = md.replace("<script type=\"math/tex; mode=display\">","")
    print("""<!DOCTYPE html><html><head><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
<style>
th, td {
  border-bottom: 1px solid #ddd;
  padding: 10px;
예제 #22
0
def test_vm_fixtures(fixture, vm_class, computation_getter):
    chaindb = ChainDB(get_db_backend())
    header = BlockHeader(
        coinbase=fixture['env']['currentCoinbase'],
        difficulty=fixture['env']['currentDifficulty'],
        block_number=fixture['env']['currentNumber'],
        gas_limit=fixture['env']['currentGasLimit'],
        timestamp=fixture['env']['currentTimestamp'],
    )
    vm = vm_class(header=header, chaindb=chaindb)
    state = vm.state
    setup_state(fixture['pre'], state)
    code = state.get_code(fixture['exec']['address'])
    # Update state_root manually
    vm._block = vm.get_block().copy(header=vm.get_header().copy(
        state_root=state.state_root))

    message = Message(
        to=fixture['exec']['address'],
        sender=fixture['exec']['caller'],
        value=fixture['exec']['value'],
        data=fixture['exec']['data'],
        code=code,
        gas=fixture['exec']['gas'],
    )
    transaction_context = BaseTransactionContext(
        origin=fixture['exec']['origin'],
        gas_price=fixture['exec']['gasPrice'],
    )
    computation = vm.state.get_computation(
        message, transaction_context).apply_computation(
            vm.state,
            message,
            transaction_context,
        )
    # Update state_root manually
    vm._block = vm.get_block().copy(
        header=vm.get_header().copy(state_root=computation.state.state_root), )

    if 'post' in fixture:
        #
        # Success checks
        #
        assert not computation.is_error

        log_entries = computation.get_log_entries()
        if 'logs' in fixture:
            actual_logs_hash = hash_log_entries(log_entries)
            expected_logs_hash = fixture['logs']
            assert expected_logs_hash == actual_logs_hash
        elif log_entries:
            raise AssertionError("Got log entries: {0}".format(log_entries))

        expected_output = fixture['out']
        assert computation.output == expected_output

        gas_meter = computation._gas_meter

        expected_gas_remaining = fixture['gas']
        actual_gas_remaining = gas_meter.gas_remaining
        gas_delta = actual_gas_remaining - expected_gas_remaining
        assert gas_delta == 0, "Gas difference: {0}".format(gas_delta)

        call_creates = fixture.get('callcreates', [])
        assert len(computation.children) == len(call_creates)

        call_creates = fixture.get('callcreates', [])
        for child_computation, created_call in zip(computation.children,
                                                   call_creates):
            to_address = created_call['destination']
            data = created_call['data']
            gas_limit = created_call['gasLimit']
            value = created_call['value']

            assert child_computation.msg.to == to_address
            assert data == child_computation.msg.data or child_computation.msg.code
            assert gas_limit == child_computation.msg.gas
            assert value == child_computation.msg.value
        expected_account_db = fixture['post']
    else:
        #
        # Error checks
        #
        assert computation.is_error
        assert isinstance(computation._error, VMError)
        expected_account_db = fixture['pre']

    verify_state(expected_account_db, vm.state)
def test_vm_fixtures(fixture, vm_class, computation_getter):
    db = get_db_backend()
    chaindb = ChainDB(db)
    consensus_context = ConsensusContext(db)
    header = BlockHeader(
        coinbase=fixture['env']['currentCoinbase'],
        difficulty=fixture['env']['currentDifficulty'],
        block_number=fixture['env']['currentNumber'],
        gas_limit=fixture['env']['currentGasLimit'],
        timestamp=fixture['env']['currentTimestamp'],
    )

    # None of the VM tests (currently) test chain ID, so the setting doesn't matter here.
    #   When they *do* start testing ID, they will have to supply it as part of the environment.
    #   For now, just hard-code it to something not used in practice:
    chain_context = ChainContext(chain_id=0)

    vm = vm_class(header=header,
                  chaindb=chaindb,
                  chain_context=chain_context,
                  consensus_context=consensus_context)
    state = vm.state
    setup_state(fixture['pre'], state)
    code = state.get_code(fixture['exec']['address'])
    # Update state_root manually
    vm._block = vm.get_block().copy(header=vm.get_header().copy(
        state_root=state.state_root))

    message = Message(
        to=fixture['exec']['address'],
        sender=fixture['exec']['caller'],
        value=fixture['exec']['value'],
        data=fixture['exec']['data'],
        code=code,
        gas=fixture['exec']['gas'],
    )
    transaction_context = BaseTransactionContext(
        origin=fixture['exec']['origin'],
        gas_price=fixture['exec']['gasPrice'],
    )
    computation = vm.state.get_computation(
        message, transaction_context).apply_computation(
            vm.state,
            message,
            transaction_context,
        )
    # Update state_root manually
    vm._block = vm.get_block().copy(
        header=vm.get_header().copy(state_root=computation.state.state_root), )

    if 'post' in fixture:
        #
        # Success checks
        #
        assert not computation.is_error

        log_entries = computation.get_log_entries()
        if 'logs' in fixture:
            actual_logs_hash = hash_log_entries(log_entries)
            expected_logs_hash = fixture['logs']
            assert expected_logs_hash == actual_logs_hash
        elif log_entries:
            raise AssertionError(f"Got log entries: {log_entries}")

        expected_output = fixture['out']
        assert computation.output == expected_output

        gas_meter = computation._gas_meter

        expected_gas_remaining = fixture['gas']
        actual_gas_remaining = gas_meter.gas_remaining
        gas_delta = actual_gas_remaining - expected_gas_remaining
        assert gas_delta == 0, f"Gas difference: {gas_delta}"

        call_creates = fixture.get('callcreates', [])
        assert len(computation.children) == len(call_creates)

        call_creates = fixture.get('callcreates', [])
        for child_computation, created_call in zip(computation.children,
                                                   call_creates):
            to_address = created_call['destination']
            data = created_call['data']
            gas_limit = created_call['gasLimit']
            value = created_call['value']

            assert child_computation.msg.to == to_address
            assert data == child_computation.msg.data or child_computation.msg.code
            assert gas_limit == child_computation.msg.gas
            assert value == child_computation.msg.value
        expected_account_db = fixture['post']
    else:
        #
        # Error checks
        #
        assert computation.is_error
        assert isinstance(computation._error, VMError)
        expected_account_db = fixture['pre']

    verify_state(expected_account_db, vm.state)