前些天,以太坊智能合约 BEC 和 SMT 的接连溢出事件,引发了大家对智能合约和区块链设计的激烈讨论。
我司基于以太坊开发也有一段时间了,基于这几个月的经验,聊一下我对以太坊以及私链/联盟链的一些看法。
首先,以太坊是一个非货币执行合约的链,发币其实是个错误的使用场景,但其他应用跑不起来(或者说没人关注),ICO需求井喷,导致各种 Token 都构建在 erc20 基础上。以太坊本身没有加密货币复式记账的 UTXO 模型,弄个 map 记录余额,用 nonce 等 tricky 的手段来防重放,这样就需要基于 erc20 的代币的开发者自己来保障其安全逻辑。如果合约逻辑有 bug,其他节点验证的时候也只是跑一遍同样的合约(p2p 副本式执行),bug 相同执行结果相同,有问题的执行结果也一样会被整个链认可,比如溢出导致发行量之外的 token 能凭空从代码中蹦出来。如果是公链的场景,整个合约对外是公开的,全世界的黑客都可以找你代码的茬,缺少 UTXO 等机制,光自己 review 肯定是不够的。
另外,溢出这种安全校验,怎么看都应该放在vm层或者标准库来实现。遗憾的是,官方文档的示例都没有使用 SafeMath。
双花和凭空产生都是虚拟货币要解决的核心问题,否则就毫无信用可言。中本聪在他的经典论文一开始就提出了这些问题,整个设计都是围绕这些问题展开,包括被以太坊认为是多余的 UTXO。
另外,使用 nonce 防双花,给应用层也带来了一些麻烦。比如你要不要自己维护 nonce。如果不自己维护 nonce,同一个账号前面一笔处理完成之后才会处理后面的 nonce,如果前一笔交易还处于 quened 中未被打包,就发起了下一笔交易,两笔交易 nonce 相同,如果下一笔的手续费低于上一笔,就会导致 relpacement transation underpriced 异常,如果手续费高于上一笔,就会导致上一笔被覆盖,这很可能并不是你希望看到的。如果你有这样的需求,你似乎没得选,只能自己维护 nonce。但这种方案也有一些限制。发起的交易必须通过统一维护的 nonce 作为出口,如果在其他地方发起交易,原有维护的 nonce 就会出现混乱。更大的问题是,一旦发出的交易发生异常,异常交易的 nonce 未被使用,以太坊要求同一个帐号的 nonce 是连续的,不能有空洞,后面的交易也会执行失败,异常交易的 nonce 需要重新被使用后它后面的 nonce 才会生效。如果你发起一笔后,WaitMined 才发起下一笔交易,那你的 tps 就会惨不忍睹了。
虽然我们目前还在使用以太坊,但对于联盟链来说,以太坊并不是一个很好的选择。solidity 和 evm 功能很弱,表达力完全无法和主流编程语言相提并论,而且还有 gaslimit,1024栈深等诸多限制。对于企业级应用,稍微复杂一点的需求都会觉得碍手碍脚。另外 Pow 在联盟链场景下,不仅浪费算力,安全性保证还不如 pbft (毕竟节点有限)。在加上金融领域的安全性和私密性要求,针对特定领域的专有链会是更合适的选择,比如 Corda。对于公链来说,分层(比如 SELinux 之于 Linux )和跨链会是区块链最核心的方向。
领取专属 10元无门槛券
私享最新 技术干货