def _set_function_info(self): if not self.abi: self.abi = find_matching_fn_abi(self.contract_abi, self.function_identifier, self.args, self.kwargs) if self.function_identifier is FallbackFn: self.selector = encode_hex(b'') elif is_text(self.function_identifier): self.selector = encode_hex(function_abi_to_4byte_selector( self.abi)) else: raise TypeError("Unsupported function identifier") self.arguments = merge_args_and_kwargs(self.abi, self.args, self.kwargs)
def hex_encode_abi_type(abi_type, value, force_size=None): """ Encodes value into a hex string in format of abi_type """ validate_abi_type(abi_type) validate_abi_value(abi_type, value) data_size = force_size or size_of_type(abi_type) if is_array_type(abi_type): sub_type = sub_type_of_array_type(abi_type) return "".join([ remove_0x_prefix(hex_encode_abi_type(sub_type, v, 256)) for v in value ]) elif is_bool_type(abi_type): return to_hex_with_size(value, data_size) elif is_uint_type(abi_type): return to_hex_with_size(value, data_size) elif is_int_type(abi_type): return to_hex_twos_compliment(value, data_size) elif is_address_type(abi_type): return pad_hex(value, data_size) elif is_bytes_type(abi_type): if is_bytes(value): return encode_hex(value) else: return value elif is_string_type(abi_type): return to_hex(text=value) else: raise ValueError("Unsupported ABI type: {0}".format(abi_type))
def to_4byte_hex(hex_or_str_or_bytes: Union[int, str, bytes]) -> str: size_of_4bytes = 4 * 8 byte_str = hexstr_if_str(to_bytes, hex_or_str_or_bytes) if len(byte_str) > 4: raise ValueError('expected value of size 4 bytes. Got: %d bytes' % len(byte_str)) hex_str = encode_hex(byte_str) return pad_hex(hex_str, size_of_4bytes)
def get_function_info(fn_name, contract_abi=None, fn_abi=None, args=None, kwargs=None): if args is None: args = tuple() if kwargs is None: kwargs = {} if fn_abi is None: fn_abi = find_matching_fn_abi(contract_abi, fn_name, args, kwargs) fn_selector = encode_hex(function_abi_to_4byte_selector(fn_abi)) fn_arguments = merge_args_and_kwargs(fn_abi, args, kwargs) return fn_abi, fn_selector, fn_arguments
def encode_abi(tron, abi, arguments, data=None): argument_types = get_abi_input_types(abi) if not check_if_arguments_can_be_encoded(abi, arguments, {}): raise TypeError( "One or more arguments could not be encoded to the necessary " "ABI type. Expected types are: {0}".format( ', '.join(argument_types), ) ) try: normalizers = [ abi_address_to_hex, abi_bytes_to_bytes, abi_string_to_text, ] normalized_arguments = map_abi_data( normalizers, argument_types, arguments, ) encoded_arguments = eth_abi_encode_abi( argument_types, normalized_arguments, ) except EncodingError as e: raise TypeError( "One or more arguments could not be encoded to the necessary " "ABI type: {0}".format(str(e)) ) if data: return to_hex(HexBytes(data) + encoded_arguments) else: return encode_hex(encoded_arguments)
def callable_check(fn_abi): return encode_hex(function_abi_to_4byte_selector( fn_abi)) == to_4byte_hex(selector)
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 })