[学习笔记] 比特币交易的时间锁

栏目: 服务器 · 发布时间: 5年前

内容简介:时间锁功能让比特币交易拥有了时间维度,这篇文章介绍时间锁的详细内容本文也是介绍比特币交易内幕细节的最后一篇文章为了理解时间锁,需要提前介绍一点区块的概念

时间锁功能让比特币交易拥有了时间维度,这篇文章介绍时间锁的详细内容

本文也是介绍比特币交易内幕细节的最后一篇文章

区块

为了理解时间锁,需要提前介绍一点区块的概念

你可以把区块(Block)想象成一个箱子,里面装着交易

这个“箱子”

  • 可以按先来后到的顺序,用 高度 标识,第一个箱子的高度为 0
  • 也可以用哈希标识,相当于这个箱子的标签
  • 每个箱子,都记录了它 前一个 箱子的标签(哈希)

网络不断产生新的交易,人们根据规则,将这些交易“塞到”新箱子里,随后将它摞在之前整理好的最后一个箱子上

容易想象,网络中的交易,被不断整理到箱子中,这些依次摞起来的箱子,形成了一条 不断延长 的“箱子”

比特币网络的总帐本,就是这样的一条链,交易填充区块,一个个区块 前向引用 ,形成 区块链

关于区块和区块链更详细的介绍,放到之后的文章

nLocktime

回忆一下比特币交易的结构

长度(字节) 描述
4 交易结构的版本
1~9 VarInt 交易包含几个输入,非零正整数
变长 输入数组
1~9 VarInt 交易包含几个输出,非零正整数
变长 输出数组
4 nLockTime

通过最后 4 字节的 nLockTime 字段,可以实现 交易 粒度的时间锁

  • nLockTime = 0 ,表示这笔交易没有时间锁定,可以被“随时”写入账本,“即时生效”
  • nLockTime < 500000000 ,指示块 高度 ,这笔交易在块高度 nLockTime 之后,才可以被写入账本
  • nLockTime >= 500000000 ,指示具体的 Unix时间戳 ,这笔交易在Unix时间戳 nLockTime 之后,才可以被写入账本

Unix时间戳是一种时间表示法,它的值,表示从 1970年1月1日 0时0分0秒 UTC 开始,经历的秒数

你可以用这个 工具 转换, 1546434313 表示的时间为 2019年1月2日 13时5分13秒 UTC ,即北京时间 2019年1月2日 21时5分13秒 UTC+8

设想如下的需求

父亲想立个遗嘱,在自己去世后,儿子可以拥有自己所有的比特币

需要保证

  • 父亲在世时,可以随时修改遗嘱
  • 父亲过世后,儿子确定可以拿到币

设置交易的 nLockTime 字段,可以实现这样的遗嘱需求

  1. 父亲计算出自己 80 岁时的Unix时间戳,值为 T
  2. 父亲构造一笔 P2PKH 交易,将自己所有的比特币,付款到儿子的公钥哈希,并设置交易 nLockTime 字段的值为 T
  3. 父亲用自己的私钥,对这笔交易签名(设置正确的解锁脚本),将签名后的交易数据交给儿子

这笔交易是合法的,但因为时间锁的设置,即使向网络“展示”这笔交易,它也不会被提前写入账本,转账不会在父亲 80 岁前发生,即儿子不会在父亲 80 岁前,拿到这笔钱

如果父亲去世时没到 80 岁,儿子也可以在未来,在父亲 80 岁这天之后,向网络“展示”交易,拿到这笔钱

如果父亲想修改遗嘱,只需要

nLockTime

完成操作 1 后,原来那些签名过的交易,都会 变得无效 ,因为对应的 UTXO 已经被消费

一般的,Alice签名了一笔交易,付款到Bob的公钥哈希,并将交易的 nLocktime 设为三个月

Alice把这笔交易发送给Bob,此时,两人都知道

UTXO

这正是 nLocktime 的局限性

nLocktime 唯一能保证的,是这笔 交易在时间锁释放之前无法被写入账本 ,即收款人无法在时间锁释放之前,收到资金

交易粒度的 nLocktime 时间锁,只在下列情况满足时,才会释放

  • nLocktime = 0 ,没有时间锁
  • nLockTime < 500000000 ,且当前的区块高度,已经超过了 nLockTime 的值
  • nLockTime >= 500000000 ,且当前的Unix时间戳,已经超过了 nLockTime 的值

OP_CHECKLOCKTIMEVERIFY

为了改善交易 nLocktime 时间锁的局限性,有更细粒度的控制,时间锁需要跟 UTXO 关联,即放到锁定脚本中

2015年12月, BIP-65 引入了全新的操作码 OP_CHECKLOCKTIMEVERIFYCLTV ,Check Lock Time Verify),来实现 UTXO 粒度的时间锁定

对一般的 P2PKH ,其锁定脚本为

OP_DUP OP_HASH160 [公钥哈希] OP_EQUALVERIFY OP_CHECKSIG

如果一个 UTXO 的锁定脚本是如下的形式

 [过期时间] OP_CHECKLOCKTIMEVERIFY OP_DROP  OP_DUP OP_HASH160 [公钥哈希] OP_EQUALVERIFY OP_CHECKSIG

|<--------------CLTV时间锁--------------->|

我们说,这是一个被 CLTV 锁定的 UTXO ,只能在锁定脚本中的 CLTV 时间锁释放后才可以被消费

其中, [过期时间] 与交易的 nLockTime 字段有相同的格式,指示一个区块高度( < 500000000 ),或一个Unix时间戳( >= 500000000 )

即,只有在当前区块高度超过 [过期时间] ,或当前Unix时间戳超过 [过期时间] 时, CLTV 时间锁才会释放,这个 UTXO 才可以被消费

CLTV的幕后细节

逻辑上 CLTV 很好理解,但其工作方式稍显复杂,具体在 BIP-65 里定义,这里也做个说明

回忆一下交易输入的结构,最后 4 字节的 nSequence 字段,这里会用到

长度(字节) 描述
32 引用的交易哈希,UTXO来自哪笔交易
4 引用的输出序号,UTXO是那笔交易的第几个输出,从 0 开始计数
1~9 VarInt 后面紧跟的解锁脚本,有多少字节
变长 解锁脚本的内容
4 nSequence

如果一笔交易要消费 CLTV 锁定的 UTXO ,需要同时满足下列所有条件

  • 输入 nSequence 字段的值,必须小于 0xffffffff
  • 锁定脚本中 [过期时间] 的值,必须大于等于 0
  • 这笔交易的 nLockTime 和锁定脚本中的 [过期时间] ,必须同时大于等于 500000000 或同时小于 500000000 ,即要么都指示Unix时间戳,要么都指示区块高度
  • 这笔交易 nLockTime 字段的值,必须大于等于 [过期时间] 的值

你能看到,交易要消费 CLTV 锁定的 UTXO ,需要配合使用 nLockTime 字段

这些条件组合有些复杂,与当前区块高度或当前Unix时间戳,好像并没有什么关系

让我们换个角度看,着重关注最后一个条件

对一笔交易

  • 为了保证交易能“即时生效”,你需要将 nLockTime 的值,设置为小于等于当前的区块高度或小于等于当前的Unix时间戳,否则这笔交易不会被写入账本
  • 为了满足上述最后一个条件,你需要将 nLockTime 的值,设置为大于等于锁定脚本中的 [过期时间] 的值,否则时间锁不会释放

画个图,直观的看一下

如果当前时间 Tc ,未到 CLTV 锁定的过期时间 Tb

[学习笔记] 比特币交易的时间锁

那么,你找不到这么一个 nLockTimeT ,同时满足 T <= Tc (交易即时生效)且 T >= Tb (释放时间锁)

如果当前时间 Tc ,超过了 CLTV 锁定的过期时间 Tb

[学习笔记] 比特币交易的时间锁

那么, nLockTime 可以被设置为大于等于 Tb 且小于等于 Tc 的任意值,一般的,都直接设置为当前的区块高度或当前的Unix时间戳 Tc

对于

  • 使用 nLockTime 字段的交易时间锁
  • 使用 CLTV 操作码的 UTXO 时间锁

这两种时间锁都是 指定某个具体的绝对时间点 为过期时间的 绝对时间

nSequence

nSequence 字段最初被设计为,标识某些还未被写入账本(仍在内存池中)的交易,允许它们在之后被更新

  • 如果某个交易的输入,其 nSequence 字段的值,小于 0xffffffff ,表示这笔交易尚未“确定”,还不是最终版本
  • 这笔交易会被暂时搁置,直到被另一个消耗了同样输入的,并且有一个更大 nSequence 值的交易替换
  • 直到收到 nSequence 值为 0xffffffff 的交易,才认为这笔交易已经准备就绪,可以随时被写入账本

但这个功能没有实现,从未在系统中使用过

BIP-68 通过复用交易输入的 nSequence 字段,实现 交易 粒度的 相对时间

相对时间的意思是,从 被引用的交易写入账本 后,经过的时间

[学习笔记] 比特币交易的时间锁

  • 高度 10000 的区块中有一笔交易,创建了一个 UTXO
  • 你现在创建一笔新交易消费这个 UTXO ,并设置新交易输入 nSequence 字段的值为 100 个区块

那么,这笔新交易不会被写入账本,除非当前区块高度已经达到或超过 10100

nSequence 是输入的一个字段,交易可以包含多个输入

只有在满足了 所有输入 上的 nSequence 相对时间锁(如果有)要求后, 交易 才被认为合法,才会被写入账本

根据 BIP-68 的设计,如果 nSequence 字段的值小于 2^310x80000000 ),表示这是一笔激活了 nSequence 相对时间锁的交易

nSequence 表示相对时间锁的过期时间,格式上与 nLockTimeCLTV 略有不同

对于这个 4 字节的值

[学习笔记] 比特币交易的时间锁

  • 最高位第 31 位,作为开关,为 1 表示 禁用 相对时间锁
  • 22 位作为类型标志,为 1 指示 多少个 512 ,为 0 指示 多少个区块
  • 16 位,作为值

[学习笔记] 比特币交易的时间锁

如果 nSequence 的值为 0x0040005a

31         22       15                0
|          |        |                 |
0000 0000 0100 0000 0000 0000 0101 1010

可以知道

  • 31 位是 0 ,启用了相对时间锁
  • 22 位是 1 ,指示多少个 512
  • 16 位是 0x005a ,值为 90
  • 超时时间是 90 * 512 = 46080

整理下 nSequence 的不同情况

  • 等于 2^32 - 1 ,即等于 0xffffffff ,表示没有设置任何时间锁
  • 小于 2^32 - 1 ,表示启用了 nLockTimeCLTV 绝对时间锁,一般都设置为 0xfffffffe
  • 小于 2^31 ,即小于 0x80000000 ,表示启用了 nSequence 相对时间锁

OP_CHECKSEQUENCEVERIFY

通过 BIP-112 引入的全新操作码 OP_CHECKSEQUENCEVERIFYCSV ,Check Sequence Verify),可以实现 UTXO 粒度的相对时间锁定

锁定脚本,形如

 [过期时间] OP_CHECKSEQUENCEVERIFY OP_DROP  OP_DUP OP_HASH160 [公钥哈希] OP_EQUALVERIFY OP_CHECKSIG

|<---------------CSV时间锁--------------->|

简单的说,被 CSV 锁定的 UTXO ,从 创建它的交易被写入账本 开始计时,只有在经过一定的秒数或一定的区块数后,这个 UTXO 才可以被消费

CLTV 类似,在消费一个 CSV 锁定的 UTXO 时,要求

  • 交易的 nVersion 字段的值,必须大于等于 2
  • 输入 nSequence 字段的值,必须小于 0x800000000
  • 锁定脚本中 [过期时间] 的值,必须大于等于 0 且小于 0x800000000
  • 输入 nSequence 和锁定脚本中的 [过期时间] ,要么都指示秒数,要么都指示区块数
  • 输入 nSequence 的值,必须大于等于 [过期时间] 的值

总结

这篇文章介绍了四种比特币交易时间锁

  • 基于交易粒度的 nLockTime 绝对时间锁,在达到指定的区块高度或具体的Unix时间戳前,这笔交易不会被写入账本
  • 基于交易粒度的 nSequence 相对时间锁,这笔交易不会被写入账本,除非其输入引用的那笔已经被写入账本的交易,经过了指定的时间或区块数
  • 基于 UTXO 粒度的 CLTV 绝对时间锁,在达到指定的区块高度或具体的Unix时间戳前,这笔 UTXO 无法被消费
  • 基于 UTXO 粒度的 CSV 相对时间锁,在创建这个 UTXO 的交易写入帐本后,除非经过了指定的时间或区块数,否则这个 UTXO 无法被消费

关于 Median-Time-PastFee Sniping ,因为需要理解区块和挖矿的相关内容,所以我把他们放在之后的文章中再介绍

时间锁的概念非常好理解,但细节繁多略显晦涩,建议你在阅读本文的同时,也看看下面列出的资料


以上所述就是小编给大家介绍的《[学习笔记] 比特币交易的时间锁》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Natural Language Processing with Python

Natural Language Processing with Python

Steven Bird、Ewan Klein、Edward Loper / O'Reilly Media / 2009-7-10 / USD 44.99

This book offers a highly accessible introduction to Natural Language Processing, the field that underpins a variety of language technologies, ranging from predictive text and email filtering to autom......一起来看看 《Natural Language Processing with Python》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具