JOVANA
Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

腳本:比特幣能做什麼、不能做什麼

你在比特幣上花的每一枚幣,都被一個微型程式鎖著。認識一下 Script——這門刻意受限的語言,它決定誰能解鎖這筆錢,以及它為何被特意做得這麼小。

鎖進微型謎題盒的幣

想像一個有巧思的行李寄存櫃:它沒有固定的鑰匙,而是在櫃門上印著一道小小的謎題。誰能答出謎題,誰就能打開它。大多數謎題都很簡單——*「證明你擁有配對的鑰匙」*——但造櫃人原則上也能印上更古怪的題目。

比特幣幾乎就是這樣運作的。你持有的每一枚幣,實際上是鏈上一個未花費輸出,每個輸出都附帶一個小程式——鎖定腳本——上面寫著那道謎題。要花掉它,你得提供一個解鎖腳本,也就是你的答案。網路把這兩段腳本拼在一起執行,如果最終給出「通過」,這枚幣就歸你支配。書寫這些謎題所用的語言,就叫 Script

Script 如何執行:一疊盤子

Script 是一門以堆疊為基礎的語言,而堆疊不過是一疊盤子:你只能往最上面加一個盤子(壓入 push),或把最上面那個拿走(彈出 pop)。腳本就是一串從左到右讀取的指令。有些指令負責壓入資料——一個數字、一段簽章、一把密鑰;另一些是操作碼(opcode),會彈出一兩個盤子,做點運算,再把結果壓回去。

要校驗一次花費,節點先擺上你的解鎖腳本,再接上鎖定腳本,然後整段一起執行。最後的判定規則簡單得令人愉快:如果堆疊頂端的盤子是「真」(一個非零值),幣就解鎖;如果堆疊最終為空、為假,或腳本撞上了被禁止的動作,這次花費就被拒絕。

unlocking:  <push 3>  <push 4>
locking:    OP_ADD  <push 7>  OP_EQUAL

stack walk-through (top is rightmost):
  push 3      -> [ 3 ]
  push 4      -> [ 3, 4 ]
  OP_ADD      -> [ 7 ]        # pop 3 and 4, push 3+4
  push 7      -> [ 7, 7 ]
  OP_EQUAL    -> [ true ]     # pop both, equal? push true

Top plate is true -> coin unlocks.
一個玩具鎖定腳本:「如果你知道兩個相加得 7 的數,就解鎖我。」

日常謎題:付款給公鑰雜湊

幾乎所有真實的幣都使用一種標準謎題,付款給公鑰雜湊(P2PKH)。用大白話說就是:*「要花掉我,請出示一把雜湊後等於這個位址的公鑰,外加一段由其配對私鑰簽出的有效簽章。」* 它把幣綁定在唯一的所有者身上,而且直到花費那一刻才暴露公鑰——這在隱私與安全上都是漂亮的一手。

locking   (on the coin):
  OP_DUP  OP_HASH160  <pubKeyHash>  OP_EQUALVERIFY  OP_CHECKSIG

unlocking (you provide):
  <signature>  <pubKey>

idea:
  1. duplicate your pubKey, hash it
  2. EQUALVERIFY: must match the address baked in
  3. CHECKSIG: signature must be valid for that key
all pass -> true -> spend allowed
付款給公鑰雜湊:先證明密鑰與位址相符,再簽章。

請留意這道謎題做的事其實少得可憐:複製、雜湊、比較、驗證一段簽章。沒有迴圈,沒有「如果價格高於 X」,也不會向網際網路發起呼叫。這種簡約並不是缺了功能——它本身就是核心用意,下一節會解釋。

刻意做小:沒有迴圈,沒有意外

Script 是刻意設計成非圖靈完備的。尤其是它沒有迴圈、不能向後跳轉——一段腳本總是筆直、有限地走完,然後停下。這聽起來像缺點,卻換來兩條無價的保證。其一,每個節點都知道腳本會很快結束;沒法寫出一段永遠執行、把網路卡死的腳本。其二,校驗一筆交易的成本在執行前就是可預測的。

即便如此,Script 也不止於「單一所有者」的謎題。一種流行的模式是多重簽章(multisig)——「N 把密鑰裡必須有 M 把簽章」。一個共享的企業錢包可以這樣鎖定資金:需要 3 選 2 的公司董事才能放款,從而消除任何單點故障。這道謎題只是收集幾段簽章,再數一數其中有效的有幾段。

2-of-3 multisig locking script:
  OP_2  <pubKey_A>  <pubKey_B>  <pubKey_C>  OP_3  OP_CHECKMULTISIG

unlocking (any two valid signatures):
  OP_0  <sig_from_A>  <sig_from_C>

meaning:
  "release the coin only if at least 2 of
   these 3 named keys each sign."

(the leading OP_0 is a dummy: OP_CHECKMULTISIG has an
 old off-by-one bug that pops one extra item.)
多重簽章:一枚共享的幣,需要三把密鑰中的兩把才能動用。

天花板——以及通往以太坊的橋

多重簽章,再加上少數幾種時間鎖和雜湊鎖的小花招,差不多就是純 Script 所能表達的極限了。你無法寫出「只有當某隊贏了比賽才付款」,或「每月把這筆房租分給十位租客」,或「營運一個小型借貸市場」。Script 能用巧妙的鎖守住一枚幣,卻撐不起一個持續存在、帶狀態、能持有資金並隨時間作出反應的程式

正是這道天花板,催生了下一個大想法。既然一枚幣能攜帶一個*小*程式,為什麼不能攜帶一個完整的程式——帶迴圈、帶記憶體,能自由表達任何規則呢?這個問題,給了我們智慧合約,以及圍繞它建構的各種網路。比特幣選擇了一把緊緻、極度安全的鎖;下一條學習線則選擇了純粹的可程式化能力,並用另一套方式去管理隨之而來的新風險。