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: dictIf 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.AttributeDictExpand 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 address : 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
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)