区块链研究实验室-最全的以太坊智能合约编码安全技巧

智能合约代码测试编写

编写测试需要做很多工作,但可以避免回归问题。 当先前正确的组件根据最近的更改而中断时,会出现回归错误。

容错和自动bug赏金

感谢Peter Borah对这两个想法的启发。 代码审查和安全审核不足以确保安全。 我们的代码需要为最坏的情况做好准备。 如果我们的智能合约存在漏洞,应该有一种方法可以安全恢复。 不仅如此,我们应该尽早找到这些漏洞。 这就是我们的合同中内置的自动错误奖励可以提供帮助的地方。

让我们来看看这个假设令牌合约的自动错误赏金的简单实现:

和以前一样,我们使用PullPayment来确保我们的付款安全。 该Bounty合同允许研究人员创建我们想要审计的令牌合同的副本。 任何人都可以通过向Bounty合同的地址发送交易来为bug赏金做出贡献。 如果任何研究人员设法破坏他的令牌合同副本,做一些不变的中断(例如,在这种情况下,使令牌的总供应量与令牌的余额不同),他将获得赏金奖励。 一旦申请赏金,合同将不再接受任何资金(无名职能被称为合同的后备功能,并且每次合同直接汇款时执行)。

至于容错,我们需要修改我们的原始合同以增加额外的安全机制。 一个简单的想法是允许合同的策展人冻结合同作为紧急机制。 让我们看看通过继承实现此行为的方法:

Stoppable允许指定可以停止合同的策展人地址。 “停止合同”是什么意思? 这是由继承自Stoppable的子契约定义的,使用函数修饰符stopInEmergency和onlyInEmergency。 我们来看一个例子:

扫描二维码关注公众号,回复: 5305373 查看本文章

现在可以由策展人停止出价,该策展人在创建合同时定义。 当StoppableBid处于正常模式时,只能调用bid函数。 如果发生奇怪的事情并且合同处于不一致状态,策展人可以介入并激活紧急状态。 这使得出价函数不可调,并允许函数撤销工作。

在这种情况下,紧急模式只允许策展人销毁合同并收回资金,但在实际情况下,恢复逻辑可能更复杂(例如将资金返还给其所有者);

限制存入的资金数额

保护我们的智能合约免受攻击的另一种方法是限制其范围。 攻击者最有可能瞄准管理着数百万美元的高调合同。 并非所有智能合约都需要拥有如此高的股份。 特别是如果我们进行实验。 在这种情况下,限制我们的合同接受的资金数额可能是有用的。 这就像对合同地址余额的硬性限制一样简单。

这是一个如何执行此操作的简化示例:

短期后备功能将拒绝任何直接支付合同。 存款功能将首先检查合约的余额是否超出期望的限额,或抛出例外。 更有趣的事情,如动态或托管限制也很容易实现。

编写简单和模块化代码

安全性来自我们的意图与我们的代码实际允许的内容之间的匹配。 这很难验证,特别是如果代码庞大而且混乱。 这就是编写简单和模块化代码的重要性。

这意味着,函数应该尽可能短,代码依赖性应该减少到最小,文件应该尽可能小,将独立逻辑分成模块,每个模块都有一个单一的责任。

命名也是在编码时表达我们意图的最佳方式之一。 仔细考虑您选择的名称,使代码尽可能清晰。

最大的问题是它太长而且复杂。尽量保持您的功能更短,比如最多30或40行代码。理想情况下,您应该能够在不到一分钟的时间内阅读功能并了解他们的工作。另一个问题是第685行中事件转移的命名错误。该名称与只有1个字符的名为transfer的函数不同!这给每个人带来了混乱。通常,建议的事件命名是它们应该以“Log”开头。在这种情况下,更好的名称是LogTransfer。

请记住,尽可能简化,模块化和命名合同。这将极大地方便其他人和您自己审核您的代码。

不要从头开始编写所有代码

最后,正如古老的谚语所写:“不要滚动你自己的加密”。我认为它也适用于智能合约代码。您正在处理资金,您的代码和数据是公开的,并且您正在一个新的实验平台上运行。赌注很高,到处乱搞的可能性很大。

这些做法有助于保护我们的智能合约但最终,我们应该创建更好的开发人员工具来构建智能合约。

回顾一下,本文中描述的安全模式是:

  1. 尽可能早地暴露bug;
  2. 赞成拉动推付款;
  3. 制定您的功能代码:条件,操作,交互;
  4. 注意平台限制;
  5. 编写智能合约测试;
  6. 容错和自动bug赏金;
  7. 限制存入的资金数额;
  8. 编写简单和模块化代码;
  9. 不要从头开始编写所有代码;

本文转载公众号:区块链研究实验室

猜你喜欢

转载自blog.csdn.net/willam1/article/details/87089499