예제 #1
0
def test_format_dict_error():
    with pytest.raises(ValueError) as exc_info:
        apply_formatters_to_dict(
            {'myfield': int},
            {'myfield': 'a'},
        )
    assert 'myfield' in str(exc_info.value)
예제 #2
0
def assert_valid_fields(transaction_dict):
    # check if any keys are missing
    missing_keys = REQUIRED_TRANSACITON_KEYS.difference(
        transaction_dict.keys())
    if missing_keys:
        raise TypeError("Transaction must include these fields: %r" %
                        missing_keys)

    # check if any extra keys were specified
    superfluous_keys = set(
        transaction_dict.keys()).difference(ALLOWED_TRANSACTION_KEYS)
    if superfluous_keys:
        raise TypeError(
            "Transaction must not include unrecognized fields: %r" %
            superfluous_keys)

    # check for valid types in each field
    valid_fields = apply_formatters_to_dict(TRANSACTION_VALID_VALUES,
                                            transaction_dict)
    if not all(valid_fields.values()):
        invalid = {
            key: transaction_dict[key]
            for key, valid in valid_fields.items() if not valid
        }
        raise TypeError("Transaction had invalid fields: %r" % invalid)
예제 #3
0
    def normalizer(d: Dict[Any, Any]) -> Dict[str, Any]:
        keys = set(d.keys())
        missing_keys = required_set_form - keys
        superfluous_keys = keys - all_keys
        if missing_keys:
            raise KeyError(f"Missing required keys: {', '.join(missing_keys)}")
        if superfluous_keys:
            raise KeyError(f"Superfluous keys: {', '.join(superfluous_keys)}")

        return apply_formatters_to_dict(formatters, d)
예제 #4
0
def transaction_param_validator(web3):
    transactions_params_validators = {
        'chainId':
        apply_formatter_if(
            # Bypass `validate_chain_id` if chainId can't be determined
            lambda _: is_not_null(web3.net.chainId),
            validate_chain_id(web3)),
    }
    return apply_formatter_at_index(
        apply_formatters_to_dict(transactions_params_validators), 0)
예제 #5
0
def _transaction_param_validator(web3_chain_id: int) -> Callable[..., Any]:
    transactions_params_validators = {
        "chainId":
        apply_formatter_if(
            # Bypass `validate_chain_id` if chainId can't be determined
            lambda _: is_not_null(web3_chain_id),
            _validate_chain_id(web3_chain_id),
        ),
    }
    return apply_formatter_at_index(
        apply_formatters_to_dict(transactions_params_validators), 0)
예제 #6
0
def transaction_param_validator(web3: "Web3") -> Callable[..., Any]:
    transactions_params_validators = {
        # type ignored b/c apply_formatter_if requires more args, but is_not_null is curried
        "chainId":
        apply_formatter_if(  # type: ignore
            # Bypass `validate_chain_id` if chainId can't be determined
            lambda _: is_not_null(web3.eth.chainId),
            validate_chain_id(web3),
        ),
    }
    return apply_formatter_at_index(
        apply_formatters_to_dict(transactions_params_validators), 0)
예제 #7
0
def serializable_unsigned_transaction_from_dict(transaction_dict):
    assert_valid_fields(transaction_dict)
    filled_transaction = pipe(
        transaction_dict,
        dict,
        partial(merge, TRANSACTION_DEFAULTS),
        chain_id_to_v,
        apply_formatters_to_dict(TRANSACTION_FORMATTERS),
    )
    if 'v' in filled_transaction:
        serializer = Transaction
    else:
        serializer = UnsignedTransaction
    return serializer.from_dict(filled_transaction)
예제 #8
0
def validation_middleware(make_request, web3):
    transaction_validator = apply_formatters_to_dict({
        'chainId': validate_chain_id(web3),
    })

    transaction_sanitizer = compose(transaction_normalizer, transaction_validator)

    def middleware(method, params):
        if method in ('eth_sendTransaction', 'eth_estimateGas', 'eth_call'):
            post_validated_params = apply_formatter_at_index(transaction_sanitizer, 0, params)
            return make_request(method, post_validated_params)
        else:
            return make_request(method, params)
    return middleware
예제 #9
0
def serializable_unsigned_transaction_from_dict(web3, transaction_dict):
    '''
    if web3 is None, fill out transaction as much as possible without calling client
    '''
    filled_transaction = pipe(
        transaction_dict,
        dict,
        partial(merge, TRANSACTION_DEFAULTS),
        chain_id_to_v,
        apply_formatters_to_dict(TRANSACTION_FORMATTERS),
    )
    if 'v' in filled_transaction:
        serializer = Transaction
    else:
        serializer = UnsignedTransaction
    return serializer.from_dict(filled_transaction)
예제 #10
0
    def assert_valid_fields(cls, dictionary: Dict[str, Any]):
        transaction_valid_values = merge(LEGACY_TRANSACTION_VALID_VALUES, {
            'type': is_int_or_prefixed_hexstr,
            'accessList': is_rpc_structured_access_list,
        })

        if 'v' in dictionary and dictionary['v'] == 0:
            # This is insane logic that is required because the way we evaluate
            # correct types is in the `if not all()` branch below, and 0 obviously
            # maps to the int(0), which maps to False... This was not an issue in non-typed
            # transaction because v=0, couldn't exist with the chain offset.
            dictionary['v'] = '0x0'
        valid_fields = apply_formatters_to_dict(
            transaction_valid_values, dictionary,
        )  # type: Dict[str, Any]
        if not all(valid_fields.values()):
            invalid = {key: dictionary[key] for key, valid in valid_fields.items() if not valid}
            raise TypeError("Transaction had invalid fields: %r" % invalid)
예제 #11
0
def serializable_unsigned_transaction_from_dict(transaction_dict):
    transaction_dict = set_transaction_type_if_needed(transaction_dict)
    if 'type' in transaction_dict:
        # We delegate to TypedTransaction, which will carry out validation & formatting.
        return TypedTransaction.from_dict(transaction_dict)

    assert_valid_fields(transaction_dict)
    filled_transaction = pipe(
        transaction_dict,
        dict,
        partial(merge, TRANSACTION_DEFAULTS),
        chain_id_to_v,
        apply_formatters_to_dict(LEGACY_TRANSACTION_FORMATTERS),
    )
    if 'v' in filled_transaction:
        serializer = Transaction
    else:
        serializer = UnsignedTransaction
    return serializer.from_dict(filled_transaction)
예제 #12
0
    def from_dict(cls, dictionary: Dict[str, Any]):
        """
        Builds a DynamicFeeTransaction from a dictionary.
        Verifies that the dictionary is well formed.
        """
        # Validate fields.
        cls.assert_valid_fields(dictionary)
        sanitized_dictionary = pipe(
            dictionary,
            dict,
            partial(merge, cls.transaction_field_defaults),
            apply_formatters_to_dict(TYPED_TRANSACTION_FORMATTERS),
        )

        # We have verified the type, we can safely remove it from the dictionary,
        # given that it is not to be included within the RLP payload.
        transaction_type = sanitized_dictionary.pop('type')
        if transaction_type != cls.transaction_type:
            raise ValueError(
                "expected transaction type %s, got %s" % (cls.transaction_type, transaction_type),
            )
        return cls(
            dictionary=sanitized_dictionary,
        )
예제 #13
0
    apply_formatters_to_dict,
    apply_key_map,
)
from hexbytes import (
    HexBytes,
)

from web3._utils.toolz import (
    compose,
)
from web3.middleware.formatting import (
    construct_formatting_middleware,
)

remap_geth_poa_fields = apply_key_map({
    'extraData': 'proofOfAuthorityData',
})

pythonic_geth_poa = apply_formatters_to_dict({
    'proofOfAuthorityData': HexBytes,
})

geth_poa_cleanup = compose(pythonic_geth_poa, remap_geth_poa_fields)

geth_poa_middleware = construct_formatting_middleware(
    result_formatters={
        'eth_getBlockByHash': geth_poa_cleanup,
        'eth_getBlockByNumber': geth_poa_cleanup,
    },
)
예제 #14
0
            lambda _: is_not_null(web3.eth.chainId),
            validate_chain_id(web3),
        ),
    }
    return apply_formatter_at_index(
        apply_formatters_to_dict(transactions_params_validators), 0)


BLOCK_VALIDATORS = {
    'extraData': check_extradata_length,
}

# types ignored b/c same reason as line 79
block_validator = apply_formatter_if(  # type: ignore
    is_not_null,
    apply_formatters_to_dict(BLOCK_VALIDATORS)  # type: ignore
)


@curry
def chain_id_validator(web3: "Web3") -> Callable[..., Any]:
    return compose(apply_formatter_at_index(transaction_normalizer, 0),
                   transaction_param_validator(web3))


def build_validators_with_web3(w3: "Web3") -> FormattersDict:
    return dict(
        request_formatters={
            'eth_sendTransaction': chain_id_validator(w3),
            'eth_estimateGas': chain_id_validator(w3),
            'eth_call': chain_id_validator(w3),
예제 #15
0
    LEGACY_TRANSACTION_FORMATTERS,
    LEGACY_TRANSACTION_VALID_VALUES,
    is_int_or_prefixed_hexstr,
    is_rpc_structured_access_list,
)

TYPED_TRANSACTION_FORMATTERS = merge(
    LEGACY_TRANSACTION_FORMATTERS, {
        'chainId': hexstr_if_str(to_int),
        'type': hexstr_if_str(to_int),
        'accessList': apply_formatter_to_array(
            apply_formatters_to_dict(
                {
                    "address": apply_one_of_formatters((
                        (is_string, hexstr_if_str(to_bytes)),
                        (is_bytes, identity),
                    )),
                    "storageKeys": apply_formatter_to_array(hexstr_if_str(to_int))
                }
            ),
        ),
        'maxPriorityFeePerGas': hexstr_if_str(to_int),
        'maxFeePerGas': hexstr_if_str(to_int),
    },
)

# Define typed transaction common sedes.
# [[{20 bytes}, [{32 bytes}...]]...], where ... means “zero or more of the thing to the left”.
access_list_sede_type = CountableList(
    List([
        Binary.fixed_length(20, allow_empty=False),
예제 #16
0
        ),
    }
    return apply_formatter_at_index(
        apply_formatters_to_dict(transactions_params_validators),
        0
    )


BLOCK_VALIDATORS = {
    'extraData': check_extradata_length,
}


block_validator = apply_formatter_if(
    is_not_null,
    apply_formatters_to_dict(BLOCK_VALIDATORS)
)


@curry
def chain_id_validator(web3):
    return compose(
        apply_formatter_at_index(transaction_normalizer, 0),
        transaction_param_validator(web3)
    )


def build_validators_with_web3(w3):
    return dict(
        request_formatters={
            'eth_sendTransaction': chain_id_validator(w3),
예제 #17
0
}
transaction_request_remapper = apply_key_map(TRANSACTION_REQUEST_KEY_MAPPING)


TRANSACTION_REQUEST_FORMATTERS = {
    'gas': to_integer_if_hex,
    'gasPrice': to_integer_if_hex,
    'value': to_integer_if_hex,
    'nonce': to_integer_if_hex,
    'maxFeePerGas': to_integer_if_hex,
    'maxPriorityFeePerGas': to_integer_if_hex,
    'accessList': apply_formatter_to_array(
        apply_key_map({'storageKeys': 'storage_keys'})
    ),
}
transaction_request_formatter = apply_formatters_to_dict(TRANSACTION_REQUEST_FORMATTERS)

transaction_request_transformer = compose(
    transaction_request_remapper,
    transaction_request_formatter,
)


FILTER_REQUEST_KEY_MAPPING = {
    'fromBlock': 'from_block',
    'toBlock': 'to_block',
}
filter_request_remapper = apply_key_map(FILTER_REQUEST_KEY_MAPPING)


FILTER_REQUEST_FORMATTERS = {
예제 #18
0
def test_apply_formatters_to_dict(formatter, value, expected):
    assert eth_utils.apply_formatters_to_dict(formatter, value) == expected

    mapper = apply_formatters_to_dict(formatter)
    assert mapper(value) == expected
예제 #19
0
        if key not in transaction:
            defaults[key] = default_val
    for key, val in transaction.items():
        if key in VALID_GENASSETTX_PARAMS:
            alreadygot[key] = transaction[key]

    transaction_merged = merge(defaults, alreadygot)
    transaction_merged['chainId'] = defaultChainId
    transaction_new = unsigned_assetcreate_formatter(transaction_merged)

    assert_check_gen_asset_params(transaction_new)

    return transaction_new


unsigned_assetcreate_formatter = apply_formatters_to_dict(
    ASSETCREATE_FORMATTERS)


def assert_check_gen_asset_params(assetcreate_params):
    for param in assetcreate_params:
        if param not in VALID_GENASSETTX_PARAMS:
            raise ValueError(
                '{} is not a valid asset create parameter'.format(param))

    for param in REQUIRED_GENASSETTX_PARAMS:
        if param not in assetcreate_params:
            raise ValueError(
                '{} is required as an asset create parameter'.format(param))


################################################################################################
예제 #20
0
def sign_transaction(transaction_dict, private_key) -> SignedTransaction:
    """
    Sign a (non-staking) transaction dictionary with the specified private key

    Parameters
    ----------
    transaction_dict: :obj:`dict` with the following keys
        nonce: :obj:`int` Transaction nonce
        gasPrice: :obj:`int` Transaction gas price in Atto
        gas: :obj:`int` Gas limit in Atto
        to: :obj:`str` Destination address
        value: :obj:`int` Amount to be transferred in Atto
        data: :obj:`str` Transaction data, used for smart contracts
        from: :obj:`str` From address, optional (if passed, must match the
                    public key address generated from private_key)
        chainId: :obj:`int` One of util.chainIds.keys(), optional
            If you want to replay your transaction across networks, do not pass it
        shardID: :obj:`int` Originating shard ID, optional (needed for cx shard transaction)
        toShardID: :obj:`int` Destination shard ID, optional (needed for cx shard transaction)
        r:  :obj:`int` First 32 bytes of the signature, optional
        s:  :obj:`int` Next  32 bytes of the signature, optional
        v:  :obj:`int` Recovery value, optional
    private_key: :obj:`str` The private key

    Returns
    -------
    A SignedTransaction object, which is a named tuple
        rawTransaction: :obj:`str` Hex bytes of the raw transaction
        hash: :obj:`str` Hex bytes of the transaction hash
        r:  :obj:`int` First 32 bytes of the signature
        s:  :obj:`int` Next  32 bytes of the signature
        v:  :obj:`int` Recovery value

    Raises
    ------
    TypeError, if the from address specified is not the same
        one as derived from the the private key
    AssertionError, if the fields for the transaction are missing,
        or if the chainId supplied is not a string,
        or if the chainId is not a key in util.py

    API Reference
    -------------
    https://readthedocs.org/projects/eth-account/downloads/pdf/stable/
    """
    account, sanitized_transaction = sanitize_transaction(
        transaction_dict, private_key)
    if 'to' in sanitized_transaction and sanitized_transaction[
            'to'] is not None:
        sanitized_transaction['to'] = convert_one_to_hex(
            sanitized_transaction['to'])
    filled_transaction = pipe(  # https://github.com/ethereum/eth-account/blob/00e7b10005c5fa7090086fcef37a76296c524e17/eth_account/_utils/transactions.py#L39
        sanitized_transaction, dict, partial(merge, TRANSACTION_DEFAULTS),
        chain_id_to_v, apply_formatters_to_dict(HARMONY_FORMATTERS))
    unsigned_transaction = serialize_transaction(filled_transaction)
    transaction_hash = unsigned_transaction.hash()

    if isinstance(unsigned_transaction,
                  (UnsignedEthereumTxData, UnsignedHarmonyTxData)):
        chain_id = None  # https://github.com/ethereum/eth-account/blob/00e7b10005c5fa7090086fcef37a76296c524e17/eth_account/_utils/signing.py#L26
    else:
        chain_id = unsigned_transaction.v
    (v, r, s) = sign_transaction_hash(account._key_obj, transaction_hash,
                                      chain_id)
    encoded_transaction = encode_transaction(unsigned_transaction,
                                             vrs=(v, r, s))
    signed_transaction_hash = keccak(encoded_transaction)
    return SignedTransaction(
        rawTransaction=HexBytes(encoded_transaction),
        hash=HexBytes(signed_transaction_hash),
        r=r,
        s=s,
        v=v,
    )
예제 #21
0
    'gasPrice': 'gas_price',
}

transaction_params_remapper = apply_key_map(TRANSACTION_PARAMS_MAPPING)

TRANSACTION_PARAMS_FORMATTERS = {
    'gas': to_integer_if_hex,
    'gasPrice': to_integer_if_hex,
    'value': to_integer_if_hex,
    'nonce': to_integer_if_hex,
}

transaction_params_formatter = compose(
    # remove nonce for now due to issue https://github.com/ethereum/eth-tester/issues/80
    remove_key_if('nonce', lambda _: True),
    apply_formatters_to_dict(TRANSACTION_PARAMS_FORMATTERS),
)

FILTER_PARAMS_MAPPINGS = {
    'fromBlock': 'from_block',
    'toBlock': 'to_block',
}

filter_params_remapper = apply_key_map(FILTER_PARAMS_MAPPINGS)

FILTER_PARAMS_FORMATTERS = {
    'fromBlock': to_integer_if_hex,
    'toBlock': to_integer_if_hex,
}

filter_params_formatter = apply_formatters_to_dict(FILTER_PARAMS_FORMATTERS)
예제 #22
0
from eth_utils.curried import (
    apply_formatter_to_array,
    apply_formatters_to_dict,
    apply_formatters_to_sequence,
    encode_hex,
    to_checksum_address,
    to_hex,
)

from eth_utils.toolz import curried

environment_formatter = apply_formatters_to_dict({
    "currentCoinbase": to_checksum_address,
    "previousHash": encode_hex,
    "currentNumber": to_hex,
    "currentDifficulty": to_hex,
    "currentGasLimit": to_hex,
    "currentTimestamp": to_hex,
})

storage_item_formatter: Callable[[List[Any]], List[Any]]
storage_item_formatter = apply_formatters_to_sequence([to_hex, to_hex])
storage_formatter = curried.itemmap(storage_item_formatter)

account_state_formatter = apply_formatters_to_dict({
    "balance":
    to_hex,
    "nonce":
    to_hex,
    "code":
    encode_hex,
예제 #23
0
def _sign_transaction_generic(account, sanitized_transaction, parent_serializer):
    """
    Sign a generic staking transaction, given the serializer base class and account

    Paramters
    ---------
    account: :obj:`eth_account.Account`, the account to use for signing
    sanitized_transaction: :obj:`dict`, The sanitized transaction (chainId checks and no from key)
    parent_serializer: :obj: The serializer class from staking_structures

    Returns
    -------
    SignedTransaction object, which can be posted to the chain by using
        blockchain.send_raw_transaction

    Raises
    ------
    Assertion / KeyError, if certain keys are missing from the dict
    rlp.exceptions.ObjectSerializationError, if data types are not as expected
    """
    # obtain the serializers
    if sanitized_transaction.get('chainId', 0) == 0:
        unsigned_serializer, signed_serializer = parent_serializer.Unsigned(), parent_serializer.Signed()                 # unsigned, signed
    else:
        unsigned_serializer, signed_serializer = parent_serializer.SignedChainId(), parent_serializer.SignedChainId()     # since chain_id_to_v adds v/r/s, unsigned is not used here
    # fill the transaction
    filled_transaction = pipe(                                                                                            # https://github.com/ethereum/eth-account/blob/00e7b10005c5fa7090086fcef37a76296c524e17/eth_account/_utils/transactions.py#L39
        sanitized_transaction,
        dict,
        partial(merge, {'chainId': None}),
        chain_id_to_v,                                                                                                    # will move chain id to v and add v/r/s
        apply_formatters_to_dict(FORMATTERS)
    )
    # get the unsigned transaction
    for f, _ in unsigned_serializer._meta.fields:
        assert f in filled_transaction, f'Could not find {f} in transaction'
    unsigned_transaction = unsigned_serializer.from_dict(\
        {f: filled_transaction[f] for f, _ in unsigned_serializer._meta.fields})                                          # drop extras silently
    # sign the unsigned transaction
    if 'v' in unsigned_transaction.as_dict():
        chain_id = unsigned_transaction.v
    else:
        chain_id = None
    transaction_hash = unsigned_transaction.hash()
    (v, r, s) = sign_transaction_hash(
        account._key_obj, transaction_hash, chain_id)
    chain_naive_transaction = dissoc(
        unsigned_transaction.as_dict(), 'v', 'r', 's')                                                                    # remove extra v/r/s added by chain_id_to_v
    # serialize it
    signed_transaction = signed_serializer(
        v=v + (8 if chain_id is None else 0),               # copied from https://github.com/harmony-one/sdk/blob/99a827782fabcd5f91f025af0d8de228956d42b4/packages/harmony-staking/src/stakingTransaction.ts#L207
        r=r,
        s=s,                                                # in the below statement, remove everything not expected by signed_serializer
        **{f: chain_naive_transaction[f] for f, _ in signed_serializer._meta.fields if f not in 'vrs'})
    # encode it
    encoded_transaction = rlp.encode(signed_transaction)
    # hash it
    signed_transaction_hash = keccak(encoded_transaction)
    # return is
    return SignedTransaction(
        rawTransaction=HexBytes(encoded_transaction),
        hash=HexBytes(signed_transaction_hash),
        r=r,
        s=s,
        v=v,
    )
예제 #24
0
        if key not in transaction:
            defaults[key] = default_val
    for key, val in transaction.items():
        if key in VALID_MAKESWAP_PARAMS:
            alreadygot[key] = transaction[key]

    transaction_merged = merge(defaults, alreadygot)
    transaction_merged['chainId'] = defaultChainId
    transaction_new = unsigned_makeswap_formatter(transaction_merged)

    assert_check_makeswap_params(transaction_new)

    return transaction_new


unsigned_makeswap_formatter = apply_formatters_to_dict(MAKESWAP_FORMATTERS)


def assert_check_makeswap_params(makeswap_params):
    for param in makeswap_params:
        if param not in VALID_MAKESWAP_PARAMS:
            raise ValueError(
                '{} is not a valid make swap parameter'.format(param))

    for param in REQUIRED_MAKESWAP_PARAMS:
        if param not in makeswap_params:
            raise ValueError(
                '{} is required as an make swap parameter'.format(param))


##############################################################################################
예제 #25
0
    'maxPriorityFeePerGas': to_integer_if_hex,
    'value': to_integer_if_hex,
    'from': to_checksum_address,
    'publicKey': apply_formatter_if(is_not_null, to_hexbytes(64)),
    'r': apply_formatter_if(is_not_null, to_hexbytes(32,
                                                     variable_length=True)),
    'raw': HexBytes,
    's': apply_formatter_if(is_not_null, to_hexbytes(32,
                                                     variable_length=True)),
    'to': apply_formatter_if(is_address, to_checksum_address),
    'hash': to_hexbytes(32),
    'v': apply_formatter_if(is_not_null, to_integer_if_hex),
    'standardV': apply_formatter_if(is_not_null, to_integer_if_hex),
}

transaction_result_formatter = apply_formatters_to_dict(
    TRANSACTION_RESULT_FORMATTERS)


def apply_list_to_array_formatter(formatter: Any) -> Callable[..., Any]:
    return to_list(apply_formatter_to_array(formatter))


LOG_ENTRY_FORMATTERS = {
    'blockHash': apply_formatter_if(is_not_null, to_hexbytes(32)),
    'blockNumber': apply_formatter_if(is_not_null, to_integer_if_hex),
    'transactionIndex': apply_formatter_if(is_not_null, to_integer_if_hex),
    'transactionHash': apply_formatter_if(is_not_null, to_hexbytes(32)),
    'logIndex': to_integer_if_hex,
    'address': to_checksum_address,
    'topics': apply_list_to_array_formatter(to_hexbytes(32)),
    'data': to_ascii_if_bytes,
예제 #26
0
def test_format_dict_error():
    with pytest.raises(ValueError) as exc_info:
        apply_formatters_to_dict({"myfield": int}, {"myfield": "a"})
    with pytest.raises(ValueError) as exc_info:
        eth_utils.apply_formatters_to_dict({"myfield": int}, {"myfield": "a"})
    assert "myfield" in str(exc_info.value)
예제 #27
0
        'chainId':
        apply_formatter_if(
            # Bypass `validate_chain_id` if chainId can't be determined
            lambda _: is_not_null(web3.net.chainId),
            validate_chain_id(web3)),
    }
    return apply_formatter_at_index(
        apply_formatters_to_dict(transactions_params_validators), 0)


BLOCK_VALIDATORS = {
    'extraData': check_extradata_length,
}

block_validator = apply_formatter_if(
    is_not_null, apply_formatters_to_dict(BLOCK_VALIDATORS))


@curry
def chain_id_validator(web3):
    return compose(apply_formatter_at_index(transaction_normalizer, 0),
                   transaction_param_validator(web3))


def build_validators_with_web3(w3):
    return dict(
        request_formatters={
            'eth_sendTransaction': chain_id_validator(w3),
            'eth_estimateGas': chain_id_validator(w3),
            'eth_call': chain_id_validator(w3),
        },
예제 #28
0
    'nonce': to_integer_if_hex,
    'gas': to_integer_if_hex,
    'gasPrice': to_integer_if_hex,
    'value': to_integer_if_hex,
    'from': to_checksum_address,
    'publicKey': apply_formatter_if(is_not_null, to_hexbytes(64)),
    'r': to_hexbytes(32, variable_length=True),
    'raw': HexBytes,
    's': to_hexbytes(32, variable_length=True),
    'to': apply_formatter_if(is_address, to_checksum_address),
    'hash': to_hexbytes(32),
    'v': apply_formatter_if(is_not_null, to_integer_if_hex),
    'standardV': apply_formatter_if(is_not_null, to_integer_if_hex),
}

transaction_formatter = apply_formatters_to_dict(TRANSACTION_FORMATTERS)

SIGNED_TX_FORMATTER = {
    'raw': HexBytes,
    'tx': transaction_formatter,
}

signed_tx_formatter = apply_formatters_to_dict(SIGNED_TX_FORMATTER)

WHISPER_LOG_FORMATTERS = {
    'sig': to_hexbytes(130),
    'topic': to_hexbytes(8),
    'payload': HexBytes,
    'padding': apply_formatter_if(is_not_null, HexBytes),
    'hash': to_hexbytes(64),
    'recipientPublicKey': apply_formatter_if(is_not_null, to_hexbytes(130)),
예제 #29
0
    for key, default_val in GENNOTATION_DEFAULTS.items():
        if key not in transaction:
            defaults[key] = default_val
    for key, val in transaction.items():
        if key in VALID_GENNOTATIONTX_PARAMS:
            alreadygot[key] = transaction[key]

    transaction_merged = merge(defaults, alreadygot)
    transaction_merged['chainId'] = defaultChainId
    transaction_new = unsigned_gennotation_formatter(transaction_merged)

    assert_check_gen_notation_params(transaction_new)

    return transaction_new


unsigned_gennotation_formatter = apply_formatters_to_dict(
    GENNOTATION_FORMATTERS)


def assert_check_gen_notation_params(gennotation_params):
    for param in gennotation_params:
        if param not in VALID_GENNOTATIONTX_PARAMS:
            raise ValueError(
                '{} is not a valid gen notation parameter'.format(param))

    for param in REQUIRED_GENNOTATIONTX_PARAMS:
        if param not in gennotation_params:
            raise ValueError(
                '{} is required as a gen notation parameter'.format(param))
예제 #30
0
from eth_utils.curried import (
    apply_formatters_to_dict,
    apply_key_map,
)
from hexbytes import (
    HexBytes, )

from vns_web3.middleware.formatting import (
    construct_formatting_middleware, )
from vns_web3.utils.toolz import (
    compose, )

remap_geth_poa_fields = apply_key_map({
    'extraData': 'proofOfAuthorityData',
})

pythonic_geth_poa = apply_formatters_to_dict({
    'proofOfAuthorityData': HexBytes,
})

geth_poa_cleanup = compose(pythonic_geth_poa, remap_geth_poa_fields)

geth_poa_middleware = construct_formatting_middleware(result_formatters={
    'eth_getBlockByHash':
    geth_poa_cleanup,
    'eth_getBlockByNumber':
    geth_poa_cleanup,
}, )
예제 #31
0
from eth_utils import (
    is_string,
)
from eth_utils.curried import (
    apply_formatter_at_index,
    apply_formatter_if,
    apply_formatters_to_dict,
)

from .formatting import (
    construct_formatting_middleware,
)

FILTER_PARAM_NORMALIZERS = apply_formatters_to_dict({
    'address': apply_formatter_if(is_string, lambda x: [x])})

METHOD_NORMALIZERS = {
    'eth_getLogs': apply_formatter_at_index(FILTER_PARAM_NORMALIZERS, 0),
    'eth_newFilter': apply_formatter_at_index(FILTER_PARAM_NORMALIZERS, 0)
}

request_parameter_normalizer = construct_formatting_middleware(
    request_formatters=METHOD_NORMALIZERS,
)