自動販賣機,而非售貨員
想像一台自動販賣機。你投進硬幣、按下按鈕,飲料就滾了出來——沒有店員、沒有討價還價,機器也不會臨時變卦。規則早已鑄進了金屬裡:*如果*投入了正確的錢,*那麼*就會送出正確的商品。機器不信任你,你也無需信任機器;你們都只信任那套機制,而它對每個人、每一次都表現得一模一樣。
智慧合約就是一台用程式碼做成的自動販賣機。它是一段永久存活於以太坊這類區塊鏈某個地址上的小程式,持有自己的資金和自己的記憶。當你向它發送請求時,它會運行內建規則並更新共享帳本——全程自動,沒有任何公司或個人居中經手。我們就此從一條只能轉移貨幣的鏈,邁向了一條能運行程式的鏈。
程式碼加狀態,住在一個地址上
普通的錢包由人持有的私鑰掌控。合約則不同:它是一個沒有密鑰、也沒有所有者的帳戶,只受自己的程式碼支配。它的地址上住著兩樣東西:程式碼(規則,一經部署便永久固定)和狀態(它當前的記憶——餘額、設定、誰投了票,以及程式所追蹤的一切)。合約每次運行時,都可能讀取並改寫這份狀態,而新的取值會被記錄到鏈上,供所有人查看。
開發者通常用 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.由此變得可能的事
一旦你能為貨幣附加自動規則,一片廣闊的天地便隨之打開。合約可以把資金託管起來,僅在條件滿足時才放行;它可以運行一場拍賣,在結束的那一刻立即付款;它可以鑄造一種固定供應的代幣、在成千上萬陌生人之間共享一個金庫,或在每次售出時把版稅分給十幾位藝術家——這一切都無需任何人被信任去按下那個按鈕。規則本身就是按鈕,而它會自己按下自己。
合約之間還能相互呼叫,像樂高積木一樣彼此咬合:一個合約的輸出成為另一個合約的輸入,整套應用便由一塊塊可組合的小部件生長出來。當合約配上一個普通人能點擊的網頁前端,結果就是一個去中心化應用——它的核心邏輯運行在共享的世界電腦上,而非某家公司的私有伺服器上。
公開且永久:一把雙刃劍
有兩種特質賦予了合約以力量,而這同樣兩種特質也要求人們心存敬畏。其一,合約是完全公開的:它的程式碼和全部狀態對任何人可見,因此它的規則可以被檢視、被驗證,而不必憑信任接受。其二,一經部署,它實際上便是不可變的——程式碼無法被編輯,連作者本人也無法悄悄改動它。正是這一點,才讓素不相識的人能夠依賴它:它明天所做的,將與今天分毫不差。
小結
一份智慧合約不過是住在某個地址上的程式碼加狀態,由每個節點以完全相同的方式運行,從而無需信任任何人。僅憑這一個念頭,一本支付帳本就化作了一台可程式化的世界電腦——在那裡,規則自我執行,應用如積木般組合,而一切都向任何人敞開核驗。
接下來,我們將放大去看真正驅動這一切的引擎——以太坊虛擬機,以及為它計量的燃料——看清網路究竟如何為運算計費,又如何讓每個節點保持誠實。