如果您花了很多时间在传统的软件开发环境中工作,那么在以太坊这样的平台上处理智能合约是一个有趣的挑战。一旦部署,智能合约就永远无法从网络中删除。
在早期,诸如“终止开关”之类的东西出现的目的是在出现问题时关闭合约。这些关闭开关不能由任何人激活,但通常需要由合约创建者 (即它们是集中控制功能)激活。
这些简单的终止开关突出了分散计算中一个极其重要的权衡:可升级性与可信任性。
可升级性
可升级性可以定义为程序员在将来某个时候修改软件行为的能力。
终止开关显然符合这个定义。终止开关通常需要在合约中预先编程,因此对精明的用户(但可能不是普通用户)是透明的。更广泛的可升级性包括发布额外或修改代码的能力,这些代码表示对系统的更改或增强。
升级智能合约的能力在更广泛的意义上是可取的,原因如下:
· 修复代码中发现的缺陷
· 当出现新的标准或找到更有效的方法时,升级代码库
· 随着需求的发展而改变代码的行为
需要注意的是,这些方面在开发期间和部署之后都是需要的。当一个完全不灵活的系统达到一定的规模时,开发起来就变得非常笨拙。常见的情况是,智能合约有成百上千条线。它们通常包含自己的数据存储,数据存储由同一合约中定义的业务规则操作。
我们在一段时间前开始尝试将表示业务规则的代码与仅管理数据的代码分离成独立的合约。为了有效,业务规则需要具有完全能够修改数据的能力。因为区块链编程环境的安全性(如可靠性)主要围绕基于发送方的行为进行限制。发送方将逻辑从处理数据的合约中分离出来意味着您需要的是保护的合约——不对外公开的合约。这些合约只能由已白名单的其他合约或地址调用。
将数据和行为分割成单独的合约会引入几个有趣的属性。
首先,由于许多原因,在区块链上迁移数据是有问题的。使用简单的CRUD功能将数据存储封装在其自己的合约中,可以减少所包含合约需要更改的可能性。然而,将业务规则移动到它们自己的、独立的合约中,允许我们升级系统的逻辑,而不需要重新创建数据的状态。
此外,拆分数据存储和业务逻辑允许我们为特定主题定义稳定的接口,同时保持实现的灵活性。
这很好,有几个原因。
首先,不依赖于不使用的东西是一种良好的软件实践。所以,如果一个外部系统依赖于我们系统的一组特定的功能,如果它们仅仅依赖于功能的子集而不是系统中的所有东西,这是很有用的。
举个例子,假设我们有一个智能的租车合约系统。我们决定把所有的代码放在一个大合约中。我们的合约包含了很多逻辑,但是一个叫carp的第三方仅仅关注人们的租车历史,以建立一个新的信誉系统。
瞧,我们需要升级汽车清洁记录在合约中的方式,因此我们修复了这个问题并部署了一个新合约。当然,我们修复了所有指向新合约的内部应用程序,并将变更通知(我们知道正在使用我们合同的人)。现在,carp必须改变他们的代码,因为我们决定改变我们处理汽车清洁的方式。然而,如果我们沟通不好,我们就破坏了他们的系统。
如果我们把逻辑分解成不同的合约,carp就不必改变任何东西了。
其次,如果我们定义指向业务逻辑实现的高级接口,那么carp只需要在我们更改高级公共API的情况下更改它们的代码。如果我们在使用定义和命名之前非常小心,这些更改可能很少。这基本上与我们期望Stripe或Twitter等主要公共api版本能够正常工作的方式相同。
最后,遵循我们所设置的模式允许我们的系统遵循开闭原则——我们可以向系统添加新的行为,而不需要修改源代码。我们可以简单地部署新组件,并在需要的地方将它们纳入白名单,这样它们就可以获得与我们的系统交互的授权。
可信任性
关于智能合约的早期观点之一是,它们具有约束力——因此有了“合约”这个词。描述是这样的:“Joe和我就谁将赢进行打赌。协议一旦达成,就无法撤销。一旦选举结束,智能合约将奖励获胜者。从这个意义上说,智能合约也是“不可信的”,因为我可以完全依赖代码来执行指定的合约,而不需要中介。
这与之前关于需要升级合约的论点形成了鲜明的对比。如果我能独自升级一份合约,那么我就能做各种恶意或有偏见的事情,而且我已经重新引入了人们信任我的必要性。
这提出了一个基本的冲突。正如Robert Martin在他的书《洁净建筑》中指出的,软件必须是软的——也就是说,它必须易于更改。“如果我不能修改代码,就会出现各种各样的问题。”另一方面,如果一合约同可以改变,还能说它是一个合约吗?
部分问题可能在于“智能合约”一词选择不当。有些东西肯定属于合约的范畴,但是像以太坊上的solid这样的通用编程环境允许创建各种各样的东西,其中一些在本质上不那么具有合约性一样。
在我看来,这是一个远未解决的问题。然而,我将提供一些想法:
首先,在规模上,我希望有非常少的用户能够真正地阅读代码并理解他们所签署的内容。因此,从这个意义上说,他们通常会相信他们所接触的公司、网站、平台等并不是恶意的。
其次,在许多情况下,这个问题可以通过要求多个开发人员签署正在部署的更改来解决。这将减少开发人员涂脂抹粉和抢劫的可能性。
第三,对于非常敏感的系统,在推出更改之前,可能需要外部审计人员在多个开发人员之外签署更改。在需要完全去中心化的情况下,可以使用TCR来管理核准的开发人员和审计人员名单。