在过去的这几年时间里, 我们一直都在从事合约审计方面的工作。在这个过程中, 区块链异常代码是一个我们无法躲避的频繁出现的问题。这种问题不像传统的程序崩溃那样, 能够提供一个明确的错误堆栈信息来供人们查看。
相反, 这类异常往往隐藏在了区块数据之中, 或者隐藏在共识校验的过程里面, 又或者隐藏在事件日志的内部。正因为如此, 我们要进行排查的途径与之前完全不同。
区块链异常代码怎么排查
链上环境有一个非常大的特点, 那就是它具有不可篡改的属性。在异常代码出现的时候, 它往往不会直接导致程序崩溃, 而是表现为交易被拒绝、gas计算发生溢出或者是状态根校验失败的情况。
我通常的做法是从区块头开始进行分析, 去比对其中的Merkle根是什么情况。通过这样的方式, 我可以把异常的覆盖范围最终锁定到那笔具体的交易上面。
真正使人感到受阻碍的关键因素在于跨合约的调用行为。当一个叫做A的系统去调用一个叫做B的系统, 然后紧接着再去调用一个叫做C的系统的时候, 只要处在中间环节的任何某一个操作发生了回滚状况, 那么就会导致整一条调用链条都需要进行回滚处理。
采用使用Tenderly来执行重放这一方式来把发生在链上的那些状态数据下载到本地来进行运行测试, 通过逐帧方式来查看调用栈的情况, 其效率要比在浏览器当中去翻阅日志高效得多。
区块链异常代码怎么修复
修复的核心原则是保持状态机的一致性, 不要只是去修改那行报错的代码, 而是需要回溯并检查它所有依赖的存储变量。在Solidity0.8版本中加入了溢出检查功能, 但是在unchecked代码块里如果发生下溢, 仍然会悄无声息地触发错误, 这一点经常被开发人员忽略。
如果出现共识层异常,例如在发生重新组织之后, 某个节点所执行的代码路径出现了偏差, 通常情况下需要进行重新同步区块操作, 或者回滚到检查点位置。同时必须给关键业务逻辑加上版本戳记, 以此避免新旧代码混合运行导致状态发生漂移现象。

其实并没有那种可以包治百病的万能公式, 但是如果说你把整个工具链都搭建好, 然后把调用栈一层一层的拆开来看, 那么绝大多数的异常问题是能够在三个小时以内找到根本原因的。
转载请注明出处:imtoken,如有疑问,请联系()。
本文地址:https://www.zmdyd.cn/gwimqb/10369.html
