错误的以太坊智能合约
2013至2014年间,Vitalik Buterin 发表了以太坊白皮书提出用区块链储存程序,用户可以在节点上调用这些程序,通过这种方式,程序可以作为创建者的代理人自动执行交易而无需人的参与。这就是智能合约。Buterin 认为这种机制足以安全地进行程序化的交易。这是一个百亿级的错误。仅2020一年,由于智能合约安全性的问题就导致价值900亿元加密资产的蒸发。
在以太坊及大批模仿者中,每个智能合约都管理自己发行的代币的账本。也就是说,在这些区块链上存在不止一个账本。原生币有一个账本。每一种代币又各有一个账本。他们都是去中心分布式账本吗?对于原生币的账本不存在争议,对于代币的账本,我们需要考察一下什么才是一个去中心。
所谓去中心指的是每个记账者(矿工)独立地决定各自所纪录的账本内容,而不是机械地复制他人的账本。这种独立性包括独立地决定每一笔交易是否合法,从而是否纪录该笔交易。只要网络中造假者不占优势,就可以通过这种方式阻止非法交易成为区块链网络的共识,从而达到保护资产安全的目的。如果一个区块链中的矿工不具有这种独立决定每一笔交易是否合法的能力,那么这个区块链就不是去中心的,矿工们都必须依赖一个中心化的权威决定来决定每笔交易是否合法,因此所有账本就是由一个中心来控制的,这个中心就可以任意决定资产的归属,区块链就不能为用户提供安全性保障。而根据以太坊的智能合约交易模式,智能合约代币的账本是由合约管理,而非矿工管理。而每个合约都是由单一的项目方发布,矿工虽然纪录合约所产生的数据,但矿工并不理解这些数据,只能是合约要求矿工记什么矿工就记什么。这就是把所有矿工从记账人变为记账的笔,而指挥这些笔的人是合约的项目方。因此这些代币的账本不是去中心的,而是中心化的账本。这是非常不安全的。
以太坊的智能合约甚至都不能称为合约。没错,合约可以通过程序执行,但并不是每个程序的执行都是一个合约。一个程序的执行要构成合约还需要额外满足一些条件。对于作为去中心化账本的区块链来说,很重要的一条就是交易必须经过验证。正如中本聪所说的:不要信任,要验证。这是区块链的金科玉律,任何时候违反它必然导致安全性问题。但以太坊并不验证智能合约的交易结果,而只是验证智能合约的执行过程。在以太坊中,用户调用智能合约时,节点会执行智能合约,只要智能合约成功返回,节点就认为交易合法并予以记录。这种模式有什么问题呢?毕竟智能合约调用是用户发起的,难道不应该接受智能合约调用的结果吗?这是以太坊的思维。
法律上,双方意思一致才是合约。合约各方必需对各方的付出和获得都达成一致,合约才能成立。那么用户在调用智能合约时,他同意的是什么?是接受智能合约所产生的任何结果,还是合约发布者宣称会产生的结果?绝大多数用户都不是程序员,不可能知道程序会怎么运行,显然他们同意的是合约发布者宣称会产生的结果。但是以太坊是不可能验证智能合约的执行结果是否与用户的预期(也就是合约发布者宣称的结果)一致,因为以太坊节点根本就没有这方面的信息。所以以太坊中所记录的每一笔智能合约交易只是证明“智能合约产生了这样的结果”,而不是“合约双方同意这样的结果”。混同这二者的后果是致命的。
更糟糕的是,以太坊将智能合约的交易结果作为合约的数据来储存。即,用户从智能合约那里获得的资产是记录在智能合约自己的账本中,而不是公共账本中。以太坊节点本身不会验证这些资产的转移。这些资产的转移是由智能合约处理和验证的。用户不能直接控制这些资产。是智能合约在控制它们。这简直就是开门辑盗。所以结果就是以太坊用户只能任凭智能合约处置,在智能合约面前没有任何安全保障。既没有交易安全,因为以太坊不能保证合约执行的结果符合用户期望;也没有价值储存安全,因为智能合约可以不经用户同意就转走用户资产。
因此我们看到以太坊自发布以来已经发生多起与智能合约有关的安全性事件。相比之下,比特币从未发生过安全性事件。大家都认为智能合约的安全问题是开发者的错误和疏忽所导致,所以业内在规范智能合约开发流程,对于智能合约进行形式验证,代码安全性审计,开发安全的智能合约语言等方面作出了很大的努力。然而智能合约的安全问题从根本上说是自以太坊发布以来业界对于去中心合约的错误理解和由此而来的不当交易模式所导致。解决了这个问题就能杜绝迄今为止的大多数智能合约安全问题。而不解决这些问题,现今的各种努力终归不能杜绝智能合约的安全隐患。