智能合同
智能合同的概念最初是由研究员尼克·萨伯在 20 世纪 90 年代中期提出的。在他的论文中,他将智能合同描述为一组以数字形式规定的承诺,包括各方履行这些承诺的协议。这个描述可以分为四个部分:
- 一系列承诺
- 数字形式
- 通信和性能协议
- 自动触发动作的性能
如您所见,这里没有直接指定区块链,因为区块链技术还没有发明,而且在接下来的 13 年里也不会发明。然而,随着区块链技术的发明,智能合约突然变得更容易实现了。
智能合约和区块链技术是独立的想法。区块链可以在没有智能合约的情况下存在(例如,比特币没有内置真正的智能合约能力),智能合约可以在没有区块链的情况下建立。然而,区块链是一种特别适合开发智能合约的技术,因为它允许无信任、分散的交易。本质上,区块链为智能合同提供了四个必要项目中的两个:用于不同方之间通信和执行操作的数字形式和协议。
在本章中,我们将介绍一些不同的区块链网络及其实现智能合约技术的方法。在本章中,我们将讨论以下主题:
- 为什么要使用智能合约?
- 智能合同的方法
- 智能合同的局限性
总的来说,各种智能合约方法可以分为不同的类型:图灵完成、限制指令、链外执行和链内执行,如下图所示:
在系统上执行的智能合约的类型决定了性能、系统上可以执行什么和不可以执行什么、复杂性,当然还有安全级别。
在我们进一步讨论之前,让我们讨论一下为什么智能合约是可取的,甚至是革命性的。
为什么选择智能合约?
智能合约之前的世界充满了不确定性。法律合同,即使是简单的合同,也不需要遵守,使用大多数法律制度的追索费用过去和现在都极其昂贵,即使在法律制度不腐败的国家也是如此。在世界上的许多地区,合同几乎不值写合同的纸,通常只有拥有强大政治或财政权力的当事人才能执行。对于经济或政治体系中的弱势行为者来说,这是一系列可怕而不公平的情况。
我们之前提到的问题主要来自人为因素。只要一个人参与了合同的执行,他们就可能腐败、懒惰、被误导、有偏见等等。相比之下,智能合同是用代码编写的,无论涉及到哪一方,都应该忠实地执行。这为更安全、更廉价、更快速、更公平的结果提供了机会。
让我们在下面的小节中更深入地了解智能合约的主要优势。
各方之间的自动化流程和解决方案
智能合同最直接的优势在于,它们减少了成功且忠实执行的协议中的劳动和痛苦。以一个简单的公司间采购订单和发票为例。想象一下,一家名为 FakeCar Inc. 的公司决定从他们的供应商 Wheelmaster 那里购买 1000 个车轮。他们商定每个车轮的价格为 20 美元,在车轮交付给 FakeCar 时付款。最开始,车轮可能是货运过来的,在去 FakeCar 的路上经过多手。一旦他们到达,FakeCar 将需要扫描和检查每个车轮,做笔记,然后发出支票或电汇给 Wheelmaster。根据所涉及的距离,车轮可能由多家公司保管:一家卡车运输公司、洲际运输公司、另一家卡车运输公司,最后是 FakeCar 的制造厂。在每个阶段,都有损坏、丢失或误送的可能。一旦交付,FakeCar 将需要发出一个转账支付发票。即使一切顺利,这个过程也可能需要数周时间。与此同时,FakeCar 和 Wheelmaster 都不得不担心他们是否会分别得到自己的车轮或钱。
现在让我们来看看这个过程如何与智能合同一起工作:
- FakeCar 在区块链上以 20 美元一个车轮的价格发出 1000 个车轮的采购订单,有效期为 1 个月。
- Wheelmaster 向供应商发出发货请求,要求在一个月内交货,并接受采购订单。
-
FakeCar 在智能合同托管中为采购订单提供资金;Wheelmaster 可以放心,如果车轮到达,他们将得到付款。
-
Wheelmaster 看到有资金可以支付车轮,就与一家跟踪区块链每一步的公司合作,并接受支付任何丢失车轮的条款。他们(或他们的保险公司)还为航运托管合同提供足够的资金,以应对航运损失。一旦 FakeCar 在收据上签字,合同将自动退款给发货人。
- 车轮发运并交付,FakeCar 的托管被释放,保险保证金返回到运输公司。这发生在 FakeCar 登记收据和运输公司签署保管变更的时候。
在这种情况下,如果所有各方都参与到一个基于区块链的智能合同生态系统中,支付和保险可以立即得到验证和处理,甚至可以跨越国界、文化和语言。结果是所有各方的结果的确定性大大增加,效率也随之提高。例如,如果 Wheelmaster 可以确定他们的发票将被支付,那么他们就可以以更高的效率做出商业决策。
真实世界的例子
在撰写本文时,使用区块链和 smart 合同的第一笔重大物流交易是在汇丰和 ing 之间的 Corda 区块链完成的,涉及从阿根廷到马来西亚的大豆运输。据银行称,这种转账过去非常耗时,需要 5 到 10 天。有了区块链,整个金融问题在 24 小时内就得到处理。
智能合约的使用仍处于初级阶段,但该技术已经让金融服务的跨境摩擦减少了 80%—90%。随着技术和周围生态系统的改善,优势可能会变得更加极端。
增加透明度
如前所述,世界各地的组织所经历的一个负面因素是,对于许多交易来说,信任是必不可少的。在金融交易中尤其如此,在金融交易中,采购订单、发票和货物在多方之间移动。这里的信任问题很多。这不仅是一个是否有人会付钱的问题,也是一个他们是否能付钱的问题。他们有按时付款的历史吗?如果没有,他们的付款历史有多糟糕?在许多情况下,任何市场中的买方和卖方的信息都非常有限。在国际上尤其如此。这就是区块链和智能合约可以提供帮助的地方。
结束集中式数据
在美国,每个人都有一个由三家大型信用机构计算的信用评分。这些机构和他们的方法是不透明的。这些信息的购买者和被报告的人都不能深入了解分数是如何计算的,也不能直接更新这些信息。信贷机构的失误可能会对某人贷款买房或买车的能力造成毁灭性打击,耗费消费者宝贵的时间和金钱。然而,如果消费者发现他们的信用报告有错误,他们必须请求发行人更新,如果该组织拒绝,他们几乎没有选择。更糟糕的是,事实证明,这些发行者对他们收集的私人财务信息管理不善。例如,2017 年,Experian 遭遇了大规模数据泄露,暴露了超过 1 亿人的记录。如果这些机构被区块链系统和智能合约所取代,人们将能够直接看到规则并更新记录,而不必付钱给一个可能诚实或不诚实的中介。
大公司在当前的市场上有一个优势:它们都有能力支付这些第三方金融数据服务的费用,也有能力支付长期跟踪信息所需的人员和系统费用。较小的公司无法获得这样的规模经济,这使他们处于竞争劣势,增加了他们的管理费用,如果他们因为信息少而做出错误的决定,甚至会让他们破产。然而,甚至更大的公司也会受益,因为汇编这些数据的成本和费用也会增加。随着更多关于信任的数据公开化,并通过智能合同实现自动化,竞争环境将变得公平,并有望将不诚实的行为者挤出市场。这将提高整个市场的信心,降低管理费用,进而提高利润,降低价格,或者两者兼而有之。
增加公平性
在美国,曾经有一个被称为红线的过程,某些种族群体的人被拒绝贷款和获得金融服务——特别是抵押贷款。这些不公平的做法在某种程度上继续存在,因为发放贷款的标准和程序以及利率的计算方式隐藏在中央集权的组织内部。这种现象并不局限于美国;在世界上的许多地方,种族、宗教和其他偏见扭曲了本应是客观的决定。有了基于智能合约的系统,规则将是公开的、可审计的,以确保公平和准确。
智能合同方法
智能合约的一种方法是允许全功能软件嵌入区块链内部或旁边,能够响应区块链事件。这是 Hyperledger Fabric、Ethereum、NEO 和其他类似公司采用的方法。这种方法提供了最大的灵活性,因为基本上没有什么是不能写入区块链系统的。这种能力的缺点是有犯错的风险。可用的选项越多,必须测试的可能的边缘情况和排列就越多,代码中存在未被发现的漏洞的风险就越高。
智能合约的另一个方法是大大缩小可能的范围,以此作为回报,让事情变得更安全,让代价高昂的错误变得更难犯。目前,灵活性和安全性之间存在权衡。例如,在 Stellar 生态系统中,智能合同是由一系列操作组成的。在 Stellar,只有十一个操作:
- 创建帐户
- 支付
- 路径支付
- 管理报价
- 创建被动报价
- 设置选项
- 改变信任
- 允许信任
- 帐户合并
- 膨胀
- 管理数据
这些操作本身有多种选择和排列,因此支持相当多的行为。然而,不可能容易地使用这些操作来执行诸如 DAO 或其他链上治理组织之类的东西。相反,这样的功能必须被托管在链外。同样,Stellar 也没有明确的方法来管理 ERC-721 令牌,这种令牌可以跟踪交易卡甚至房地产等等价物。Stellar 的智能合约系统面向可替代资产的转移,如货币。因此,它可以快速扩展,轻松处理多签名账户和托管,并在几秒钟内以高吞吐量处理交易。以太坊更加灵活,但是多重签名能力、令牌本身等等需要用 Solidity 编写的软件来创建。以太坊显然更加灵活,但是需要更多的代码,因此存在更高的缺陷风险。
以太坊智能合约示例
智能合约使用最广泛的区块链是以太坊。在本文介绍的所有支持智能合约的网络中,它不仅是使用量最大的网络,而且拥有最大的公共分布式应用生态系统。以太坊如此受欢迎的原因之一是它对智能合约的表示相对直观,易于阅读。在这一节中,我们将看到一个基于以太坊的普通智能合同,它满足前面的所有四个标准,并且相对容易理解:一个代币销售合同。下面的代码将用 Solidity 编写;更多详情请参见第十三章、坚固度 101 、第十五章、以太坊发展。
前提
智能合约的第一个方面是它必须做出一系列程序化的承诺。我们选择代币销售合同的原因是,它有一个非常简单的承诺:如果你发送合同以太坊,合同将自动向你的帐户发送一个新的代币。让我们来看一些基本代码,这些代码明确不是用于生产的;这是简化的代码,使某些概念更加清晰。这段代码来自于StandardToken
合同,是 OpenZeppelin(你可以在参考资料部分找到相同的链接)项目的一部分,它基于该项目,具有全功能和经过审计的代码来实现相同的效果,但理解起来更复杂。
首先,这里是一个ERC20
令牌的接口契约,我们将把它保存为一个名为ERC20.sol
的文件:
pragma solidity ^0.4.23;
interface ERC20 {
function totalSupply() public view returns (uint256);
function balanceOf(address who) public view returns (uint256);
function transfer(address to, uint256 value) public returns (bool);
function allowance(address owner, address spender) public view returns (uint256);
function transferFrom(address from, address to, uint256 value) public returns (bool);
function approve(address spender, uint256 value) public returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}
接下来,我们将在众卖合同中引用令牌接口,它将发送一个ERC20
令牌来响应以太网中的支付:
pragma solidity ^0.4.23;
import "./ERC20.sol";
contract Crowdsale {
// The token being sold, conforms to ERC20 standard.
ERC20 public token;
// 1 tokens per Eth, both have 18 decimals.
uint256 public rate = 1;
constructor(ERC20 _token) public {
token = _token;
}
function () external payable {
uint256 _tokenAmount = msg.value * rate;
token.transfer(msg.sender, _tokenAmount);
}
}
这是一个非常简化的契约,但同样,它对于一个完整的真实世界来说是不够的。然而,它确实阐明了智能合约的关键概念。让我们来看看每一块。constructor
方法需要引用一个ERC20
令牌,这个令牌将会给发送以太坊的买家,如下面的代码所示:
constructor(ERC20 _token) public {
token = _token;
}
由于 Solidity 的工作方式,除非已经加载了令牌,否则该契约不能起作用。所以这是这段代码隐含的第一个承诺:必须有一个ERC20
令牌可供购买。第二个承诺是转化率,放在很简单的 1。每兑换一个威(以太坊的最小货币单位),购买此代币的人将获得 1 个单位的新代币。以太坊有 18 个小数位,按照惯例,大多数代币也是如此,因此可以推测,这将使以太坊到此代币的转换现在为 1:1。这就把我们带到了智能合同的必要方面中的第四项:自动履行。下面的代码处理这个问题:
function () external payable {
uint 256 _tokenAmount = msg.value * rate; //Calculate tokens purchased
token.transfer(msg.sender, _tokenAmount); //Execute send on token contract.
}
由于这是代码,智能合同应该是数字形式的要求是显而易见的。这里的自动化方面也很简单。在以太坊中,msg.value
保存作为命令的一部分发送的以太货币的值。当契约收到以太坊时,它会计算购买者应该收到并发送的令牌数量:不需要人工交互,也不需要或不可能有可信方。同样,没有人可以干预,因为一旦它被部署到网络上,以太坊中的代码是不可改变的。因此,使用此智能合约的发送方可以绝对放心,他们将收到他们的令牌。
安全考虑
在智能合约所处的领域中理解智能合约是很重要的:去中心化的异步网络。由于生活在这种生态系统中,有些安全考虑并不总是显而易见,可能会导致问题。为了说明,我们将研究ERC20
标准的两个相关函数:approve
和transferFrom
。下面是 OpenZeppelin 的approve
函数的代码:
function approve(address _spender, uint256 _value) public returns (bool) {
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
approve
功能允许代币所有者说他们已经批准将他们的代币转移到另一个账户。然后,响应于不同的事件,可以进行未来的转移。这是如何发生的取决于应用程序,但是例如代币销售,通过批准转移,区块链应用程序可以稍后调用transferFrom
并移动代币,可能是为了接受支付,然后执行操作。让我们看看这段代码:
function transferFrom(address _from,address _to,uint256 _value) public returns (bool) {
require(_to != address(0)); // check to make sure we aren't transfering to nowhere.
// checks to ensure that the number of tokens being moved is valid.
require(_value <= balances[_from]);
require(_value <= allowed[_from][msg.sender]);
// execute the transfer.
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
//Record the transfer to the blockchain.
emit Transfer(_from, _to, _value);
// let the calling code or app know that the transfer was a success.
return true;
}
这两个功能一起工作。希望使用应用程序的用户使用approve
来允许支付,应用程序调用transferFrom
来接受支付。但是由于调用的异步性质,缺陷是可能存在的。
想象一个应用程序,用户可以支付代币来加入数字俱乐部——40 个代币为基本会员,60 个代币为增强会员。用户也可以将代币交易给其他人,或者随意出售。这两个函数的理想情况是,用户批准 40 个令牌,应用程序注册并调用transferFrom
来移动这 40 个令牌,然后作为智能契约的一部分授予访问权限。到目前为止一切顺利。
重要的是要记住,这里的每个动作都需要时间,而且事件的顺序并不固定。实际发生的情况是,用户向网络发送一条消息,触发approve
,应用程序发送另一条消息,触发transferFrom
,然后当区块被挖掘时,一切都解决了。如果这些交易顺序错误(transferFrom
在approve
之前执行),交易将失败。此外,如果用户改变主意,决定将其批准从 40 更改为 60,该怎么办?以下是用户的意图:
- 用户 :
approve
40(第 1 块) - 用户 :
approve
60(区块 1) - App :
transferFrom
60 至 App(块 1) - App :授予增强会员资格(区块 2)
最终,用户支付了 60 个代币,得到了想要的东西。但是因为这些事件都是异步的,并且顺序是由矿工决定的,所以不能保证这个顺序。以下是可能发生的情况:
- 用户 :
approve
40(第 1 块) - App :
transferFrom
40 至 App(块 1) - 用户 :
approve
60(区块 2,因为矿工没有将其包括在区块 1 中) - App :
transferFrom
60 至 App(块 2)
现在用户无意中支付了 100 个代币。这里还有另一种排列:
- 用户 :
approve
40(第 1 块) - 用户 :
approve
60(区块 1) - App :
transferFrom
40 至 App(块 2) - App :授予基本会员资格(模块 2)
- App :
transferFrom
60 到 App(块 3) |失败
在该序列结束时,用户仍然有 20 个令牌被批准,并且获取增强成员资格的尝试已经失败。虽然可以并且应该通过允许升级 20 个令牌的会员资格以及在调用transferFrom
之前检查最大批准来编写一个没有这些问题的应用程序,但是对于应用程序作者来说,这种对细节的关注并不能得到保证或者是自动的。
需要理解的重要一点是,竞争条件和排序问题在以太坊中极其重要。用户不能控制区块链上事件的顺序,应用程序也不能。取而代之的是,由挖掘器来决定哪些事务发生在哪些块中,以及以何种顺序发生。在以太坊,影响矿工给予交易优先权的是气价。其他影响可能涉及最大区块气体限制、区块中已经存在的事务数量,以及成功解决区块的矿工是否已经在网络上看到该事务。出于这些原因,智能合约不能假定事件的顺序是预期的。
处理智能合同中的威胁
每个分散式网络将不得不处理由不同排序引起的竞争情况。仔细评估智能合约中可能存在的竞争条件和其他攻击是非常重要的。要知道是否可能出现竞态条件错误,就像要知道是否直接或间接地涉及到一个以上的函数调用一样简单。在前一种情况下,用户和应用程序都调用函数;因此,竞争条件是可能的,被称为前跑的攻击也是可能的。在一个方法中也可能有竞争条件,所以聪明的契约开发者不应该放松警惕。
每个网络都有不同的合同执行模式,因此每个网络都有不同的最佳实践。对于以太坊,Consensys 在https://consensys.github.io/smart-contract-best-practices/维护了一份智能合同最佳实践列表。
在发布任何智能合约之前,强烈建议组织编写大量的单元测试和模拟测试,然后根据该网络的最佳实践审核智能合约。
智能合同的局限性
智能合约拥有巨大的力量,但也有局限性。值得注意的是,这些系统的好坏取决于建造它们的人。到目前为止,许多智能合同系统由于不可预见的错误和事件而失败,这些错误和事件不是初始设计的一部分。在许多情况下,这些仅仅是技术缺陷,至少可以及时修复。然而,随着最近将区块链技术用于一切的热潮,我们可能会开始看到更多实质性的失败,因为人们无法理解该技术的局限性。要让区块链真正发挥最大的商业影响力,它的优势和局限都必须得到解决。
数据质量和错误
与所有系统一样,智能合约的好坏取决于它们所作用的数据。从网络接收到错误或不正确信息的智能协定仍将执行。在区块链系统中,这可能是一个大问题,因为由人或合同发起的大多数交易都是不可撤销的。因此,如果将信息放在错误、欺诈或有其他缺陷的区块链上,智能合约仍然会忠实地执行。智能合同现在将帮助传播错误,而不是加速网络的正常运行。
使用前面的例子,在 FakeCar 和 Wheelmaster 之间运输轮胎,如果在运输过程中,装有轮胎的箱子被闯入并更换了轮胎,会怎么样?如果 FakeCar 大楼的工作人员在没有检查每一个箱子的情况下扫描了收到的箱子,智能合同就会看到这一更新并释放托管。托运人的保险债券将被退回,Wheelmaster 将得到付款,而 FakeCar 将不再拥有他们订购的车轮。对于精明的契约纯粹主义者来说,事情应该是这样的。但在这些情况下,公司可能会拒绝使用智能合同或要求额外的批准层——本质上是再造旧的系统。
因此,在设计智能合同系统时,设计师尝试并想象每一种可能出错的方式是至关重要的。与 DAO 和迄今为止使用的其他智能合约系统一样,小错误可能会产生大后果。
许多智能合同涉及某种程度的人际互动。例如,多签名钱包需要多人授权才能执行交易。这些接触点引入了与旧系统相同的出错可能性,但也可能带来不可挽回的后果。
法律效力
智能合约做它们被编程要做的事情。如果智能合同在法院被认定无效,如何解决?目前的答案是,没有人真正知道,但它可能会发生,而且很可能会发生。世界上大多数国家对什么可以和不可以通过合同约定以及合同中可以合法使用的条款都有限制。例如,在美国,对某些金融产品收取的利息金额有限制。其他法规控制特定行业的支付条件和条款。违反当地和国家法律的智能合同有被取消的风险,导致参与组织甚至合同作者的偿还、损害或其他后果。
意义的稳定性
在我们前面看到的令牌销售合同中,用户可以确保他们将收到他们购买的令牌。他们不能确定的是这些代币将来会有价值或者仍然有用。此外,如果这些令牌代表其他东西(对系统的访问、真实世界的资产或其他东西),那么令牌的存在并不能保证这种访问将会保持,人们将继续接受资产的令牌(参见前面提到的法律有效性问题),等等。对于国家货币来说,使用和接受这种货币是由一个拥有强大权力的政府授权的。有了代币,代币的接受和使用没有强制要求。对一些人来说,这正是吸引力所在——代币的价值更可信,因为它不是建立在政府的强制执行上,而是建立在社会认可和使用上。
随着时间的推移,法律框架和贸易可能会变得更加稳定,这将不再是一个问题。
摘要
智能合同是不同方之间用代码编写的协议。智能合同的关键在于它们包含数字形式的承诺。所有这些承诺都可以使用数字协议来实现。合同的结果是自动触发的。
在这一点上,你应该对什么是智能合约,它们是如何工作的,以及它们的优点和局限性有一个坚实的理解。您应该能够理解智能合约生态系统中固有的危险,并能够衡量基于智能合约的系统开发中可能存在的风险。至少,您应该认识到,出于安全原因,需要对智能合约进行仔细和全面的评估。请记住,使用智能契约,代码的执行很少或没有人工干预。智能合约中的错误意味着错误造成的损害会随着代码的运行速度而成倍增加。
接下来,我们将更深入地探讨智能合约,有一章专门讨论以太坊的开发。
参考
- http://firstmonday.org/ojs/index.php/fm/article/view/548
- Nick Szabo,智能合同:数字市场的组成部分,1996 年
- https://www . CNBC . com/2018/05/14/HSBC-makes-worlds-first-trade-finance-transaction-using-block chain . html
- http://fortune . com/2017/12/22/experian-data-breach-alter yx-Amazon-equifax/
- https://github . com/openzeppelin/openzeppelin-solid/blob/master/contracts/token/ERC 20/standard ken . sol