def __init__(self, full_node, solidity_node, event_server=None, private_key=None): """Connect to the Tron network. Args: full_node (:obj:`str`): A provider connected to a valid full node solidity_node (:obj:`str`): A provider connected to a valid solidity node event_server (:obj:`str`, optional): Optional for smart contract events. Expects a valid event server URL private_key (str): Optional default private key used when signing transactions """ self._default_address = AttributeDict({}) # 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=full_node, solidity_node=solidity_node, event_server=event_server)) if private_key is not None: self.private_key = private_key for module_name, module_class in DEFAULT_MODULES.items(): module_class.attach(self, module_name) self.transaction = TransactionBuilder(self)
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)
class Tron: # Providers HTTPProvider = HttpProvider _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) @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): """Get a private key""" return self._private_key @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 = 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) 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}) 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 Address() @property def create_account(self) -> 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() @staticmethod def is_valid_provider(provider) -> bool: """Check connected provider Args: provider(HttpProvider): Provider """ return isinstance(provider, HttpProvider) 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()
class Tron: # Providers HTTPProvider = HttpProvider _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) @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): """Get a private key""" return self._private_key @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 = 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 contract_address = kwargs.setdefault('contract_address', self.default_address.hex) event_name = kwargs.setdefault('event_name', 'Notify') since_timestamp = kwargs.setdefault('since_timestamp', 0) block_number = kwargs.setdefault('block_number', '') size = kwargs.setdefault('size', 20) page = kwargs.setdefault('page', 1) 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) return self.manager.request( "/event/contract/{0}?since={1}&size={2}&page={3}".format( route, since_timestamp, size, page), 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): """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 Account() @property def create_account(self) -> 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. """ generate_key = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1) return PrivateKey(generate_key.to_string().hex()) @staticmethod def is_valid_provider(provider) -> bool: """Check connected provider Args: provider(HttpProvider): Provider """ return isinstance(provider, HttpProvider) @staticmethod @apply_to_return_value(HexBytes) def sha3(primitive=None, text=None, hexstr=None): if isinstance(primitive, (bytes, int, type(None))): input_bytes = to_bytes(primitive, hexstr=hexstr, text=text) return keccak(input_bytes) raise TypeError( "You called sha3 with first arg %r and keywords %r. You must call it with one of " "these approaches: sha3(text='txt'), sha3(hexstr='0x747874'), " "sha3(b'\\x74\\x78\\x74'), or sha3(0x747874)." % (primitive, { 'text': text, 'hexstr': hexstr })) def is_connected(self): """List of available providers""" return self.manager.is_connected()
class Tron: _default_block = None _private_key = None # Encoding and Decoding toBytes = staticmethod(to_bytes) toInt = staticmethod(to_int) toHex = staticmethod(to_hex) toText = staticmethod(to_text) # Currency Utility toSun = staticmethod(to_sun) fromSun = staticmethod(from_sun) # Validate address isAddress = staticmethod(is_address) def __init__(self, full_node, solidity_node, event_server=None, private_key=None): """Connect to the Tron network. Args: full_node (:obj:`str`): A provider connected to a valid full node solidity_node (:obj:`str`): A provider connected to a valid solidity node event_server (:obj:`str`, optional): Optional for smart contract events. Expects a valid event server URL private_key (str): Optional default private key used when signing transactions """ self._default_address = AttributeDict({}) # 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=full_node, solidity_node=solidity_node, event_server=event_server)) if private_key is not None: self.private_key = private_key for module_name, module_class in DEFAULT_MODULES.items(): module_class.attach(self, module_name) self.transaction = TransactionBuilder(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): """Get a private key""" return self._private_key @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 = 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, contract_address=None, since=0, event_name=None, block_number=None): """Will return all events matching the filters. Args: contract_address (str): Address to query for events. since (int): Filter for events since certain timestamp. event_name (str): Name of the event to filter by. block_number (str): Specific block number to query """ 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') 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) return self.manager.request("/event/contract/{0}?since={1}".format( route, since), 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): """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 Account() @property def create_account(self) -> PrivateKey: """Create account""" generate_key = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1) return PrivateKey(generate_key.to_string().hex()) def generate_address(self): """Generates a random private key and address pair 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. Returns: Value is the corresponding address for the password, encoded in hex. Convert it to base58 to use as the address. """ return self.manager.request('/wallet/generateaddress') @staticmethod def is_valid_provider(provider) -> bool: """Check connected provider Args: provider(HttpProvider): Provider """ return isinstance(provider, HttpProvider) @staticmethod @deprecated_for("This method has been renamed to keccak") @apply_to_return_value(HexBytes) def sha3(primitive=None, text=None, hexstr=None): """Returns the Keccak SHA256 of the given value. Text is encoded to UTF-8 before computing the hash, just like Solidity. Any of the following are valid and equivalent: """ return Tron.keccak(primitive, text, hexstr) @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()