先把问题说准
比特币首先要解决的,不是“怎样在区块链上运行所有软件”,而是“怎样让陌生人不依赖银行,也能直接转移一种稀缺的数字价值”。
在数字世界里,复制一张照片几乎没有成本。若“数字货币”也只是一个文件,人就可以把同一份钱复制后花两次。这就是双花问题。比特币把交易、密码学签名、工作量证明和一个由全网共同维护的历史顺序结合起来,给出了第一个大规模运行的答案:任何人都能验证哪些币尚未被花费,任何单一机构都不能随意改账。比特币白皮书从一开始就把目标写得很清楚——一种无需金融机构居中的点对点电子现金系统。[1]
因此,“比特币为什么不够”必须补全宾语:
对无主数字现金
它并非“不够”。稀缺性、可验证所有权和抗审查价值转移正是设计中心。
对通用链上应用
它缺少方便的长期可变状态、通用执行环境和应用之间的原生组合方式。
比特币更像一套全球共同验证的“数字产权与结算规则”;以太坊则把这套账本进一步抽象成了“全球共同验证的状态机”。
先记住:这不是“计算器与超级计算机”的简单性能比较,也不是“新技术必然替代旧技术”。它更像保险柜与操作系统:保险柜功能更少,恰恰可能更容易审计;操作系统更灵活,也必须管理更多复杂性。
比特币把“钱”建模成尚未花费的输出
UTXO 是 Unspent Transaction Output 的缩写,直译是“未花费的交易输出”。它不是账户里的一个余额数字,而是一张张可以被整体花掉的数字票据。
想象你的钱包里没有一个写着“余额 0.75 BTC”的格子,而是放着两张票据:0.40 BTC 和 0.35 BTC。你要支付 0.60 BTC 时,不能从第一张票据上直接撕下 0.20。你会把两张票据都作为输入交出去,再创建新的输出:
- 0.60 BTC 锁给收款人;
- 0.14 BTC 作为找零,重新锁给自己;
- 剩余 0.01 BTC 由输入与输出的差额体现,作为矿工费。
每个 UTXO 还附带一段锁定条件。之后谁想花它,就必须提供让这段条件返回真的数据。最常见的条件大意是:“请给出与某个公钥匹配、且能通过验证的签名。”所以,比特币的交易同时完成两件事:消费旧票据,创建带新锁的新票据。官方开发者文档也把交易描述为由一个或多个输入、输出组成;每个输入消费之前的输出,每个新输出等待将来被消费。[2]
互动图示 · 亲手拼一笔 UTXO 交易
选择输入票据钱包里的未花费输出
将被创建的新输出
已选择 0.75 BTC。足以支付 0.60 BTC 与 0.01 BTC 费用,将创建 0.14 BTC 找零。
本例金额只为解释数据模型,不代表真实网络费率。试着只选择 0.40 BTC,观察为什么交易无法成立。
UTXO 模型的力量
这种设计很接近“可验证的数字现金”。不同 UTXO 彼此相对独立,节点只需确认:输入引用的输出存在、尚未花费,而且解锁数据满足条件。它带来清晰的所有权边界,也允许一部分交易并行验证。
UTXO 模型的应用开发摩擦
但是,应用状态不能自然地写成“这个合约地址里有一个不断变化的变量”。如果你要长期维护订单簿、借贷仓位、游戏角色或投票计数,就要把新状态不断编码进下一批 UTXO,并严格控制哪些后续交易路径有效。并非理论上什么都做不了,而是状态连续性、更新规则和多人协作都更难表达、组合与开发。
Bitcoin Script 是程序,但不是通用应用运行时
说“比特币不能编程”并不准确。比特币从一开始就有脚本语言。更准确的说法是:它的脚本被刻意设计成一种受限、无状态、非图灵完备的花费条件语言。
Bitcoin Script 是一种类似 Forth 的栈式语言。数据和操作码依次进入栈、从栈顶取值并计算。经典的 P2PKH 支付条件可简化写成:
它没有问“这个人是谁”,而是机械地验证两件事:给出的公钥经过哈希后是否等于锁中指定的公钥哈希;给出的签名是否能用这把公钥验证。最终栈顶为真,花费才有效。
互动图示 · 看一遍 P2PKH 栈如何验证
教学化简版花费者先提供数字签名。它将成为后面 OP_CHECKSIG 的输入。
这是经典 P2PKH 的心智模型。现代 SegWit 交易把签名与公钥放在 witness 中,但“提供数据,使锁定条件验证为真”的核心没有改变。
限制一:脚本自身没有长期可变存储
脚本执行时有临时栈,也能依据规则读取一部分交易上下文;但它不像一个以太坊合约那样,拥有可以在多次调用之间持续读写的键值存储。一次验证结束,栈就消失。要延续“状态”,通常需要把状态体现在后续交易与新 UTXO 中。
限制二:没有循环或任意跳转
Bitcoin Script 支持条件分支,但没有循环或 goto。因此验证工作量较容易从脚本大小推断,不会有一段脚本让所有节点陷入无限循环。比特币开发者文档明确说,这种语言被有意设计为无状态且非图灵完备,以获得更可预测、更简单的安全模型。[2]
限制三:它主要回答“能不能花”
脚本执行的中心任务,是判断某个输入是否有权消费之前的输出。它当然能表达比“单签名”更复杂的条件,但缺少一个面向任意应用的统一模型:代码部署在地址上、保留内部变量、接受任何用户反复调用、再同步调用其他程序。
Bitcoin Script 更接近一个“可编程的锁”;EVM 更接近一个“带持久硬盘、按使用量计费的确定性虚拟机”。
别低估比特币:受限脚本仍然很有用
“不适合灵活运行复杂程序”绝不等于“只能做最简单转账”。只要问题能被表达成清晰的花费条件,比特币脚本可以非常强大。
多重签名
例如三把钥匙中至少两把签名,资金才能移动。适合组织金库、共同托管与备份方案。
时间锁
要求等到某个区块高度或相对时间后才能花费,用于延迟恢复、通道和分阶段结算。
哈希锁
只有公开某个秘密值的原像才能解锁,可与时间锁组合成原子交换或支付路径。
支付通道
双方预先锁定资金,在链下更新余额承诺,最后把结果结算回比特币;闪电网络由此扩展支付。
这就是为什么把所有“智能合约”都等同于以太坊合约会误导。广义上,智能合约是自动执行预先约定条件的机制;比特币早已有这种能力。以太坊白皮书也承认,比特币支持一种较弱但真实的智能合约形式,包括多签等条件化花费。[3]
Taproot 等升级让复杂花费路径在隐私、效率和表达方式上更好,但没有把比特币改造成一个拥有任意持久合约存储、通用调用和全局应用状态的 EVM 式平台。它仍然保留“货币与结算优先、脚本克制”的核心方向。
判断口诀:如果需求主要是“在什么条件下,这些 BTC 可以被花掉”,比特币脚本往往很自然;如果需求是“这个应用要长期保存并更新大量相互关联的业务状态”,开发难度会迅速上升。
复杂链上应用真正缺的是什么?
复杂应用不是“多算几道数学题”这么简单。它通常需要一份长期存在、多人共享、能按规则不断变化,而且能被其他应用直接读取或调用的状态。
设想一个最小化的链上借贷市场。它至少要持续记录:
- 每个用户存入了多少抵押物、借出了多少资产;
- 利率指数、抵押率与清算阈值;
- 价格预言机给出的最新价格;
- 谁可以更新参数、哪些资产被允许;
- 一次还款或清算后,所有相关余额如何原子地一起变化。
长期记住
状态不能在一次验证后消失;下一位用户调用时必须看到上一笔交易留下的结果。
按规则更新
一次操作可能读取多项数据、计算条件,再同时更新多个字段;失败则全部撤销。
互相调用
借贷市场读取价格、交换代币、发出事件;不同程序在同一交易里形成组合。
你可以尝试用一串 UTXO、预签名交易、时间锁、哈希锁和链下协调来构造复杂协议;许多优秀的比特币系统正是这样做的。但每个新应用都要自己设计“状态怎样从一批输出滚动到下一批输出”,并处理并发、重组、依赖交易和参与者协调。它更像用精密的金融票据搭出一台机器,而不是在统一操作系统里写一个程序。
真正缺少的是一层统一抽象:任意人都能部署程序;程序拥有持久状态;交易可以调用程序;所有节点得到同一个确定结果。
以太坊的回答:从账本升级为通用状态机
以太坊没有抛弃区块链账本,而是把“账本能记录什么”扩大了:不只记录谁拥有多少原生资产,还记录账户、合约代码,以及每个合约的持久存储。
以太坊可以抽象成一个确定性状态转换函数:
旧的全局状态 S + 一组有效交易 T → 新的全局状态 S′
官方 EVM 文档也用这个模型解释以太坊:交易是账户发出的密码学签名指令;合约创建交易会产生带字节码的合约账户,之后的消息调用会执行其代码。EVM 规定状态如何从一个区块转换到下一个区块。[4]
以太坊增加了四块关键拼图
代码驻留在地址上
合约被编译成字节码并部署;任何符合规则的用户或合约都能发起调用。
合约有持久存储
变量在一次交易结束后仍然存在,成为全局状态的一部分,供后续调用读取。
合约可以同步调用合约
一笔交易能穿过多个应用,读取并改变多处状态;失败时可以整体回滚。
每一步计算被计量
通用程序可能很重甚至不停止,Gas 给执行设上限并为稀缺计算资源定价。
互动图示 · 一次合约调用如何改变共享状态
S + TX → S′调用前 · State S
调用后 · State S′
注意,这里的“世界计算机”不是说以太坊像云服务器一样快速或便宜。恰恰相反,每个执行节点都要对同一交易得到同一结果,所以计算昂贵、吞吐受限。它的独特价值在于:没有单一运营者,却有一份公开、可验证、按确定规则变化的共享状态。
为什么“通用程序”必须同时发明 Gas?
一旦允许循环、动态调用和任意复杂计算,就出现一个根本问题:节点怎样知道一段程序何时结束?又由谁为全网重复执行付费?
在一般情况下,不存在一个万能算法,能在运行前判断任意程序是否最终停止。这就是停机问题。如果攻击者提交一个无限循环,而节点必须免费执行到底,网络就会被拖住。
以太坊的解法不是提前证明所有程序都会停止,而是给每笔交易一份有限的“计算预算”:
- 每个 EVM 操作消耗一定 Gas;
- 交易发送者设置最多愿意提供多少 Gas;
- Gas 用尽,执行停止,当前调用造成的状态变化回滚;
- 已经消耗的计算资源仍需付费,因此滥用不是免费的。
官方文档将 Gas 定义为衡量计算工作量的单位,并明确指出,它既为计算资源定价,也防止网络被垃圾请求或无限循环卡住。[5]
互动图示 · 给程序一份有限预算
抽象 Gas 单位当前预算为 7。完整程序需要 10 个教学单位,因此会在写入状态时耗尽。把上限调到 10 或更高再试一次。这里的数值只用于演示,不是实际 EVM Gas 报价。
重要边界:Gas 只解决“资源有上限、计算有价格”的问题,并不会自动保证合约业务逻辑正确。重入、权限、预言机、升级等风险仍需要开发者、审计和安全机制处理。
差别不只是“图灵完备”四个字
常见说法是“比特币脚本非图灵完备,以太坊 EVM 图灵完备”。这方向没错,却过度压缩了真正影响开发体验的差别。
图灵完备大意是,只要给足时间与存储,一种计算模型能表达任何可计算过程。EVM 允许条件跳转、循环与递归调用,所以在表达能力上是图灵完备的;但每次真实交易都受 Gas 上限约束,因此实际执行永远是有限的。以太坊白皮书也把 Gas 作为处理无限循环和计算浪费的核心机制。[3]
然而,即使没有原生循环,人也可以把计算拆成多笔交易,把“下一步”编码进新的 UTXO,或在链外计算后把结果提交上链。所以真正的分水岭是四个维度共同作用:
| 维度 | Bitcoin | Ethereum |
|---|---|---|
| 核心抽象 | 带花费条件的 UTXO;交易消费旧输出、创建新输出。 | 账户与合约构成的全局状态;交易执行状态转换。 |
| 程序角色 | 脚本主要验证“这个输出现在能否被花费”。 | 合约可实现一般业务逻辑,并长期接受反复调用。 |
| 控制流 | 有条件分支,无循环或任意跳转;非图灵完备。 | 有跳转、循环、递归式调用;表达力接近通用计算。 |
| 持久状态 | 脚本自身无可变存储;状态通常滚动编码在 UTXO 图中。 | 每个合约有持久键值存储,属于全局状态的一部分。 |
| 程序组合 | 协议常靠多笔依赖交易、预签名路径和链下协调组合。 | 合约可在同一交易里同步调用其他合约,共享原子执行。 |
| 资源边界 | 受限脚本与共识限制使验证成本更容易预测。 | Gas 对每步计算与存储计量,预算用尽则停止并回滚。 |
| 设计中心 | 稳健的数字货币、产权与结算层。 | 可编程资产、智能合约与去中心化应用平台。 |
从开发者视角看,最大飞跃不是“多了循环”,而是“代码 + 持久状态 + 合约调用 + 资源计量”被做成一套所有应用共用的原生平台。
两种设计哲学,没有免费的午餐
以太坊获得了更强表达力,也把更多复杂性带进共识关键路径。比特币保留更窄的能力边界,也因此保留了更小、更保守的基础层。
少做,但把核心做得极稳
脚本克制、状态模型局部、协议升级保守。好处是规则面更小、验证更可预测;代价是通用应用往往需要额外层、专门协议和更多链下协调。
提供统一的可编程结算层
应用开发快、合约可组合、状态原生共享。代价是执行与状态更复杂、攻击面更大、计算昂贵,所有节点还要承担长期状态与验证成本。
你获得的能力,也会成为新的风险面
- 可组合性:一个合约可以调用另一个合约;同样,依赖项故障也可能沿调用链传播。
- 持久状态:应用可以记住一切;同样,全网长期保存与访问状态会带来成本。
- 通用代码:开发者可以快速创造新机制;同样,代码漏洞可能直接控制真实资产。
- 原子执行:复杂操作可以一笔完成;同样,交易排序、抢跑与 MEV 会成为新问题。
因此,成熟的判断不是“以太坊比比特币更先进”,而是:它们分别优化了不同目标函数。如果你要的是尽可能保守的无主数字货币,比特币的限制可能是优点;如果你要的是无需许可的通用应用平台,以太坊的抽象更合适。
把整课压缩成一条推导链
不要死记“比特币非图灵完备、以太坊图灵完备”。沿着问题一步步推导,你会得到更牢固的心智模型。
-
先解决数字所有权
比特币用 UTXO、签名和全网共识,让任何人都能验证哪些数字票据尚未被花费。
-
给数字票据加可编程的锁
Script 让输出不只属于单把钥匙,还能受多签、时间、秘密值等条件控制。
-
复杂应用需要长期共享状态
订单、仓位、投票与角色要在多次调用之间持续存在,并由许多用户共同更新。
-
于是需要通用状态转换引擎
以太坊把代码和存储放进共享状态,让交易成为调用程序、生成新状态的指令。
-
通用计算必须有资源计量
Gas 限制每次执行的工作量,并让请求者为全网消耗的计算与存储付费。
比特币不是因为“做不到转账之外的任何事”才催生以太坊,而是因为它的可编程性围绕花费条件展开;以太坊要解决的是更一般的问题:让陌生人共同维护并执行任意可验证的应用状态。
五题自测
最小术语表
- UTXO
- 尚未被消费的交易输出;比特币所有权与余额由这组输出推导。
- Script
- 比特币用于规定与验证输出花费条件的栈式脚本语言。
- State
- 某一时刻系统认可的全部相关数据;交易会把旧状态变成新状态。
- Smart contract
- 部署在链上、按确定规则被交易触发执行的程序;广义概念也可包含比特币条件脚本。
- EVM
- 以太坊虚拟机;所有执行节点按相同规则执行合约字节码并验证结果。
- Gas
- 衡量 EVM 计算工作量的单位,用来限制执行并为稀缺资源定价。
- Persistent storage
- 合约跨交易保留的键值数据,是以太坊全局状态的一部分。
- Composability
- 一个合约在同一执行环境中调用其他合约、组合已有功能的能力。
Lesson complete
比特币证明了价值可以去中心化;以太坊追问:程序和共享状态呢?
资料与延伸阅读
- Satoshi Nakamoto, Bitcoin: A Peer-to-Peer Electronic Cash System — 比特币要解决的问题、交易链与双花防护的原始说明。
- Bitcoin Developer Guide: Transactions — UTXO、P2PKH 验证,以及 Script 无状态、非图灵完备的官方开发者说明。
- Ethereum Whitepaper — 比特币脚本限制、通用状态转换、EVM 与 Gas 的原始设计动机。该白皮书具有历史价值,但不代表今天全部协议细节。
- ethereum.org: Ethereum Virtual Machine — 从账本到状态机、状态转换函数、合约代码与存储。
- ethereum.org: Gas and fees — Gas 如何计量计算、防止垃圾请求与无限循环。