Files
CategoryResourceRepost/极客时间专栏/左耳听风/区块链/67 | 区块链技术细节:智能合约.md
louzefeng d3828a7aee mod
2024-07-11 05:50:32 +00:00

189 lines
11 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<audio id="audio" title="67 | 区块链技术细节:智能合约" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/eb/9c/ebb5748624658d23bb4a419f26c4a09c.mp3"></audio>
要讲清楚智能合约我先给你看几个案例。第一个案例是打赌。比如张三和李四打赌周末拜仁和皇马的足球比赛谁会赢。如果拜仁赢了张三给李四100元如果反过来李四给张三100元如果打成平局则不赢不输。
张三和李四都怕对方不认账所以他们需要找一个他们都信得过的人来做公证两人都把100元钱给这个公证人。然后如果拜仁赢了公证人把全部200元给李四如果皇马赢了则全部给张三如果是平局则分别退还100元。
<img src="https://static001.geekbang.org/resource/image/b0/bb/b0370516ca22b23fc6c1fe47e90c80bb.png" alt="" />
上面这个模型什么都好就是有一个问题这个“公证人”跑路了怎么办因为他们只赌100元公证人犯不着为了200元跑路。但是如果有一万人把赌金交给公证人呢如果张三李四赌金是100万呢公证人的人性会受到极大的挑战他还有那么可信吗
# 银行的资金托管业务
也就是说,当业务大到一定程度的时候,个人的信用是不足以来当中间公证人这个角色了。这时,你要找更为靠谱的机构,这个机构叫银行,银行的信用等级至少在这几方面上要比个人高。
<li>
银行是机构,所以受政府监管,受法律约束;
</li>
<li>
银行的钱很多,就算是里面有员工作案,银行也赔得起;
</li>
<li>
银行里有比较安全的资金管理流程和措施;
</li>
因此,银行的受信程度很高,可以来做担保。
下面,我们来看一个示例,银行在二手房交易中的“资金托管”业务。因为房屋交易时涉及到的资金数目太大,买家怕交了钱后,卖家不过户,卖家也怕过了户后,买家不给钱。而一般像“链家”或是“我爱我家”这样的房屋中介是没有能力来做大额交易的担保的(政府也不会让它们来做)。
于是银行就出来了。买家先到银行开个户把购房款全额存进去。这个账户和一般的账户不一样这叫资金托管账户钱一旦进入后你就取不出来了除非满足了某个条件。在开户时房屋的买卖方和银行三方约定一旦房产证从卖家过户到买家30天后没有纠纷钱就划给卖家了。
<img src="https://static001.geekbang.org/resource/image/cf/95/cf2c80beb5379a37fe5d15bb99caa095.png" alt="" />
这其实跟在淘宝上买东西差不多,买家把钱转给支付宝,然后买家确认收到货后,在支付宝上点确认,钱就划给商家了。唯一不一样的是,支付宝没有资格担保像房屋交易这么大的交易金额。这是国家为了防范相关的金融风险所采取的措施。
# 以太坊的智能合约
对于以太坊来说智能合约其实就是一段可执行的程序片段由发布人使用一种类似于JavaScript或是Python的编程语言来编写。就像最开始那个民间担保的案例一样合同的发布可以写成如下形式
```
Contract MyContract{
    function transferFrom(  address _from, address _to, uint256 _value) {
        if ( isBayernWin ) {
            blanceOf[_from] +=  _value
            blanceOf[_to] -= value
        }else if ( isRealMadridWin ) {
            blanceOf[_from] -= _value
            blanceOf[_to] += value
        }
    }
}
```
嗯,合同都要用代码来写了。看来,我们程序员离统治世界又近了一步。
我们把合约代码在本地编译成功后发布到区块链上,可以理解为一个特殊的交易(包括可执行代码),然后会被矿工打包记录在某一个区块中。当需要调用这个智能合约的方法时,只需要向这个智能合约的地址发送一笔交易即可。
每个节点的电脑都需要安装以太坊客户端客户端自带了一个和JVM类似的一个EVM。通过交易触发智能合约后智能合约的代码就会在EVM中执行了。这种方式相当于把程序部署到了非常非常多的电脑上随时都可以通过交易来触发这些智能合约的执行也从而完成了分布式程序的部署和调用。
<img src="https://static001.geekbang.org/resource/image/f0/cb/f000316a917d59fffd8a067b4201b0cb.png" alt="" />
这感觉就是Funciton-as-a-Service的一种实现啊。
如果人与人之间的交易条件(合约)就像代码一样被严格地执行,你觉得这个世界会变成什么样呢?是不是会少一些无赖,少一些扯皮,多了很多效率,多了很多确定性呢?
# 有银行担保的国际业务
我们再来看一个国际贸易的流程。
假如中国某出口商和美国一个进口方做生意,会遇到货币不一样的问题。如果没有货币兑换,那就只有通过大家都认可的黄金交易了。你给我发一船货,我给你发一船黄金,风险也高,交易的效率非常低下。
如果有银行在中间协调,比如中国的某个银行和美国的某个银行签了互信协议,那么国际贸易的银行担保流程如下。下面是描述这一过程的图片。
<img src="https://static001.geekbang.org/resource/image/9d/59/9d19c5e890bafa85f8704b002bd79759.png" alt="" />
<li>
首先,出口商和进口商签订买卖合同。
</li>
<li>
然后美国的进口方到美国银行那边申请信用证信用证需要用钱来开的也是有价格属性的比如200万美金的信用证就需要用200万美金来申请
</li>
<li>
美国的银行向中国银行开具信用证中国银行根本不关心进口方有没有把钱给了美国银行反正你开了200万美金面额的信用证我以后要问你要钱的。
</li>
<li>
中国银行收到信用证后,给出口商发出通知信用证,告之可以发货。
</li>
<li>
出口商发货,由相关承运人从中国把货运到美国。
</li>
<li>
然后,中国出口商把提货单交给中国的银行。
</li>
<li>
中国的银行向美国银行发出“寄单索汇”业务。
</li>
<li>
美国银行收到提货单后,通知进口方到单。
</li>
<li>
进口方把货款的钱补完比如补300万美金“赎回”提货单。
</li>
<li>
然后美国银行向中国银行付款。
</li>
<li>
美国进口方到承运人提货。
</li>
看看,这个过程如此复杂,而且很机械,感觉完全可以用程序来实现。如果用以太坊的智能合约来写一下,这段代码会写成什么样呢?
好像可以写得很简单。
<li>
进口方把钱垫到区块链上。
</li>
<li>
出口方发货方发货。
</li>
<li>
进口方验货后,钱就到了出口方。
</li>
当然,这也需要写在程序中。
<li>
一个是进口方的钱垫到区块链上,就需要被冻结掉。
</li>
<li>
另外还需要物流信息,不然,进口方说没有收到,不好验证。但物流信息要是造假怎么办?
</li>
<li>
另一个是需要把进口方验货的标准给写进来。代码不知道条件怎么满足,也许需要进口方那边点个确认。如果不点确认,则有个过期时间,时间一到就自动确认。
</li>
<li>
另外,如果进口方觉得有问题,需要退货,或是需要重新议价,那么需要相关的关联合同。
</li>
其中比较难办的是第2步需要其他方也进入区块链。如果不进来这事就不好玩了。但是物流信息怎么才能做到真实可靠的呢这需要双方选择一个都相信的中心化的物流公司还是我们搞一个去中心化的物流公司去中心化的物流公司是个什么形态你能想象得出来吗我想象不出来。
# 合同的Bug
另外我们要小心智能合同。有程序的地方就会有Bug现实生活中会有Bug合同也会有Bug。出现了Bug后大家可以相互协商给合同打补丁附加条款或是重新签合同。然而代码合同则不一样Bug也会被残酷无情地执行一旦执行就很难补救了。
最著名的例子就是以太坊一个叫The DAO的应用它是一个去中心化的风险投资基金以智能合约的形式运行在以太坊区块链上。它也是一个盈利性的去中心化自治组织它将利用自己掌控的以太币资金通过投资以太坊上的应用为其成员创造价值。在The DAO创建期任何人都可以向它的众筹合约发送以太币获得DAO代币。
因为 The DAO这个程序写得不好黑客在其智能合约里找到Bug把所有的钱给调走了大约7000多万美刀。这成为有史以来最大宗的数字劫案而且FBI也找不到人。这个项目因为钱被偷走而倒闭以后引起了以太坊的强行分叉变成ETH和ETC。关于技术细节可参见其 [漏洞分析文章](http://www.8btc.com/thedao-expolit-analysis),整个事件的始末可以参见《[彭博社深度还原The DAO 大劫案始末](https://www.leiphone.com/news/201706/JnNEqj90inEWLTJD.html)》。
还有一个案例是2017年发生的智能钱包多签名钱包Parity被盗事件。它号称自己的智能合约被很多很厉害的安全人员都审查过都认为没问题。但最后还是被黑客利用了一个叫做initwallet的函数反复调用它转走了3000万美金。
老实说我觉得任何合同都是会有Bug的无论是在现实生活中还是在代码中。唯一的不同是现实生活中的合同出现Bug可以自行协商解决也可以通过法律或仲裁的方式解决。然而在数字社会中代码无论好坏都会被计算机残酷无情地严格执行。
有时候当你是利益方时你会觉得是好事。但有时候你是受害方时你还是会想有挽回的余地。现实生活中可以做到但我不知道代码世界中的合同如何解决这些Bug所以还是不要叫“智能合约”至少现在还不是。
文末给出了《区块链技术》系列文章的目录,希望你能在这个列表里找到自己感兴趣的内容。
<li>
[区块链的革命性及技术概要](https://time.geekbang.org/column/article/5197)
</li>
<li>
[区块链技术细节:哈希算法](https://time.geekbang.org/column/article/5363)
</li>
<li>
[区块链技术细节:加密和挖矿](https://time.geekbang.org/column/article/5438)
</li>
<li>
[去中心化的共识机制](https://time.geekbang.org/column/article/5612)
</li>
<li>
[智能合约](https://time.geekbang.org/column/article/5623)
</li>
<li>
[传统金融和虚拟货币](https://time.geekbang.org/column/article/5636)
</li>