错误一:经典重入
经典重入仍然是合约第一大杀手。任何 call、transfer、send 之后还有状态变更的逻辑都要警惕。修复方式有两条:使用 checks-effects-interactions 模式;引入 ReentrancyGuard 修饰符。两者结合更稳。
做交易类合约时,建议参考 Binance合约 的风控逻辑,把异常调用直接拒绝并触发告警事件。
错误二:整数溢出与边界
虽然 0.8 之后默认有溢出检查,但许多优化场景仍使用 unchecked 块。一旦人为关闭检查,就要自己写边界判断。常见误区是把 unchecked 范围写得过大,让本该回滚的逻辑悄然通过。
错误三:存储槽冲突
升级型合约最容易踩存储槽冲突。新版本插入了一个新字段,老版本的存储位置被覆盖,导致逻辑错乱。修复方式是使用 OpenZeppelin 的 Storage Layout 工具,每次升级前做差分检查。
错误四:签名重放
链下签名验证必须包含 nonce、chainId、合约地址三要素,否则会被跨链或跨合约重放。EIP-712 标准已经把这些字段固化,开发时直接采用即可。
注册测试账户时,可以在 Binance注册 流程完成后绑定专用邮箱,避免与生产环境混淆,减少误操作风险。
错误五:随机数被预测
用区块时间戳或区块哈希做随机数已经被无数案例打脸。正确做法是接入 Chainlink VRF 或 BNB Chain VRF,把随机数源外置。
错误六:tx.origin 鉴权
tx.origin 容易被中间合约劫持,应当使用 msg.sender 进行鉴权。资深合约里几乎看不到 tx.origin 的踪迹。
错误七:Gas 限制硬编码
硬编码 Gas 上限会在主网升级时翻车。建议使用相对值(如 gasleft() 的百分比)或者通过治理参数动态调整。
错误八:事件参数缺失
关键状态变更如果没有 indexed 事件,链下数据分析与告警会非常痛苦。养成每次状态变更都 emit 事件的习惯。
配合 Binance教程 中介绍的链上数据看板做法,可以快速复盘事件流,加速问题定位。
错误九:依赖外部价格
直接读取单一 DEX 池子的价格容易被瞬间操纵。使用时间加权平均价或多预言机聚合才是稳妥做法,再叠加 Binance现货 的链下行情做交叉校验更安全。
错误十:忘记取消授权
用户授权过的代币长期闲置容易被钓鱼合约清空。在交互流程中加入授权回收引导,可以显著降低用户损失。
总结
常见错误并不复杂,但被忽视的概率却出奇高。把上面十条做成代码评审清单,每次合并前对照走一遍,能挡住绝大多数潜在攻击。