代码拉取完成,页面将自动刷新
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<meta name="generator" content="pdoc 0.9.1" />
<title>tronpytool API documentation</title>
<meta name="description" content="" />
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Package <code>tronpytool</code></h1>
</header>
<section id="section-intro">
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">#!/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'
]</code></pre>
</details>
</section>
<section>
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
<dl>
<dt><code class="name"><a title="tronpytool.common" href="common/index.html">tronpytool.common</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="tronpytool.compile" href="compile/index.html">tronpytool.compile</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="tronpytool.constants" href="constants.html">tronpytool.constants</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="tronpytool.contract" href="contract.html">tronpytool.contract</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="tronpytool.exceptions" href="exceptions.html">tronpytool.exceptions</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="tronpytool.main" href="main.html">tronpytool.main</a></code></dt>
<dd>
<div class="desc"><p>tronpytool.main
…</p></div>
</dd>
<dt><code class="name"><a title="tronpytool.manager" href="manager.html">tronpytool.manager</a></code></dt>
<dd>
<div class="desc"><p>tronpytool.manager
…</p></div>
</dd>
<dt><code class="name"><a title="tronpytool.module" href="module.html">tronpytool.module</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="tronpytool.providers" href="providers/index.html">tronpytool.providers</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="tronpytool.transactionbuilder" href="transactionbuilder.html">tronpytool.transactionbuilder</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="tronpytool.trx" href="trx.html">tronpytool.trx</a></code></dt>
<dd>
<div class="desc"><p>tronpytool.trx
…</p></div>
</dd>
</dl>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="tronpytool.Account"><code class="flex name class">
<span>class <span class="ident">Account</span></span>
</code></dt>
<dd>
<div class="desc"><p>The primary entry point for working with Ethereum private keys.</p>
<p>It does <strong>not</strong> require a connection to an Ethereum node.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">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</code></pre>
</details>
<h3>Static methods</h3>
<dl>
<dt id="tronpytool.Account.decrypt"><code class="name flex">
<span>def <span class="ident">decrypt</span></span>(<span>keyfile_json, password)</span>
</code></dt>
<dd>
<div class="desc"><p>Decrypts a private key that was encrypted using an Ethereum client or
:meth:<code>~Account.encrypt</code>.</p>
<p>: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</p>
<p>.. code-block:: python</p>
<pre><code>>>> 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')
</code></pre></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@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))</code></pre>
</details>
</dd>
<dt id="tronpytool.Account.encrypt"><code class="name flex">
<span>def <span class="ident">encrypt</span></span>(<span>private_key, password, kdf=None, iterations=None)</span>
</code></dt>
<dd>
<div class="desc"><p>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:<code>json.dumps</code> and save it to disk where your
client keeps key files.</p>
<p>:param private_key: The raw private key
:type private_key: hex str, bytes, int or :class:<code>eth_keys.datatypes.PrivateKey</code>
: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</p>
<p>If kdf is not set, the default key derivation function falls back to the
environment variable :envvar:<code>ETH_ACCOUNT_KDF</code>. If that is not set, then
'scrypt' will be used as the default.</p>
<p>.. code-block:: python</p>
<pre><code>>>> 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))
</code></pre></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@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)</code></pre>
</details>
</dd>
</dl>
<h3>Methods</h3>
<dl>
<dt id="tronpytool.Account.create"><code class="name flex">
<span>def <span class="ident">create</span></span>(<span>self, extra_entropy='')</span>
</code></dt>
<dd>
<div class="desc"><p>Creates a new private key, and returns it as a :class:<code>~eth_account.local.LocalAccount</code>.</p>
<p>: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</p>
<p>.. code-block:: python</p>
<pre><code>>>> 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
</code></pre></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@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)</code></pre>
</details>
</dd>
<dt id="tronpytool.Account.from_key"><code class="name flex">
<span>def <span class="ident">from_key</span></span>(<span>self, private_key)</span>
</code></dt>
<dd>
<div class="desc"><p>Returns a convenient object for working with the given private key.</p>
<p>:param private_key: The raw private key
:type private_key: hex str, bytes, int or :class:<code>eth_keys.datatypes.PrivateKey</code>
:return: object with methods for signing and encrypting
:rtype: LocalAccount</p>
<p>.. code-block:: python</p>
<pre><code>>>> 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
</code></pre></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@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)</code></pre>
</details>
</dd>
<dt id="tronpytool.Account.privateKeyToAccount"><code class="name flex">
<span>def <span class="ident">privateKeyToAccount</span></span>(<span>self, private_key)</span>
</code></dt>
<dd>
<div class="desc"><div class="admonition caution">
<p class="admonition-title">Caution: Deprecated for :meth:<code>~eth_account.account.Account.from_key</code>.</p>
<p>This method will be removed in v0.5</p>
</div></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@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)</code></pre>
</details>
</dd>
<dt id="tronpytool.Account.recoverHash"><code class="name flex">
<span>def <span class="ident">recoverHash</span></span>(<span>self, message_hash, vrs=None, signature=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Get the address of the account that signed the message with the given hash.
You must specify exactly one of: vrs or signature</p>
<div class="admonition caution">
<p class="admonition-title">Caution: Deprecated for :meth:<code>~eth_account.account.Account.recover_message</code>.</p>
<p>This method might be removed as early as v0.5</p>
</div>
<p>: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</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@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)</code></pre>
</details>
</dd>
<dt id="tronpytool.Account.recoverTransaction"><code class="name flex">
<span>def <span class="ident">recoverTransaction</span></span>(<span>self, serialized_transaction)</span>
</code></dt>
<dd>
<div class="desc"><div class="admonition caution">
<p class="admonition-title">Caution: Deprecated for :meth:<code>~eth_account.account.Account.recover_transaction</code>.</p>
<p>This method will be removed in v0.5</p>
</div></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@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)</code></pre>
</details>
</dd>
<dt id="tronpytool.Account.recover_message"><code class="name flex">
<span>def <span class="ident">recover_message</span></span>(<span>self, signable_message: eth_account.messages.SignableMessage, vrs=None, signature=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Get the address of the account that signed the given message.
You must specify exactly one of: vrs or signature</p>
<p>: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</p>
<p>.. code-block:: python</p>
<pre><code>>>> 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)
</code></pre></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@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)</code></pre>
</details>
</dd>
<dt id="tronpytool.Account.recover_transaction"><code class="name flex">
<span>def <span class="ident">recover_transaction</span></span>(<span>self, serialized_transaction)</span>
</code></dt>
<dd>
<div class="desc"><p>Get the address of the account that signed this transaction.</p>
<p>:param serialized_transaction: the complete signed transaction
:type serialized_transaction: hex str, bytes or int
:returns: address of signer, hex-encoded & checksummed
:rtype: str</p>
<p>.. code-block:: python</p>
<pre><code>>>> raw_transaction = '0xf86a8086d55698372431831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca008025a009ebb6ca057a0535d6186462bc0b465b561c94a295bdb0621fc19208ab149a9ca0440ffd775ce91a833ab410777204d5341a6f9fa91216a6f3ee2c051fea6a0428', # noqa: E501
>>> Account.recover_transaction(raw_transaction)
'0x2c7536E3605D9C16a7a3D7b1898e529396a65c23'
</code></pre></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@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))</code></pre>
</details>
</dd>
<dt id="tronpytool.Account.setKeyBackend"><code class="name flex">
<span>def <span class="ident">setKeyBackend</span></span>(<span>self, backend)</span>
</code></dt>
<dd>
<div class="desc"><div class="admonition caution">
<p class="admonition-title">Caution: Deprecated for :meth:<code>~eth_account.account.Account.set_key_backend</code>.</p>
<p>This method will be removed in v0.5</p>
</div></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">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)</code></pre>
</details>
</dd>
<dt id="tronpytool.Account.set_key_backend"><code class="name flex">
<span>def <span class="ident">set_key_backend</span></span>(<span>self, backend)</span>
</code></dt>
<dd>
<div class="desc"><p>Change the backend used by the underlying eth-keys library.</p>
<p><em>(The default is fine for most users)</em></p>
<p>:param backend: any backend that works in
<code>eth_keys.KeyApi(backend) <https://github.com/ethereum/eth-keys/#keyapibackendnone></code>_</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">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)</code></pre>
</details>
</dd>
<dt id="tronpytool.Account.signHash"><code class="name flex">
<span>def <span class="ident">signHash</span></span>(<span>self, message_hash, private_key)</span>
</code></dt>
<dd>
<div class="desc"><div class="admonition warning">
<p class="admonition-title">Warning: <em>Never</em> sign a hash that you didn't generate,</p>
<p>it can be an arbitrary transaction. For example, it might
send all of your account's ether to an attacker.
Instead, prefer :meth:<code>~eth_account.account.Account.sign_message</code>,
which cannot accidentally sign a transaction.</p>
</div>
<p>Sign the provided hash.</p>
<div class="admonition caution">
<p class="admonition-title">Caution: Deprecated for :meth:<code>~eth_account.account.Account.sign_message</code>.</p>
<p>This method will be removed in v0.5</p>
</div>
<p>: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:<code>eth_keys.datatypes.PrivateKey</code>
:returns: Various details about the signature - most
importantly the fields: v, r, and s
:rtype: ~eth_account.datastructures.AttributeDict</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@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)</code></pre>
</details>
</dd>
<dt id="tronpytool.Account.signTransaction"><code class="name flex">
<span>def <span class="ident">signTransaction</span></span>(<span>self, transaction_dict, private_key)</span>
</code></dt>
<dd>
<div class="desc"><div class="admonition caution">
<p class="admonition-title">Caution: Deprecated for :meth:<code>~eth_account.account.Account.sign_transaction</code>.</p>
<p>This method will be removed in v0.5</p>
</div></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@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)</code></pre>
</details>
</dd>
<dt id="tronpytool.Account.sign_message"><code class="name flex">
<span>def <span class="ident">sign_message</span></span>(<span>self, signable_message: eth_account.messages.SignableMessage, private_key)</span>
</code></dt>
<dd>
<div class="desc"><p>Sign the provided message.</p>
<p>This API supports any messaging format that will encode to EIP-191_ messages.</p>
<p>If you would like historical compatibility with
:meth:<code>w3.eth.sign() <web3.eth.Eth.sign></code>
you can use :meth:<code>~eth_account.messages.encode_defunct</code>.</p>
<p>Other options are the "validator", or "structured data" standards. (Both of these
are in <em>DRAFT</em> status currently, so be aware that the implementation is not
guaranteed to be stable). You can import all supported message encoders in
<code>eth_account.messages</code>.</p>
<p>: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:<code>eth_keys.datatypes.PrivateKey</code>
:returns: Various details about the signature - most importantly the fields: v, r, and s
:rtype: ~eth_account.datastructures.AttributeDict</p>
<p>.. code-block:: python</p>
<pre><code>>>> 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}
</code></pre>
<p>.. _EIP-191: <a href="https://eips.ethereum.org/EIPS/eip-191">https://eips.ethereum.org/EIPS/eip-191</a></p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@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)</code></pre>
</details>
</dd>
<dt id="tronpytool.Account.sign_transaction"><code class="name flex">
<span>def <span class="ident">sign_transaction</span></span>(<span>self, transaction_dict, private_key)</span>
</code></dt>
<dd>
<div class="desc"><p>Sign a transaction using a local private key. Produces signature details
and the hex-encoded transaction suitable for broadcast using
:meth:<code>w3.eth.sendRawTransaction() <web3.eth.Eth.sendRawTransaction></code>.</p>
<p>Create the transaction dict for a contract method with
<code>my_contract.functions.my_function().buildTransaction()
<http://web3py.readthedocs.io/en/latest/contracts.html#methods></code>_</p>
<p>: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:<code>eth_keys.datatypes.PrivateKey</code>
:returns: Various details about the signature - most
importantly the fields: v, r, and s
:rtype: AttributeDict</p>
<p>.. code-block:: python</p>
<pre><code>>>> 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)
</code></pre></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@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,
})</code></pre>
</details>
</dd>
</dl>
</dd>
<dt id="tronpytool.HttpProvider"><code class="flex name class">
<span>class <span class="ident">HttpProvider</span></span>
<span>(</span><span>node_url, request_kwargs=None)</span>
</code></dt>
<dd>
<div class="desc"><p>A Connection object to make HTTP requests to a particular node.</p>
<p>Initializes a :class:<code>~tronpytool.providers.http.HttpProvider</code>
instance.</p>
<p>Args:
node_url (str):
Url of the node to connect to.
request_kwargs (dict): Optional params to send with each request.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">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'])</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li><a title="tronpytool.providers.base.BaseProvider" href="providers/base.html#tronpytool.providers.base.BaseProvider">BaseProvider</a></li>
</ul>
<h3>Methods</h3>
<dl>
<dt id="tronpytool.HttpProvider.get_request_kwargs"><code class="name flex">
<span>def <span class="ident">get_request_kwargs</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Header settings</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@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</code></pre>
</details>
</dd>
<dt id="tronpytool.HttpProvider.is_connected"><code class="name flex">
<span>def <span class="ident">is_connected</span></span>(<span>self) ‑> bool</span>
</code></dt>
<dd>
<div class="desc"><p>Connection check</p>
<p>This method sends a test request to the connected node
to determine its health.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>bool</code></dt>
<dd>True if successful,</dd>
</dl>
<p>False otherwise.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">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</code></pre>
</details>
</dd>
<dt id="tronpytool.HttpProvider.request"><code class="name flex">
<span>def <span class="ident">request</span></span>(<span>self, path, json=None, params=None, method=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Performs an HTTP request with the given parameters.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>path</code></strong> : <code>str</code></dt>
<dd>API endpoint path (e.g.: <code>'/transactions'</code>).</dd>
<dt><strong><code>json</code></strong> : <code>dict</code></dt>
<dd>JSON data to send along with the request.</dd>
<dt><strong><code>params</code></strong> : <code>dict</code></dt>
<dd>Dictionary of URL (query) parameters.</dd>
<dt><strong><code>method</code></strong> : <code>str</code></dt>
<dd>HTTP method (e.g.: <code>'GET'</code>).</dd>
</dl></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">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</code></pre>
</details>
</dd>
</dl>
<h3>Inherited members</h3>
<ul class="hlist">
<li><code><b><a title="tronpytool.providers.base.BaseProvider" href="providers/base.html#tronpytool.providers.base.BaseProvider">BaseProvider</a></b></code>:
<ul class="hlist">
<li><code><a title="tronpytool.providers.base.BaseProvider.format_user_agent" href="providers/base.html#tronpytool.providers.base.BaseProvider.format_user_agent">format_user_agent</a></code></li>
<li><code><a title="tronpytool.providers.base.BaseProvider.status_page" href="providers/base.html#tronpytool.providers.base.BaseProvider.status_page">status_page</a></code></li>
</ul>
</li>
</ul>
</dd>
<dt id="tronpytool.Tron"><code class="flex name class">
<span>class <span class="ident">Tron</span></span>
<span>(</span><span>**kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>Connect to the Tron network.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>kwargs</code></strong> : <code>Any</code></dt>
<dd>We fill the most necessary parameters</dd>
</dl>
<p>for working with blockchain Tron</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">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()</code></pre>
</details>
<h3>Static methods</h3>
<dl>
<dt id="tronpytool.Tron.create_account"><code class="name flex">
<span>def <span class="ident">create_account</span></span>(<span>) ‑> <a title="tronpytool.common.account.PrivateKey" href="common/account.html#tronpytool.common.account.PrivateKey">PrivateKey</a></span>
</code></dt>
<dd>
<div class="desc"><p>Create account</p>
<p>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.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@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()</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.fromSun"><code class="name flex">
<span>def <span class="ident">fromSun</span></span>(<span>number: int) ‑> Union[int, decimal.Decimal]</span>
</code></dt>
<dd>
<div class="desc"><p>Helper function that will convert a value in SUN to TRX.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>number</code></strong> : <code>int</code></dt>
<dd>Value in SUN to convert to TRX</dd>
</dl></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">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</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.generate_address"><code class="name flex">
<span>def <span class="ident">generate_address</span></span>(<span>priv_key=None) ‑> dict</span>
</code></dt>
<dd>
<div class="desc"><p>Address utilities Generate a random address.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@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(),
}</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.isAddress"><code class="name flex">
<span>def <span class="ident">isAddress</span></span>(<span>value: str) ‑> bool</span>
</code></dt>
<dd>
<div class="desc"><p>Checks if the given string in a supported value is an address
in any of the known formats.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>value</code></strong> : <code>str</code></dt>
<dd>Address</dd>
</dl></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">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</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.keccak"><code class="name flex">
<span>def <span class="ident">keccak</span></span>(<span>primitive=None, text=None, hexstr=None)</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@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}
)
)</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.toBytes"><code class="name flex">
<span>def <span class="ident">toBytes</span></span>(<span>primitive=None, hexstr=None, text=None)</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">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")</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.toHex"><code class="name flex">
<span>def <span class="ident">toHex</span></span>(<span>primitive: Union[bytes, int, bool] = None, hexstr: <function NewType.<locals>.new_type at 0x7ff648077310> = None, text: str = None) ‑> <function NewType.<locals>.new_type at 0x7ff648077310></span>
</code></dt>
<dd>
<div class="desc"><p>Auto converts any supported value into its hex representation.
Trims leading zeros, as defined in:
<a href="https://github.com/ethereum/wiki/wiki/JSON-RPC#hex-value-encoding">https://github.com/ethereum/wiki/wiki/JSON-RPC#hex-value-encoding</a></p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@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)))
)</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.toInt"><code class="name flex">
<span>def <span class="ident">toInt</span></span>(<span>value=None, hexstr=None, text=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Converts value to it's integer representation.</p>
<p>Values are converted this way:</p>
<ul>
<li>value:</li>
<li>bytes: big-endian integer</li>
<li>bool: True => 1, False => 0</li>
<li>hexstr: interpret hex as integer</li>
<li>text: interpret as string of digits, like '12' => 12</li>
</ul></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">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)</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.toJSON"><code class="name flex">
<span>def <span class="ident">toJSON</span></span>(<span>obj: object) ‑> object</span>
</code></dt>
<dd>
<div class="desc"><p>Convert a complex object (like a transaction object) to a JSON string</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">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)</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.toSun"><code class="name flex">
<span>def <span class="ident">toSun</span></span>(<span>number: int) ‑> int</span>
</code></dt>
<dd>
<div class="desc"><p>Helper function that will convert a value in TRX to SUN.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>number</code></strong> : <code>int</code></dt>
<dd>Value in TRX to convert to SUN</dd>
</dl></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">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)</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.toText"><code class="name flex">
<span>def <span class="ident">toText</span></span>(<span>primitive=None, hexstr=None, text=None)</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">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.")</code></pre>
</details>
</dd>
</dl>
<h3>Instance variables</h3>
<dl>
<dt id="tronpytool.Tron.address"><code class="name">var <span class="ident">address</span> : <a title="tronpytool.common.account.Address" href="common/account.html#tronpytool.common.account.Address">Address</a></code></dt>
<dd>
<div class="desc"><p>Helper object that allows you to convert
between hex/base58 and private key representations of a TRON address.</p>
<h2 id="note">Note</h2>
<p>If you wish to convert generic data to hexadecimal strings,
please use the function tron.to_hex.
return a static class</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@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()</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.default_address"><code class="name">var <span class="ident">default_address</span> : eth_account.datastructures.AttributeDict</code></dt>
<dd>
<div class="desc"><p>Get a TRON Address</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@property
def default_address(self) -> AttributeDict:
"""Get a TRON Address"""
return self._default_address</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.default_block"><code class="name">var <span class="ident">default_block</span></code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@property
def default_block(self):
return self._default_block</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.private_key"><code class="name">var <span class="ident">private_key</span> : str</code></dt>
<dd>
<div class="desc"><p>Get a private key</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@property
def private_key(self) -> str:
"""Get a private key"""
return self._private_key</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.providers"><code class="name">var <span class="ident">providers</span></code></dt>
<dd>
<div class="desc"><p>List providers</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@property
def providers(self):
"""List providers"""
return self.manager.providers</code></pre>
</details>
</dd>
</dl>
<h3>Methods</h3>
<dl>
<dt id="tronpytool.Tron.getKey"><code class="name flex">
<span>def <span class="ident">getKey</span></span>(<span>self) ‑> <a title="tronpytool.common.account.PrivateKey" href="common/account.html#tronpytool.common.account.PrivateKey">PrivateKey</a></span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def getKey(self) -> "PrivateKey":
return self.private_key_class</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.get_address_from_passphrase"><code class="name flex">
<span>def <span class="ident">get_address_from_passphrase</span></span>(<span>self, passphrase: str) ‑> dict</span>
</code></dt>
<dd>
<div class="desc"><p>Get an address from a passphrase, compatiable with <code>wallet/createaddress</code>.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">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)</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.get_event_result"><code class="name flex">
<span>def <span class="ident">get_event_result</span></span>(<span>self, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>Will return all events matching the filters.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>kwargs</code></strong> : <code>any</code></dt>
<dd>List parameters</dd>
</dl></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">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')</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.get_event_transaction_id"><code class="name flex">
<span>def <span class="ident">get_event_transaction_id</span></span>(<span>self, tx_id)</span>
</code></dt>
<dd>
<div class="desc"><p>Will return all events within a transactionID.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>tx_id</code></strong> : <code>str</code></dt>
<dd>TransactionID to query for events.</dd>
</dl></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">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</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.is_connected"><code class="name flex">
<span>def <span class="ident">is_connected</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>List of available providers</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def is_connected(self):
"""List of available providers"""
return self.manager.is_connected()</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.setNetwork"><code class="name flex">
<span>def <span class="ident">setNetwork</span></span>(<span>self, networkname='nile')</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def setNetwork(self, networkname="nile"):
group = constants.conf_for_name(networkname)
self.manager = TronManager(self, constants.to_providers_set(group))
return self</code></pre>
</details>
</dd>
<dt id="tronpytool.Tron.solidity_sha3"><code class="name flex">
<span>def <span class="ident">solidity_sha3</span></span>(<span>self, abi_types, values)</span>
</code></dt>
<dd>
<div class="desc"><p>Executes keccak256 exactly as Solidity does.
Takes list of abi_types as inputs – <code>[uint24, int8[], bool]</code>
and list of corresponding values
– <code>[20, [-1, 5, 0], True]</code></p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>abi_types</code></strong> : <code>any</code></dt>
<dd>types abi</dd>
<dt><strong><code>values</code></strong> : <code>any</code></dt>
<dd>values</dd>
</dl>
<h2 id="examples">Examples</h2>
<pre><code class="python-repl">>>> tron = Tron()
>>> sol = tron.solidity_sha3(['uint8[]'], [[1, 2, 3, 4, 5]])
>>> assert sol.hex() == '0x5917e5a395fb9b454434de59651d36822a9e29c5ec57474df3e67937b969460c'
</code></pre></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">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)</code></pre>
</details>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<h1>Index</h1>
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
<ul>
<li><code><a title="tronpytool.common" href="common/index.html">tronpytool.common</a></code></li>
<li><code><a title="tronpytool.compile" href="compile/index.html">tronpytool.compile</a></code></li>
<li><code><a title="tronpytool.constants" href="constants.html">tronpytool.constants</a></code></li>
<li><code><a title="tronpytool.contract" href="contract.html">tronpytool.contract</a></code></li>
<li><code><a title="tronpytool.exceptions" href="exceptions.html">tronpytool.exceptions</a></code></li>
<li><code><a title="tronpytool.main" href="main.html">tronpytool.main</a></code></li>
<li><code><a title="tronpytool.manager" href="manager.html">tronpytool.manager</a></code></li>
<li><code><a title="tronpytool.module" href="module.html">tronpytool.module</a></code></li>
<li><code><a title="tronpytool.providers" href="providers/index.html">tronpytool.providers</a></code></li>
<li><code><a title="tronpytool.transactionbuilder" href="transactionbuilder.html">tronpytool.transactionbuilder</a></code></li>
<li><code><a title="tronpytool.trx" href="trx.html">tronpytool.trx</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="tronpytool.Account" href="#tronpytool.Account">Account</a></code></h4>
<ul class="two-column">
<li><code><a title="tronpytool.Account.create" href="#tronpytool.Account.create">create</a></code></li>
<li><code><a title="tronpytool.Account.decrypt" href="#tronpytool.Account.decrypt">decrypt</a></code></li>
<li><code><a title="tronpytool.Account.encrypt" href="#tronpytool.Account.encrypt">encrypt</a></code></li>
<li><code><a title="tronpytool.Account.from_key" href="#tronpytool.Account.from_key">from_key</a></code></li>
<li><code><a title="tronpytool.Account.privateKeyToAccount" href="#tronpytool.Account.privateKeyToAccount">privateKeyToAccount</a></code></li>
<li><code><a title="tronpytool.Account.recoverHash" href="#tronpytool.Account.recoverHash">recoverHash</a></code></li>
<li><code><a title="tronpytool.Account.recoverTransaction" href="#tronpytool.Account.recoverTransaction">recoverTransaction</a></code></li>
<li><code><a title="tronpytool.Account.recover_message" href="#tronpytool.Account.recover_message">recover_message</a></code></li>
<li><code><a title="tronpytool.Account.recover_transaction" href="#tronpytool.Account.recover_transaction">recover_transaction</a></code></li>
<li><code><a title="tronpytool.Account.setKeyBackend" href="#tronpytool.Account.setKeyBackend">setKeyBackend</a></code></li>
<li><code><a title="tronpytool.Account.set_key_backend" href="#tronpytool.Account.set_key_backend">set_key_backend</a></code></li>
<li><code><a title="tronpytool.Account.signHash" href="#tronpytool.Account.signHash">signHash</a></code></li>
<li><code><a title="tronpytool.Account.signTransaction" href="#tronpytool.Account.signTransaction">signTransaction</a></code></li>
<li><code><a title="tronpytool.Account.sign_message" href="#tronpytool.Account.sign_message">sign_message</a></code></li>
<li><code><a title="tronpytool.Account.sign_transaction" href="#tronpytool.Account.sign_transaction">sign_transaction</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="tronpytool.HttpProvider" href="#tronpytool.HttpProvider">HttpProvider</a></code></h4>
<ul class="">
<li><code><a title="tronpytool.HttpProvider.get_request_kwargs" href="#tronpytool.HttpProvider.get_request_kwargs">get_request_kwargs</a></code></li>
<li><code><a title="tronpytool.HttpProvider.is_connected" href="#tronpytool.HttpProvider.is_connected">is_connected</a></code></li>
<li><code><a title="tronpytool.HttpProvider.request" href="#tronpytool.HttpProvider.request">request</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="tronpytool.Tron" href="#tronpytool.Tron">Tron</a></code></h4>
<ul class="">
<li><code><a title="tronpytool.Tron.address" href="#tronpytool.Tron.address">address</a></code></li>
<li><code><a title="tronpytool.Tron.create_account" href="#tronpytool.Tron.create_account">create_account</a></code></li>
<li><code><a title="tronpytool.Tron.default_address" href="#tronpytool.Tron.default_address">default_address</a></code></li>
<li><code><a title="tronpytool.Tron.default_block" href="#tronpytool.Tron.default_block">default_block</a></code></li>
<li><code><a title="tronpytool.Tron.fromSun" href="#tronpytool.Tron.fromSun">fromSun</a></code></li>
<li><code><a title="tronpytool.Tron.generate_address" href="#tronpytool.Tron.generate_address">generate_address</a></code></li>
<li><code><a title="tronpytool.Tron.getKey" href="#tronpytool.Tron.getKey">getKey</a></code></li>
<li><code><a title="tronpytool.Tron.get_address_from_passphrase" href="#tronpytool.Tron.get_address_from_passphrase">get_address_from_passphrase</a></code></li>
<li><code><a title="tronpytool.Tron.get_event_result" href="#tronpytool.Tron.get_event_result">get_event_result</a></code></li>
<li><code><a title="tronpytool.Tron.get_event_transaction_id" href="#tronpytool.Tron.get_event_transaction_id">get_event_transaction_id</a></code></li>
<li><code><a title="tronpytool.Tron.isAddress" href="#tronpytool.Tron.isAddress">isAddress</a></code></li>
<li><code><a title="tronpytool.Tron.is_connected" href="#tronpytool.Tron.is_connected">is_connected</a></code></li>
<li><code><a title="tronpytool.Tron.keccak" href="#tronpytool.Tron.keccak">keccak</a></code></li>
<li><code><a title="tronpytool.Tron.private_key" href="#tronpytool.Tron.private_key">private_key</a></code></li>
<li><code><a title="tronpytool.Tron.providers" href="#tronpytool.Tron.providers">providers</a></code></li>
<li><code><a title="tronpytool.Tron.setNetwork" href="#tronpytool.Tron.setNetwork">setNetwork</a></code></li>
<li><code><a title="tronpytool.Tron.solidity_sha3" href="#tronpytool.Tron.solidity_sha3">solidity_sha3</a></code></li>
<li><code><a title="tronpytool.Tron.toBytes" href="#tronpytool.Tron.toBytes">toBytes</a></code></li>
<li><code><a title="tronpytool.Tron.toHex" href="#tronpytool.Tron.toHex">toHex</a></code></li>
<li><code><a title="tronpytool.Tron.toInt" href="#tronpytool.Tron.toInt">toInt</a></code></li>
<li><code><a title="tronpytool.Tron.toJSON" href="#tronpytool.Tron.toJSON">toJSON</a></code></li>
<li><code><a title="tronpytool.Tron.toSun" href="#tronpytool.Tron.toSun">toSun</a></code></li>
<li><code><a title="tronpytool.Tron.toText" href="#tronpytool.Tron.toText">toText</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.9.1</a>.</p>
</footer>
</body>
</html>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。