예제 #1
0
def push_n(evm: Evm, num_bytes: int) -> None:
    """
    Pushes a N-byte immediate onto the stack.

    Parameters
    ----------
    evm :
        The current EVM frame.

    num_bytes :
        The number of immediate bytes to be read from the code and pushed to
        the stack.

    Raises
    ------
    StackOverflowError
        If `len(stack)` is equals `1024`.
    OutOfGasError
        If `evm.gas_left` is less than `3`.
    """
    assert evm.pc + num_bytes < len(evm.code)
    evm.gas_left = subtract_gas(evm.gas_left, GAS_VERY_LOW)

    data_to_push = U256.from_be_bytes(evm.code[evm.pc + 1:evm.pc + num_bytes +
                                               1])
    push(evm.stack, data_to_push)

    evm.pc += num_bytes
예제 #2
0
def signextend(evm: Evm) -> None:
    """
    Sign extend operation. In other words, extend a signed number which
    fits in N bytes to 32 bytes.

    Parameters
    ----------
    evm :
        The current EVM frame.

    Raises
    ------
    StackUnderflowError
        If `len(stack)` is less than `2`.
    OutOfGasError
        If `evm.gas_left` is less than `5`.
    """
    evm.gas_left = subtract_gas(evm.gas_left, GAS_LOW)

    # byte_num would be 0-indexed when inserted to the stack.
    byte_num = pop(evm.stack)
    value = pop(evm.stack)

    if byte_num > 31:
        # Can't extend any further
        result = value
    else:
        # U256(0).to_be_bytes() gives b'' instead b'\x00'. # noqa: SC100
        value_bytes = value.to_be_bytes() or b"\x00"

        # Now among the obtained value bytes, consider only
        # N `least significant bytes`, where N is `byte_num + 1`.
        value_bytes = value_bytes[len(value_bytes) - 1 - byte_num:]
        sign_bit = value_bytes[0] >> 7
        if sign_bit == 0:
            result = U256.from_be_bytes(value_bytes)
        else:
            num_bytes_prepend = 32 - (byte_num + 1)
            result = U256.from_be_bytes(
                bytearray([0xFF] * num_bytes_prepend) + value_bytes)

    push(evm.stack, result)
예제 #3
0
def json_to_state(raw: Any) -> State:
    state = {}
    for (addr, acc_state) in raw.items():
        account = Account(
            nonce=hex2uint(acc_state.get("nonce", "0x0")),
            balance=hex2uint(acc_state.get("balance", "0x0")),
            code=hex2bytes(acc_state.get("code", "")),
            storage={},
        )

        for (k, v) in acc_state.get("storage", {}).items():
            account.storage[hex2bytes32(k)] = U256.from_be_bytes(
                hex2bytes32(v)
            )

        state[hex2address(addr)] = account

    return state
예제 #4
0
def test_u256_from_be_bytes_too_large() -> None:
    with pytest.raises(ValueError):
        U256.from_be_bytes(bytes([0xFF] * 33))
예제 #5
0
def test_u256_from_be_bytes_is_big_endian() -> None:
    value = U256.from_be_bytes(bytes([0xAB, 0xCD]))
    assert value == 0xABCD
예제 #6
0
def test_u256_from_be_bytes_one() -> None:
    value = U256.from_be_bytes(bytes([1]))
    assert value == 1
예제 #7
0
def test_u256_from_be_bytes_empty() -> None:
    value = U256.from_be_bytes(b"")
    assert value == 0