Esempio n. 1
0
 class UnsignedChainId(HashableRLP):
     fields = (
         ('directive', big_endian_int),
         (
             'stakeMsg',
             List(
                 [  # list with the following members
                     Binary.fixed_length(
                         20, allow_empty=True),  # validatorAddress
                     List([Text()] * 5,
                          True),  # description is Text of 5 elements
                     List([big_endian_int],
                          True),  # new rate is in a list
                     big_endian_int,  # min self delegation
                     big_endian_int,  # max total delegation
                     Binary.fixed_length(
                         48, allow_empty=True),  # slot key to remove
                     Binary.fixed_length(
                         48, allow_empty=True),  # slot key to add
                 ],
                 True)),  # strictly these number of elements
         ('nonce', big_endian_int),
         ('gasPrice', big_endian_int),
         ('gasLimit', big_endian_int),
         ('chainId', big_endian_int),
     )
Esempio n. 2
0
def verify_eth_getProof_inclusion(proof, root):
    trie_root = Binary.fixed_length(32, allow_empty=True)
    hash32 = Binary.fixed_length(32)

    class _Account(rlp.Serializable):
        fields = [('nonce', big_endian_int), ('balance', big_endian_int),
                  ('storage', trie_root), ('code_hash', hash32)]

    acc = _Account(proof.nonce, proof.balance, proof.storageHash,
                   proof.codeHash)
    rlp_account = rlp.encode(acc)
    trie_key = keccak(bytes.fromhex(proof.address[2:]))

    assert rlp_account == HexaryTrie.get_from_proof(
        root, trie_key, format_proof_nodes(
            proof.accountProof)), "Failed to verify account proof {}".format(
                proof.address)
    for storage_proof in proof.storageProof:
        trie_key = keccak(pad_bytes(b'\x00', 32, storage_proof.key))
        root = proof.storageHash
        if storage_proof.value == b'\x00':
            rlp_value = b''
        else:
            rlp_value = rlp.encode(storage_proof.value)
        assert rlp_value == HexaryTrie.get_from_proof(
            root, trie_key, format_proof_nodes(storage_proof.proof)
        ), "Failed to verify storage proof {}".format(storage_proof.key)
    return True
Esempio n. 3
0
 class UnsignedChainId(HashableRLP):
     fields = (
         ('directive', big_endian_int),
         (
             'stakeMsg',
             List(
                 [  # list with the following members
                     Binary.fixed_length(
                         20, allow_empty=True),  # validatorAddress
                     List([Text()] * 5,
                          True),  # description is Text of 5 elements
                     List(
                         [List([big_endian_int], True)] * 3, True
                     ),  # commission rate is made up of 3 integers in an array [ [int1], [int2], [int3] ]
                     big_endian_int,  # min self delegation
                     big_endian_int,  # max total delegation
                     CountableList(
                         Binary.fixed_length(48, allow_empty=True)
                     ),  # bls-public-keys array of unspecified length, each key of 48
                     big_endian_int,  # amount
                 ],
                 True)),  # strictly these number of elements
         ('nonce', big_endian_int),
         ('gasPrice', big_endian_int),
         ('gasLimit', big_endian_int),
         ('chainId', big_endian_int),
     )
Esempio n. 4
0
    def verify_eth_get_proof(self, proof, root):
        values = []
        trie_root = Binary.fixed_length(32, allow_empty=True)
        hash32 = Binary.fixed_length(32)

        class _Account(rlp.Serializable):
            fields = [('nonce', big_endian_int), ('balance', big_endian_int),
                      ('storage', trie_root), ('code_hash', hash32)]

        acc = _Account(proof.nonce, proof.balance, proof.storageHash,
                       proof.codeHash)
        rlp_account = rlp.encode(acc)
        trie_key = keccak(bytes.fromhex(proof.address[2:]))

        if rlp_account != HexaryTrie.get_from_proof(
                root, trie_key, self.format_proof_nodes(proof.accountProof)):
            return False

        for storage_proof in proof.storageProof:
            trie_key = keccak(pad_bytes(b'\x00', 32, storage_proof.key))
            root = proof.storageHash
            if storage_proof.value == b'\x00':
                rlp_value = b''
            else:
                rlp_value = rlp.encode(storage_proof.value)

            if rlp_value != HexaryTrie.get_from_proof(
                    root, trie_key, self.format_proof_nodes(
                        storage_proof.proof)):
                return False
            else:
                values.append(
                    {storage_proof.key.hex(): storage_proof.value.hex()})

        return True, values
Esempio n. 5
0
class Eight(rlp.Serializable):
    fields = [('f0', big_endian_int), ('f1', big_endian_int),
              ('f2', big_endian_int), ('f3', big_endian_int),
              ('f4', big_endian_int), ('f5', big_endian_int),
              ('f6', Binary.fixed_length(20)), ('f7', Binary.fixed_length(20))]

    def __init__(self, *args):
        args = normalize_args(args)
        super().__init__(*args)
    def serialize(cls, obj):
        sedes_list = List([
            big_endian_int,
            List([
                Binary.fixed_length(20),
                Binary.fixed_length(20), big_endian_int
            ])
        ])

        tx_elems = [obj.output_type, [obj.output_guard, obj.token, obj.amount]]

        tx_sedes = rlp.sedes.List(sedes_list)
        return tx_sedes.serialize(tx_elems)
Esempio n. 7
0
 class UnsignedChainId(HashableRLP):
     fields = (
         ('directive', big_endian_int),
         ('stakeMsg',
          List([
              Binary.fixed_length(20, allow_empty=True),
              Binary.fixed_length(20, allow_empty=True), big_endian_int
          ], True)),
         ('nonce', big_endian_int),
         ('gasPrice', big_endian_int),
         ('gasLimit', big_endian_int),
         ('chainId', big_endian_int),
     )
Esempio n. 8
0
class SignedTransaction(rlp.Serializable):
    fields = [
        ('nonce', big_endian_int),
        ('gasprice', big_endian_int),
        ('startgas', big_endian_int),
        ('to', Binary.fixed_length(20, allow_empty=True)),
        ('value', big_endian_int),
        ('data', binary),
        ('v', big_endian_int),
        ('r', big_endian_int),
        ('s', big_endian_int),
    ]

    def __init__(self, nonce: int, gasprice: int, startgas: int, to: bytes, value: int, data: str,
                 v: int, r: int, s: int):
        super(SignedTransaction, self).__init__(nonce, gasprice, startgas, to, value, data, v, r, s)

    def sender(self, value: str) -> None:
        self._sender = value

    def to_dict(self) -> dict:
        d = {}
        for name, _ in self.__class__._meta.fields:
            d[name] = getattr(self, name)
        return d
Esempio n. 9
0
def test_binary_fixed_lenght_of_zero():
    sedes = Binary.fixed_length(0)
    assert sedes.serialize(b'') == b''

    with pytest.raises(SerializationError):
        sedes.serialize(b'a')
    with pytest.raises(SerializationError):
        sedes.serialize(b'arst')
Esempio n. 10
0
 class BlockHeader(rlp.Serializable):
     fields = [('parent_hash', hash32), ('uncles_hash', hash32),
               ('coinbase', address), ('state_root', trie_root),
               ('transaction_root', trie_root), ('receipt_root', trie_root),
               ('bloom', uint256), ('difficulty', big_endian_int),
               ('block_number', big_endian_int),
               ('gas_limit', big_endian_int), ('gas_used', big_endian_int),
               ('timestamp', big_endian_int), ('extra_data', binary),
               ('mix_hash', binary), ('nonce', Binary(8, allow_empty=True))]
Esempio n. 11
0
class UnsignedHarmonyTxData(HashableRLP):
    fields = (
        ('nonce', big_endian_int),
        ('gasPrice', big_endian_int),
        ('gas', big_endian_int),
        ('shardID', big_endian_int),
        ('toShardID', big_endian_int),
        ('to', Binary.fixed_length(20, allow_empty=True)),
        ('value', big_endian_int),
        ('data', binary),
    )
Esempio n. 12
0
class Transaction(ExtendedRLP):
    fields = (
        ('nonce', big_endian_int),
        ('gasPrice', big_endian_int),
        ('gas', big_endian_int),
        ('to', Binary.fixed_length(20, allow_empty=True)),
        ('value', big_endian_int),
        ('data', binary),
        ('v', big_endian_int),
        ('r', big_endian_int),
        ('s', big_endian_int),
    )
Esempio n. 13
0
class Transaction(rlp.Serializable):
    fields = [
        ("nonce", big_endian_int),
        ("gas_price", big_endian_int),
        ("gas", big_endian_int),
        ("to", Binary.fixed_length(20, allow_empty=True)),
        ("value", big_endian_int),
        ("data", binary),
        ("v", big_endian_int),
        ("r", big_endian_int),
        ("s", big_endian_int),
    ]
def verify_eth_get_proof(proof, root):
    trie_root = Binary.fixed_length(32, allow_empty=True)
    hash32 = Binary.fixed_length(32)

    class _Account(rlp.Serializable):
        fields = [('nonce', big_endian_int), ('balance', big_endian_int),
                  ('storage', trie_root), ('code_hash', hash32)]

    acc = _Account(proof.nonce, proof.balance,
                   w3.toBytes(hexstr=w3.toHex(proof.storageHash)),
                   w3.toBytes(hexstr=w3.toHex(proof.codeHash)))
    rlp_account = rlp.encode(acc)
    trie_key = keccak(w3.toBytes(hexstr=proof.address))
    trie_proof = format_proof_nodes(proof.accountProof)

    leaf = HexaryTrie.get_from_proof(root, trie_key, trie_proof)

    if acc == b'':
        print("Verify that the account does not exist")
    else:
        assert rlp_account == leaf, "Failed to verify account proof {}".format(
            proof.address)
        print("Succeed to verify account proof {}".format(proof.address))
    return True
Esempio n. 15
0
class RPLTransaction(rlp.Serializable):
    fields = [
        ("nonce", big_endian_int),
        ("gas_price", big_endian_int),
        ("gas", big_endian_int),
        ("to", Binary.fixed_length(20, allow_empty=True)),
        ("value", big_endian_int),
        ("data", binary),
        ("v", big_endian_int),
        ("r", big_endian_int),
        ("s", big_endian_int),
    ]

    @staticmethod
    def new_tx(*, nonce, gas_price, gas, to, value, data, v, r, s):
        return RPLTransaction(nonce, gas_price, gas, to, value, data, v, r, s)
Esempio n. 16
0
class BlockHeader(rlp.Serializable):
    fields = [('parent_hash', hash32), ('uncles_hash', hash32),
              ('coinbase', address), ('state_root', trie_root),
              ('transaction_root', trie_root), ('receipt_root', trie_root),
              ('bloom', int256), ('difficulty', big_endian_int),
              ('block_number', big_endian_int), ('gas_limit', big_endian_int),
              ('gas_used', big_endian_int), ('timestamp', big_endian_int),
              ('extra_data', binary), ('mix_hash', binary),
              ('nonce', Binary(8, allow_empty=True))]

    @property
    def hash(self) -> Hash32:
        return keccak(rlp.encode(self))

    @property
    def mining_hash(self) -> Hash32:
        return keccak(rlp.encode(self[:-2], MiningHeader))
Esempio n. 17
0
class BlockHeader(rlp.Serializable):
    fields = [('parent_hash', hash32), ('uncles_hash', hash32),
              ('coinbase', address), ('state_root', trie_root),
              ('transaction_root', trie_root), ('receipts_root', trie_root),
              ('bloom', int256), ('difficulty', big_endian_int),
              ('block_number', big_endian_int), ('gas_limit', big_endian_int),
              ('gas_used', big_endian_int), ('timestamp', big_endian_int),
              ('extra_data', binary), ('mix_hash', binary),
              ('nonce', Binary(8, allow_empty=True))]

    def __init__(self,
                 coinbase,
                 difficulty,
                 block_number,
                 gas_limit,
                 timestamp,
                 parent_hash=ZERO_HASH32,
                 uncles_hash=EMPTY_UNCLE_HASH,
                 state_root=BLANK_ROOT_HASH,
                 transaction_root=BLANK_ROOT_HASH,
                 receipts_root=BLANK_ROOT_HASH,
                 bloom=0,
                 gas_used=0,
                 extra_data=b'',
                 mix_hash=ZERO_HASH32,
                 nonce=GENESIS_NONCE):
        super(BlockHeader, self).__init__(
            parent_hash=parent_hash,
            uncles_hash=uncles_hash,
            coinbase=coinbase,
            state_root=state_root,
            transaction_root=transaction_root,
            receipts_root=receipts_root,
            bloom=bloom,
            difficulty=difficulty,
            block_number=block_number,
            gas_limit=gas_limit,
            gas_used=gas_used,
            timestamp=timestamp,
            extra_data=extra_data,
            mix_hash=mix_hash,
            nonce=nonce,
        )
Esempio n. 18
0
#!/usr/bin/env python
from rlp.sedes import big_endian_int, binary, Binary
from rlp import Serializable
from Cryptodome.Hash import keccak


def sha3_256(x):
    return keccak.new(digest_bits=256, data=x.encode()).digest()


address = Binary.fixed_length(20, allow_empty=True)


def sha3(seed):
    return sha3_256(str(seed))


class Transaction(Serializable):
    fields = [
        ('nonce', big_endian_int),
        ('epoch', big_endian_int),
        ('txtype', big_endian_int),
        ('to', address),
        ('value', big_endian_int),
        ('maxfee', big_endian_int),
        ('tips', big_endian_int),
        ('data', binary),
    ]

    def __init__(self, nonce, epoch, txtype, to, value, maxfee, tips, data):
        super(Transaction, self).__init__(
Esempio n. 19
0
from rlp.sedes import (
    BigEndianInt,
    Binary,
)

from eth.constants import (
    COLLATION_SIZE, )

address = Binary.fixed_length(20, allow_empty=True)
collation_body = Binary.fixed_length(COLLATION_SIZE)
hash32 = Binary.fixed_length(32)
int32 = BigEndianInt(32)
int256 = BigEndianInt(256)
trie_root = Binary.fixed_length(32, allow_empty=True)
Esempio n. 20
0
    if chain_id is None:
        return transaction_dict
    else:
        return dict(transaction_dict, v=chain_id, r=0, s=0)


@curry
def fill_transaction_defaults(transaction):
    return merge(TRANSACTION_DEFAULTS, transaction)


UNSIGNED_TRANSACTION_FIELDS = (
    ('nonce', big_endian_int),
    ('gasPrice', big_endian_int),
    ('gas', big_endian_int),
    ('to', Binary.fixed_length(20, allow_empty=True)),
    ('value', big_endian_int),
    ('data', binary),
)


class Transaction(HashableRLP):
    fields = UNSIGNED_TRANSACTION_FIELDS + (
        ('v', big_endian_int),
        ('r', big_endian_int),
        ('s', big_endian_int),
    )


class UnsignedTransaction(HashableRLP):
    fields = UNSIGNED_TRANSACTION_FIELDS
Esempio n. 21
0
class BlockHeader(rlp.Serializable):
    fields = [('parent_hash', hash32), ('uncles_hash', hash32),
              ('coinbase', address), ('state_root', trie_root),
              ('transaction_root', trie_root), ('receipt_root', trie_root),
              ('bloom', int256), ('difficulty', big_endian_int),
              ('block_number', big_endian_int), ('gas_limit', big_endian_int),
              ('gas_used', big_endian_int), ('timestamp', big_endian_int),
              ('extra_data', binary), ('mix_hash', binary),
              ('nonce', Binary(8, allow_empty=True))]

    def __init__(self,
                 difficulty,
                 block_number,
                 gas_limit,
                 timestamp=None,
                 coinbase=ZERO_ADDRESS,
                 parent_hash=ZERO_HASH32,
                 uncles_hash=EMPTY_UNCLE_HASH,
                 state_root=BLANK_ROOT_HASH,
                 transaction_root=BLANK_ROOT_HASH,
                 receipt_root=BLANK_ROOT_HASH,
                 bloom=0,
                 gas_used=0,
                 extra_data=b'',
                 mix_hash=ZERO_HASH32,
                 nonce=GENESIS_NONCE):
        if timestamp is None:
            timestamp = int(time.time())
        super(BlockHeader, self).__init__(
            parent_hash=parent_hash,
            uncles_hash=uncles_hash,
            coinbase=coinbase,
            state_root=state_root,
            transaction_root=transaction_root,
            receipt_root=receipt_root,
            bloom=bloom,
            difficulty=difficulty,
            block_number=block_number,
            gas_limit=gas_limit,
            gas_used=gas_used,
            timestamp=timestamp,
            extra_data=extra_data,
            mix_hash=mix_hash,
            nonce=nonce,
        )

    @property
    def hash(self):
        return keccak(rlp.encode(self))

    @property
    def mining_hash(self):
        return keccak(
            rlp.encode(self, BlockHeader.exclude(['mix_hash', 'nonce'])))

    @property
    def hex_hash(self):
        return encode_hex(self.hash)

    @classmethod
    def from_parent(cls,
                    parent,
                    gas_limit,
                    difficulty,
                    coinbase=ZERO_ADDRESS,
                    timestamp=None,
                    nonce=None,
                    extra_data=None):
        """
        Initialize a new block header with the `parent` header as the block's
        parent hash.
        """
        if timestamp is None:
            timestamp = int(time.time())

        header_kwargs = {
            'parent_hash': parent.hash,
            'coinbase': coinbase,
            'state_root': parent.state_root,
            'gas_limit': gas_limit,
            'difficulty': difficulty,
            'block_number': parent.block_number + 1,
            'timestamp': timestamp,
        }
        if nonce is not None:
            header_kwargs['nonce'] = nonce
        if extra_data is not None:
            header_kwargs['extra_data'] = extra_data

        header = cls(**header_kwargs)
        return header
Esempio n. 22
0
class TypedTransaction(SignedTransactionMethods, SignedTransactionAPI,
                       TransactionDecoderAPI):
    rlp_type = Binary(min_length=1)  # must have at least one byte for the type
    _inner: SignedTransactionAPI

    decoders: Dict[int, Type[TransactionDecoderAPI]] = {
        ACCESS_LIST_TRANSACTION_TYPE: AccessListPayloadDecoder,
    }

    def __init__(self, type_id: int,
                 proxy_target: SignedTransactionAPI) -> None:
        self.type_id = type_id
        self._inner = proxy_target

    @classmethod
    def get_payload_codec(cls, type_id: int) -> Type[TransactionDecoderAPI]:
        if type_id in cls.decoders:
            return cls.decoders[type_id]
        elif type_id in VALID_TRANSACTION_TYPES:
            raise UnrecognizedTransactionType(type_id,
                                              "Unknown transaction type")
        else:
            raise ValidationError(
                f"Cannot build typed transaction with {hex(type_id)} >= 0x80")

    def encode(self) -> bytes:
        return self._type_byte + self._inner.encode()

    @classmethod
    def decode(cls, encoded: bytes) -> SignedTransactionAPI:
        type_id = to_int(encoded[0])
        payload = encoded[1:]

        payload_codec = cls.get_payload_codec(type_id)
        inner_transaction = payload_codec.decode(payload)
        return cls(type_id, inner_transaction)

    @classmethod
    def serialize(cls, obj: 'TypedTransaction') -> DecodedZeroOrOneLayerRLP:
        encoded = obj.encode()
        return cls.rlp_type.serialize(encoded)

    @classmethod
    def deserialize(
            cls, encoded_unchecked: DecodedZeroOrOneLayerRLP
    ) -> SignedTransactionAPI:
        # binary checks a few basics, like the length of the bytes
        encoded = cls.rlp_type.deserialize(encoded_unchecked)
        return cls.decode(encoded)

    @cached_property
    def _type_byte(self) -> bytes:
        return to_bytes(self.type_id)

    @property
    def chain_id(self) -> int:
        return self._inner.chain_id

    @property
    def nonce(self) -> int:
        return self._inner.nonce

    @property
    def gas_price(self) -> int:
        return self._inner.gas_price

    @property
    def gas(self) -> int:
        return self._inner.gas

    @property
    def to(self) -> Address:
        return self._inner.to

    @property
    def value(self) -> int:
        return self._inner.value

    @property
    def data(self) -> bytes:
        return self._inner.data

    @property
    def y_parity(self) -> int:
        return self._inner.y_parity

    @property
    def r(self) -> int:
        return self._inner.r

    @property
    def s(self) -> int:
        return self._inner.s

    @property
    def access_list(self) -> Sequence[Tuple[Address, Sequence[int]]]:
        return self._inner.access_list

    def get_sender(self) -> Address:
        return self._inner.get_sender()

    def get_message_for_signing(self) -> bytes:
        return self._inner.get_message_for_signing()

    def check_signature_validity(self) -> None:
        self._inner.check_signature_validity()

    @cached_property
    def hash(self) -> Hash32:
        return keccak(self.encode())

    def get_intrinsic_gas(self) -> int:
        return self._inner.get_intrinsic_gas()

    def copy(self, **overrides: Any) -> 'TypedTransaction':
        inner_copy = self._inner.copy(**overrides)
        return type(self)(self.type_id, inner_copy)

    def __eq__(self, other: Any) -> bool:
        if not isinstance(other, TypedTransaction):
            return False
        else:
            return self.type_id == other.type_id and self._inner == other._inner

    def make_receipt(
        self, status: bytes, gas_used: int,
        log_entries: Tuple[Tuple[bytes, Tuple[int, ...], bytes], ...]
    ) -> ReceiptAPI:

        inner_receipt = self._inner.make_receipt(status, gas_used, log_entries)

        return TypedReceipt(ACCESS_LIST_TRANSACTION_TYPE, inner_receipt)

    def __hash__(self) -> int:
        return hash((self.type_id, self._inner))
Esempio n. 23
0
class Denoms():
    def __init__(self):
        self.wei = 1
        self.babbage = 10**3
        self.lovelace = 10**6
        self.shannon = 10**9
        self.szabo = 10**12
        self.finney = 10**15
        self.ether = 10**18
        self.turing = 2**256


denoms = Denoms()

address = Binary.fixed_length(20, allow_empty=True)
int20 = BigEndianInt(20)
int32 = BigEndianInt(32)
int256 = BigEndianInt(256)
hash32 = Binary.fixed_length(32)
trie_root = Binary.fixed_length(32, allow_empty=True)


class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKGREEN = '\033[92m'
    WARNING = '\033[91m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
Esempio n. 24
0
class BlockHeader(rlp.Serializable, BlockHeaderAPI):
    fields = [('parent_hash', hash32), ('uncles_hash', hash32),
              ('coinbase', address), ('state_root', trie_root),
              ('transaction_root', trie_root), ('receipt_root', trie_root),
              ('bloom', uint256), ('difficulty', big_endian_int),
              ('block_number', big_endian_int), ('gas_limit', big_endian_int),
              ('gas_used', big_endian_int), ('timestamp', big_endian_int),
              ('extra_data', binary), ('mix_hash', binary),
              ('nonce', Binary(8, allow_empty=True))]

    @overload
    def __init__(self, **kwargs: HeaderParams) -> None:
        ...

    @overload  # noqa: F811
    def __init__(self,
                 difficulty: int,
                 block_number: BlockNumber,
                 gas_limit: int,
                 timestamp: int = None,
                 coinbase: Address = ZERO_ADDRESS,
                 parent_hash: Hash32 = ZERO_HASH32,
                 uncles_hash: Hash32 = EMPTY_UNCLE_HASH,
                 state_root: Hash32 = BLANK_ROOT_HASH,
                 transaction_root: Hash32 = BLANK_ROOT_HASH,
                 receipt_root: Hash32 = BLANK_ROOT_HASH,
                 bloom: int = 0,
                 gas_used: int = 0,
                 extra_data: bytes = b'',
                 mix_hash: Hash32 = ZERO_HASH32,
                 nonce: bytes = GENESIS_NONCE) -> None:
        ...

    def __init__(
            self,  # type: ignore  # noqa: F811
            difficulty: int,
            block_number: BlockNumber,
            gas_limit: int,
            timestamp: int = None,
            coinbase: Address = ZERO_ADDRESS,
            parent_hash: Hash32 = ZERO_HASH32,
            uncles_hash: Hash32 = EMPTY_UNCLE_HASH,
            state_root: Hash32 = BLANK_ROOT_HASH,
            transaction_root: Hash32 = BLANK_ROOT_HASH,
            receipt_root: Hash32 = BLANK_ROOT_HASH,
            bloom: int = 0,
            gas_used: int = 0,
            extra_data: bytes = b'',
            mix_hash: Hash32 = ZERO_HASH32,
            nonce: bytes = GENESIS_NONCE) -> None:
        if timestamp is None:
            timestamp = int(time.time())
        super().__init__(
            parent_hash=parent_hash,
            uncles_hash=uncles_hash,
            coinbase=coinbase,
            state_root=state_root,
            transaction_root=transaction_root,
            receipt_root=receipt_root,
            bloom=bloom,
            difficulty=difficulty,
            block_number=block_number,
            gas_limit=gas_limit,
            gas_used=gas_used,
            timestamp=timestamp,
            extra_data=extra_data,
            mix_hash=mix_hash,
            nonce=nonce,
        )

    def __str__(self) -> str:
        return f'<BlockHeader #{self.block_number} {encode_hex(self.hash)[2:10]}>'

    _hash = None

    @property
    def hash(self) -> Hash32:
        if self._hash is None:
            self._hash = keccak(rlp.encode(self))
        return self._hash

    @property
    def mining_hash(self) -> Hash32:
        return keccak(rlp.encode(self[:-2], MiningHeader))

    @property
    def hex_hash(self) -> str:
        return encode_hex(self.hash)

    @classmethod
    def from_parent(cls,
                    parent: BlockHeaderAPI,
                    gas_limit: int,
                    difficulty: int,
                    timestamp: int,
                    coinbase: Address = ZERO_ADDRESS,
                    nonce: bytes = None,
                    extra_data: bytes = None,
                    transaction_root: bytes = None,
                    receipt_root: bytes = None) -> 'BlockHeader':
        """
        Initialize a new block header with the `parent` header as the block's
        parent hash.
        """
        header_kwargs: Dict[str, HeaderParams] = {
            'parent_hash': parent.hash,
            'coinbase': coinbase,
            'state_root': parent.state_root,
            'gas_limit': gas_limit,
            'difficulty': difficulty,
            'block_number': parent.block_number + 1,
            'timestamp': timestamp,
        }
        if nonce is not None:
            header_kwargs['nonce'] = nonce
        if extra_data is not None:
            header_kwargs['extra_data'] = extra_data
        if transaction_root is not None:
            header_kwargs['transaction_root'] = transaction_root
        if receipt_root is not None:
            header_kwargs['receipt_root'] = receipt_root

        header = cls(**header_kwargs)
        return header

    @property
    def is_genesis(self) -> bool:
        # if removing the block_number == 0 test, consider the validation consequences.
        # validate_header stops trying to check the current header against a parent header.
        # Can someone trick us into following a high difficulty header with genesis parent hash?
        return self.parent_hash == GENESIS_PARENT_HASH and self.block_number == 0
Esempio n. 25
0
from rlp.sedes import (
    BigEndianInt,
    Binary,
)

hash32 = Binary.fixed_length(32)
uint64 = BigEndianInt(64)
Esempio n. 26
0
# Copyright (c) 2015 Heiko Hees
from utils import big_endian_to_int, sha3, isaddress, ishash, int_to_big_endian, pex
import rlp
from rlp.sedes import Binary

from rlp.sedes import big_endian_int as t_int
from rlp.sedes import binary as t_binary
from rlp.sedes import List as t_list

t_address = Binary.fixed_length(20, allow_empty=False)
t_hash = Binary.fixed_length(32, allow_empty=False)
t_hash_optional = Binary.fixed_length(32, allow_empty=True)


class RLPHashable(rlp.Serializable):
    rlp_ = None

    @property
    def hash(self):
        return sha3(getattr(self, 'rlp_', None) or rlp.encode(self))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.hash == other.hash

    def __hash__(self):
        return big_endian_to_int(self.hash)

    def __ne__(self, other):
        return not self.__eq__(other)

    def __repr__(self):
Esempio n. 27
0
class Log(rlp.Serializable):
    fields = [
        ('address', Binary.fixed_length(20, allow_empty=True)),
        ('topics', CountableList(BigEndianInt(32))),
        ('data', Binary())
    ]
        return hash((
            self.signature,
            self.sequence_number,
            tuple(self.items()),
        ))

    def __repr__(self) -> str:
        base64_rlp = base64.urlsafe_b64encode(rlp.encode(self))
        unpadded_base64_rlp = base64_rlp.rstrip(b"=")
        return "".join((
            ENR_REPR_PREFIX,
            unpadded_base64_rlp.decode("ASCII"),
        ))


IDENTITY_SCHEME_ENR_KEY = b"id"

ENR_KEY_SEDES_MAPPING = {
    b"id": binary,
    b"secp256k1": Binary.fixed_length(33),
    b"ip": Binary.fixed_length(IP_V4_SIZE),
    b"tcp": big_endian_int,
    b"udp": big_endian_int,
    b"ip6": Binary.fixed_length(IP_V6_SIZE),
    b"tcp6": big_endian_int,
    b"udp6": big_endian_int,
}

# Must use raw for values with an unknown key as they may be lists or individual values.
FALLBACK_ENR_VALUE_SEDES = raw
Esempio n. 29
0
from p2p.discv5.constants import (
    TOPIC_HASH_SIZE,
    IP_V4_SIZE,
    IP_V6_SIZE,
)

# https://github.com/python/mypy/issues/5264#issuecomment-399407428
if TYPE_CHECKING:
    MessageTypeRegistryBaseType = UserDict[int, Type["BaseMessage"]]
else:
    MessageTypeRegistryBaseType = UserDict

#
# Custom sedes objects
#
topic_sedes = Binary.fixed_length(TOPIC_HASH_SIZE)


class IPAddressSedes(Binary):
    def __init__(self) -> None:
        super().__init__()

    def is_valid_length(self, length: int) -> bool:
        return length in (IP_V4_SIZE, IP_V6_SIZE)


ip_address_sedes = IPAddressSedes()


class MessageTypeRegistry(MessageTypeRegistryBaseType):
    def register(
Esempio n. 30
0
def is_bitcoin_available():
    try:
        import bitcoin  # noqa
    except ImportError:
        return False
    else:
        return True


# in the yellow paper it is specified that s should be smaller than secpk1n (eq.205)
secpk1n = 115792089237316195423570985008687907852837564279074904382605163141518161494337
TT256 = 2 ** 256


address_sedes = Binary.fixed_length(20, allow_empty=True)


class Transaction(rlp.Serializable):
    """
    # Derived from `pyethereum.transaction.Transaction`

    A transaction is stored as:
    [nonce, gasprice, startgas, to, value, data, v, r, s]

    nonce is the number of transactions already sent by that account, encoded
    in binary form (eg.  0 -> '', 7 -> '\x07', 1000 -> '\x03\xd8').

    (v,r,s) is the raw Electrum-style signature of the transaction without the
    signature made with the private key corresponding to the sending account,
    with 0 <= v <= 3. From an Electrum-style signature (65 bytes) it is
Esempio n. 31
0
class BlockHeader(rlp.Serializable):
    fields = [('parent_hash', hash32), ('uncles_hash', hash32),
              ('coinbase', address), ('state_root', trie_root),
              ('transaction_root', trie_root), ('receipt_root', trie_root),
              ('bloom', int256), ('difficulty', big_endian_int),
              ('block_number', big_endian_int), ('gas_limit', big_endian_int),
              ('gas_used', big_endian_int), ('timestamp', big_endian_int),
              ('extra_data', binary), ('mix_hash', binary),
              ('nonce', Binary(8, allow_empty=True))]

    @overload
    def __init__(self, **kwargs: HeaderParams) -> None:
        ...

    @overload  # noqa: F811
    def __init__(self,
                 difficulty: int,
                 block_number: int,
                 gas_limit: int,
                 timestamp: int = None,
                 coinbase: Address = ZERO_ADDRESS,
                 parent_hash: Hash32 = ZERO_HASH32,
                 uncles_hash: Hash32 = EMPTY_UNCLE_HASH,
                 state_root: Hash32 = BLANK_ROOT_HASH,
                 transaction_root: Hash32 = BLANK_ROOT_HASH,
                 receipt_root: Hash32 = BLANK_ROOT_HASH,
                 bloom: int = 0,
                 gas_used: int = 0,
                 extra_data: bytes = b'',
                 mix_hash: Hash32 = ZERO_HASH32,
                 nonce: bytes = GENESIS_NONCE) -> None:
        ...

    def __init__(
            self,  # noqa: F811
            difficulty,
            block_number,
            gas_limit,
            timestamp=None,
            coinbase=ZERO_ADDRESS,
            parent_hash=ZERO_HASH32,
            uncles_hash=EMPTY_UNCLE_HASH,
            state_root=BLANK_ROOT_HASH,
            transaction_root=BLANK_ROOT_HASH,
            receipt_root=BLANK_ROOT_HASH,
            bloom=0,
            gas_used=0,
            extra_data=b'',
            mix_hash=ZERO_HASH32,
            nonce=GENESIS_NONCE):
        if timestamp is None:
            timestamp = int(time.time())
        super(BlockHeader, self).__init__(
            parent_hash=parent_hash,
            uncles_hash=uncles_hash,
            coinbase=coinbase,
            state_root=state_root,
            transaction_root=transaction_root,
            receipt_root=receipt_root,
            bloom=bloom,
            difficulty=difficulty,
            block_number=block_number,
            gas_limit=gas_limit,
            gas_used=gas_used,
            timestamp=timestamp,
            extra_data=extra_data,
            mix_hash=mix_hash,
            nonce=nonce,
        )

    def __repr__(self) -> str:
        return '<BlockHeader #{0} {1}>'.format(
            self.block_number,
            encode_hex(self.hash)[2:10],
        )

    _hash = None

    @property
    def hash(self) -> Hash32:
        if self._hash is None:
            self._hash = keccak(rlp.encode(self))
        return self._hash

    @property
    def mining_hash(self) -> Hash32:
        return keccak(rlp.encode(self[:-2], MiningHeader))

    @property
    def hex_hash(self):
        return encode_hex(self.hash)

    @classmethod
    def from_parent(cls,
                    parent: 'BlockHeader',
                    gas_limit: int,
                    difficulty: int,
                    timestamp: int,
                    coinbase: Address = ZERO_ADDRESS,
                    nonce: bytes = None,
                    extra_data: bytes = None,
                    transaction_root: bytes = None,
                    receipt_root: bytes = None) -> 'BlockHeader':
        """
        Initialize a new block header with the `parent` header as the block's
        parent hash.
        """
        header_kwargs = {
            'parent_hash': parent.hash,
            'coinbase': coinbase,
            'state_root': parent.state_root,
            'gas_limit': gas_limit,
            'difficulty': difficulty,
            'block_number': parent.block_number + 1,
            'timestamp': timestamp,
        }
        if nonce is not None:
            header_kwargs['nonce'] = nonce
        if extra_data is not None:
            header_kwargs['extra_data'] = extra_data
        if transaction_root is not None:
            header_kwargs['transaction_root'] = transaction_root
        if receipt_root is not None:
            header_kwargs['receipt_root'] = receipt_root

        header = cls(**header_kwargs)
        return header

    def create_execution_context(
        self, prev_hashes: Union[Tuple[bytes],
                                 Tuple[bytes, bytes]]) -> ExecutionContext:

        return ExecutionContext(
            coinbase=self.coinbase,
            timestamp=self.timestamp,
            block_number=self.block_number,
            difficulty=self.difficulty,
            gas_limit=self.gas_limit,
            prev_hashes=prev_hashes,
        )
Esempio n. 32
0
 def has_sig(self):
     if Binary.is_valid_type(self.signature) and sig65.is_valid_length(
             len(self.signature)):
         return True
     else:
         return False
Esempio n. 33
0
from rlp.sedes import (
    BigEndianInt,
    Binary,
)


address = Binary.fixed_length(20, allow_empty=True)
hash32 = Binary.fixed_length(32)
int32 = BigEndianInt(32)
int256 = BigEndianInt(256)
trie_root = Binary.fixed_length(32, allow_empty=True)
Esempio n. 34
0
def test_binary():
    b1 = Binary()
    f = {
        '': b'',
        'asdf': b'asdf',
        ('\x00' * 20): (b'\x00' * 20),
        'fdsa': b'fdsa'
    }
    for k in f:
        assert b1.serialize(k) == f[k]
    for d in ([], 5, str):
        with pytest.raises(SerializationError):
            b1.serialize(d)

    b2 = Binary.fixed_length(5)
    f = {
        'asdfg': b'asdfg',
        b'\x00\x01\x02\x03\x04': b'\x00\x01\x02\x03\x04',
        utils.str_to_bytes('ababa'): b'ababa'
    }
    for k in f:
        assert b2.serialize(k) == f[k]

    for d in ('asdf', 'asdfgh', '', 'bababa'):
        with pytest.raises(SerializationError):
            b2.serialize(d)

    b3 = Binary(2, 4)
    f = {
        'as': b'as',
        'dfg': b'dfg',
        'hjkl': b'hjkl',
        b'\x00\x01\x02': b'\x00\x01\x02'
    }
    for k in f:
        assert b3.serialize(k) == f[k]
    for d in ('', 'a', 'abcde', 'äää'):
        with pytest.raises(SerializationError):
            b3.serialize(d)

    b4 = Binary(min_length=3)
    f = {'abc': b'abc', 'abcd': b'abcd', ('x' * 132): (b'x' * 132)}
    for k in f:
        assert b4.serialize(k) == f[k]
    for d in ('ab', '', 'a', 'xy'):
        with pytest.raises(SerializationError):
            b4.serialize(d)

    b5 = Binary(max_length=3)
    f = {'': b'', 'ab': b'ab', 'abc': b'abc'}
    for k in f:
        assert b5.serialize(k) == f[k]
    for d in ('abcd', 'vwxyz', 'a' * 32):
        with pytest.raises(SerializationError):
            b5.serialize(d)

    b6 = Binary(min_length=3, max_length=5, allow_empty=True)
    f = {'': b'', 'abc': b'abc', 'abcd': b'abcd', 'abcde': b'abcde'}
    for k in f:
        assert b6.serialize(k) == f[k]
    for d in ('a', 'ab', 'abcdef', 'abcdefgh' * 10):
        with pytest.raises(SerializationError):
            b6.serialize(d)