Package tronpytool

Expand source code
#!/usr/bin/env python
# --------------------------------------------------------------------
# Copyright (c) iEXBase. All rights reserved.
# Licensed under the MIT License.
# See License.txt in the project root for license information.
# --------------------------------------------------------------------

import sys

import pkg_resources
from eth_account import Account  # noqa: E402

# from tronpytool.compile.solwrap import SolcWrap
from .main import Tron  # noqa: E402
from .providers.http import HttpProvider  # noqa: E402

if sys.version_info < (3, 5):
    raise EnvironmentError("Python 3.5 or above is required")

__version__ = pkg_resources.get_distribution("tronpytool").version

__all__ = [
    '__version__',
    'HttpProvider',
    'Account',
    'Tron'
    #  'SolcWrap'
]

Sub-modules

tronpytool.common
tronpytool.compile
tronpytool.constants
tronpytool.contract
tronpytool.exceptions
tronpytool.main

tronpytool.main …

tronpytool.manager

tronpytool.manager …

tronpytool.module
tronpytool.providers
tronpytool.transactionbuilder
tronpytool.trx

tronpytool.trx …

Classes

class Account

The primary entry point for working with Ethereum private keys.

It does not require a connection to an Ethereum node.

Expand source code
class Account(object):
    """
    The primary entry point for working with Ethereum private keys.

    It does **not** require a connection to an Ethereum node.
    """
    _keys = keys

    _default_kdf = os.getenv('ETH_ACCOUNT_KDF', 'scrypt')

    @combomethod
    def create(self, extra_entropy=''):
        r"""
        Creates a new private key, and returns it as a :class:`~eth_account.local.LocalAccount`.

        :param extra_entropy: Add extra randomness to whatever randomness your OS can provide
        :type extra_entropy: str or bytes or int
        :returns: an object with private key and convenience methods

        .. code-block:: python

            >>> from eth_account import Account
            >>> acct = Account.create('KEYSMASH FJAFJKLDSKF7JKFDJ 1530')
            >>> acct.address
            '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E'
            >>> acct.key
            b"\xb2\}\xb3\x1f\xee\xd9\x12''\xbf\t9\xdcv\x9a\x96VK-\xe4\xc4rm\x03[6\xec\xf1\xe5\xb3d"

            # These methods are also available: sign_message(), sign_transaction(), encrypt()
            # They correspond to the same-named methods in Account.*
            # but without the private key argument
        """
        extra_key_bytes = text_if_str(to_bytes, extra_entropy)
        key_bytes = keccak(os.urandom(32) + extra_key_bytes)
        return self.from_key(key_bytes)

    @staticmethod
    def decrypt(keyfile_json, password):
        """
        Decrypts a private key that was encrypted using an Ethereum client or
        :meth:`~Account.encrypt`.

        :param keyfile_json: The encrypted key
        :type keyfile_json: dict or str
        :param str password: The password that was used to encrypt the key
        :returns: the raw private key
        :rtype: ~hexbytes.main.HexBytes

        .. code-block:: python

            >>> encrypted = {
             'address': '5ce9454909639d2d17a3f753ce7d93fa0b9ab12e',
             'crypto': {'cipher': 'aes-128-ctr',
              'cipherparams': {'iv': '78f214584844e0b241b433d7c3bb8d5f'},
              'ciphertext': 'd6dbb56e4f54ba6db2e8dc14df17cb7352fdce03681dd3f90ce4b6c1d5af2c4f',
              'kdf': 'pbkdf2',
              'kdfparams': {'c': 1000000,
               'dklen': 32,
               'prf': 'hmac-sha256',
               'salt': '45cf943b4de2c05c2c440ef96af914a2'},
              'mac': 'f5e1af09df5ded25c96fcf075ada313fb6f79735a914adc8cb02e8ddee7813c3'},
             'id': 'b812f3f9-78cc-462a-9e89-74418aa27cb0',
             'version': 3}

            >>> import getpass
            >>> Account.decrypt(encrypted, getpass.getpass())
            HexBytes('0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364')

        """
        if isinstance(keyfile_json, str):
            keyfile = json.loads(keyfile_json)
        elif is_dict(keyfile_json):
            keyfile = keyfile_json
        else:
            raise TypeError("The keyfile should be supplied as a JSON string, or a dictionary.")
        password_bytes = text_if_str(to_bytes, password)
        return HexBytes(decode_keyfile_json(keyfile, password_bytes))

    @classmethod
    def encrypt(cls, private_key, password, kdf=None, iterations=None):
        """
        Creates a dictionary with an encrypted version of your private key.
        To import this keyfile into Ethereum clients like geth and parity:
        encode this dictionary with :func:`json.dumps` and save it to disk where your
        client keeps key files.

        :param private_key: The raw private key
        :type private_key: hex str, bytes, int or :class:`eth_keys.datatypes.PrivateKey`
        :param str password: The password which you will need to unlock the account in your client
        :param str kdf: The key derivation function to use when encrypting your private key
        :param int iterations: The work factor for the key derivation function
        :returns: The data to use in your encrypted file
        :rtype: dict

        If kdf is not set, the default key derivation function falls back to the
        environment variable :envvar:`ETH_ACCOUNT_KDF`. If that is not set, then
        'scrypt' will be used as the default.

        .. code-block:: python

            >>> import getpass
            >>> encrypted = Account.encrypt(
                0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364,
                getpass.getpass()
            )

            {
                'address': '5ce9454909639d2d17a3f753ce7d93fa0b9ab12e',
                'crypto': {
                    'cipher': 'aes-128-ctr',
                    'cipherparams': {
                        'iv': '0b7845a5c3597d3d378bde9b7c7319b7'
                    },
                    'ciphertext': 'a494f1feb3c854e99c1ff01e6aaa17d43c0752009073503b908457dc8de5d2a5',  # noqa: E501
                    'kdf': 'scrypt',
                    'kdfparams': {
                        'dklen': 32,
                        'n': 262144,
                        'p': 8,
                        'r': 1,
                        'salt': '13c4a48123affaa29189e9097726c698'
                    },
                    'mac': 'f4cfb027eb0af9bd7a320b4374a3fa7bef02cfbafe0ec5d1fd7ad129401de0b1'
                },
                'id': 'a60e0578-0e5b-4a75-b991-d55ec6451a6f',
                'version': 3
            }

             >>> with open('my-keyfile', 'w') as f:
                 f.write(json.dumps(encrypted))
        """
        if isinstance(private_key, keys.PrivateKey):
            key_bytes = private_key.to_bytes()
        else:
            key_bytes = HexBytes(private_key)

        if kdf is None:
            kdf = cls._default_kdf

        password_bytes = text_if_str(to_bytes, password)
        assert len(key_bytes) == 32

        return create_keyfile_json(key_bytes, password_bytes, kdf=kdf, iterations=iterations)

    @combomethod
    def privateKeyToAccount(self, private_key):
        """
        .. CAUTION:: Deprecated for :meth:`~eth_account.account.Account.from_key`.
            This method will be removed in v0.5
        """
        warnings.warn(
            "privateKeyToAccount is deprecated in favor of from_key",
            category=DeprecationWarning,
        )
        return self.from_key(private_key)

    @combomethod
    def from_key(self, private_key):
        r"""
        Returns a convenient object for working with the given private key.

        :param private_key: The raw private key
        :type private_key: hex str, bytes, int or :class:`eth_keys.datatypes.PrivateKey`
        :return: object with methods for signing and encrypting
        :rtype: LocalAccount

        .. code-block:: python

            >>> acct = Account.from_key(
              0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364)
            >>> acct.address
            '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E'
            >>> acct.key
            b"\xb2\}\xb3\x1f\xee\xd9\x12''xbf\t9\xdcv\x9a\x96VK-\xe4\xc4rm\x03[6\xec\xf1\xe5\xb3d"

            # These methods are also available: sign_message(), sign_transaction(), encrypt()
            # They correspond to the same-named methods in Account.*
            # but without the private key argument
        """
        key = self._parsePrivateKey(private_key)
        return LocalAccount(key, self)

    @combomethod
    def recover_message(self, signable_message: SignableMessage, vrs=None, signature=None):
        r"""
        Get the address of the account that signed the given message.
        You must specify exactly one of: vrs or signature

        :param signable_message: the message that was signed
        :param vrs: the three pieces generated by an elliptic curve signature
        :type vrs: tuple(v, r, s), each element is hex str, bytes or int
        :param signature: signature bytes concatenated as r+s+v
        :type signature: hex str or bytes or int
        :returns: address of signer, hex-encoded & checksummed
        :rtype: str

        .. code-block:: python

            >>> from eth_account.messages import encode_defunct
            >>> message = encode_defunct(text="I♥SF")
            >>> vrs = (
                  28,
                  '0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb3',
                  '0x3e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce')
            >>> Account.recover_message(message, vrs=vrs)
            '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E'

            # All of these recover calls are equivalent:

            # variations on vrs
            >>> vrs = (
                  '0x1c',
                  '0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb3',
                  '0x3e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce')
            >>> Account.recover_message(message, vrs=vrs)
            >>> vrs = (
                  b'\x1c',
                  b'\\xe6\\xca\\x9b\\xbaX\\xc8\\x86\\x11\\xfa\\xd6jl\\xe8\\xf9\\x96\\x90\\x81\\x95Y8\\x07\\xc4\\xb3\\x8b\\xd5(\\xd2\\xcf\\xf0\\x9dN\\xb3',  # noqa: E501
                  b'>[\\xfb\\xbfM>9\\xb1\\xa2\\xfd\\x81jv\\x80\\xc1\\x9e\\xbe\\xba\\xf3\\xa1A\\xb29\\x93J\\xd4<\\xb3?\\xce\\xc8\\xce')  # noqa: E501
            >>> Account.recover_message(message, vrs=vrs)
            >>> # Caution about this approach: likely problems if there are leading 0s
            >>> vrs = (
                  0x1c,
                  0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb3,
                  0x3e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce)
            >>> Account.recover_message(message, vrs=vrs)

            # variations on signature
            >>> signature = '0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb33e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce1c'  # noqa: E501
            >>> Account.recover_message(message, signature=signature)
            >>> signature = b'\\xe6\\xca\\x9b\\xbaX\\xc8\\x86\\x11\\xfa\\xd6jl\\xe8\\xf9\\x96\\x90\\x81\\x95Y8\\x07\\xc4\\xb3\\x8b\\xd5(\\xd2\\xcf\\xf0\\x9dN\\xb3>[\\xfb\\xbfM>9\\xb1\\xa2\\xfd\\x81jv\\x80\\xc1\\x9e\\xbe\\xba\\xf3\\xa1A\\xb29\\x93J\\xd4<\\xb3?\\xce\\xc8\\xce\\x1c'  # noqa: E501
            >>> Account.recover_message(message, signature=signature)
            >>> # Caution about this approach: likely problems if there are leading 0s
            >>> signature = 0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb33e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce1c  # noqa: E501
            >>> Account.recover_message(message, signature=signature)
        """
        message_hash = _hash_eip191_message(signable_message)
        return self._recover_hash(message_hash, vrs, signature)

    @combomethod
    def recoverHash(self, message_hash, vrs=None, signature=None):
        """
        Get the address of the account that signed the message with the given hash.
        You must specify exactly one of: vrs or signature

        .. CAUTION:: Deprecated for :meth:`~eth_account.account.Account.recover_message`.
            This method might be removed as early as v0.5

        :param message_hash: the hash of the message that you want to verify
        :type message_hash: hex str or bytes or int
        :param vrs: the three pieces generated by an elliptic curve signature
        :type vrs: tuple(v, r, s), each element is hex str, bytes or int
        :param signature: signature bytes concatenated as r+s+v
        :type signature: hex str or bytes or int
        :returns: address of signer, hex-encoded & checksummed
        :rtype: str
        """
        warnings.warn(
            "recoverHash is deprecated in favor of recover_message",
            category=DeprecationWarning,
        )
        return self._recover_hash(message_hash, vrs, signature)

    @combomethod
    def _recover_hash(self, message_hash, vrs=None, signature=None):
        hash_bytes = HexBytes(message_hash)
        if len(hash_bytes) != 32:
            raise ValueError("The message hash must be exactly 32-bytes")
        if vrs is not None:
            v, r, s = map(hexstr_if_str(to_int), vrs)
            v_standard = to_standard_v(v)
            signature_obj = self._keys.Signature(vrs=(v_standard, r, s))
        elif signature is not None:
            signature_bytes = HexBytes(signature)
            signature_bytes_standard = to_standard_signature_bytes(signature_bytes)
            signature_obj = self._keys.Signature(signature_bytes=signature_bytes_standard)
        else:
            raise TypeError("You must supply the vrs tuple or the signature bytes")
        pubkey = signature_obj.recover_public_key_from_msg_hash(hash_bytes)
        return pubkey.to_checksum_address()

    @combomethod
    def recoverTransaction(self, serialized_transaction):
        """
        .. CAUTION:: Deprecated for :meth:`~eth_account.account.Account.recover_transaction`.
            This method will be removed in v0.5
        """
        warnings.warn(
            "recoverTransaction is deprecated in favor of recover_transaction",
            category=DeprecationWarning,
        )
        return self.recover_transaction(serialized_transaction)

    @combomethod
    def recover_transaction(self, serialized_transaction):
        """
        Get the address of the account that signed this transaction.

        :param serialized_transaction: the complete signed transaction
        :type serialized_transaction: hex str, bytes or int
        :returns: address of signer, hex-encoded & checksummed
        :rtype: str

        .. code-block:: python

            >>> raw_transaction = '0xf86a8086d55698372431831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca008025a009ebb6ca057a0535d6186462bc0b465b561c94a295bdb0621fc19208ab149a9ca0440ffd775ce91a833ab410777204d5341a6f9fa91216a6f3ee2c051fea6a0428',  # noqa: E501
            >>> Account.recover_transaction(raw_transaction)
            '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23'
        """
        txn_bytes = HexBytes(serialized_transaction)
        txn = Transaction.from_bytes(txn_bytes)
        msg_hash = hash_of_signed_transaction(txn)
        return self._recover_hash(msg_hash, vrs=vrs_from(txn))

    def setKeyBackend(self, backend):
        """
        .. CAUTION:: Deprecated for :meth:`~eth_account.account.Account.set_key_backend`.
            This method will be removed in v0.5
        """
        warnings.warn(
            "setKeyBackend is deprecated in favor of set_key_backend",
            category=DeprecationWarning,
        )
        self.set_key_backend(backend)

    def set_key_backend(self, backend):
        """
        Change the backend used by the underlying eth-keys library.

        *(The default is fine for most users)*

        :param backend: any backend that works in
            `eth_keys.KeyApi(backend) <https://github.com/ethereum/eth-keys/#keyapibackendnone>`_

        """
        self._keys = KeyAPI(backend)

    @combomethod
    def sign_message(self, signable_message: SignableMessage, private_key):
        r"""
        Sign the provided message.

        This API supports any messaging format that will encode to EIP-191_ messages.

        If you would like historical compatibility with
        :meth:`w3.eth.sign() <web3.eth.Eth.sign>`
        you can use :meth:`~eth_account.messages.encode_defunct`.

        Other options are the "validator", or "structured data" standards. (Both of these
        are in *DRAFT* status currently, so be aware that the implementation is not
        guaranteed to be stable). You can import all supported message encoders in
        ``eth_account.messages``.

        :param signable_message: the encoded message for signing
        :param private_key: the key to sign the message with
        :type private_key: hex str, bytes, int or :class:`eth_keys.datatypes.PrivateKey`
        :returns: Various details about the signature - most importantly the fields: v, r, and s
        :rtype: ~eth_account.datastructures.AttributeDict

        .. code-block:: python

            >>> msg = "I♥SF"
            >>> from eth_account.messages import encode_defunct
            >>> msghash = encode_defunct(text=msg)
            SignableMessage(version=b'E', header=b'thereum Signed Message:\n6', body=b'I\xe2\x99\xa5SF')
            >>> # If you're curious about the internal fields of SignableMessage, take a look at EIP-191, linked above
            >>> key = "0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364"
            >>> Account.sign_message(msghash, key)
            {'messageHash': HexBytes('0x1476abb745d423bf09273f1afd887d951181d25adc66c4834a70491911b7f750'),  # noqa: E501
             'r': 104389933075820307925104709181714897380569894203213074526835978196648170704563,
             's': 28205917190874851400050446352651915501321657673772411533993420917949420456142,
             'signature': HexBytes('0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb33e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce1c'),  # noqa: E501
             'v': 28}

        .. _EIP-191: https://eips.ethereum.org/EIPS/eip-191
        """
        message_hash = _hash_eip191_message(signable_message)
        return self._sign_hash(message_hash, private_key)

    @combomethod
    def signHash(self, message_hash, private_key):
        """
        .. WARNING:: *Never* sign a hash that you didn't generate,
            it can be an arbitrary transaction. For example, it might
            send all of your account's ether to an attacker.
            Instead, prefer :meth:`~eth_account.account.Account.sign_message`,
            which cannot accidentally sign a transaction.

        Sign the provided hash.

        .. CAUTION:: Deprecated for :meth:`~eth_account.account.Account.sign_message`.
            This method will be removed in v0.5

        :param message_hash: the 32-byte message hash to be signed
        :type message_hash: hex str, bytes or int
        :param private_key: the key to sign the message with
        :type private_key: hex str, bytes, int or :class:`eth_keys.datatypes.PrivateKey`
        :returns: Various details about the signature - most
          importantly the fields: v, r, and s
        :rtype: ~eth_account.datastructures.AttributeDict
        """
        warnings.warn(
            "signHash is deprecated in favor of sign_message",
            category=DeprecationWarning,
        )
        return self._sign_hash(message_hash, private_key)

    @combomethod
    def _sign_hash(self, message_hash, private_key):
        msg_hash_bytes = HexBytes(message_hash)
        if len(msg_hash_bytes) != 32:
            raise ValueError("The message hash must be exactly 32-bytes")

        key = self._parsePrivateKey(private_key)

        (v, r, s, eth_signature_bytes) = sign_message_hash(key, msg_hash_bytes)
        return AttributeDict({
            'messageHash': msg_hash_bytes,
            'r': r,
            's': s,
            'v': v,
            'signature': HexBytes(eth_signature_bytes),
        })

    @combomethod
    def signTransaction(self, transaction_dict, private_key):
        """
        .. CAUTION:: Deprecated for :meth:`~eth_account.account.Account.sign_transaction`.
            This method will be removed in v0.5
        """
        warnings.warn(
            "signTransaction is deprecated in favor of sign_transaction",
            category=DeprecationWarning,
        )
        return self.sign_transaction(transaction_dict, private_key)

    @combomethod
    def sign_transaction(self, transaction_dict, private_key):
        """
        Sign a transaction using a local private key. Produces signature details
        and the hex-encoded transaction suitable for broadcast using
        :meth:`w3.eth.sendRawTransaction() <web3.eth.Eth.sendRawTransaction>`.

        Create the transaction dict for a contract method with
        `my_contract.functions.my_function().buildTransaction()
        <http://web3py.readthedocs.io/en/latest/contracts.html#methods>`_

        :param dict transaction_dict: the transaction with keys:
          nonce, chainId, to, data, value, gas, and gasPrice.
        :param private_key: the private key to sign the data with
        :type private_key: hex str, bytes, int or :class:`eth_keys.datatypes.PrivateKey`
        :returns: Various details about the signature - most
          importantly the fields: v, r, and s
        :rtype: AttributeDict

        .. code-block:: python

            >>> transaction = {
                    # Note that the address must be in checksum format or native bytes:
                    'to': '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55',
                    'value': 1000000000,
                    'gas': 2000000,
                    'gasPrice': 234567897654321,
                    'nonce': 0,
                    'chainId': 1
                }
            >>> key = '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318'
            >>> signed = Account.sign_transaction(transaction, key)
            {'hash': HexBytes('0x6893a6ee8df79b0f5d64a180cd1ef35d030f3e296a5361cf04d02ce720d32ec5'),
             'r': 4487286261793418179817841024889747115779324305375823110249149479905075174044,
             'rawTransaction': HexBytes('0xf86a8086d55698372431831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca008025a009ebb6ca057a0535d6186462bc0b465b561c94a295bdb0621fc19208ab149a9ca0440ffd775ce91a833ab410777204d5341a6f9fa91216a6f3ee2c051fea6a0428'),  # noqa: E501
             's': 30785525769477805655994251009256770582792548537338581640010273753578382951464,
             'v': 37}
            >>> w3.eth.sendRawTransaction(signed.rawTransaction)
        """
        if not isinstance(transaction_dict, Mapping):
            raise TypeError("transaction_dict must be dict-like, got %r" % transaction_dict)

        account = self.from_key(private_key)

        # allow from field, *only* if it matches the private key
        if 'from' in transaction_dict:
            if transaction_dict['from'] == account.address:
                sanitized_transaction = dissoc(transaction_dict, 'from')
            else:
                raise TypeError("from field must match key's %s, but it was %s" % (
                    account.address,
                    transaction_dict['from'],
                ))
        else:
            sanitized_transaction = transaction_dict

        # sign transaction
        (
            v,
            r,
            s,
            rlp_encoded,
        ) = sign_transaction_dict(account._key_obj, sanitized_transaction)

        transaction_hash = keccak(rlp_encoded)

        return AttributeDict({
            'rawTransaction': HexBytes(rlp_encoded),
            'hash': HexBytes(transaction_hash),
            'r': r,
            's': s,
            'v': v,
        })

    @combomethod
    def _parsePrivateKey(self, key):
        """
        Generate a :class:`eth_keys.datatypes.PrivateKey` from the provided key. If the
        key is already of type :class:`eth_keys.datatypes.PrivateKey`, return the key.

        :param key: the private key from which a :class:`eth_keys.datatypes.PrivateKey`
                    will be generated
        :type key: hex str, bytes, int or :class:`eth_keys.datatypes.PrivateKey`
        :returns: the provided key represented as a :class:`eth_keys.datatypes.PrivateKey`
        """
        if isinstance(key, self._keys.PrivateKey):
            return key

        try:
            return self._keys.PrivateKey(HexBytes(key))
        except ValidationError as original_exception:
            raise ValueError(
                "The private key must be exactly 32 bytes long, instead of "
                "%d bytes." % len(key)
            ) from original_exception

Static methods

def decrypt(keyfile_json, password)

Decrypts a private key that was encrypted using an Ethereum client or :meth:~Account.encrypt.

:param keyfile_json: The encrypted key :type keyfile_json: dict or str :param str password: The password that was used to encrypt the key :returns: the raw private key :rtype: ~hexbytes.main.HexBytes

.. code-block:: python

>>> encrypted = {
 'address': '5ce9454909639d2d17a3f753ce7d93fa0b9ab12e',
 'crypto': {'cipher': 'aes-128-ctr',
  'cipherparams': {'iv': '78f214584844e0b241b433d7c3bb8d5f'},
  'ciphertext': 'd6dbb56e4f54ba6db2e8dc14df17cb7352fdce03681dd3f90ce4b6c1d5af2c4f',
  'kdf': 'pbkdf2',
  'kdfparams': {'c': 1000000,
   'dklen': 32,
   'prf': 'hmac-sha256',
   'salt': '45cf943b4de2c05c2c440ef96af914a2'},
  'mac': 'f5e1af09df5ded25c96fcf075ada313fb6f79735a914adc8cb02e8ddee7813c3'},
 'id': 'b812f3f9-78cc-462a-9e89-74418aa27cb0',
 'version': 3}

>>> import getpass
>>> Account.decrypt(encrypted, getpass.getpass())
HexBytes('0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364')
Expand source code
@staticmethod
def decrypt(keyfile_json, password):
    """
    Decrypts a private key that was encrypted using an Ethereum client or
    :meth:`~Account.encrypt`.

    :param keyfile_json: The encrypted key
    :type keyfile_json: dict or str
    :param str password: The password that was used to encrypt the key
    :returns: the raw private key
    :rtype: ~hexbytes.main.HexBytes

    .. code-block:: python

        >>> encrypted = {
         'address': '5ce9454909639d2d17a3f753ce7d93fa0b9ab12e',
         'crypto': {'cipher': 'aes-128-ctr',
          'cipherparams': {'iv': '78f214584844e0b241b433d7c3bb8d5f'},
          'ciphertext': 'd6dbb56e4f54ba6db2e8dc14df17cb7352fdce03681dd3f90ce4b6c1d5af2c4f',
          'kdf': 'pbkdf2',
          'kdfparams': {'c': 1000000,
           'dklen': 32,
           'prf': 'hmac-sha256',
           'salt': '45cf943b4de2c05c2c440ef96af914a2'},
          'mac': 'f5e1af09df5ded25c96fcf075ada313fb6f79735a914adc8cb02e8ddee7813c3'},
         'id': 'b812f3f9-78cc-462a-9e89-74418aa27cb0',
         'version': 3}

        >>> import getpass
        >>> Account.decrypt(encrypted, getpass.getpass())
        HexBytes('0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364')

    """
    if isinstance(keyfile_json, str):
        keyfile = json.loads(keyfile_json)
    elif is_dict(keyfile_json):
        keyfile = keyfile_json
    else:
        raise TypeError("The keyfile should be supplied as a JSON string, or a dictionary.")
    password_bytes = text_if_str(to_bytes, password)
    return HexBytes(decode_keyfile_json(keyfile, password_bytes))
def encrypt(private_key, password, kdf=None, iterations=None)

Creates a dictionary with an encrypted version of your private key. To import this keyfile into Ethereum clients like geth and parity: encode this dictionary with :func:json.dumps and save it to disk where your client keeps key files.

:param private_key: The raw private key :type private_key: hex str, bytes, int or :class:eth_keys.datatypes.PrivateKey :param str password: The password which you will need to unlock the account in your client :param str kdf: The key derivation function to use when encrypting your private key :param int iterations: The work factor for the key derivation function :returns: The data to use in your encrypted file :rtype: dict

If kdf is not set, the default key derivation function falls back to the environment variable :envvar:ETH_ACCOUNT_KDF. If that is not set, then 'scrypt' will be used as the default.

.. code-block:: python

>>> import getpass
>>> encrypted = Account.encrypt(
    0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364,
    getpass.getpass()
)

{
    'address': '5ce9454909639d2d17a3f753ce7d93fa0b9ab12e',
    'crypto': {
        'cipher': 'aes-128-ctr',
        'cipherparams': {
            'iv': '0b7845a5c3597d3d378bde9b7c7319b7'
        },
        'ciphertext': 'a494f1feb3c854e99c1ff01e6aaa17d43c0752009073503b908457dc8de5d2a5',  # noqa: E501
        'kdf': 'scrypt',
        'kdfparams': {
            'dklen': 32,
            'n': 262144,
            'p': 8,
            'r': 1,
            'salt': '13c4a48123affaa29189e9097726c698'
        },
        'mac': 'f4cfb027eb0af9bd7a320b4374a3fa7bef02cfbafe0ec5d1fd7ad129401de0b1'
    },
    'id': 'a60e0578-0e5b-4a75-b991-d55ec6451a6f',
    'version': 3
}

 >>> with open('my-keyfile', 'w') as f:
     f.write(json.dumps(encrypted))
Expand source code
@classmethod
def encrypt(cls, private_key, password, kdf=None, iterations=None):
    """
    Creates a dictionary with an encrypted version of your private key.
    To import this keyfile into Ethereum clients like geth and parity:
    encode this dictionary with :func:`json.dumps` and save it to disk where your
    client keeps key files.

    :param private_key: The raw private key
    :type private_key: hex str, bytes, int or :class:`eth_keys.datatypes.PrivateKey`
    :param str password: The password which you will need to unlock the account in your client
    :param str kdf: The key derivation function to use when encrypting your private key
    :param int iterations: The work factor for the key derivation function
    :returns: The data to use in your encrypted file
    :rtype: dict

    If kdf is not set, the default key derivation function falls back to the
    environment variable :envvar:`ETH_ACCOUNT_KDF`. If that is not set, then
    'scrypt' will be used as the default.

    .. code-block:: python

        >>> import getpass
        >>> encrypted = Account.encrypt(
            0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364,
            getpass.getpass()
        )

        {
            'address': '5ce9454909639d2d17a3f753ce7d93fa0b9ab12e',
            'crypto': {
                'cipher': 'aes-128-ctr',
                'cipherparams': {
                    'iv': '0b7845a5c3597d3d378bde9b7c7319b7'
                },
                'ciphertext': 'a494f1feb3c854e99c1ff01e6aaa17d43c0752009073503b908457dc8de5d2a5',  # noqa: E501
                'kdf': 'scrypt',
                'kdfparams': {
                    'dklen': 32,
                    'n': 262144,
                    'p': 8,
                    'r': 1,
                    'salt': '13c4a48123affaa29189e9097726c698'
                },
                'mac': 'f4cfb027eb0af9bd7a320b4374a3fa7bef02cfbafe0ec5d1fd7ad129401de0b1'
            },
            'id': 'a60e0578-0e5b-4a75-b991-d55ec6451a6f',
            'version': 3
        }

         >>> with open('my-keyfile', 'w') as f:
             f.write(json.dumps(encrypted))
    """
    if isinstance(private_key, keys.PrivateKey):
        key_bytes = private_key.to_bytes()
    else:
        key_bytes = HexBytes(private_key)

    if kdf is None:
        kdf = cls._default_kdf

    password_bytes = text_if_str(to_bytes, password)
    assert len(key_bytes) == 32

    return create_keyfile_json(key_bytes, password_bytes, kdf=kdf, iterations=iterations)

Methods

def create(self, extra_entropy='')

Creates a new private key, and returns it as a :class:~eth_account.local.LocalAccount.

:param extra_entropy: Add extra randomness to whatever randomness your OS can provide :type extra_entropy: str or bytes or int :returns: an object with private key and convenience methods

.. code-block:: python

>>> from eth_account import Account
>>> acct = Account.create('KEYSMASH FJAFJKLDSKF7JKFDJ 1530')
>>> acct.address
'0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E'
>>> acct.key
b"\xb2\}\xb3\x1f\xee\xd9\x12''\xbf\t9\xdcv\x9a\x96VK-\xe4\xc4rm\x03[6\xec\xf1\xe5\xb3d"

# These methods are also available: sign_message(), sign_transaction(), encrypt()
# They correspond to the same-named methods in Account.*
# but without the private key argument
Expand source code
@combomethod
def create(self, extra_entropy=''):
    r"""
    Creates a new private key, and returns it as a :class:`~eth_account.local.LocalAccount`.

    :param extra_entropy: Add extra randomness to whatever randomness your OS can provide
    :type extra_entropy: str or bytes or int
    :returns: an object with private key and convenience methods

    .. code-block:: python

        >>> from eth_account import Account
        >>> acct = Account.create('KEYSMASH FJAFJKLDSKF7JKFDJ 1530')
        >>> acct.address
        '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E'
        >>> acct.key
        b"\xb2\}\xb3\x1f\xee\xd9\x12''\xbf\t9\xdcv\x9a\x96VK-\xe4\xc4rm\x03[6\xec\xf1\xe5\xb3d"

        # These methods are also available: sign_message(), sign_transaction(), encrypt()
        # They correspond to the same-named methods in Account.*
        # but without the private key argument
    """
    extra_key_bytes = text_if_str(to_bytes, extra_entropy)
    key_bytes = keccak(os.urandom(32) + extra_key_bytes)
    return self.from_key(key_bytes)
def from_key(self, private_key)

Returns a convenient object for working with the given private key.

:param private_key: The raw private key :type private_key: hex str, bytes, int or :class:eth_keys.datatypes.PrivateKey :return: object with methods for signing and encrypting :rtype: LocalAccount

.. code-block:: python

>>> acct = Account.from_key(
  0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364)
>>> acct.address
'0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E'
>>> acct.key
b"\xb2\}\xb3\x1f\xee\xd9\x12''xbf\t9\xdcv\x9a\x96VK-\xe4\xc4rm\x03[6\xec\xf1\xe5\xb3d"

# These methods are also available: sign_message(), sign_transaction(), encrypt()
# They correspond to the same-named methods in Account.*
# but without the private key argument
Expand source code
@combomethod
def from_key(self, private_key):
    r"""
    Returns a convenient object for working with the given private key.

    :param private_key: The raw private key
    :type private_key: hex str, bytes, int or :class:`eth_keys.datatypes.PrivateKey`
    :return: object with methods for signing and encrypting
    :rtype: LocalAccount

    .. code-block:: python

        >>> acct = Account.from_key(
          0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364)
        >>> acct.address
        '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E'
        >>> acct.key
        b"\xb2\}\xb3\x1f\xee\xd9\x12''xbf\t9\xdcv\x9a\x96VK-\xe4\xc4rm\x03[6\xec\xf1\xe5\xb3d"

        # These methods are also available: sign_message(), sign_transaction(), encrypt()
        # They correspond to the same-named methods in Account.*
        # but without the private key argument
    """
    key = self._parsePrivateKey(private_key)
    return LocalAccount(key, self)
def privateKeyToAccount(self, private_key)

Caution: Deprecated for :meth:~eth_account.account.Account.from_key.

This method will be removed in v0.5

Expand source code
@combomethod
def privateKeyToAccount(self, private_key):
    """
    .. CAUTION:: Deprecated for :meth:`~eth_account.account.Account.from_key`.
        This method will be removed in v0.5
    """
    warnings.warn(
        "privateKeyToAccount is deprecated in favor of from_key",
        category=DeprecationWarning,
    )
    return self.from_key(private_key)
def recoverHash(self, message_hash, vrs=None, signature=None)

Get the address of the account that signed the message with the given hash. You must specify exactly one of: vrs or signature

Caution: Deprecated for :meth:~eth_account.account.Account.recover_message.

This method might be removed as early as v0.5

:param message_hash: the hash of the message that you want to verify :type message_hash: hex str or bytes or int :param vrs: the three pieces generated by an elliptic curve signature :type vrs: tuple(v, r, s), each element is hex str, bytes or int :param signature: signature bytes concatenated as r+s+v :type signature: hex str or bytes or int :returns: address of signer, hex-encoded & checksummed :rtype: str

Expand source code
@combomethod
def recoverHash(self, message_hash, vrs=None, signature=None):
    """
    Get the address of the account that signed the message with the given hash.
    You must specify exactly one of: vrs or signature

    .. CAUTION:: Deprecated for :meth:`~eth_account.account.Account.recover_message`.
        This method might be removed as early as v0.5

    :param message_hash: the hash of the message that you want to verify
    :type message_hash: hex str or bytes or int
    :param vrs: the three pieces generated by an elliptic curve signature
    :type vrs: tuple(v, r, s), each element is hex str, bytes or int
    :param signature: signature bytes concatenated as r+s+v
    :type signature: hex str or bytes or int
    :returns: address of signer, hex-encoded & checksummed
    :rtype: str
    """
    warnings.warn(
        "recoverHash is deprecated in favor of recover_message",
        category=DeprecationWarning,
    )
    return self._recover_hash(message_hash, vrs, signature)
def recoverTransaction(self, serialized_transaction)

Caution: Deprecated for :meth:~eth_account.account.Account.recover_transaction.

This method will be removed in v0.5

Expand source code
@combomethod
def recoverTransaction(self, serialized_transaction):
    """
    .. CAUTION:: Deprecated for :meth:`~eth_account.account.Account.recover_transaction`.
        This method will be removed in v0.5
    """
    warnings.warn(
        "recoverTransaction is deprecated in favor of recover_transaction",
        category=DeprecationWarning,
    )
    return self.recover_transaction(serialized_transaction)
def recover_message(self, signable_message: eth_account.messages.SignableMessage, vrs=None, signature=None)

Get the address of the account that signed the given message. You must specify exactly one of: vrs or signature

:param signable_message: the message that was signed :param vrs: the three pieces generated by an elliptic curve signature :type vrs: tuple(v, r, s), each element is hex str, bytes or int :param signature: signature bytes concatenated as r+s+v :type signature: hex str or bytes or int :returns: address of signer, hex-encoded & checksummed :rtype: str

.. code-block:: python

>>> from eth_account.messages import encode_defunct
>>> message = encode_defunct(text="I♥SF")
>>> vrs = (
      28,
      '0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb3',
      '0x3e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce')
>>> Account.recover_message(message, vrs=vrs)
'0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E'

# All of these recover calls are equivalent:

# variations on vrs
>>> vrs = (
      '0x1c',
      '0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb3',
      '0x3e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce')
>>> Account.recover_message(message, vrs=vrs)
>>> vrs = (
      b'\x1c',
      b'\\xe6\\xca\\x9b\\xbaX\\xc8\\x86\\x11\\xfa\\xd6jl\\xe8\\xf9\\x96\\x90\\x81\\x95Y8\\x07\\xc4\\xb3\\x8b\\xd5(\\xd2\\xcf\\xf0\\x9dN\\xb3',  # noqa: E501
      b'>[\\xfb\\xbfM>9\\xb1\\xa2\\xfd\\x81jv\\x80\\xc1\\x9e\\xbe\\xba\\xf3\\xa1A\\xb29\\x93J\\xd4<\\xb3?\\xce\\xc8\\xce')  # noqa: E501
>>> Account.recover_message(message, vrs=vrs)
>>> # Caution about this approach: likely problems if there are leading 0s
>>> vrs = (
      0x1c,
      0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb3,
      0x3e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce)
>>> Account.recover_message(message, vrs=vrs)

# variations on signature
>>> signature = '0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb33e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce1c'  # noqa: E501
>>> Account.recover_message(message, signature=signature)
>>> signature = b'\\xe6\\xca\\x9b\\xbaX\\xc8\\x86\\x11\\xfa\\xd6jl\\xe8\\xf9\\x96\\x90\\x81\\x95Y8\\x07\\xc4\\xb3\\x8b\\xd5(\\xd2\\xcf\\xf0\\x9dN\\xb3>[\\xfb\\xbfM>9\\xb1\\xa2\\xfd\\x81jv\\x80\\xc1\\x9e\\xbe\\xba\\xf3\\xa1A\\xb29\\x93J\\xd4<\\xb3?\\xce\\xc8\\xce\\x1c'  # noqa: E501
>>> Account.recover_message(message, signature=signature)
>>> # Caution about this approach: likely problems if there are leading 0s
>>> signature = 0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb33e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce1c  # noqa: E501
>>> Account.recover_message(message, signature=signature)
Expand source code
@combomethod
def recover_message(self, signable_message: SignableMessage, vrs=None, signature=None):
    r"""
    Get the address of the account that signed the given message.
    You must specify exactly one of: vrs or signature

    :param signable_message: the message that was signed
    :param vrs: the three pieces generated by an elliptic curve signature
    :type vrs: tuple(v, r, s), each element is hex str, bytes or int
    :param signature: signature bytes concatenated as r+s+v
    :type signature: hex str or bytes or int
    :returns: address of signer, hex-encoded & checksummed
    :rtype: str

    .. code-block:: python

        >>> from eth_account.messages import encode_defunct
        >>> message = encode_defunct(text="I♥SF")
        >>> vrs = (
              28,
              '0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb3',
              '0x3e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce')
        >>> Account.recover_message(message, vrs=vrs)
        '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E'

        # All of these recover calls are equivalent:

        # variations on vrs
        >>> vrs = (
              '0x1c',
              '0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb3',
              '0x3e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce')
        >>> Account.recover_message(message, vrs=vrs)
        >>> vrs = (
              b'\x1c',
              b'\\xe6\\xca\\x9b\\xbaX\\xc8\\x86\\x11\\xfa\\xd6jl\\xe8\\xf9\\x96\\x90\\x81\\x95Y8\\x07\\xc4\\xb3\\x8b\\xd5(\\xd2\\xcf\\xf0\\x9dN\\xb3',  # noqa: E501
              b'>[\\xfb\\xbfM>9\\xb1\\xa2\\xfd\\x81jv\\x80\\xc1\\x9e\\xbe\\xba\\xf3\\xa1A\\xb29\\x93J\\xd4<\\xb3?\\xce\\xc8\\xce')  # noqa: E501
        >>> Account.recover_message(message, vrs=vrs)
        >>> # Caution about this approach: likely problems if there are leading 0s
        >>> vrs = (
              0x1c,
              0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb3,
              0x3e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce)
        >>> Account.recover_message(message, vrs=vrs)

        # variations on signature
        >>> signature = '0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb33e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce1c'  # noqa: E501
        >>> Account.recover_message(message, signature=signature)
        >>> signature = b'\\xe6\\xca\\x9b\\xbaX\\xc8\\x86\\x11\\xfa\\xd6jl\\xe8\\xf9\\x96\\x90\\x81\\x95Y8\\x07\\xc4\\xb3\\x8b\\xd5(\\xd2\\xcf\\xf0\\x9dN\\xb3>[\\xfb\\xbfM>9\\xb1\\xa2\\xfd\\x81jv\\x80\\xc1\\x9e\\xbe\\xba\\xf3\\xa1A\\xb29\\x93J\\xd4<\\xb3?\\xce\\xc8\\xce\\x1c'  # noqa: E501
        >>> Account.recover_message(message, signature=signature)
        >>> # Caution about this approach: likely problems if there are leading 0s
        >>> signature = 0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb33e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce1c  # noqa: E501
        >>> Account.recover_message(message, signature=signature)
    """
    message_hash = _hash_eip191_message(signable_message)
    return self._recover_hash(message_hash, vrs, signature)
def recover_transaction(self, serialized_transaction)

Get the address of the account that signed this transaction.

:param serialized_transaction: the complete signed transaction :type serialized_transaction: hex str, bytes or int :returns: address of signer, hex-encoded & checksummed :rtype: str

.. code-block:: python

>>> raw_transaction = '0xf86a8086d55698372431831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca008025a009ebb6ca057a0535d6186462bc0b465b561c94a295bdb0621fc19208ab149a9ca0440ffd775ce91a833ab410777204d5341a6f9fa91216a6f3ee2c051fea6a0428',  # noqa: E501
>>> Account.recover_transaction(raw_transaction)
'0x2c7536E3605D9C16a7a3D7b1898e529396a65c23'
Expand source code
@combomethod
def recover_transaction(self, serialized_transaction):
    """
    Get the address of the account that signed this transaction.

    :param serialized_transaction: the complete signed transaction
    :type serialized_transaction: hex str, bytes or int
    :returns: address of signer, hex-encoded & checksummed
    :rtype: str

    .. code-block:: python

        >>> raw_transaction = '0xf86a8086d55698372431831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca008025a009ebb6ca057a0535d6186462bc0b465b561c94a295bdb0621fc19208ab149a9ca0440ffd775ce91a833ab410777204d5341a6f9fa91216a6f3ee2c051fea6a0428',  # noqa: E501
        >>> Account.recover_transaction(raw_transaction)
        '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23'
    """
    txn_bytes = HexBytes(serialized_transaction)
    txn = Transaction.from_bytes(txn_bytes)
    msg_hash = hash_of_signed_transaction(txn)
    return self._recover_hash(msg_hash, vrs=vrs_from(txn))
def setKeyBackend(self, backend)

Caution: Deprecated for :meth:~eth_account.account.Account.set_key_backend.

This method will be removed in v0.5

Expand source code
def setKeyBackend(self, backend):
    """
    .. CAUTION:: Deprecated for :meth:`~eth_account.account.Account.set_key_backend`.
        This method will be removed in v0.5
    """
    warnings.warn(
        "setKeyBackend is deprecated in favor of set_key_backend",
        category=DeprecationWarning,
    )
    self.set_key_backend(backend)
def set_key_backend(self, backend)

Change the backend used by the underlying eth-keys library.

(The default is fine for most users)

:param backend: any backend that works in eth_keys.KeyApi(backend) <https://github.com/ethereum/eth-keys/#keyapibackendnone>_

Expand source code
def set_key_backend(self, backend):
    """
    Change the backend used by the underlying eth-keys library.

    *(The default is fine for most users)*

    :param backend: any backend that works in
        `eth_keys.KeyApi(backend) <https://github.com/ethereum/eth-keys/#keyapibackendnone>`_

    """
    self._keys = KeyAPI(backend)
def signHash(self, message_hash, private_key)

Warning: Never sign a hash that you didn't generate,

it can be an arbitrary transaction. For example, it might send all of your account's ether to an attacker. Instead, prefer :meth:~eth_account.account.Account.sign_message, which cannot accidentally sign a transaction.

Sign the provided hash.

Caution: Deprecated for :meth:~eth_account.account.Account.sign_message.

This method will be removed in v0.5

:param message_hash: the 32-byte message hash to be signed :type message_hash: hex str, bytes or int :param private_key: the key to sign the message with :type private_key: hex str, bytes, int or :class:eth_keys.datatypes.PrivateKey :returns: Various details about the signature - most importantly the fields: v, r, and s :rtype: ~eth_account.datastructures.AttributeDict

Expand source code
@combomethod
def signHash(self, message_hash, private_key):
    """
    .. WARNING:: *Never* sign a hash that you didn't generate,
        it can be an arbitrary transaction. For example, it might
        send all of your account's ether to an attacker.
        Instead, prefer :meth:`~eth_account.account.Account.sign_message`,
        which cannot accidentally sign a transaction.

    Sign the provided hash.

    .. CAUTION:: Deprecated for :meth:`~eth_account.account.Account.sign_message`.
        This method will be removed in v0.5

    :param message_hash: the 32-byte message hash to be signed
    :type message_hash: hex str, bytes or int
    :param private_key: the key to sign the message with
    :type private_key: hex str, bytes, int or :class:`eth_keys.datatypes.PrivateKey`
    :returns: Various details about the signature - most
      importantly the fields: v, r, and s
    :rtype: ~eth_account.datastructures.AttributeDict
    """
    warnings.warn(
        "signHash is deprecated in favor of sign_message",
        category=DeprecationWarning,
    )
    return self._sign_hash(message_hash, private_key)
def signTransaction(self, transaction_dict, private_key)

Caution: Deprecated for :meth:~eth_account.account.Account.sign_transaction.

This method will be removed in v0.5

Expand source code
@combomethod
def signTransaction(self, transaction_dict, private_key):
    """
    .. CAUTION:: Deprecated for :meth:`~eth_account.account.Account.sign_transaction`.
        This method will be removed in v0.5
    """
    warnings.warn(
        "signTransaction is deprecated in favor of sign_transaction",
        category=DeprecationWarning,
    )
    return self.sign_transaction(transaction_dict, private_key)
def sign_message(self, signable_message: eth_account.messages.SignableMessage, private_key)

Sign the provided message.

This API supports any messaging format that will encode to EIP-191_ messages.

If you would like historical compatibility with :meth:w3.eth.sign() <web3.eth.Eth.sign> you can use :meth:~eth_account.messages.encode_defunct.

Other options are the "validator", or "structured data" standards. (Both of these are in DRAFT status currently, so be aware that the implementation is not guaranteed to be stable). You can import all supported message encoders in eth_account.messages.

:param signable_message: the encoded message for signing :param private_key: the key to sign the message with :type private_key: hex str, bytes, int or :class:eth_keys.datatypes.PrivateKey :returns: Various details about the signature - most importantly the fields: v, r, and s :rtype: ~eth_account.datastructures.AttributeDict

.. code-block:: python

>>> msg = "I♥SF"
>>> from eth_account.messages import encode_defunct
>>> msghash = encode_defunct(text=msg)
SignableMessage(version=b'E', header=b'thereum Signed Message:\n6', body=b'I\xe2\x99\xa5SF')
>>> # If you're curious about the internal fields of SignableMessage, take a look at EIP-191, linked above
>>> key = "0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364"
>>> Account.sign_message(msghash, key)
{'messageHash': HexBytes('0x1476abb745d423bf09273f1afd887d951181d25adc66c4834a70491911b7f750'),  # noqa: E501
 'r': 104389933075820307925104709181714897380569894203213074526835978196648170704563,
 's': 28205917190874851400050446352651915501321657673772411533993420917949420456142,
 'signature': HexBytes('0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb33e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce1c'),  # noqa: E501
 'v': 28}

.. _EIP-191: https://eips.ethereum.org/EIPS/eip-191

Expand source code
@combomethod
def sign_message(self, signable_message: SignableMessage, private_key):
    r"""
    Sign the provided message.

    This API supports any messaging format that will encode to EIP-191_ messages.

    If you would like historical compatibility with
    :meth:`w3.eth.sign() <web3.eth.Eth.sign>`
    you can use :meth:`~eth_account.messages.encode_defunct`.

    Other options are the "validator", or "structured data" standards. (Both of these
    are in *DRAFT* status currently, so be aware that the implementation is not
    guaranteed to be stable). You can import all supported message encoders in
    ``eth_account.messages``.

    :param signable_message: the encoded message for signing
    :param private_key: the key to sign the message with
    :type private_key: hex str, bytes, int or :class:`eth_keys.datatypes.PrivateKey`
    :returns: Various details about the signature - most importantly the fields: v, r, and s
    :rtype: ~eth_account.datastructures.AttributeDict

    .. code-block:: python

        >>> msg = "I♥SF"
        >>> from eth_account.messages import encode_defunct
        >>> msghash = encode_defunct(text=msg)
        SignableMessage(version=b'E', header=b'thereum Signed Message:\n6', body=b'I\xe2\x99\xa5SF')
        >>> # If you're curious about the internal fields of SignableMessage, take a look at EIP-191, linked above
        >>> key = "0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364"
        >>> Account.sign_message(msghash, key)
        {'messageHash': HexBytes('0x1476abb745d423bf09273f1afd887d951181d25adc66c4834a70491911b7f750'),  # noqa: E501
         'r': 104389933075820307925104709181714897380569894203213074526835978196648170704563,
         's': 28205917190874851400050446352651915501321657673772411533993420917949420456142,
         'signature': HexBytes('0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb33e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce1c'),  # noqa: E501
         'v': 28}

    .. _EIP-191: https://eips.ethereum.org/EIPS/eip-191
    """
    message_hash = _hash_eip191_message(signable_message)
    return self._sign_hash(message_hash, private_key)
def sign_transaction(self, transaction_dict, private_key)

Sign a transaction using a local private key. Produces signature details and the hex-encoded transaction suitable for broadcast using :meth:w3.eth.sendRawTransaction() <web3.eth.Eth.sendRawTransaction>.

Create the transaction dict for a contract method with my_contract.functions.my_function().buildTransaction() <http://web3py.readthedocs.io/en/latest/contracts.html#methods>_

:param dict transaction_dict: the transaction with keys: nonce, chainId, to, data, value, gas, and gasPrice. :param private_key: the private key to sign the data with :type private_key: hex str, bytes, int or :class:eth_keys.datatypes.PrivateKey :returns: Various details about the signature - most importantly the fields: v, r, and s :rtype: AttributeDict

.. code-block:: python

>>> transaction = {
        # Note that the address must be in checksum format or native bytes:
        'to': '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55',
        'value': 1000000000,
        'gas': 2000000,
        'gasPrice': 234567897654321,
        'nonce': 0,
        'chainId': 1
    }
>>> key = '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318'
>>> signed = Account.sign_transaction(transaction, key)
{'hash': HexBytes('0x6893a6ee8df79b0f5d64a180cd1ef35d030f3e296a5361cf04d02ce720d32ec5'),
 'r': 4487286261793418179817841024889747115779324305375823110249149479905075174044,
 'rawTransaction': HexBytes('0xf86a8086d55698372431831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca008025a009ebb6ca057a0535d6186462bc0b465b561c94a295bdb0621fc19208ab149a9ca0440ffd775ce91a833ab410777204d5341a6f9fa91216a6f3ee2c051fea6a0428'),  # noqa: E501
 's': 30785525769477805655994251009256770582792548537338581640010273753578382951464,
 'v': 37}
>>> w3.eth.sendRawTransaction(signed.rawTransaction)
Expand source code
@combomethod
def sign_transaction(self, transaction_dict, private_key):
    """
    Sign a transaction using a local private key. Produces signature details
    and the hex-encoded transaction suitable for broadcast using
    :meth:`w3.eth.sendRawTransaction() <web3.eth.Eth.sendRawTransaction>`.

    Create the transaction dict for a contract method with
    `my_contract.functions.my_function().buildTransaction()
    <http://web3py.readthedocs.io/en/latest/contracts.html#methods>`_

    :param dict transaction_dict: the transaction with keys:
      nonce, chainId, to, data, value, gas, and gasPrice.
    :param private_key: the private key to sign the data with
    :type private_key: hex str, bytes, int or :class:`eth_keys.datatypes.PrivateKey`
    :returns: Various details about the signature - most
      importantly the fields: v, r, and s
    :rtype: AttributeDict

    .. code-block:: python

        >>> transaction = {
                # Note that the address must be in checksum format or native bytes:
                'to': '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55',
                'value': 1000000000,
                'gas': 2000000,
                'gasPrice': 234567897654321,
                'nonce': 0,
                'chainId': 1
            }
        >>> key = '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318'
        >>> signed = Account.sign_transaction(transaction, key)
        {'hash': HexBytes('0x6893a6ee8df79b0f5d64a180cd1ef35d030f3e296a5361cf04d02ce720d32ec5'),
         'r': 4487286261793418179817841024889747115779324305375823110249149479905075174044,
         'rawTransaction': HexBytes('0xf86a8086d55698372431831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca008025a009ebb6ca057a0535d6186462bc0b465b561c94a295bdb0621fc19208ab149a9ca0440ffd775ce91a833ab410777204d5341a6f9fa91216a6f3ee2c051fea6a0428'),  # noqa: E501
         's': 30785525769477805655994251009256770582792548537338581640010273753578382951464,
         'v': 37}
        >>> w3.eth.sendRawTransaction(signed.rawTransaction)
    """
    if not isinstance(transaction_dict, Mapping):
        raise TypeError("transaction_dict must be dict-like, got %r" % transaction_dict)

    account = self.from_key(private_key)

    # allow from field, *only* if it matches the private key
    if 'from' in transaction_dict:
        if transaction_dict['from'] == account.address:
            sanitized_transaction = dissoc(transaction_dict, 'from')
        else:
            raise TypeError("from field must match key's %s, but it was %s" % (
                account.address,
                transaction_dict['from'],
            ))
    else:
        sanitized_transaction = transaction_dict

    # sign transaction
    (
        v,
        r,
        s,
        rlp_encoded,
    ) = sign_transaction_dict(account._key_obj, sanitized_transaction)

    transaction_hash = keccak(rlp_encoded)

    return AttributeDict({
        'rawTransaction': HexBytes(rlp_encoded),
        'hash': HexBytes(transaction_hash),
        'r': r,
        's': s,
        'v': v,
    })
class HttpProvider (node_url, request_kwargs=None)

A Connection object to make HTTP requests to a particular node.

Initializes a :class:~tronpytool.providers.http.HttpProvider instance.

Args: node_url (str): Url of the node to connect to. request_kwargs (dict): Optional params to send with each request.

Expand source code
class HttpProvider(BaseProvider):
    """A Connection object to make HTTP requests to a particular node."""

    def __init__(self, node_url, request_kwargs=None):
        """Initializes a :class:`~tronpytool.providers.http.HttpProvider`
        instance.

         Args:
            node_url (str):  Url of the node to connect to.
            request_kwargs (dict): Optional params to send with each request.

        """

        self.node_url = node_url.rstrip('/')
        uri = urlparse(node_url)
        # This condition checks the node that will connect
        # to work with methods.
        if uri.scheme not in HTTP_SCHEMES:
            raise NotImplementedError(
                'TronAPI does not know how to connect to scheme %r in %r' % (
                    uri.scheme,
                    self.node_url,
                )
            )

        self._request_kwargs = request_kwargs or {}
        self.session = Session()

    @to_dict
    def get_request_kwargs(self):
        """Header settings"""
        if 'headers' not in self._request_kwargs:
            yield 'headers', self._http_default_headers()
        for key, value in self._request_kwargs.items():
            yield key, value

    def request(self, path, json=None, params=None, method=None):
        """Performs an HTTP request with the given parameters.

           Args:
               path (str): API endpoint path (e.g.: ``'/transactions'``).
               json (dict): JSON data to send along with the request.
               params (dict): Dictionary of URL (query) parameters.
               method (str): HTTP method (e.g.: ``'GET'``).

        """
        try:
            response = self._request(
                method=method,
                url=self.node_url + path if path else self.node_url,
                json=json,
                params=params,
                **self.get_request_kwargs(),
            )
        except TrxConnectionError as err:
            raise err

        return response.data

    def is_connected(self) -> bool:
        """Connection check

        This method sends a test request to the connected node
        to determine its health.

        Returns:
            bool: True if successful,
            False otherwise.
        """
        response = self.request(path=self.status_page, method='get')
        if 'blockID' in response or response == 'OK':
            return True

        return False

    def _request(self, **kwargs):

        kwargs.setdefault('timeout', 60)

        response = self.session.request(**kwargs)
        text = response.text

        try:
            json = response.json()
        except ValueError:
            json = None

        if not (200 <= response.status_code < 300):
            exc_cls = HTTP_EXCEPTIONS.get(response.status_code, TransportError)
            raise exc_cls(response.status_code, text, json, kwargs.get('url'))

        data = json if json is not None else text
        log.debug(data)

        # Additional error interceptor that will occur in case of failed requests
        if 'Error' in data:
            raise ValueError(data['Error'])

        self.__error_manager(data)

        return HttpResponse(response.status_code, response.headers, data)

    @staticmethod
    def __error_manager(data):
        """Manager error

        Args:
            data (any): response data

        """
        # Additional error interceptor that will occur in case of failed requests
        if 'Error' in data:
            raise ValueError(data['Error'])

        # Convert hash errors
        if 'code' in data and 'message' in data:
            data['message'] = to_text(hexstr=data['message'])

Ancestors

Methods

def get_request_kwargs(self)

Header settings

Expand source code
@to_dict
def get_request_kwargs(self):
    """Header settings"""
    if 'headers' not in self._request_kwargs:
        yield 'headers', self._http_default_headers()
    for key, value in self._request_kwargs.items():
        yield key, value
def is_connected(self) ‑> bool

Connection check

This method sends a test request to the connected node to determine its health.

Returns

bool
True if successful,

False otherwise.

Expand source code
def is_connected(self) -> bool:
    """Connection check

    This method sends a test request to the connected node
    to determine its health.

    Returns:
        bool: True if successful,
        False otherwise.
    """
    response = self.request(path=self.status_page, method='get')
    if 'blockID' in response or response == 'OK':
        return True

    return False
def request(self, path, json=None, params=None, method=None)

Performs an HTTP request with the given parameters.

Args

path : str
API endpoint path (e.g.: '/transactions').
json : dict
JSON data to send along with the request.
params : dict
Dictionary of URL (query) parameters.
method : str
HTTP method (e.g.: 'GET').
Expand source code
def request(self, path, json=None, params=None, method=None):
    """Performs an HTTP request with the given parameters.

       Args:
           path (str): API endpoint path (e.g.: ``'/transactions'``).
           json (dict): JSON data to send along with the request.
           params (dict): Dictionary of URL (query) parameters.
           method (str): HTTP method (e.g.: ``'GET'``).

    """
    try:
        response = self._request(
            method=method,
            url=self.node_url + path if path else self.node_url,
            json=json,
            params=params,
            **self.get_request_kwargs(),
        )
    except TrxConnectionError as err:
        raise err

    return response.data

Inherited members

class Tron (**kwargs)

Connect to the Tron network.

Args

kwargs : Any
We fill the most necessary parameters

for working with blockchain Tron

Expand source code
class Tron:
    # Providers
    # SolcWrap = SolcWrap

    _default_block = None
    _private_key = None
    _default_address = AttributeDict({})

    # Encoding and Decoding
    toBytes = staticmethod(to_bytes)
    toInt = staticmethod(to_int)
    toHex = staticmethod(to_hex)
    toText = staticmethod(to_text)
    toJSON = staticmethod(to_json)

    # Currency Utility
    toSun = staticmethod(to_sun)
    fromSun = staticmethod(from_sun)

    # Validate address
    isAddress = staticmethod(is_address)

    def __init__(self, **kwargs):
        """Connect to the Tron network.

        Args:
            kwargs (Any): We fill the most necessary parameters
            for working with blockchain Tron

        """

        # We check the obtained nodes, if the necessary parameters
        # are not specified, then we take the default
        kwargs.setdefault('full_node', constants.DEFAULT_NODES['full_node'])
        kwargs.setdefault('solidity_node', constants.DEFAULT_NODES['solidity_node'])
        kwargs.setdefault('event_server', constants.DEFAULT_NODES['event_server'])

        # The node manager allows you to automatically determine the node
        # on the router or manually refer to a specific node.
        # solidity_node, full_node or event_server
        self.manager = TronManager(self, dict(
            full_node=kwargs.get('full_node'),
            solidity_node=kwargs.get('solidity_node'),
            event_server=kwargs.get('event_server')
        ))

        # If the parameter of the private key is not empty,
        # then write to the variable
        if 'private_key' in kwargs:
            self.private_key = kwargs.get('private_key')

        # We check whether the default wallet address is set when
        # defining the class, and then written to the variable
        if 'default_address' in kwargs:
            self.default_address = kwargs.get('default_address')

        # If custom methods are not declared,
        # we take the default from the list
        modules = kwargs.setdefault('modules', DEFAULT_MODULES)
        for module_name, module_class in modules.items():
            module_class.attach(self, module_name)

        self.transaction_builder = TransactionBuilder(self)

    def setNetwork(self, networkname="nile"):
        group = constants.conf_for_name(networkname)
        self.manager = TronManager(self, constants.to_providers_set(group))
        return self

    @property
    def default_block(self):
        return self._default_block

    @default_block.setter
    def default_block(self, block_id):
        """Sets the default block used as a reference for all future calls."""
        if block_id in ('latest', 'earliest', 0):
            self._default_block = block_id
            return

        if not is_integer(block_id) or not block_id:
            raise ValueError('Invalid block ID provided')

        self._default_block = abs(block_id)

    @property
    def providers(self):
        """List providers"""
        return self.manager.providers

    @property
    def private_key(self) -> str:
        """Get a private key"""
        return self._private_key

    def getKey(self) -> "PrivateKey":
        return self.private_key_class


    @private_key.setter
    def private_key(self, value: str) -> None:
        """Set a private key used with the TronAPI instance,
        used for obtaining the address, signing transactions etc...

        Args:
            value (str): Private key
        """
        try:
            private_key = PrivateKey(value)
        except ValueError:
            raise TronError('Invalid private key provided')
        self.private_key_class = private_key
        self._private_key = str(private_key).lower()

    @property
    def default_address(self) -> AttributeDict:
        """Get a TRON Address"""
        return self._default_address

    @default_address.setter
    def default_address(self, address: str) -> None:
        """Sets the address used with all Tron API.
        Will not sign any transactions.

        Args:
             address (str) Tron Address

        """

        if not self.isAddress(address):
            raise InvalidTronError('Invalid address provided')

        _hex = self.address.to_hex(address)
        _base58 = self.address.from_hex(address)
        _private_base58 = self.address.from_private_key(self._private_key).base58

        # check the addresses
        if self._private_key and _private_base58 != _base58:
            self._private_key = None

        self._default_address = AttributeDict({
            'hex': _hex,
            'base58': _base58
        })

    def get_event_result(self, **kwargs):
        """Will return all events matching the filters.

        Args:
            kwargs (any): List parameters
        """

        # Check the most necessary parameters
        since_timestamp = kwargs.setdefault('since_timestamp', 0)
        event_name = kwargs.setdefault('event_name', 'Notify')
        block_number = kwargs.setdefault('block_number', '')
        size = kwargs.setdefault('size', 20)
        page = kwargs.setdefault('page', 1)
        only_confirmed = kwargs.setdefault('only_confirmed', None)
        only_unconfirmed = kwargs.setdefault('only_unconfirmed', None)
        previous_last = kwargs.setdefault('previous_last_event_fingerprint', None)
        contract_address = kwargs.setdefault('contract_address', self.default_address.hex)
        sort = kwargs.setdefault('sort', None)
        from_timestamp = kwargs.setdefault('from_timestamp', None)

        if not self.isAddress(contract_address):
            raise InvalidTronError('Invalid contract address provided')

        if event_name and not contract_address:
            raise TronError('Usage of event name filtering requires a contract address')

        if block_number and event_name is None:
            raise TronError('Usage of block number filtering requires an event name')

        if not is_integer(page):
            raise ValueError('Invalid size provided')

        if not is_integer(since_timestamp):
            raise ValueError('Invalid sinceTimestamp provided')

        # If the size exceeds 200, displays an error
        if size > 200:
            raise ValueError('Defaulting to maximum accepted size: 200')

        # We collect all parameters in one array
        route_params = []
        if contract_address:
            route_params.append(contract_address)
        if event_name:
            route_params.append(event_name)
        if block_number:
            route_params.append(block_number)

        route = '/'.join(route_params)

        qs = {
            'since': since_timestamp,
            'page': page,
            'size': size
        }

        if only_confirmed is not None:
            qs.update({'onlyConfirmed': only_confirmed})

        if only_unconfirmed is not None and not only_confirmed:
            qs.update({'onlyUnconfirmed': only_unconfirmed})

        if previous_last is not None:
            qs.update({'previousLastEventFingerprint': previous_last})

        if from_timestamp is not None:
            qs.update({'fromTimestamp': from_timestamp})

        if sort is not None:
            qs.update({'sort': sort})

        return self.manager.request("/event/contract/{0}?{1}"
                                    .format(route, urlencode(qs)), method='get')

    def get_event_transaction_id(self, tx_id):
        """Will return all events within a transactionID.

        Args:
            tx_id (str): TransactionID to query for events.
        """
        response = self.manager.request('/event/transaction/' + tx_id, method='get')
        return response

    @property
    def address(self) -> Address:
        """Helper object that allows you to convert
        between hex/base58 and private key representations of a TRON address.

        Note:
            If you wish to convert generic data to hexadecimal strings,
            please use the function tron.to_hex.
            return a static class
        """
        return Address()

    # Address utilities
    @staticmethod
    def generate_address(priv_key=None) -> dict:
        """Address utilities Generate a random address."""
        if priv_key is None:
            priv_key = PrivateKeyFactory.random()
        return {
            "base58check_address": priv_key.public_key.to_base58check_address(),
            "hex_address": priv_key.public_key.to_hex_address(),
            "private_key": priv_key.hex(),
            "public_key": priv_key.public_key.hex(),
        }

    def get_address_from_passphrase(self, passphrase: str) -> dict:
        """Get an address from a passphrase, compatiable with `wallet/createaddress`."""
        priv_key = PrivateKeyFactory.from_passphrase(passphrase.encode())
        return self.generate_address(priv_key)

    @staticmethod
    def create_account() -> PrivateKey:
        """Create account

        Warning: Please control risks when using this API.
        To ensure environmental security, please do not invoke APIs
        provided by other or invoke this very API on a public network.

        """
        return Account.create()

    def solidity_sha3(self, abi_types, values):
        """
            Executes keccak256 exactly as Solidity does.
            Takes list of abi_types as inputs -- `[uint24, int8[], bool]`
            and list of corresponding values  -- `[20, [-1, 5, 0], True]`

            Args:
                abi_types (any): types abi
                values (any): values

            Examples:
                >>> tron = Tron()
                >>> sol = tron.solidity_sha3(['uint8[]'], [[1, 2, 3, 4, 5]])
                >>> assert sol.hex() == '0x5917e5a395fb9b454434de59651d36822a9e29c5ec57474df3e67937b969460c'

        """
        if len(abi_types) != len(values):
            raise ValueError(
                "Length mismatch between provided abi types and values.  Got "
                "{0} types and {1} values.".format(len(abi_types), len(values))
            )

        normalized_values = map_abi_data([abi_resolver()], abi_types, values)

        hex_string = add_0x_prefix(''.join(
            remove_0x_prefix(hex_encode_abi_type(abi_type, value))
            for abi_type, value
            in zip(abi_types, normalized_values)
        ))
        return self.keccak(hexstr=hex_string)

    @staticmethod
    @apply_to_return_value(HexBytes)
    def keccak(primitive=None, text=None, hexstr=None):
        if isinstance(primitive, (bytes, int, type(None))):
            input_bytes = to_bytes(primitive, hexstr=hexstr, text=text)
            return tron_keccak(input_bytes)

        raise TypeError(
            "You called keccak with first arg %r and keywords %r. You must call it with one of "
            "these approaches: keccak(text='txt'), keccak(hexstr='0x747874'), "
            "keccak(b'\\x74\\x78\\x74'), or keccak(0x747874)." % (
                primitive,
                {'text': text, 'hexstr': hexstr}
            )
        )

    def is_connected(self):
        """List of available providers"""
        return self.manager.is_connected()

Static methods

def create_account() ‑> PrivateKey

Create account

Warning: Please control risks when using this API. To ensure environmental security, please do not invoke APIs provided by other or invoke this very API on a public network.

Expand source code
@staticmethod
def create_account() -> PrivateKey:
    """Create account

    Warning: Please control risks when using this API.
    To ensure environmental security, please do not invoke APIs
    provided by other or invoke this very API on a public network.

    """
    return Account.create()
def fromSun(number: int) ‑> Union[int, decimal.Decimal]

Helper function that will convert a value in SUN to TRX.

Args

number : int
Value in SUN to convert to TRX
Expand source code
def from_sun(number: int) -> Union[int, decimal.Decimal]:
    """Helper function that will convert a value in SUN to TRX.

    Args:
        number (int): Value in SUN to convert to TRX

    """
    if number == 0:
        return 0

    if number < MIN_SUN or number > MAX_SUN:
        raise ValueError("value must be between 1 and 2**256 - 1")

    unit_value = UNITS['sun']

    with localcontext() as ctx:
        ctx.prec = 999
        d_number = decimal.Decimal(value=number, context=ctx)
        result_value = d_number / unit_value

    return result_value
def generate_address(priv_key=None) ‑> dict

Address utilities Generate a random address.

Expand source code
@staticmethod
def generate_address(priv_key=None) -> dict:
    """Address utilities Generate a random address."""
    if priv_key is None:
        priv_key = PrivateKeyFactory.random()
    return {
        "base58check_address": priv_key.public_key.to_base58check_address(),
        "hex_address": priv_key.public_key.to_hex_address(),
        "private_key": priv_key.hex(),
        "public_key": priv_key.public_key.hex(),
    }
def isAddress(value: str) ‑> bool

Checks if the given string in a supported value is an address in any of the known formats.

Args

value : str
Address
Expand source code
def is_address(value: str) -> bool:
    """Checks if the given string in a supported value is an address
    in any of the known formats.
    Args:
        value (str): Address
    """
    if is_checksum_address(value):
        return True
    elif is_hex_address(value):
        return True

    return False
def keccak(primitive=None, text=None, hexstr=None)
Expand source code
@staticmethod
@apply_to_return_value(HexBytes)
def keccak(primitive=None, text=None, hexstr=None):
    if isinstance(primitive, (bytes, int, type(None))):
        input_bytes = to_bytes(primitive, hexstr=hexstr, text=text)
        return tron_keccak(input_bytes)

    raise TypeError(
        "You called keccak with first arg %r and keywords %r. You must call it with one of "
        "these approaches: keccak(text='txt'), keccak(hexstr='0x747874'), "
        "keccak(b'\\x74\\x78\\x74'), or keccak(0x747874)." % (
            primitive,
            {'text': text, 'hexstr': hexstr}
        )
    )
def toBytes(primitive=None, hexstr=None, text=None)
Expand source code
def to_bytes(primitive=None, hexstr=None, text=None):
    assert_one_val(primitive, hexstr=hexstr, text=text)

    if is_boolean(primitive):
        return b'\x01' if primitive else b'\x00'
    elif isinstance(primitive, bytes):
        return primitive
    elif is_integer(primitive):
        return to_bytes(hexstr=to_hex(primitive))
    elif hexstr is not None:
        if len(hexstr) % 2:
            hexstr = '0x0' + remove_0x_prefix(hexstr)
        return decode_hex(hexstr)
    elif text is not None:
        return text.encode('utf-8')
    raise TypeError("expected an int in first arg, or keyword of hexstr or text")
def toHex(primitive: Union[bytes, int, bool] = None, hexstr: .new_type at 0x7ff648077310> = None, text: str = None) ‑> .new_type at 0x7ff648077310>

Auto converts any supported value into its hex representation. Trims leading zeros, as defined in: https://github.com/ethereum/wiki/wiki/JSON-RPC#hex-value-encoding

Expand source code
@validate_conversion_arguments
def to_hex(
        primitive: Primitives = None, hexstr: HexStr = None, text: str = None
) -> HexStr:
    """
    Auto converts any supported value into its hex representation.
    Trims leading zeros, as defined in:
    https://github.com/ethereum/wiki/wiki/JSON-RPC#hex-value-encoding
    """
    if hexstr is not None:
        return HexStr(add_0x_prefix(hexstr.lower()))

    if text is not None:
        return HexStr(encode_hex(text.encode("utf-8")))

    if is_boolean(primitive):
        return HexStr("0x1") if primitive else HexStr("0x0")

    if isinstance(primitive, (bytes, bytearray)):
        return HexStr(encode_hex(primitive))
    elif is_string(primitive):
        raise TypeError(
            "Unsupported type: The primitive argument must be one of: bytes,"
            "bytearray, int or bool and not str"
        )

    if is_integer(primitive):
        return HexStr(hex(primitive))

    raise TypeError(
        "Unsupported type: '{0}'.  Must be one of: bool, str, bytes, bytearray"
        "or int.".format(repr(type(primitive)))
    )
def toInt(value=None, hexstr=None, text=None)

Converts value to it's integer representation.

Values are converted this way:

  • value:
  • bytes: big-endian integer
  • bool: True => 1, False => 0
  • hexstr: interpret hex as integer
  • text: interpret as string of digits, like '12' => 12
Expand source code
def to_int(value=None, hexstr=None, text=None):
    """Converts value to it's integer representation.

    Values are converted this way:

     * value:
       * bytes: big-endian integer
       * bool: True => 1, False => 0
     * hexstr: interpret hex as integer
     * text: interpret as string of digits, like '12' => 12
    """
    assert_one_val(value, hexstr=hexstr, text=text)

    if hexstr is not None:
        return int(hexstr, 16)
    elif text is not None:
        return int(text)
    elif isinstance(value, bytes):
        return big_endian_to_int(value)
    elif isinstance(value, str):
        raise TypeError("Pass in strings with keyword hexstr or text")
    else:
        return int(value)
def toJSON(obj: object) ‑> object

Convert a complex object (like a transaction object) to a JSON string

Expand source code
def to_json(obj: object) -> object:
    """Convert a complex object (like a transaction object) to a JSON string"""
    return FriendlyJsonSerialize().json_encode(obj, cls=TronJsonEncoder)
def toSun(number: int) ‑> int

Helper function that will convert a value in TRX to SUN.

Args

number : int
Value in TRX to convert to SUN
Expand source code
def to_sun(number: int) -> int:
    """Helper function that will convert a value in TRX to SUN.

    Args:
        number (int): Value in TRX to convert to SUN

    """
    if is_integer(number) or is_string(number):
        d_number = decimal.Decimal(value=number)
    elif isinstance(number, float):
        d_number = decimal.Decimal(value=str(number))
    elif isinstance(number, decimal.Decimal):
        d_number = number
    else:
        raise TypeError("Unsupported type.  Must be one of integer, float, or string")

    s_number = str(number)
    unit_value = UNITS['sun']

    if d_number == 0:
        return 0

    if d_number < 1 and '.' in s_number:
        with localcontext() as ctx:
            multiplier = len(s_number) - s_number.index('.') - 1
            ctx.prec = multiplier
            d_number = decimal.Decimal(value=number, context=ctx) * 10 ** multiplier
        unit_value /= 10 ** multiplier

    with localcontext() as ctx:
        ctx.prec = 999
        result_value = decimal.Decimal(value=d_number, context=ctx) * unit_value

    if result_value < MIN_SUN or result_value > MAX_SUN:
        raise ValueError("Resulting wei value must be between 1 and 2**256 - 1")

    return int(result_value)
def toText(primitive=None, hexstr=None, text=None)
Expand source code
def to_text(primitive=None, hexstr=None, text=None):
    assert_one_val(primitive, hexstr=hexstr, text=text)

    if hexstr is not None:
        return to_bytes(hexstr=hexstr).decode('utf-8')
    elif text is not None:
        return text
    elif isinstance(primitive, str):
        return to_text(hexstr=primitive)
    elif isinstance(primitive, bytes):
        return primitive.decode('utf-8')
    elif is_integer(primitive):
        byte_encoding = int_to_big_endian(primitive)
        return to_text(byte_encoding)
    raise TypeError("Expected an int, bytes or hexstr.")

Instance variables

var addressAddress

Helper object that allows you to convert between hex/base58 and private key representations of a TRON address.

Note

If you wish to convert generic data to hexadecimal strings, please use the function tron.to_hex. return a static class

Expand source code
@property
def address(self) -> Address:
    """Helper object that allows you to convert
    between hex/base58 and private key representations of a TRON address.

    Note:
        If you wish to convert generic data to hexadecimal strings,
        please use the function tron.to_hex.
        return a static class
    """
    return Address()
var default_address : eth_account.datastructures.AttributeDict

Get a TRON Address

Expand source code
@property
def default_address(self) -> AttributeDict:
    """Get a TRON Address"""
    return self._default_address
var default_block
Expand source code
@property
def default_block(self):
    return self._default_block
var private_key : str

Get a private key

Expand source code
@property
def private_key(self) -> str:
    """Get a private key"""
    return self._private_key
var providers

List providers

Expand source code
@property
def providers(self):
    """List providers"""
    return self.manager.providers

Methods

def getKey(self) ‑> PrivateKey
Expand source code
def getKey(self) -> "PrivateKey":
    return self.private_key_class
def get_address_from_passphrase(self, passphrase: str) ‑> dict

Get an address from a passphrase, compatiable with wallet/createaddress.

Expand source code
def get_address_from_passphrase(self, passphrase: str) -> dict:
    """Get an address from a passphrase, compatiable with `wallet/createaddress`."""
    priv_key = PrivateKeyFactory.from_passphrase(passphrase.encode())
    return self.generate_address(priv_key)
def get_event_result(self, **kwargs)

Will return all events matching the filters.

Args

kwargs : any
List parameters
Expand source code
def get_event_result(self, **kwargs):
    """Will return all events matching the filters.

    Args:
        kwargs (any): List parameters
    """

    # Check the most necessary parameters
    since_timestamp = kwargs.setdefault('since_timestamp', 0)
    event_name = kwargs.setdefault('event_name', 'Notify')
    block_number = kwargs.setdefault('block_number', '')
    size = kwargs.setdefault('size', 20)
    page = kwargs.setdefault('page', 1)
    only_confirmed = kwargs.setdefault('only_confirmed', None)
    only_unconfirmed = kwargs.setdefault('only_unconfirmed', None)
    previous_last = kwargs.setdefault('previous_last_event_fingerprint', None)
    contract_address = kwargs.setdefault('contract_address', self.default_address.hex)
    sort = kwargs.setdefault('sort', None)
    from_timestamp = kwargs.setdefault('from_timestamp', None)

    if not self.isAddress(contract_address):
        raise InvalidTronError('Invalid contract address provided')

    if event_name and not contract_address:
        raise TronError('Usage of event name filtering requires a contract address')

    if block_number and event_name is None:
        raise TronError('Usage of block number filtering requires an event name')

    if not is_integer(page):
        raise ValueError('Invalid size provided')

    if not is_integer(since_timestamp):
        raise ValueError('Invalid sinceTimestamp provided')

    # If the size exceeds 200, displays an error
    if size > 200:
        raise ValueError('Defaulting to maximum accepted size: 200')

    # We collect all parameters in one array
    route_params = []
    if contract_address:
        route_params.append(contract_address)
    if event_name:
        route_params.append(event_name)
    if block_number:
        route_params.append(block_number)

    route = '/'.join(route_params)

    qs = {
        'since': since_timestamp,
        'page': page,
        'size': size
    }

    if only_confirmed is not None:
        qs.update({'onlyConfirmed': only_confirmed})

    if only_unconfirmed is not None and not only_confirmed:
        qs.update({'onlyUnconfirmed': only_unconfirmed})

    if previous_last is not None:
        qs.update({'previousLastEventFingerprint': previous_last})

    if from_timestamp is not None:
        qs.update({'fromTimestamp': from_timestamp})

    if sort is not None:
        qs.update({'sort': sort})

    return self.manager.request("/event/contract/{0}?{1}"
                                .format(route, urlencode(qs)), method='get')
def get_event_transaction_id(self, tx_id)

Will return all events within a transactionID.

Args

tx_id : str
TransactionID to query for events.
Expand source code
def get_event_transaction_id(self, tx_id):
    """Will return all events within a transactionID.

    Args:
        tx_id (str): TransactionID to query for events.
    """
    response = self.manager.request('/event/transaction/' + tx_id, method='get')
    return response
def is_connected(self)

List of available providers

Expand source code
def is_connected(self):
    """List of available providers"""
    return self.manager.is_connected()
def setNetwork(self, networkname='nile')
Expand source code
def setNetwork(self, networkname="nile"):
    group = constants.conf_for_name(networkname)
    self.manager = TronManager(self, constants.to_providers_set(group))
    return self
def solidity_sha3(self, abi_types, values)

Executes keccak256 exactly as Solidity does. Takes list of abi_types as inputs – [uint24, int8[], bool] and list of corresponding values – [20, [-1, 5, 0], True]

Args

abi_types : any
types abi
values : any
values

Examples

>>> tron = Tron()
>>> sol = tron.solidity_sha3(['uint8[]'], [[1, 2, 3, 4, 5]])
>>> assert sol.hex() == '0x5917e5a395fb9b454434de59651d36822a9e29c5ec57474df3e67937b969460c'
Expand source code
def solidity_sha3(self, abi_types, values):
    """
        Executes keccak256 exactly as Solidity does.
        Takes list of abi_types as inputs -- `[uint24, int8[], bool]`
        and list of corresponding values  -- `[20, [-1, 5, 0], True]`

        Args:
            abi_types (any): types abi
            values (any): values

        Examples:
            >>> tron = Tron()
            >>> sol = tron.solidity_sha3(['uint8[]'], [[1, 2, 3, 4, 5]])
            >>> assert sol.hex() == '0x5917e5a395fb9b454434de59651d36822a9e29c5ec57474df3e67937b969460c'

    """
    if len(abi_types) != len(values):
        raise ValueError(
            "Length mismatch between provided abi types and values.  Got "
            "{0} types and {1} values.".format(len(abi_types), len(values))
        )

    normalized_values = map_abi_data([abi_resolver()], abi_types, values)

    hex_string = add_0x_prefix(''.join(
        remove_0x_prefix(hex_encode_abi_type(abi_type, value))
        for abi_type, value
        in zip(abi_types, normalized_values)
    ))
    return self.keccak(hexstr=hex_string)