合约编程误区
介绍常见的合约编程错误带来的风险。
继承覆盖关键变量
如上合约代码,关键功能性函数已忽略。
看似 onlyOwner
modifier 工作正常,且整个合约没有修改 owner
的入口,那么按照逻辑,只有合约作者可以通过调用 distributeDividends
获得收益。
然而实际执行中,合约的余额并没有发送给 owner
, 而是被发到了 T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb
这样一个地址。通过调用 owner()
检查,并没有发现 owner
被修改。
问题出在 address private owner;
一句,该私有变量申明通过合约继承链,屏蔽掉了父合约 owned
中的真正的 owner
变量。所以在 owner.transfer()
中使用的地址是一个未初始化的 address
类型,值为 "410000000000000000000000000000000000000000"
, 用 base58check 编码后正好是 T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb
.
检查合约继承链中的所有变量定义,避免覆盖关键变量。
使用可预测变量获取随机数
如上合约代码,是一个简单的猜数字游戏。
uint256(keccak256(abi.encodePacked(block.difficulty, now)))
多见于以太坊合约的随机数生成,然而, 对于 TRON 来说,block.difficulty
恒为 0, 且 now
(即 block.timestamp) 可准确预测。
最终结果是,攻击者可以提前计算随机数值,选择在合适的时间点发送交易,达到控制随机数的目的。
检查所有随机数生成源头,避免可预测的随机数。
相关细节参考: 波场Solidity智能合约安全实践:合约内随机数的实现.
最后更新于