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 能用巧妙的锁守住一枚币,却撑不起一个持续存在、带状态、能持有资金并随时间作出反应的程序

正是这道天花板,催生了下一个大想法。既然一枚币能携带一个*小*程序,为什么不能携带一个完整的程序——带循环、带内存,能自由表达任何规则呢?这个问题,给了我们智能合约,以及围绕它构建的各种网络。比特币选择了一把紧致、极度安全的锁;下一条学习线则选择了纯粹的可编程性,并用另一套方式去管理随之而来的新风险。