[学习笔记] 比特币交易的脚本

上篇文章讲到,比特币交易的输出,可以被“绑定”到收款方的公钥或公钥的哈希(数字指纹)上。

在之后需要消费这个 UTXO 时,除非提供了正确的证明和授权信息(签名),否则无法支付。

通过交易链条,任何人都可以验证交易的合法性。

这篇文章记录与比特币脚本有关的细节,说说验证交易的工具。

栈(Stack)是计算机中一种简单的数据结构,你可以把栈想象成弹匣。

Imgur

栈允许两个操作:

  • Push,向栈中压入一个元素,就像你向弹匣中压入一枚子弹
  • Pop,弹出栈顶的一个元素,就像你从弹匣最上面退出一枚子弹

能看到,栈中的元素,都是后进先出(LIFO,Last In First Out)的。

基于栈执行的脚本

脚本,可以理解成一系列动作和数据依次执行的说明书。脚本包含两类元素:

  • 动作,定义操作是什么,称为操作码
  • 数据,操作码操作的对象,称为操作数

举个例子,定义:

  • ADD,加法运算,做两次弹出栈顶元素的操作,先将这两个数相加,再将计算结果压入栈中
  • EQUAL,判等运算,做两次弹出栈顶元素的操作,先判断这两个数是否相等,再将计算结果压入栈中
  • 如果当前元素是一个操作数,则直接将操作数压入栈中

脚本从左到右执行,内容为

2 3 ADD 5 EQUAL

模拟一下脚本执行的过程,左边的STACK表示栈的当前状态,EXECUTION POINTER表示脚本当前执行到的位置。

最后,脚本的运行结果为真(TRUE)

比特币的交易脚本,正是这种基于栈结构执行的脚本,只不过定义了更丰富的操作码,具体可以参考比特币操作码说明书。

锁定脚本与解锁脚本

容易想到,可以

  • 在交易的输出上,附上包含公钥或公钥哈希的锁定脚本,将输出与公钥关联
  • 在交易的输入上,需要提供包含数字签名的解锁脚本,只有对应私钥的持有者,才能提供正确的签名

这样在验证交易时,只需要将解锁脚本和锁定脚本连起来从左到右执行,验证签名即可。如果

  • 脚本在执行过程中没有发生错误(例如在没有元素的栈中弹出元素会发生错误)
  • 脚本执行完时,栈顶元素为,或栈中没有元素

则视为交易有效

只有有效合法的交易才会被比特币网络接受。

这样的设计让任何人都可以验证交易,得到确定且一致的结果。

一般的,

锁定脚本(Locking Script)是放置在输出上的加密难题(cryptographic puzzle),指定了今后花费这笔 UTXO 必须要满足的条件,是交易输出的一部分。锁定脚本往往包含一个公钥或公钥的哈希,常用scriptPubKey表示,也被称为见证脚本(Witness Script),但锁定脚本有更广泛的可能性

解锁脚本(Unlocking Script)解决或满足了,之前放置在这笔 UTXO 上的加密难题或条件,解锁 UTXO 用于支付,是交易输入的一部分。解锁脚本往往包含一个数字签名,常用scriptSig表示,但解锁脚本有更广泛的可能性

组合不同的操作码,能写出更多样更复杂的脚本,来满足不同的使用场景,这就是为什么比特币被称为“可编程加密货币”的原因。

如果一笔 UTXO 上的锁定脚本为

2 3 ADD EQUAL

提供什么样的解锁脚本,才能花费这笔 UTXO?欢迎留言。 😋

总结

  • 栈是一种后入先出的数据结构
  • 比特币的脚本语言基于栈结构执行,定义了各种操作码,规则简单同时又十分强大
  • 锁定脚本是放置在交易输出上的加密难题,指定了今后花费这笔 UTXO 的条件
  • 锁定脚本有广泛的可能性,一般会包含一个公钥或公钥哈希,常用scriptPubKey表示
  • 解锁脚本是交易输入的一部分,解决或满足之前放置在 UTXO 上的加密难题或条件
  • 解锁脚本有广泛的可能性,一般会包含一个数字签名,常用scriptSig表示
  • 任何人都可以验证交易,得到确定且一致的结果,只需要将解锁脚本和锁定脚本连起来从左到右执行即可

参考