最近,区块链技术已经成为很多行业游戏规则的变革者,在比特币中涌现的分布式分类技术在数字货币之外也有了非常广阔的应用前景。
区块链技术最有前途的一个应用就是开发智能合约。
智能合约是自我执行合约,在智能合约中,合约条款由代码规定。基本上,这意味着可以用计算机程序编写具有法律效力的合约,而且这个合约可以自动执行。
至少在1996年Nick Szabo 就提出了这一概念,尽管这个概念已经出现了一段时间了,但是直到图灵完成Ethereum区块链,智能合约的使用才开始普及。
在Ethereum区块链上的合约,存在于合约地址,并且可以被事务调用引用。
执行用代码书写的合约并且在一个不可改变的公开的区块链中存储信息造成一定的风险和问题,这也是我们要在这篇文章中讨论的。在即将写的第二部分中,我们将会查看一些关于智能合约安全漏洞的更加具体的例子。
代码就是法律?
对于智能合约的字面解释导致了“代码就是法律”的词意变化,这一词义的改变意味着智能合约具有约束力,并且被理解为法律文件。很多软件工程师意识到创造一个完全无误差的代码是不可能的,一想到计算机程序具有法律效力就让人手心出汗。这里有很多明显的问题:
1. 代码含有bug。写一个没有bug的代码实在是太难了,即使采取了所有可能的预防措施,在复杂的软件中也总会出现没有预料到的执行路径或可能的漏洞。
2. 法律合约是受解释和仲裁的约束。很难去创造一个缜密的合约。在任意一个大的合约里,可能出现的文稿错误以及一些条款需要解释和仲裁。避免这些争论就是法庭的作用。假设在一个合法合约的39至40 页规定售价是100美金,然后在某一页中打了一个额外的0,法庭将以“契约精神”来裁决。一台电脑只能执行预先写好的条款,区块链的不变性增加了这样这个问题即合约不容易修改
3. 软件工程师不是法律专家,反之亦然。起草一份好的合约需要各种各样的技能,不一定与编写的计算机程序兼容。
两个运用高知名度智能合约的例子
DAO攻击
关于DAO攻击已经说过很多了,在此我们不在重复。我们可以在这里找到一个关于DAO的攻击和后果的很好的概述。
总之,在2016年6月一个攻击者设法转移了一大笔众筹基金(3.5m ETH,大约是当时ETH总量的15%)到他的孩子的账户,其中资金被锁定28天,导致为了找到解决方案要与时间竞争。
在这种情况下,需要注意的一点是,合约通过一种出乎意料的方式被攻击。在这种特殊的情况下重放漏洞被利用。我们将会在后面的跟进中进行详细的讲解。
奇偶校验破解
事实上,这是由奇偶校验提供的多重签名wallet contract的第二次破解。很多初创公司使用多重签名wallet contract,其大部分逻辑在librarycontract中实现。每一个wallet包含于一个轻量级的客户端协议,并连接到单点故障。
在library contract中有一个关键的bug,它包括在一个初始化的函数中,能够被准确的调用一次。
在2017年12月,某些人初始化了合约,这样就成为了合约的拥有者。这样就允许特调用所有者函数。这就是他用来调用一下函数的特权:
// kills the contract sending everything to `_to`.
function kill(address _to)onlymanyowners(sha3(msg.data)) external {
suicide(_to);
}
这是相当于自毁按钮,可以使合约失效。调用这个函数会导致客户合约中所有的资金被冻结,有可能是永久冻结。
虽然肇事者声称这只是一个意外,但是在撰写该报告时,仍旧不清楚这个黑客是否构成蓄意攻击。还是真的只是一个意外。
两次攻击表明,即使是区块链生态系统中最大的玩家编写的相对简单的合约,也很容易因为一个基本的bug产生严重后果。
应该采取什么措施?
#p#分页标题#e#
最近的历史表明,在公共区块链上执行智能合约是危险的,并且没有足够安全的方案可以用准确的语言、解释和仲裁的空间,来代替传统的法律制度。
这不意味着我们应该放弃智能合约。智能合约是非常有用的工具并且开发了有趣的应用。然而,我们不应该把它视为有法律约束力的合约的替代品,而应该把它视为自动化的补充工具。
此外,我们应该采取一些措施来避免漏洞。
在library contracts中应该使用开源代码和社区可接受的事实标准。例如 开放的Zeppelin合约。
使用推荐的路径和最佳实践指南,例如Consensys中提供的准则。
考虑由信誉好的供应商审计您的智能合约。
在本系列即将发表的文章中,我们将会了解一些已知的漏洞,包括代码示例,以及如何防止它们。