def exp(evm: Evm) -> None: """ Exponential operation of the top 2 elements. Pushes the result back on the stack. Parameters ---------- evm : The current EVM frame. Raises ------ StackUnderflowError If `len(stack)` is less than `2`. """ base = Uint(pop(evm.stack)) exponent = Uint(pop(evm.stack)) gas_used = GAS_EXPONENTIATION if exponent != 0: # This is equivalent to 1 + floor(log(y, 256)). But in python the log # function is inaccurate leading to wrong results. exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + 7) // 8 gas_used += GAS_EXPONENTIATION * exponent_bytes evm.gas_left = subtract_gas(evm.gas_left, gas_used) result = U256(pow(base, exponent, U256_CEIL_VALUE)) push(evm.stack, result)
def mulmod(evm: Evm) -> None: """ Modulo multiplication of the top 2 elements with the 3rd element. Pushes the result back on the stack. Parameters ---------- evm : The current EVM frame. Raises ------ StackUnderflowError If `len(stack)` is less than `3`. OutOfGasError If `evm.gas_left` is less than `8`. """ evm.gas_left = subtract_gas(evm.gas_left, GAS_MID) x = Uint(pop(evm.stack)) y = Uint(pop(evm.stack)) z = Uint(pop(evm.stack)) if z == 0: result = U256(0) else: result = U256((x * y) % z) push(evm.stack, result)
def test_uint_to_be_bytes32_max_value() -> None: encoded = Uint(2**256 - 1).to_be_bytes32() assert encoded == bytes([ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ])
def test_uint_rpow_modulo() -> None: value = Uint.__rpow__(Uint(2), 4, 3) assert isinstance(value, int) assert value == 1
def test_uint_from_be_bytes_empty() -> None: value = Uint.from_be_bytes(b"") assert value == 0
def test_uint_rsub_too_big() -> None: with pytest.raises(ValueError): 6 - Uint(7)
def test_uint_rsub_float() -> None: value = (6.0) - Uint(5) assert not isinstance(value, int) assert value == 1.0
def test_uint_iadd() -> None: value = Uint(5) value += 4 assert isinstance(value, Uint) assert value == 9
def test_uint_iadd_float() -> None: value = Uint(5) value += 1.0 # type: ignore assert not isinstance(value, int) assert value == 6.0
def test_uint_to_be_bytes_zero() -> None: encoded = Uint(0).to_be_bytes() assert encoded == bytes([])
def test_uint_new() -> None: value = Uint(5) assert isinstance(value, int) assert isinstance(value, Uint) assert value == 5
def test_uint_ipow_modulo() -> None: value = Uint(4).__ipow__(2, 3) assert isinstance(value, Uint) assert value == 1
def test_uint_ipow_modulo_negative() -> None: with pytest.raises(ValueError): Uint(4).__ipow__(2, -3)
def test_uint_ipow_negative() -> None: value = Uint(3) with pytest.raises(ValueError): value **= -2
def test_uint_ipow() -> None: value = Uint(3) value **= 2 assert isinstance(value, Uint) assert value == 9
def test_uint_rpow_modulo_negative() -> None: with pytest.raises(ValueError): Uint.__rpow__(Uint(2), 4, -3)
def test_uint_from_be_bytes_one() -> None: value = Uint.from_be_bytes(bytes([1])) assert value == 1
def test_uint_to_be_bytes_one() -> None: encoded = Uint(1).to_be_bytes() assert encoded == bytes([1])
def test_uint_from_be_bytes_is_big_endian() -> None: value = Uint.from_be_bytes(bytes([0xAB, 0xCD])) assert value == 0xABCD
def test_uint_to_be_bytes_is_big_endian() -> None: encoded = Uint(0xABCD).to_be_bytes() assert encoded == bytes([0xAB, 0xCD])
def test_uint_add_float() -> None: value = Uint(5) + (1.0) assert not isinstance(value, int) assert value == 6.0
def test_uint_to_be_bytes32_zero() -> None: encoded = Uint(0).to_be_bytes32() assert encoded == bytes([0] * 32)
def test_uint_iadd_negative() -> None: value = Uint(5) with pytest.raises(ValueError): value += -4
def test_uint_to_be_bytes32_one() -> None: encoded = Uint(1).to_be_bytes32() assert encoded == bytes([0] * 31 + [1])
def test_uint_rsub() -> None: value = 6 - Uint(5) assert isinstance(value, Uint) assert value == 1
def test_uint_rpow() -> None: value = 3**Uint(2) assert isinstance(value, Uint) assert value == 9
def test_uint_rsub_negative() -> None: with pytest.raises(ValueError): (-4) - Uint(5)
def test_uint_add_negative() -> None: with pytest.raises(ValueError): Uint(5) + (-4)
def test_uint_sub() -> None: value = Uint(5) - 4 assert isinstance(value, Uint) assert value == 1
def test_uint_rpow_negative() -> None: with pytest.raises(ValueError): (-3)**Uint(2)