使用tron-api-python调用合约发代币报错:Validate TransferContract error, no OwnerAccount
问题:使用tron-api-python发送代币时触发"Validate TransferContract error, no OwnerAccount"错误
发送TRX转账正常,但调用智能合约发送指定代币(如USDT)时触发验证错误,相关代码及报错信息如下:
原代码
from tronapi import Tron from tronapi import HttpProvider full_node = HttpProvider('https://nile.trongrid.io') solidity_node = HttpProvider('https://nile.trongrid.io') event_server = HttpProvider('https://nile.trongrid.io') tron = Tron(full_node=full_node, solidity_node=solidity_node, event_server=event_server) trx_kwargs = dict() trx_kwargs["private_key"] = '59d4b72df50290d7f78e2c16fc27758d6e235f3959f2212f2497fc55da33e888' trx_kwargs["default_address"] = 'TRNDt7bjFoTq7p52iw5u2BLNhsff1ux7Fc' trron = Tron(**trx_kwargs) kwargs = dict() kwargs["contract_address"] = tron.address.to_hex("TLBaRhANQoJFTqre9Nf1mjuwNWjCJeYqUL") # USDT contract address kwargs["function_selector"] = "transfer(address,uint256)" # function to call and types. for reference on tronscan it looks like this: transfer(address _to,uint256 _value) kwargs["fee_limit"] = 5000000 # fee limit in tron (5 TRX here) kwargs["call_value"] = 0 # I have no idea Towallet = 'TTG8u8fUKqJwMtB59ppaWqgFVGDb5ojWPU' Amount = 10.3 # added message send = trron.trx.send_transaction(trron.address.to_hex(Towallet), Amount) txid = send["txid"] print(send) print(f'your txid is {txid}')
报错核心信息
ValueError: class org.tron.core.exception.ContractValidateException : Validate TransferContract error, no OwnerAccount.
完整报错栈:
Traceback (most recent call last): File "main.py", line 26, in <module> send = trron.trx.send_transaction(trron.address.to_hex(Towallet), Amount) File "/home/runner/newtrx/venv/lib/python3.8/site-packages/tronapi/trx.py", line 421, in send_transaction tx = self.tron.transaction_builder.send_transaction( File "/home/runner/newtrx/venv/lib/python3.8/site-packages/tronapi/transactionbuilder.py", line 68, in send_transaction response = self.tron.manager.request('/wallet/createtransaction', { File "/home/runner/newtrx/venv/lib/python3.8/site-packages/tronapi/manager.py", line 124, in request return self.full_node.request(url, json=params, method=method) File "/home/runner/newtrx/venv/lib/python3.8/site-packages/tronapi/providers/http.py", line 84, in request response = self._request( File "/home/runner/newtrx/venv/lib/python3.8/site-packages/tronapi/providers/http.py", line 133, in _request raise ValueError(data['Error']) ValueError: class org.tron.core.exception.ContractValidateException : Validate TransferContract error, no OwnerAccount.
错误原因
- 调用方法错误:
send_transaction是专门用于TRX原生转账的方法,无法调用ERC20类代币的合约transfer方法,强行调用会导致合约验证失败。 - 金额单位未转换:代币(如USDT)有固定小数位数(USDT为6位),直接传入浮点数10.3会导致金额格式错误,合约无法识别。
- 实例初始化冗余:原代码创建了两个独立的Tron实例,第二个实例
trron未传入节点配置,可能导致节点连接异常,进而影响账户信息校验。
修复方案
步骤1:合并Tron实例配置
将节点信息与账户私钥、默认地址合并到同一个Tron实例中,避免冗余配置导致的异常。
步骤2:使用代币专用转账方法
使用trx.send_token方法发送代币,或直接加载合约调用transfer函数。
步骤3:转换金额为最小单位
根据代币的小数位数,将显示金额转换为合约可识别的最小单位整数(如USDT的10.3需转换为10300000)。
修复后的完整代码
from tronapi import Tron from tronapi import HttpProvider # 初始化测试网节点 full_node = HttpProvider('https://nile.trongrid.io') solidity_node = HttpProvider('https://nile.trongrid.io') event_server = HttpProvider('https://nile.trongrid.io') # 合并节点与账户信息创建Tron实例 tron = Tron( full_node=full_node, solidity_node=solidity_node, event_server=event_server, private_key='59d4b72df50290d7f78e2c16fc27758d6e235f3959f2212f2497fc55da33e888', default_address='TRNDt7bjFoTq7p52iw5u2BLNhsff1ux7Fc' ) # 配置转账参数 contract_address = tron.address.to_hex("TLBaRhANQoJFTqre9Nf1mjuwNWjCJeYqUL") # USDT测试网合约地址 to_wallet = 'TTG8u8fUKqJwMtB59ppaWqgFVGDb5ojWPU' # 接收地址 amount = int(10.3 * 10**6) # 转换为USDT最小单位(6位小数) # 执行代币转账 try: tx_result = tron.trx.send_token(to_wallet, amount, contract_address, fee_limit=5000000) txid = tx_result["txid"] print(f'交易成功,TXID: {txid}') print(tx_result) except Exception as e: print(f'交易失败: {e}')
可选方案:直接调用合约transfer函数
如果需要更灵活的合约调用,可直接加载合约执行transfer方法:
# 加载代币合约 contract = tron.contract(contract_address) # 调用transfer方法(接收地址需转hex格式,金额为最小单位) tx_result = contract.functions.transfer(tron.address.to_hex(to_wallet), amount).with_fee_limit(5000000).send() print(f'交易成功,TXID: {tx_result["txid"]}')
内容的提问来源于stack exchange,提问作者Mr2C2R
相关产品推荐
相关产品推荐

