def update_setting(self, contract_address, user_fee_percentage, owner_address=None): """Update userFeePercentage. Args: contract_address (str): the address of the contract to be modified user_fee_percentage (int): the percentage of resources specified for users using this contract owner_address (str): is the address of the creator Returns: Contains unsigned transaction Transaction """ if owner_address is None: owner_address = self.tron.default_address.hex if not self.tron.isAddress(owner_address): raise InvalidAddress('Invalid owner_address provided') if not self.tron.isAddress(contract_address): raise InvalidAddress('Invalid contract_address provided') if not is_integer(user_fee_percentage) or user_fee_percentage < 0 or \ user_fee_percentage > 100: raise ValueError('Invalid user_fee_percentage provided') return self.tron.manager.request('wallet/updatesetting', { 'owner_address': self.tron.address.to_hex(owner_address), 'contract_address': self.tron.address.to_hex(contract_address), 'consume_user_resource_percent': user_fee_percentage })
def validate_address(value): """ Helper function for validating an address """ if is_bytes(value): if not is_binary_address(value): raise InvalidAddress( "Address must be 20 bytes when input type is bytes", value) return if not isinstance(value, str): raise TypeError( 'Address {} must be provided as a string'.format(value)) if not is_hex_address(value): raise InvalidAddress( "Address must be 20 bytes, as a hex string with a 0x prefix", value) if not is_checksum_address(value): if value == value.lower(): raise InvalidAddress( "Web3.py only accepts checksum addresses. " "The software that gave you this non-checksum address should be considered unsafe, " "please file it as a bug on their platform. " "Try using an ENS name instead. Or, if you must accept lower safety, " "use Web3.toChecksumAddress(lower_case_address).", value, ) else: raise InvalidAddress( "Address has an invalid EIP-55 checksum. " "After looking up the address from the original source, try again.", value, )
def update_energy_limit(self, contract_address, origin_energy_limit, owner_address=None): """Update energy limit. Args: contract_address (str): The address of the contract to be modified origin_energy_limit (int): The maximum energy set by the creator that is created owner_address (str): Is the address of the creator Returns: Contains unsigned transaction Transaction """ if owner_address is None: owner_address = self.tron.default_address.hex if not self.tron.isAddress(owner_address): raise InvalidAddress('Invalid owner_address provided') if not self.tron.isAddress(contract_address): raise InvalidAddress('Invalid contractAddress provided') if not is_integer(origin_energy_limit) or origin_energy_limit < 0 or \ origin_energy_limit > 10000000: raise ValueError('Invalid originEnergyLimit provided') return self.tron.manager.request('wallet/updateenergylimit', { 'owner_address': self.tron.address.to_hex(owner_address), 'contract_address': self.tron.address.to_hex(contract_address), 'origin_energy_limit': origin_energy_limit })
def create_token_exchange(self, first_token_name: str, first_token_balance: int, second_token_name: str, second_token_balance: int, owner_address=None): """Create an exchange between a token and another token. DO NOT USE THIS FOR TRX. Token Names should be a CASE SENSITIVE string. Args: first_token_name (str): the id of the first token first_token_balance (int): balance of the first token second_token_name (str): the id of the second token second_token_balance (int): balance of the second token owner_address: owner address """ if owner_address is None: owner_address = self.tron.default_address.hex if not self.tron.isAddress(owner_address): raise InvalidAddress('Invalid address provided') if second_token_balance <= 0 or first_token_balance <= 0: raise ValueError('Invalid amount provided') return self.tron.manager.request('/wallet/exchangecreate', { 'owner_address': self.tron.address.to_hex(owner_address), 'first_token_id': self.tron.toHex(text=first_token_name), 'first_token_balance': first_token_balance, 'second_token_id': self.tron.toHex(text=second_token_name), 'second_token_balance': second_token_balance })
def withdraw_exchange_tokens(self, exchange_id: int, token_name: str, token_amount: int = 0, owner_address=None): """Withdraws tokens from a bancor style exchange. Will withdraw at market rate both tokens. Args: exchange_id (int): non-negative integer exchange id token_name (str): token name token_amount (int): number of tokens withdraw owner_address (str): owner address in hex """ if owner_address is None: owner_address = self.tron.default_address.hex if not self.tron.isAddress(owner_address): raise InvalidAddress('Invalid owner_address provided') if exchange_id < 0: raise ValueError('Invalid exchange_id provided') if token_amount < 1: raise ValueError('Invalid token_amount provided') return self.tron.manager.request('/wallet/exchangewithdraw', { 'owner_address': self.tron.address.to_hex(owner_address), 'exchange_id': exchange_id, 'token_id': self.tron.toHex(text=token_name), 'quant': token_amount })
def create_proposal(self, parameters: Any, issuer_address=None): """Creates a proposal to modify the network. Can only be created by a current Super Representative. Args: parameters (Any): proposal parameters issuer_address: owner address Examples: >>> from tronapi import Tron >>> data = [ >>> {'key': 1, 'value': 2}, >>> {'key': 1, 'value': 2} >>> ] >>> tron = Tron() >>> tron.transaction.create_proposal(data) """ if issuer_address is None: issuer_address = self.tron.default_address.hex if not self.tron.isAddress(issuer_address): raise InvalidAddress('Invalid issuerAddress provided') return self.tron.manager.request('/wallet/proposalcreate', { 'owner_address': self.tron.address.to_hex(issuer_address), 'parameters': parameters })
def purchase_token(self, to: str, token_id: str, amount: int, buyer=None): """Purchase a Token Creates an unsigned ICO token purchase transaction. Args: to (str): is the address of the Token issuer token_id (str): is the name of the token amount (int): is the number of tokens created buyer (str): is the address of the Token owner """ if buyer is None: buyer = self.tron.default_address.hex if not self.tron.isAddress(to): raise InvalidAddress('Invalid to address provided') if not len(token_id): raise ValueError('Invalid token ID provided') if amount <= 0: raise ValueError('Invalid amount provided') _to = self.tron.address.to_hex(to) _from = self.tron.address.to_hex(buyer) return self.tron.manager.request('/wallet/participateassetissue', { 'to_address': _to, 'owner_address': _from, 'asset_name': self.tron.toHex(text=token_id), 'amount': int(amount) })
def deploy(cls, **kwargs): """Deploy Contract Deploys a contract. Returns TransactionExtention, which contains an unsigned transaction. Example: .. code-block:: python >>> MyContract.deploy( fee_limit=10**9, call_value=0, consume_user_resource_percent=10 ) Args: **kwargs: Transaction parameters for the deployment transaction as a dict """ if not cls.bytecode: raise ValueError( "Cannot deploy a contract that does not have 'bytecode' associated " "with it") # Maximum TRX consumption, measured in SUN (1 TRX = 1,000,000 SUN). fee_limit = kwargs.setdefault('fee_limit', 0) # The same as User Pay Ratio. # The percentage of resources specified for users who use this contract. # This field accepts integers between [0, 100]. user_fee_percentage = kwargs.setdefault( 'consume_user_resource_percent', 0) # Amount of TRX transferred with this transaction, measured in SUN (1TRX = 1,000,000 SUN) call_value = kwargs.setdefault('call_value', 0) # Contract owner address, converted to a hex string owner_address = kwargs.setdefault('owner_address', cls.tron.default_address.hex) # We write all the results in one object transaction = dict(**kwargs) # Smart Contract's Application Binary Interface transaction.setdefault('abi', cls.abi) # The compiled contract's identifier, used to interact with the Virtual Machine. transaction.setdefault('bytecode', to_hex(cls.bytecode)) if not is_integer(fee_limit) or fee_limit <= 0 or \ fee_limit > 10 ** 9: raise ValueError('Invalid fee limit provided') if not is_integer(call_value) or call_value < 0: raise ValueError('Invalid call value provided') if not is_integer(user_fee_percentage) or user_fee_percentage < 0 or \ user_fee_percentage > 100: raise ValueError('Invalid user fee percentage provided') if not cls.tron.isAddress(owner_address): raise InvalidAddress('Invalid issuer address provided') return cls.tron.manager.request('/wallet/deploycontract', transaction)
def transact(self, **kwargs): """Deploy Contract Deploys a contract. Returns TransactionExtention, which contains an unsigned transaction. Args: **kwargs: Additional options to send """ # Maximum TRX consumption, measured in SUN (1 TRX = 1,000,000 SUN). fee_limit = kwargs.setdefault('fee_limit', 1000000000) # The same as User Pay Ratio. # The percentage of resources specified for users who use this contract. # This field accepts integers between [0, 100]. user_fee_percentage = kwargs.setdefault( 'consume_user_resource_percent', 0) # Amount of TRX transferred with this transaction, measured in SUN (1TRX = 1,000,000 SUN) call_value = kwargs.setdefault('call_value', 0) # Contract owner address, converted to a hex string owner_address = kwargs.setdefault('owner_address', self.tron.default_address.hex) # The max energy which will be consumed by the owner # in the process of excution or creation of the contract, # is an integer which should be greater than 0. origin_energy_limit = kwargs.setdefault('origin_energy_limit', 10000000) # The compiled contract's identifier, used to interact with the Virtual Machine. bytecode = to_hex(self.bytecode) if not is_integer( fee_limit) or fee_limit <= 0 or fee_limit > 1000000000: raise ValueError('Invalid fee limit provided') if not is_integer(call_value) or call_value < 0: raise ValueError('Invalid call value provided') if not is_integer(user_fee_percentage) or user_fee_percentage < 0 or \ user_fee_percentage > 100: raise ValueError('Invalid user fee percentage provided') if not is_integer(origin_energy_limit) or origin_energy_limit < 0: return ValueError('Invalid origin_energy_limit provided') if not self.tron.isAddress(owner_address): raise InvalidAddress('Invalid issuer address provided') # We write all the results in one object transact_transaction = dict(**kwargs) transact_transaction.setdefault( 'owner_address', self.tron.address.to_hex(owner_address)) transact_transaction.setdefault('abi', self.abi) transact_transaction.setdefault('bytecode', bytecode) return self.tron.manager.request('/wallet/deploycontract', transact_transaction)
def withdraw_block_rewards(self, address: str = None): """Withdraw block rewards Creates an unsigned Super Representative award balance withdraw transaction. Args: address (str): Optional address to withdraw from. """ if not address: address = self.tron.default_address.hex if not self.tron.isAddress(address): raise InvalidAddress('Invalid address provided') return self.tron.manager.request('/wallet/withdrawbalance', { 'owner_address': self.tron.address.to_hex(address) })
def vote(self, votes: List[Tuple[str, int]], voter_address: str = None): """Vote Vote on the super representative Args: votes (dict): dictionary of SR address : vote count key-value pair voter_address: voter address Examples: >>> from tronapi import Tron >>> data = [ >>> ('TRJpw2uqohP7FUmAEJgt57wakRn6aGQU6Z', 1) >>> ] >>> tron = Tron() >>> tron.transaction.vote(data) """ if voter_address is None: voter_address = self.tron.default_address.hex _view_vote = [] # We create a cycle to check all the received data for voting. for sr_address, vote_count in votes: if not self.tron.isAddress(sr_address): raise InvalidAddress('Invalid SR address provided: ' + sr_address) if not is_integer(vote_count) or vote_count <= 0: raise ValueError('Invalid vote count provided for SR: ' + sr_address) _view_vote.append({ 'vote_address': self.tron.address.to_hex(sr_address), 'vote_count': int(vote_count) }) return self.tron.manager.request( '/wallet/votewitnessaccount', { 'owner_address': self.tron.address.to_hex(voter_address), 'votes': _view_vote })
def trade_exchange_tokens(self, exchange_id: int, token_name: str, token_amount_sold: int = 0, token_amount_expected: int = 0, owner_address: str = None): """Trade tokens on a bancor style exchange. Expected value is a validation and used to cap the total amt of token 2 spent. Args: exchange_id (int): non-negative integer exchange id token_name (str): token name token_amount_sold (int): amount f token actually sold token_amount_expected (int): amount of token expected owner_address (str): token owner address in hex """ if owner_address is None: owner_address = self.tron.default_address.hex if not self.tron.isAddress(owner_address): raise InvalidAddress('Invalid owner_address provided') if exchange_id < 0: raise ValueError('Invalid exchange_id provided') if token_amount_sold < 1: raise ValueError('Invalid token_amount_sold provided') if token_amount_expected < 1: raise ValueError('Invalid token_amount_expected provided') return self.tron.manager.request( '/wallet/exchangewithdraw', { 'owner_address': self.tron.address.to_hex(owner_address), 'exchange_id': exchange_id, 'token_id': self.tron.toHex(text=token_name), 'quant': token_amount_sold, 'expected': token_amount_expected })
def trigger_smart_contract(self, contract_address, function_selector, fee_limit: int = 1000000000, call_value: int = 0, parameters=None, issuer_address=None ): """Trigger Smart Contract (Beta Version) Calls a function on a contract Args: contract_address (str): Contract address, converted to a hex string function_selector (str): Function signature. No spaces. fee_limit (int): Maximum TRX consumption, measured in SUN(1TRX = 1,000,000SUN) call_value (int): Amount of TRX transferred with this transaction, measured in SUN(1TRX = 1,000,000SUN) parameters (any): Call the virtual machine format of the parameter [1, 2], use the js tool provided by remix, convert the parameter array [1, 2] called by the contract caller into the parameter format required by the virtual machine. issuer_address (str): address that is trigger the contract Examples: >>> tron = Tron() >>> tron.transaction_builder.trigger_smart_contract( >>> '413c8143e98b3e2fe1b1a8fb82b34557505a752390', >>> 'set(uint256,uint256)', >>> 30000, >>> 0, >>> [ >>> {'type': 'int256', 'value': 1}, >>> {'type': 'int256', 'value': 1} >>> ]) Returns: TransactionExtention, TransactionExtention contains unsigned Transaction """ if parameters is None: parameters = [] if issuer_address is None: issuer_address = self.tron.default_address.hex if not self.tron.isAddress(contract_address): raise InvalidAddress('Invalid contract address provided') if not is_string(function_selector): raise ValueError('Invalid function selector provided') if not is_integer(call_value) or call_value < 0: raise ValueError('Invalid call value provided') if not is_integer(fee_limit) or fee_limit <= 0 or fee_limit > 1000000000: raise ValueError('Invalid fee limit provided') if len(parameters) > 0: types = [] values = [] for abi in parameters: if 'type' not in abi or not is_string(abi['type']): raise ValueError('Invalid parameter type provided: ' + abi['type']) if abi['type'] == 'address': abi['value'] = self.tron.address.to_hex(abi['value']).replace('41', '0x', 2) types.append(abi['type']) values.append(abi['value']) try: parameters = encode_hex(encode_abi(types, values)).replace('0x', '', 2) except ValueError as ex: print(ex) else: parameters = '' return self.tron.manager.request('/wallet/triggersmartcontract', { 'contract_address': self.tron.address.to_hex(contract_address), 'owner_address': self.tron.address.to_hex(issuer_address), 'function_selector': function_selector, 'fee_limit': int(fee_limit), 'call_value': int(call_value), 'parameter': parameters })
def trigger_smart_contract(self, **kwargs): """Trigger Smart Contract Calls a function on a contract Args: **kwargs: Fill in the required parameters Examples: >>> tron = Tron() >>> tron.transaction_builder.trigger_smart_contract( >>> contract_address='413c8143e98b3e2fe1b1a8fb82b34557505a752390', >>> function_selector='set(uint256,uint256)', >>> fee_limit=30000, >>> call_value=0, >>> parameters=[ >>> {'type': 'int256', 'value': 1}, >>> {'type': 'int256', 'value': 1} ] ) Returns: TransactionExtention, TransactionExtention contains unsigned Transaction """ contract_address = kwargs.setdefault('contract_address', None) function_selector = kwargs.setdefault('function_selector', None) parameters = kwargs.setdefault('parameters', []) issuer_address = kwargs.setdefault('issuer_address', self.tron.default_address.hex) call_value = kwargs.setdefault('call_value', 0) fee_limit = kwargs.setdefault('fee_limit', 1000000000) token_value = kwargs.setdefault('token_value', 0) token_id = kwargs.setdefault('token_id', 0) if not is_integer(token_value) or token_value < 0: raise ValueError('Invalid options.tokenValue provided') if not is_integer(token_id) or token_id < 0: raise ValueError('Invalid options.tokenId provided') if not self.tron.isAddress(contract_address): raise InvalidAddress('Invalid contract address provided') if not is_string(function_selector): raise ValueError('Invalid function selector provided') if not is_integer(call_value) or call_value < 0: raise ValueError('Invalid call value provided') if not is_integer( fee_limit) or fee_limit <= 0 or fee_limit > 1000000000: raise ValueError('Invalid fee limit provided') function_selector = function_selector.replace('/\s*/g', '') if len(parameters) > 0: types = [] values = [] for abi in parameters: if 'type' not in abi or not is_string(abi['type']): raise ValueError('Invalid parameter type provided: ' + abi['type']) if abi['type'] == 'address': abi['value'] = self.tron.address.to_hex( abi['value']).replace('41', '0x', 2) types.append(abi['type']) values.append(abi['value']) try: parameters = encode_hex(encode_abi(types, values)).replace( '0x', '', 2) except ValueError as ex: print(ex) else: parameters = '' data = { 'contract_address': self.tron.address.to_hex(contract_address), 'owner_address': self.tron.address.to_hex(issuer_address), 'function_selector': function_selector, 'fee_limit': int(fee_limit), 'call_value': int(call_value), 'parameter': parameters } if token_value: data.call_token_value = int(token_value) if token_id: data.token_id = int(token_id) return self.tron.manager.request('/wallet/triggersmartcontract', data)
def create_smart_contract(self, **kwargs): """Deploy Contract Deploys a contract. Returns TransactionExtention, which contains an unsigned transaction. Example: .. code-block:: python >>> from tronapi import Tron >>> >>> tron = Tron() >>> tron.transaction_builder.create_smart_contract( >>> fee_limit=10**9, >>> call_value=0, >>> consume_user_resource_percent=10 >>> ) Args: **kwargs: Transaction parameters for the deployment transaction as a dict """ if 'bytecode' not in kwargs: raise ValueError( "Cannot deploy a contract that does not have 'bytecode' associated " "with it") # Maximum TRX consumption, measured in SUN (1 TRX = 1,000,000 SUN). fee_limit = kwargs.setdefault('fee_limit', 0) # The same as User Pay Ratio. # The percentage of resources specified for users who use this contract. # This field accepts integers between [0, 100]. user_fee_percentage = kwargs.setdefault( 'consume_user_resource_percent', 0) # Amount of TRX transferred with this transaction, measured in SUN (1TRX = 1,000,000 SUN) call_value = kwargs.setdefault('call_value', 0) # Contract owner address, converted to a hex string owner_address = kwargs.setdefault('owner_address', self.tron.default_address.hex) # The max energy which will be consumed by the owner # in the process of excution or creation of the contract, # is an integer which should be greater than 0. origin_energy_limit = kwargs.setdefault('origin_energy_limit', 10000000) if not is_hex(kwargs.get('bytecode')): raise ValueError('Invalid bytecode provided') if not is_integer(fee_limit) or fee_limit <= 0 or \ fee_limit > 1000000000: raise ValueError('Invalid fee limit provided') if not is_integer(call_value) or call_value < 0: raise ValueError('Invalid call value provided') if not is_integer(user_fee_percentage) or user_fee_percentage < 0 or \ user_fee_percentage > 100: raise ValueError('Invalid user fee percentage provided') if not is_integer(origin_energy_limit) or origin_energy_limit < 0: return ValueError('Invalid origin_energy_limit provided') if not self.tron.isAddress(owner_address): raise InvalidAddress('Invalid issuer address provided') # We write all the results in one object transaction = dict(**kwargs) transaction.setdefault('owner_address', self.tron.address.to_hex(owner_address)) return self.tron.manager.request('/wallet/deploycontract', transaction)