コード例 #1
0
ファイル: system.py プロジェクト: jacqueswww/py-evm
    def get_stack_data(self,
                       computation: BaseComputation) -> CreateOpcodeStackData:

        endowment, memory_start, memory_length, salt = computation.stack_pop(
            num_items=4,
            type_hint=constants.UINT256,
        )

        return CreateOpcodeStackData(endowment, memory_start, memory_length,
                                     salt)
コード例 #2
0
ファイル: system.py プロジェクト: cd4761/ecc-trinity
    def apply_create_message(self, computation: BaseComputation, child_msg: Message) -> None:
        child_computation = computation.apply_child_computation(child_msg)

        if child_computation.is_error:
            computation.stack_push_int(0)
        else:
            computation.stack_push_bytes(child_msg.storage_address)

        computation.return_gas(child_computation.get_gas_remaining())
コード例 #3
0
ファイル: storage.py プロジェクト: vovyl/py-evm
def sstore(computation: BaseComputation) -> None:
    slot, value = computation.stack_pop_ints(2)

    current_value = computation.state.get_storage(
        address=computation.msg.storage_address,
        slot=slot,
    )

    is_currently_empty = not bool(current_value)
    is_going_to_be_empty = not bool(value)

    if is_currently_empty:
        gas_refund = 0
    elif is_going_to_be_empty:
        gas_refund = constants.REFUND_SCLEAR
    else:
        gas_refund = 0

    if is_currently_empty and is_going_to_be_empty:
        gas_cost = constants.GAS_SRESET
    elif is_currently_empty:
        gas_cost = constants.GAS_SSET
    elif is_going_to_be_empty:
        gas_cost = constants.GAS_SRESET
    else:
        gas_cost = constants.GAS_SRESET

    computation.consume_gas(gas_cost, reason="SSTORE: {0}[{1}] -> {2} ({3})".format(
        encode_hex(computation.msg.storage_address),
        slot,
        value,
        current_value,
    ))

    if gas_refund:
        computation.refund_gas(gas_refund)

    computation.state.set_storage(
        address=computation.msg.storage_address,
        slot=slot,
        value=value,
    )
コード例 #4
0
def modexp(computation: BaseComputation) -> BaseComputation:
    """
    https://github.com/ethereum/EIPs/pull/198
    """
    data = computation.msg.data_as_bytes

    gas_fee = _compute_modexp_gas_fee(data)
    computation.consume_gas(gas_fee, reason='MODEXP Precompile')

    result = _modexp(data)

    _, _, modulus_length = _extract_lengths(data)

    # Modulo 0 is undefined, return zero
    # https://math.stackexchange.com/questions/516251/why-is-n-mod-0-undefined
    result_bytes = b'' if modulus_length == 0 else zpad_left(
        int_to_big_endian(result), to_size=modulus_length)

    computation.output = result_bytes
    return computation
コード例 #5
0
def jump(computation: BaseComputation) -> None:
    jump_dest = computation.stack_pop(type_hint=constants.UINT256)

    computation.code.pc = jump_dest

    next_opcode = computation.code.peek()

    if next_opcode != JUMPDEST:
        raise InvalidJumpDestination("Invalid Jump Destination")

    if not computation.code.is_valid_opcode(jump_dest):
        raise InvalidInstruction("Jump resulted in invalid instruction")
コード例 #6
0
ファイル: system.py プロジェクト: cd4761/ecc-trinity
def _selfdestruct(computation: BaseComputation, beneficiary: Address) -> None:
    local_balance = computation.state.get_balance(computation.msg.storage_address)
    beneficiary_balance = computation.state.get_balance(beneficiary)

    # 1st: Transfer to beneficiary
    computation.state.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.state.set_balance(computation.msg.storage_address, 0)

    computation.logger.debug2(
        "SELFDESTRUCT: %s (%s) -> %s",
        encode_hex(computation.msg.storage_address),
        local_balance,
        encode_hex(beneficiary),
    )

    # 3rd: Register the account to be deleted
    computation.register_account_for_deletion(beneficiary)
    raise Halt('SELFDESTRUCT')
コード例 #7
0
def jump(computation: BaseComputation) -> None:
    jump_dest = computation.stack_pop1_int()

    computation.code.program_counter = jump_dest

    next_opcode = computation.code.peek()

    if next_opcode != JUMPDEST:
        raise InvalidJumpDestination("Invalid Jump Destination")

    if not computation.code.is_valid_opcode(jump_dest):
        raise InvalidInstruction("Jump resulted in invalid instruction")
コード例 #8
0
ファイル: memory.py プロジェクト: cd4761/ecc-trinity
def mload(computation: BaseComputation) -> None:
    start_position = computation.stack_pop1_int()

    computation.extend_memory(start_position, 32)

    value = computation.memory_read_bytes(start_position, 32)
    computation.stack_push_bytes(value)
コード例 #9
0
def sha3(computation: BaseComputation) -> None:
    start_position, size = computation.stack_pop_ints(2)

    computation.extend_memory(start_position, size)

    sha3_bytes = computation.memory_read_bytes(start_position, size)
    word_count = ceil32(len(sha3_bytes)) // 32

    gas_cost = constants.GAS_SHA3WORD * word_count
    computation.consume_gas(gas_cost, reason="SHA3: word gas cost")

    result = keccak(sha3_bytes)

    computation.stack_push_bytes(result)
コード例 #10
0
ファイル: memory.py プロジェクト: vardan10/py-evm
def mload(computation: BaseComputation) -> None:
    start_position = computation.stack_pop(type_hint=constants.UINT256)

    computation.extend_memory(start_position, 32)

    value = computation.memory_read(start_position, 32)
    computation.stack_push(value)
コード例 #11
0
def ecpairing(computation: BaseComputation) -> BaseComputation:
    if len(computation.msg.data) % 192:
        # data length must be an exact multiple of 192
        raise VMError("Invalid ECPAIRING parameters")

    num_points = len(computation.msg.data) // 192
    gas_fee = constants.GAS_ECPAIRING_BASE + num_points * constants.GAS_ECPAIRING_PER_POINT

    computation.consume_gas(gas_fee, reason='ECPAIRING Precompile')

    try:
        result = _ecpairing(computation.msg.data)
    except ValidationError:
        raise VMError("Invalid ECPAIRING parameters")

    if result is True:
        computation.output = pad32(b'\x01')
    elif result is False:
        computation.output = pad32(b'\x00')
    else:
        raise Exception("Invariant: unreachable code path")
    return computation
コード例 #12
0
def exp(computation: BaseComputation, gas_per_byte: int) -> None:
    """
    Exponentiation
    """
    base, exponent = computation.stack_pop_ints(2)

    bit_size = exponent.bit_length()
    byte_size = ceil8(bit_size) // 8

    if exponent == 0:
        result = 1
    elif base == 0:
        result = 0
    else:
        result = pow(base, exponent, constants.UINT_256_CEILING)

    computation.consume_gas(
        gas_per_byte * byte_size,
        reason="EXP: exponent bytes",
    )

    computation.stack_push_int(result)
コード例 #13
0
ファイル: flow.py プロジェクト: cd4761/ecc-trinity
def jumpi(computation: BaseComputation) -> None:
    jump_dest, check_value = computation.stack_pop_ints(2)

    if check_value:
        computation.code.pc = jump_dest

        next_opcode = computation.code.peek()

        if next_opcode != JUMPDEST:
            raise InvalidJumpDestination("Invalid Jump Destination")

        if not computation.code.is_valid_opcode(jump_dest):
            raise InvalidInstruction("Jump resulted in invalid instruction")
コード例 #14
0
def ecrecover(computation: BaseComputation) -> BaseComputation:
    computation.consume_gas(constants.GAS_ECRECOVER,
                            reason="ECRecover Precompile")
    data = computation.msg.data_as_bytes
    raw_message_hash = data[:32]
    message_hash = pad32r(raw_message_hash)

    v_bytes = pad32r(data[32:64])
    v = big_endian_to_int(v_bytes)

    r_bytes = pad32r(data[64:96])
    r = big_endian_to_int(r_bytes)

    s_bytes = pad32r(data[96:128])
    s = big_endian_to_int(s_bytes)

    try:
        validate_lt_secpk1n(r, title="ECRecover: R")
        validate_lt_secpk1n(s, title="ECRecover: S")
        validate_lte(v, 28, title="ECRecover: V")
        validate_gte(v, 27, title="ECRecover: V")
    except ValidationError:
        return computation

    canonical_v = v - 27

    try:
        signature = keys.Signature(vrs=(canonical_v, r, s))
        public_key = signature.recover_public_key_from_msg_hash(message_hash)
    except BadSignature:
        return computation

    address = public_key.to_canonical_address()
    padded_address = pad32(address)

    computation.output = padded_address
    return computation
コード例 #15
0
ファイル: call.py プロジェクト: cd4761/ecc-trinity
    def get_call_params(self, computation: BaseComputation) -> CallParams:
        gas = computation.stack_pop1_int()
        to = force_bytes_to_address(computation.stack_pop1_bytes())

        (
            memory_input_start_position,
            memory_input_size,
            memory_output_start_position,
            memory_output_size,
        ) = computation.stack_pop_ints(4)

        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
        )
コード例 #16
0
ファイル: memory.py プロジェクト: vardan10/py-evm
def mstore(computation: BaseComputation) -> None:
    start_position = computation.stack_pop(type_hint=constants.UINT256)
    value = computation.stack_pop(type_hint=constants.BYTES)

    padded_value = value.rjust(32, b'\x00')
    normalized_value = padded_value[-32:]

    computation.extend_memory(start_position, 32)

    computation.memory_write(start_position, 32, normalized_value)
コード例 #17
0
ファイル: memory.py プロジェクト: cd4761/ecc-trinity
def mstore(computation: BaseComputation) -> None:
    start_position = computation.stack_pop1_int()
    value = computation.stack_pop1_bytes()

    padded_value = value.rjust(32, b'\x00')
    normalized_value = padded_value[-32:]

    computation.extend_memory(start_position, 32)

    computation.memory_write(start_position, 32, normalized_value)
コード例 #18
0
ファイル: system.py プロジェクト: cd4761/ecc-trinity
    def apply_create_message(self, computation: BaseComputation, child_msg: Message) -> None:
        # We need to ensure that creation operates on empty storage **and**
        # that if the initialization code fails that we revert the account back
        # to its original state root.
        snapshot = computation.state.snapshot()

        computation.state.delete_storage(child_msg.storage_address)

        child_computation = computation.apply_child_computation(child_msg)

        if child_computation.is_error:
            computation.state.revert(snapshot)
            computation.stack_push_int(0)
        else:
            computation.state.commit(snapshot)
            computation.stack_push_bytes(child_msg.storage_address)

        computation.return_gas(child_computation.get_gas_remaining())
コード例 #19
0
ファイル: state.py プロジェクト: aashutoshrathi/py-evm
    def finalize_computation(self, transaction: BaseTransaction,
                             computation: BaseComputation) -> BaseComputation:
        # Self Destruct Refunds
        num_deletions = len(computation.get_accounts_for_deletion())
        if num_deletions:
            computation.refund_gas(REFUND_SELFDESTRUCT * num_deletions)

        # Gas Refunds
        gas_remaining = computation.get_gas_remaining()
        gas_refunded = computation.get_gas_refund()
        gas_used = transaction.gas - gas_remaining
        gas_refund = min(gas_refunded, gas_used // 2)
        gas_refund_amount = (gas_refund +
                             gas_remaining) * transaction.gas_price

        if gas_refund_amount:
            self.vm_state.logger.trace(
                'TRANSACTION REFUND: %s -> %s',
                gas_refund_amount,
                encode_hex(computation.msg.sender),
            )

            self.vm_state.account_db.delta_balance(computation.msg.sender,
                                                   gas_refund_amount)

        # Miner Fees
        transaction_fee = \
            (transaction.gas - gas_remaining - gas_refund) * transaction.gas_price
        self.vm_state.logger.trace(
            'TRANSACTION FEE: %s -> %s',
            transaction_fee,
            encode_hex(self.vm_state.coinbase),
        )
        self.vm_state.account_db.delta_balance(self.vm_state.coinbase,
                                               transaction_fee)

        # Process Self Destructs
        for account, beneficiary in computation.get_accounts_for_deletion():
            # TODO: need to figure out how we prevent multiple selfdestructs from
            # the same account and if this is the right place to put this.
            self.vm_state.logger.trace('DELETING ACCOUNT: %s',
                                       encode_hex(account))

            # TODO: this balance setting is likely superflous and can be
            # removed since `delete_account` does this.
            self.vm_state.account_db.set_balance(account, 0)
            self.vm_state.account_db.delete_account(account)

        return computation
コード例 #20
0
def calldatacopy(computation: BaseComputation) -> None:
    (
        mem_start_position,
        calldata_start_position,
        size,
    ) = computation.stack_pop_ints(3)

    computation.extend_memory(mem_start_position, size)

    word_count = ceil32(size) // 32
    copy_gas_cost = word_count * constants.GAS_COPY

    computation.consume_gas(copy_gas_cost, reason="CALLDATACOPY fee")

    value = computation.msg.data_as_bytes[
        calldata_start_position:calldata_start_position + size]
    padded_value = value.ljust(size, b'\x00')

    computation.memory_write(mem_start_position, size, padded_value)
コード例 #21
0
def extcodecopy(computation: BaseComputation) -> None:
    account = force_bytes_to_address(computation.stack_pop1_bytes())
    (
        mem_start_position,
        code_start_position,
        size,
    ) = computation.stack_pop_ints(3)

    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.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)
コード例 #22
0
def codecopy(computation: BaseComputation) -> None:
    (
        mem_start_position,
        code_start_position,
        size,
    ) = computation.stack_pop_ints(3)

    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="CODECOPY: word gas cost",
    )

    with computation.code.seek(code_start_position):
        code_bytes = computation.code.read(size)

    padded_code_bytes = code_bytes.ljust(size, b'\x00')

    computation.memory_write(mem_start_position, size, padded_code_bytes)
コード例 #23
0
    def __call__(self, computation: BaseComputation) -> None:
        computation.consume_gas(
            self.gas_cost,
            reason=self.mnemonic,
        )

        (
            gas,
            value,
            to,
            sender,
            code_address,
            memory_input_start_position,
            memory_input_size,
            memory_output_start_position,
            memory_output_size,
            should_transfer_value,
            is_static,
        ) = self.get_call_params(computation)

        computation.extend_memory(memory_input_start_position,
                                  memory_input_size)
        computation.extend_memory(memory_output_start_position,
                                  memory_output_size)

        call_data = computation.memory_read(memory_input_start_position,
                                            memory_input_size)

        #
        # Message gas allocation and fees
        #
        child_msg_gas, child_msg_gas_fee = self.compute_msg_gas(
            computation, gas, to, value)
        computation.consume_gas(child_msg_gas_fee, reason=self.mnemonic)

        # Pre-call checks
        sender_balance = computation.state.account_db.get_balance(
            computation.msg.storage_address)

        insufficient_funds = should_transfer_value and sender_balance < value
        stack_too_deep = computation.msg.depth + 1 > constants.STACK_DEPTH_LIMIT

        if insufficient_funds or stack_too_deep:
            computation.return_data = b''
            if insufficient_funds:
                err_message = "Insufficient Funds: have: {0} | need: {1}".format(
                    sender_balance,
                    value,
                )
            elif stack_too_deep:
                err_message = "Stack Limit Reached"
            else:
                raise Exception("Invariant: Unreachable code path")

            self.logger.debug2(
                "%s failure: %s",
                self.mnemonic,
                err_message,
            )
            computation.return_gas(child_msg_gas)
            computation.stack_push(0)
        else:
            if code_address:
                code = computation.state.account_db.get_code(code_address)
            else:
                code = computation.state.account_db.get_code(to)

            child_msg_kwargs = {
                'gas': child_msg_gas,
                'value': value,
                'to': to,
                'data': call_data,
                'code': code,
                'code_address': code_address,
                'should_transfer_value': should_transfer_value,
                'is_static': is_static,
            }
            if sender is not None:
                child_msg_kwargs['sender'] = sender

            child_msg = computation.prepare_child_message(**child_msg_kwargs)

            child_computation = computation.apply_child_computation(child_msg)

            if child_computation.is_error:
                computation.stack_push(0)
            else:
                computation.stack_push(1)

            if not child_computation.should_erase_return_data:
                actual_output_size = min(memory_output_size,
                                         len(child_computation.output))
                computation.memory_write(
                    memory_output_start_position,
                    actual_output_size,
                    child_computation.output[:actual_output_size],
                )

            if child_computation.should_return_gas:
                computation.return_gas(child_computation.get_gas_remaining())
コード例 #24
0
def gas(computation: BaseComputation) -> None:
    gas_remaining = computation.get_gas_remaining()

    computation.stack_push_int(gas_remaining)
コード例 #25
0
def gaslimit(computation: BaseComputation) -> None:
    computation.stack_push_int(computation.state.gas_limit)
コード例 #26
0
def program_counter(computation: BaseComputation) -> None:
    pc = max(computation.code.program_counter - 1, 0)

    computation.stack_push_int(pc)
コード例 #27
0
def blockhash(computation: BaseComputation) -> None:
    block_number = computation.stack_pop1_int()

    block_hash = computation.state.get_ancestor_hash(block_number)

    computation.stack_push_bytes(block_hash)
コード例 #28
0
ファイル: EVM384.py プロジェクト: alita-moore/BLS12-381-Huff
def sub(computation: BaseComputation) -> None:
    left, right = computation.stack_pop_ints(2)

    result = (left - right) & constants.UINT_256_MAX

    computation.stack_push_int(result)
コード例 #29
0
def dup_XX(computation: BaseComputation, position: int) -> None:
    """
    Stack item duplication.
    """
    computation.stack_dup(position)
コード例 #30
0
def basefee(computation: BaseComputation) -> None:
    computation.stack_push_int(computation.state.base_fee)