自动售货机,而非售货员
想象一台自动售货机。你投进硬币、按下按钮,饮料就滚了出来——没有店员、没有讨价还价,机器也不会临时变卦。规则早已铸进了金属里:*如果*投入了正确的钱,*那么*就会送出正确的商品。机器不信任你,你也无需信任机器;你们都只信任那套机制,而它对每个人、每一次都表现得一模一样。
智能合约就是一台用代码做成的自动售货机。它是一段永久存活于以太坊这类区块链某个地址上的小程序,持有自己的资金和自己的记忆。当你向它发送请求时,它会运行内置规则并更新共享账本——全程自动,没有任何公司或个人居中经手。我们就此从一条只能转移货币的链,迈向了一条能运行程序的链。
代码加状态,住在一个地址上
普通的钱包由人持有的私钥掌控。合约则不同:它是一个没有密钥、也没有所有者的账户,只受自己的代码支配。它的地址上住着两样东西:代码(规则,一经部署便永久固定)和状态(它当前的记忆——余额、设置、谁投了票,以及程序所追踪的一切)。合约每次运行时,都可能读取并改写这份状态,而新的取值会被记录到链上,供所有人查看。
开发者通常用 Solidity 来编写这段代码,它是一门专为此而生的语言。下面是一个还值得展示的、几乎最小的合约:一个共享计数器,世界上任何人都能把它往上推一格,而它永远不会忘记自己的总数。
contract Counter {
uint public total; // STATE: lives on-chain forever
function increment() public { // a rule anyone can call
total = total + 1; // read state, write new state
}
}
// Deploy once -> the contract gets a permanent address.
// Anyone, anywhere can call increment(). The new
// total is agreed on by the whole network.每个节点都运行它,且结果完全一致
下面这一点,正是合约可信的关键。当你调用 `increment()` 时,你的请求并不是在某处的某一台机器上运行,而是在网络中每一个全节点上、于一个名为以太坊虚拟机(EVM)的共享沙盒里运行。EVM 是一颗小巧而严格确定的处理器:给它同样的代码和同样的初始状态,它就会在地球上每一台计算机上算出同样的结果。
正因为成千上万台彼此独立的机器都运行同一步、都得出同一个总数,它们当中没有任何一台能够作弊。如果某个节点谎报结果,它的答案只会与其他所有人的答案对不上,从而被丢弃。这正是人们把以太坊称作世界计算机的原因:它不是一台快的计算机,而是一台每一步都受整个网络核验、并被永久记录的计算机。
在成千上万台机器上运行代码并非免费,因此每一步操作都标着一个用燃料费支付的小价签。下面的轨迹展示了 EVM 在逐步执行我们的 `increment()` 调用时是如何计收燃料的。便宜的动作只花一点点;改写永久存储则花费最多,因为每个节点都必须把这一改动永远保存下来。
Calling increment() -- the EVM charges gas per step
step operation gas
---- --------- ----
1 load current total from storage ~2100
2 add 1 to it ~3
3 store new total back to storage ~5000
4 done
total ~ 7100 gas
You pay (gas used) x (gas price) as the fee.
Reading is cheap; writing storage is the costly part.由此变得可能的事
一旦你能为货币附加自动规则,一片广阔的天地便随之打开。合约可以把资金托管起来,仅在条件满足时才放行;它可以运行一场拍卖,在结束的那一刻立即付款;它可以铸造一种固定供应的代币、在成千上万陌生人之间共享一个金库,或在每次售出时把版税分给十几位艺术家——这一切都无需任何人被信任去按下那个按钮。规则本身就是按钮,而它会自己按下自己。
合约之间还能相互调用,像乐高积木一样彼此咬合:一个合约的输出成为另一个合约的输入,整套应用便由一块块可组合的小部件生长出来。当合约配上一个普通人能点击的网页前端,结果就是一个去中心化应用——它的核心逻辑运行在共享的世界计算机上,而非某家公司的私有服务器上。
公开且永久:一把双刃剑
有两种特质赋予了合约以力量,而这同样两种特质也要求人们心存敬畏。其一,合约是完全公开的:它的代码和全部状态对任何人可见,因此它的规则可以被检视、被验证,而不必凭信任接受。其二,一经部署,它实际上便是不可变的——代码无法被编辑,连作者本人也无法悄悄改动它。正是这一点,才让素不相识的人能够依赖它:它明天所做的,将与今天分毫不差。
小结
一份智能合约不过是住在某个地址上的代码加状态,由每个节点以完全相同的方式运行,从而无需信任任何人。仅凭这一个念头,一本支付账本就化作了一台可编程的世界计算机——在那里,规则自我执行,应用如积木般组合,而一切都向任何人敞开核验。
接下来,我们将放大去看真正驱动这一切的引擎——以太坊虚拟机,以及为它计量的燃料——看清网络究竟如何为运算计费,又如何让每个节点保持诚实。