1.发送智能合约调用交易时,为什么要填写fee_limit字段?

答案
防止合约调用交易消耗过多的energy。

解释
fee_limit表示的是合约调用者愿意承担这笔交易消耗的最大energy的值。

fee_limit单位是sun,最大可以设为1.5e10,如果用户不设置fee_limit,默认值是0。比如在交易中fee_limit设置为1000sun,那么表示合约调用者在这笔交易最多只會消耗1000/420energy(目前energy的单价是420sun)。

如果交易执行消耗的energy数值超过了fee_limit*energy单价,就会停止合约执行,并触发OUT_OF_ENERGY错误。

有些合约函数中会存在复杂的循环,用户在不知道的情况下误调用,可能会导致用户消耗过多的energy,于是用户可以设定这个fee_limit字段来设置一个上限。

有一些情况会导致所有的fee_limit被扣除:

  • 合约执行过程中遇到非法指令
  • 合约调用超时,触发OUT_OF_TIME错误
  • 如果你访问数组的索引太大或为负数(例如 x[i] 其中 i >= x.length 或 i < 0)
  • 如果你访问固定长度 bytesN 的索引太大或为负数
  • 如果你用零当除数做除法或模运算(例如 5 / 0 或 23 % 0 )
  • 如果你移位负数位
  • 如果你将一个太大或负数值转换为一个枚举类型
  • 如果你调用未被初始化的内部函数类型变量
  • 合约中调用assert的参数(表达式)最终结果是false
  • 发生JVMStackOverFlowException
  • 发生OutOfMem异常,即内存超过了3M
  • 合约运行过程中,发生了加法等溢出
  • 在动态能量模型启用后,不同维护周期同一合约调用的能量消耗也是动态的,fee_limit需要做相应的调整

2.调用合约时,为什么会触发OUT_OF_TIME错误?

答案
合约函数复杂度太高或者SR节点的性能波动。

解释
目前TRON 有一个全局设定, 智能合约调用的交易,执行时间不能超过80ms, 这个80ms参数可以通过SR投票修改。如果合约代码复杂很高,导致执行时间超过80ms,会触发OUT_OF_TIME错误,同时扣除全部fee_limit费用。

如果同一个合约函数,有时会触发OUT_OF_TIME错误,有时不会触发OUT_OF_TIME错误,说明合约代码的复杂度在一个临界值,由于不同的SR的机器性能不一样, 所以会导致间歇性触发。

另外需要注意的是由于SR机器性能的波动,会存在很小的概率导致复杂度非常低的合约函数调用也会触发OUT_OF_TIME错误。建议用户根据合约复杂度设置适当的fee_limit,防止fee_limit设置的过大引起过大的损失。

3.波场网络的销毁地址是什么?

销毁地址指该地址不受任何人控制,也就是任何人都没有该地址的私钥。例如0地址,1地址,2地址... 这些特殊地址均可作为销毁地址

Hex格式Base58格式
0410000000000000000000000000000000000000000T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb
1410000000000000000000000000000000000000001T9yD14Nj9j7xAB4dbGeiX9h8unkKLxmGkn
2410000000000000000000000000000000000000002T9yD14Nj9j7xAB4dbGeiX9h8unkKT76qbH

4.调用合约,返回revert报错如何进行排查?

答案
1.首先根据txid,通过wallet/gettransactioninfobyid接口查询返回的结果中contractResult字段,如果字段不为空, 可以看到message的abi编码值,将编码值转成字符串,查找报错原因
例如 txid:e5e013e81cb50a4c495a11c8130ad165a4e98d89b9e3fb5b79e6111bf23b31ed
返回contractResult数据:
"contractResult": [ "08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001e536166654d6174683a207375627472616374696f6e206f766572666c6f770000"
]
将1e536166654d6174683a207375627472616374696f6e206f766572666c6f77转成字符串是:SafeMath: subtraction overflow,这笔交易是因为转账时转出地址做减法操作时溢出,具体原因可能是余额不足,需要检查该地址的余额及转出金额。其他报错可根据具体报错原因进行排查。

2.如果contractResult为空,则可能是合约中不带message的require断言失败导致,需要查看合约源码进行分析。

5.如何计算调用合约时消耗的带宽及能量?

答案
1.带宽根据交易protobuf编码后的字节数计算。

2.能量根据合约执行的指令来计算,不同的指令消耗的能量不一样 ,越复杂的合约消耗的能量越多。合约消耗的能量可以通过在测试网测试或者通过tronscan查看该合约的历史交易来预估,或者通过调用API来预估。
资源模型可参考文档

如何通过API调用来预估能量消耗
wallet/triggerconstantcontract API既可以调用合约只读函数(view 或 pure修饰的函数),用于合约数据查询;也可以调用合约非只读函数,用于预判交易是否可以执行成功或者预估交易的能量消耗,返回结果中的energy_used 字段就是能量消耗量,因此,当返回值中result.result=true时,交易的fee_limit可以设置为energy_used x 能量单价

wallet/estimateenergyAPI也可以预估能量消耗。
注意:triggerconstantcontract和estimateenergy均不会产生上链交易,也不会改变当前节点的状态。

6.交易广播成功后,为什么链上查询不到?

答案
交易广播成功但是没有上链,是因为节点所在网络或其他未知原因导致该交易没有广播给SR节点,这种情况下,因为交易都有有效期,最好加上延迟判断,超过交易的有效期再加一点额外的时间还未上链,可以判断这个交易已经超过有效期,可以重新发起交易,或者在有效期内重新广播该交易。

7.如何解决“OUT_OF_ENERGY”报错?

答案
1.需要检查调用合约的地址是否有TRX及是否足够支付燃烧能量或带宽费用,否则该地址需要获取足够的TRX。
2.如果有足够的TRX,则交易设置的feelimit较小,需要提高feelimit设置。

8.如何解决节点区块同步慢或者停止同步问题?

答案
1.提高机器配置,推荐16core 32GRAM 1T硬盘(ssd)

确保单个物理cpu的逻辑core的数量大于等于16,下面的命令的结果中,cpu cores和siblings两者的最大值需要大于等于16

$cat /proc/cpuinfo | grep -e "cpu cores" -e "siblings" | sort | uniq
cpu cores : 8
siblings : 16
2.提高验证交易的时间容忍度
节点配置文件中maxTimeRatio配置项的值提高到20.0或者以上

vm = {
supportConstant = false
minTimeRatio = 0.0
maxTimeRatio = 20.0
saveInternalTx = false
}
3.修改java-tron的启动参数,增加并行垃圾回收参数:XX:+UseConcMarkSweepGC 及-Xmx参数
类似
java -Xmx24g -XX:+UseConcMarkSweepGC -jar FullNode.jar -c .....
-XX:+UseConcMarkSweepGC 要放在 -jar 参数前面,不能放在最后面
-xmx可以设置成物理内存的80%

9.如何解决SERVER_BUSY报错?

答案
如果节点未处理的交易数量超过2000会返回server busy错误, 根据机器情况,可以通过修改节点配置文件中的node.maxTransactionPendingSize来增加PendingSize。 比如设置node.maxTransactionPendingSize = 5000。

10.如何解决TronGrid 503 Service Temporarily Unavailable报错?

答案
为了保证请求资源的合理分配,目前TronGrid对所有请求都有IP频率限制。超出访问频率限制后,TronGrid将返回4xx或5xx 错误码。解决方法为:首先,请确保您在URL中使用了API Key。没有API Key的请求将受到严格的速率限制,甚至被完全拒绝。其次,可以适当降低请TronGrid请求频率,比如,在Dapp启动时限制请求次数;不要时时轮训Trongrid,因为TRON网络3s左右才生产一个区块,因此,以更快的速度请求新数据通常是没有意义的。

11.如何解决调用合约pureView方法时返回的Transaction中缺少Constant_result字段?

答案
此问题目前只见于用户将java-tron版本从GreatVoyage-v4.2.2(Lucretius)或其他更高版本降级到GreatVoyage-v4.2.1(Origen)(或者GreatVoyage-v4.2.0(Plato)版本) 后,如果用户遇到此问题,需要使用修复工具对数据库进行修复,修复完成之后使用 GreatVoyage-v4.2.2.1(Epictetus)或者更高版本即可正常启动节点。 详细操作步骤参看DBReqair.jar使用指南

12. 常见广播错误码说明

错误码原因解决方案
SIGERROR签名错误1. 检查用以签名的私钥是否和发起交易的地址一致

2. 检查私钥格式是否错误
BANDWITH_ERROR发起交易需要的带宽不足,并且没有足够的TRX燃烧向账户中充值TRX,或者用其他账号代理带宽给此账号
DUP_TRANSACTION_ERROR广播了相同哈希的交易1. 重新创建交易

2. 换一个节点重新广播
TAPOS_ERRORreference block与交易不在同一条链上1. 如果是通过自建节点API创建交易,可以修改节点配置 trx.reference.block = "solid"

2. 如果是本地创建的交易,建议引用最新已固化的区块
TOO_BIG_TRANSACTION_ERROR交易过大,可能是交易的memo过长减少交易的大小
TRANSACTION_EXPIRATION_ERROR交易过期。节点配置中,默认的交易过期时间是60秒,如果交易生成与广播的间隔超过此时间即为超时在交易过期前广播交易。

1. 如果是通过自建节点API创建交易,可以更改节点配置trx.expiration.timeInMilliseconds=60000,默认为60秒
2. 如果是通过公共节点API创建交易,则无法更改节点配置,即无法更改交易的过期时间
3. 如果本地构建的交易,可以将交易过期时间调大
SERVER_BUSY网络繁忙等待,错开网络繁忙的时间再重新发送交易
NOT_ENOUGH_EFFECTIVE_CONNECTION节点未同步到最新区块通过Tronscan查询当前的区块高度,并与本地节点/wallet/getnowblock的结果进行比较
OTHER_ERROR未知错误只能通过节点日志来获取到详细的错误信息
CONTRACT_VALIDATE_ERROR交易(系统合约)验证失败任何的参数错误都可能导致这个错误,需要解析错误消息查看详情。常见错误消息见下表

CONTRACT_VALIDATE_ERROR常见错误说明

错误信息说明
account does not exist发起交易的账号未激活
Validate *** error, no OwnerAccountOwner address不正确
No contract or not a valid smart contract合约地址错误
this node does not support constant节点的vm.supportconstant没有设置为‘true’,常见于自建节点

13.如何加快节点启动速度?

答案
如果节点采用LevelDB存储,那么从GreatVoyage-v4.3.0(Bacon)版本开始,可以使用LevelDB启动优化工具来提升节点启动速度。工具优化了manifest的文件大小以及LevelDB的启动过程,减少了内存占用,提升了节点启动速度。详细操作步骤参看LevelDB启动优化工具使用指南

14.如何使用tronWeb调用ABI不在链上的合约?

答案
请参考文档 如何使用tronWeb调用ABI不在链上的合约

15.如何通过扫块判断地址上资金的转入和转出?

答案
对于交易所或者钱包,通常需要获取一个账户的历史交易信息,或者监控一个账户地址资金的实时转入和转出情况,交易所或者钱包可以搭建一个全节点,然后通过解析历史区块来获取一个账户地址的交易记录,具体参考这里

16.为什么同一个TRC20代币的两笔转账交易消耗的能量会不一样?

答案
这是由于TVM虚拟机的特性的原因导致,TVM中的SSTORE存储指令,给变量赋值时,如果变量值为空,则消耗20000能量,否则,仅消耗5000能量,因此对于某一个TRC20代币的转账,如果接收账户中该TRC20代币余额为0时,转账消耗的能量会比余额不为0时多消耗15000能量。

除了上述原因,个别热门TRC20代币合约会由于动态能量模型的原因,导致在不同时间段调用,产生的能量消耗是不一样的。

17.为什么使用多重签名进行 Stake 2.0 质押会提示权限不足?

主网 Stake 2.0 生效之前激活的账户,使用多重签名的方式发起 Stake 2.0 相关操作可能会提示权限不足。

原因是Stake 2.0 生效之前已激活账户的多重签名权限组不包含 Stake 2.0 相关操作的权限位,需要更新您帐户的多重签名设置,根据您的需求将1个或多个Stake2.0 相关权限位添加到您当前的多重签名权限组中,下面是TronLink 钱包权限更新页面: