转帖说明:我不支持扩容派的bch,只是由于比特币与bch的很多技术细节是一样的。
作者:老刘
时间:2018年9月16日
来源:https://x.btckan.com/tshare/zh/article/blog/13142
阅读本文前,建议先了解比特币转账、输入、输出、P2SH脚本等基本概念。如不了解,可先阅读我的另一篇文章《比特币转账原理》。
一、Locktime
遗嘱需求
我们设想一种需求:父亲想立个遗嘱,在去世后把自己的BCH留给儿子。我们进一步细分这个需求,可以得出如下两个子需求:
- 当父亲过世时,儿子可以拿到币
- 当父亲在世时,父亲可以随时更改遗嘱
为了满足上面的需求,我们可以使用locktime来设置转账。
在每个比特币转账的数据里,都有一个locktime字段。协议规定,只有当前时间大于或等于locktime时间时,这笔转账才可以被广播和打包,否则节点将会丢弃这样的转账。
父亲可以生成这样一笔转账:把自己的BCH全部转到儿子的地址,但locktime设置为自己80岁那一年,然后把这笔转账数据发给儿子。儿子就可以在父亲80岁以后,把这笔转账广播到网络上,节点检查locktime小于现在的时间,认为转账合法,就会广播也会被打包。这就满足了第一个自需求。你可能会问:80岁时父亲还在世,或者提前去世了怎么办?别急,往后看,父亲是可以随时更改这笔转账的。
假设父亲想更改遗嘱,去世后把一半BCH捐给慈善组织。那么他可以先做一笔locktime为0的转账,把币转入一个新地址。因为这笔转账locktime为0,所以转账有效并被打包进入矿池。这样原来遗嘱中给儿子的转账就变得无效了。然后父亲再生成两笔新的转账,一笔给慈善组织,另一笔给儿子,locktime都设置为自己80岁那一年。这样就完成了更改遗嘱的目的,满足了第二个子需求。
因为父亲可以随时更改遗嘱,所以为了解决80岁这个去世时间不准的问题,父亲可以对遗嘱进行定期更新。
关键知识
- locktime不满足条件不会被广播,不会被打包。
- 因为没被打包和广播(没进内存池),locktime设置在未来时间的转账,可以被双花而变得无效。
- locktime的时间是绝对时间。有两种表达方式,一种是时间戳,另一种是块高度。
二、Check Lock Time Verify (CLTV)
锁仓验资需求
有一个BCH100群,进群的资格是拥有100个BCH,群主会定期验资。假设有些人为了能入群,每次验资时都找别人借100个BCH,借完再还回去。我们希望可以避免这种情况,提出了如下需求:
- 任何申请人必须把100BCH锁仓一年才可入群
- 一年后,如果想继续留在群里,需要重复上述操作
比特币脚本中有一个操作码OP_CHECKLOCKTIMEVERIFY,这个操作码可以让一个输出的币锁定到未来某个时间后才可以被花掉。
验资时我们可以这样做:入群申请者把100BCH转到一个P2SH地址,用OP_CHECKLOCKTIMEVERIFY这个操作码锁定一年后才可被自己再次使用。待这笔转账被打包后,把转账ID、赎回脚本和特定消息的签名发给群主进行验证。
- 转账ID用于确定这笔转账;
- 赎回脚本用于确认这是一笔包含OP_CHECKLOCKTIMEVERIFY的锁定脚本,并确认锁定周期为一年;
- 特定消息签名用于证明申请者就是转账的发起者。
通过上面的操作,就可以保证申请者在群的一年时间内,是一直持有100BCH的。
关键知识
跟locktime不一样的是:
- 包含OP_CHECKLOCKTIMEVERIFY的输出是会被打包的,但要花这个输出,需要等待锁定期。
- 因为会被打包,所以不可被双花,锁定期便不可更改。
跟locktime一样的是:
- 时间也是绝对时间。同样有两种表达方式,一种是时间戳,另一种是块高度。
三、Sequence和Check Sequence Verify (CSV)
上面的locktime和CLTV都是检查绝对时间,比如:2020年1月1日0点0分0秒之后币可以被使用。而sequence和CSV则是检查相对时间,比如:一年之后币可用。
sequence是转账的输入中的一个字段,使用方法类似locktime。CSV是操作码,使用方法类似CLTV。
参考资料:
- 《Mastering Bitcoin 2nd Edition》https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch07.asciidoc
- 《nSequence/nLocktime vs CHECKSEQUENCEVERIFY vs CHECKLOCKTIMEVERIFY》https://www.reddit.com/r/Bitcoin/comments/5i1ax7/nsequencenlocktime_vs_checksequenceverify_vs/