Ejemplo n.º 1
0
def ecpairing(
        computation: BaseComputation,
        gas_cost_base: int = constants.GAS_ECPAIRING_BASE,
        gas_cost_per_point: int = constants.GAS_ECPAIRING_PER_POINT) -> 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 = gas_cost_base + num_points * gas_cost_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
Ejemplo n.º 2
0
def ecadd(computation: BaseComputation) -> BaseComputation:
    computation.consume_gas(constants.GAS_ECADD, reason='ECADD Precompile')

    try:
        result = _ecadd(computation.msg.data_as_bytes)
    except ValidationError:
        raise VMError("Invalid ECADD parameters")

    result_x, result_y = result
    result_bytes = b''.join((
        pad32(int_to_big_endian(result_x.n)),
        pad32(int_to_big_endian(result_y.n)),
    ))
    computation.output = result_bytes
    return computation
Ejemplo n.º 3
0
def test_sar(vm_class, val1, val2, expected):
    computation = run_general_computation(vm_class)
    computation.stack_push_bytes(decode_hex(val1))
    computation.stack_push_bytes(decode_hex(val2))
    computation.opcodes[opcode_values.SAR](computation)

    result = computation.stack_pop1_int()
    assert encode_hex(pad32(int_to_big_endian(result))) == expected
Ejemplo n.º 4
0
def test_extcodehash(vm_class, address, expected):
    computation = prepare_general_computation(vm_class)

    computation.stack_push(decode_hex(address))
    computation.opcodes[opcode_values.EXTCODEHASH](computation)

    result = computation.stack_pop(type_hint=constants.BYTES)
    assert encode_hex(pad32(result)) == expected
Ejemplo n.º 5
0
def test_sar(vm_class, val1, val2, expected):
    computation = prepare_general_computation(vm_class)
    computation.stack_push(decode_hex(val1))
    computation.stack_push(decode_hex(val2))
    computation.opcodes[opcode_values.SAR](computation)

    result = computation.stack_pop(type_hint=constants.UINT256)
    assert encode_hex(pad32(int_to_big_endian(result))) == expected
Ejemplo n.º 6
0
def test_extcodehash(vm_class, address, expected):
    computation = run_general_computation(vm_class)

    computation.stack_push_bytes(decode_hex(address))
    computation.opcodes[opcode_values.EXTCODEHASH](computation)

    result = computation.stack_pop1_bytes()
    assert encode_hex(pad32(result)) == expected
Ejemplo n.º 7
0
    async def getStorageAt(self, address: Address, position: int, at_block: Union[str, int]) -> str:
        if not is_integer(position) or position < 0:
            raise TypeError("Position of storage must be a whole number, but was: %r" % position)

        state = await state_at_block(self.chain, at_block)
        stored_val = state.get_storage(address, position)

        return encode_hex(pad32(int_to_big_endian(stored_val)))
Ejemplo n.º 8
0
def new_get_storage(self, address: Address, slot: int, from_journal: bool=True) -> int:
        account = self._get_account(address, from_journal)
        storage = HashTrie(HexaryTrie(self._journaldb, account.storage_root))

        slot_as_key = pad32(int_to_big_endian(slot))

        encoded_value = storage[slot_as_key]
        if not encoded_value:
            return 0
        return rlp.decode(encoded_value, sedes=rlp.sedes.big_endian_int)
Ejemplo n.º 9
0
def ripemd160(computation: BaseComputation) -> BaseComputation:
    word_count = ceil32(len(computation.msg.data)) // 32
    gas_fee = constants.GAS_RIPEMD160 + word_count * constants.GAS_RIPEMD160WORD

    computation.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
Ejemplo n.º 10
0
    def get_storage(self, address: Address, slot: int, from_journal: bool=True) -> int:
        validate_canonical_address(address, title="Storage Address")
        validate_uint256(slot, title="Storage Slot")

        account = self._get_account(address, from_journal)
        storage = HashTrie(HexaryTrie(self._journaldb, account.storage_root))

        slot_as_key = pad32(int_to_big_endian(slot))

        if slot_as_key in storage:
            encoded_value = storage[slot_as_key]
            return rlp.decode(encoded_value, sedes=rlp.sedes.big_endian_int)
        else:
            return 0
Ejemplo n.º 11
0
    def set_storage(self, address: Address, slot: int, value: int) -> None:
        validate_uint256(value, title="Storage Value")
        validate_uint256(slot, title="Storage Slot")
        validate_canonical_address(address, title="Storage Address")

        account = self._get_account(address)
        storage = HashTrie(HexaryTrie(self._journaldb, account.storage_root))

        slot_as_key = pad32(int_to_big_endian(slot))

        if value:
            encoded_value = rlp.encode(value)
            storage[slot_as_key] = encoded_value
        else:
            del storage[slot_as_key]

        self._set_account(address, account.copy(storage_root=storage.root_hash))
Ejemplo n.º 12
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
Ejemplo n.º 13
0
def generate_random_keypair() -> Tuple[bytes, Address]:
    key_object = keys.PrivateKey(
        pad32(int_to_big_endian(random.getrandbits(8 * 32))))
    return key_object.to_bytes(), Address(
        key_object.public_key.to_canonical_address())
Ejemplo n.º 14
0
def pad32_dict_values(some_dict):
    return {
        key: encode_hex(pad32(decode_hex(value)))
        for key, value in some_dict.items()
    }
Ejemplo n.º 15
0
def generate_random_keypair_and_address(
) -> Tuple[PrivateKey, PublicKey, Address]:
    priv_key = keys.PrivateKey(
        pad32(int_to_big_endian(random.getrandbits(8 * 32))))
    return priv_key, priv_key.public_key, Address(
        priv_key.public_key.to_canonical_address())
Ejemplo n.º 16
0
 def _decode_key(self, key: bytes) -> bytes:
     padded_slot = pad32(key)
     return keccak(padded_slot)
Ejemplo n.º 17
0
def generate_privkey() -> datatypes.PrivateKey:
    """Generate a new SECP256K1 private key and return it"""
    privkey = ec.generate_private_key(CURVE, default_backend())
    return keys.PrivateKey(
        pad32(int_to_big_endian(privkey.private_numbers().private_value)))
Ejemplo n.º 18
0
def test_pad_32(value, expected):
    assert pad32(value) == expected