深入比特币原理(五)——高级交易与脚本

摘要:
只有当需要解锁P2SH地址上的比特币进行付款时才会发生,延迟了占用较多空间交易发生的时间。交易大小导致的交易速度减慢,交易费增加等负担转移到收款人承担。

【摘要】 多重签名交易允许同一笔交易输出需要多个私钥才能解锁,即锁定脚本设置条件,有N个公钥(注意不是公钥hash)被记录在脚本中,其中至少有M个必须提供签名才能解锁,也被成为M-N方案。

一、多重签名交易

多重签名交易允许同一笔交易输出需要多个私钥才能解锁,即锁定脚本设置条件,有N个公钥(注意不是公钥hash)被记录在脚本中,其中至少有M个必须提供签名才能解锁,也被成为M-N方案。N是密钥的总数,M是验证所需的签名数量

锁定脚本一般的形式为:
M <Public Key 1> <Public Key 2> ... <Public Key N> N CHECKMULTISIG
锁定脚本示例:2-3多重签名条件
2 <Public Key A> <Public Key B> <Public Key C> 3 CHECKMULTISIG

解锁脚本示例:
0 <Signature B> <Signature C>
第一位需要补0是因为比特币代码的一个BUG,调用时会从堆栈上多取出一个数字,取出后它被立刻丢去,并不用于之后的运算。这个数具体是什么值无关紧要,可堆栈上不能缺失它,不然无法正常执行CHECKMULTISIG。修复该代码会引起比特币分叉,所以现在通过补0的方式来规避

最终实际的解锁脚本验证如下:
0 <Signature B> <Signature C> 2 <Public Key A> <Public Key B> <Public Key C> 3 CHECKMULTISIG

二、P2SH(Pay-to-Script-Hash)

多重签名会有如下问题:

1.交易臃肿,N个公钥都要包含在交易的输出中(锁定脚本中),增加了交易的大小同时增加了交易费用,另外还增加了矿工维护UTXO的负担。

2.付款用户必须根据你提供的所有公钥信息对交易中的锁定脚本进行定制,给支付带来极大的不便利。

此处展开一下分析多重签名为什么要进行定制,而P2PKH不需要呢?

1.P2PKH的锁定脚本包含的内容是公钥哈希,公钥哈希可以通过比特币地址解码得到,所以只要知道比特币地址就可以正常生成锁定脚本进行支付。

2.多重签名锁定脚本需要包含N个公钥,不可能从单一的地址得到所有的公钥,所以锁定脚本必须定制。

P2SH的出现即是为了解决多重签名存在的这些问题,P2SH增加赎回脚本(Redeem Script)概念,P2SH脚本内容示例:

赎回脚本:2 PubKey1 PubKey2 PubKey3 PubKey4 PubKey5 5 CHECKMULTISIG
锁定脚本:HASH160 <20-byte hash of redeem script> EQUAL

解锁脚本:Sig1 Sig2 <redeem script>

从脚本内容可以看到,锁定脚本从原来的多重签名锁定脚本变成了原脚本的哈希,而赎回脚本内容即为原来的多重签名锁定脚本内容,解锁脚本中增加了赎回脚本的内容。

所以执行的情况变成如下:

1.先对比解锁脚本中的赎回脚本内容哈希与锁定脚本中是否一致
Sig1 Sig2 <redeem script> HASH160 <20-byte hash of redeem script> EQUAL

2.如果上面的对比结果一致,则变成执行如下内容(回到了多重脚本验证的情况)

Sig1 Sig2 2 PubKey1 PubKey2 PubKey3 PubKey4 PubKey5 5 CHECKMULTISIG

注:P2SH会使用P2SH地址,地址的内容即为赎回脚本哈希的base58check编码结果,P2SH地址版本前缀为0x05,编码后地址以“3”开头,如下

深入比特币原理(五)——高级交易与脚本第1张

P2SH的好处:
1.锁定脚本简化,减小了交易的空间占用
2.P2SH地址使付款人无需关心复杂的操作,只需向地址支付即可
3.P2SH使多重签名脚本的负担转移到收款人身上,而不是付款人
(1)多重签名导致的交易大小扩大仍然存在,只是由锁定脚本转移到了解锁脚本上。
(2)只有当需要解锁P2SH地址上的比特币进行付款时才会发生,延迟了占用较多空间交易发生的时间。
(2)交易大小导致的交易速度减慢,交易费增加等负担转移到收款人承担。

三、数据记录输出(RETURN)
比特币去中心化分布式数据库的特性,使许多开发者开始利用交易脚本作出除支付以外的尝试,如数字公证服务、证券证明、智能合约等。
基于上面的需求,RETURN命令出现,该命令可以用于范围特定的数据,并记录到比特币区块链当中作为永久保存,它有如下特点:
1.使用RETURN命令的输出无法被用于支付,所以不应该包含比特币在RETURN输出中,尝试包含RETURN的输出作为输入的交易会被认为无效。
2.RETURN的数据量大小限制为80bytes,通常包含hash值(如SHA256结果)与服务内容的前缀(如Proof of Existence的前缀为8-byte DOCPROOF)。
3.使用RETURN的输出不会被存储在矿工的UTXO集中,避免了内存占用,但是会写入到区块链中。

RETURN脚本示例
scriptPubkey:RETURN <data>
scriptSig:
从脚本可以看到通常输入脚本为NULL

四、时间锁(Timelock)

时间锁主要用于延迟支付,即指定某笔交易或UTXO在某一个区块高度或时间戳才进行支付或可以被使用。

1.交易时间锁(nLocktime)

比特币的交易中存在"locktime"参数,用于表示该笔交易在何时被广播到比特币网络中

0 < locktime < 500million:代表区块高度(block height)

locktime >= 500million:代表时间戳(从1970-1-1开始的Unix时间戳)

交易时间锁的特点:

交易时间锁要求该笔交易在指定时间后才向全网广播,所以在时间到达前该交易并不计入区块链中。导致如果在时间到达前付款人发起另一笔交易,双重支付并产生同一笔输入,则实际上前一笔交易会失效,这使收款人没有任何保障。

但是由于这个特性,给了付款人考虑时间,如果付款人对于交易后悔,可以防止该交易生效。

2.检查锁定时间验证(Check Lock Time Verify(以下简称CLTV))

CLTV是一种基于UTXO的时间锁,通过在P2SH赎回脚本(redeem script)中添加CHECKLOCKTIMEVERIFY命令对时间进行校验。将时间锁写入脚本中就保证了UTXO被锁定,在锁定时间到达前没有人可以使用该UTXO。

CLTV赎回脚本示例:

<Block height or Time> CHECKLOCKTIMEVERIFY DROP DUP HASH160 <Bob's Public Key Hash> EQUALVERIFY CHECKSIG

当要解锁前,需要先校验<Block height or Time>,如果校验成功,删除<Block height or Time>,正常执行解锁脚本。

如下情况将导致校验失败:

1.堆栈是空的

2.<Block height or Time>小于0

3.顶层堆栈项(<Block height or Time>)和nLocktime字段的锁定时间类型(区块高度或者时间戳)不相同

4.顶层堆栈项大于交易的nLocktime字段

5.输入的nSequence字段为0xffffffff

从失败情况可以发现,在CLTV交易中,nLocktime字段仍然要设置,并且要大于CLTV时间,时间类型需要保持一致。

到这里我们已经将比特币上主要的高级交易类型学习完了,随着时间的推移,比特币脚本的能力会被进一步挖掘,比特币将通过脚本进一步向区块链”平台“发展。

有兴趣可以去https://blockchain.info查看一下区块中的信息,如果看见类似下面这种无法解码的output,说明不是标准的交易,很可能就是用于货币以外的其他用途了。

深入比特币原理(五)——高级交易与脚本第2张

作者:Aaron

免责声明:文章转载自《深入比特币原理(五)——高级交易与脚本》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇js给select下拉框赋值触发change事件Oracle常见的33个等待事件下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

AAC头部格式,RTP打包格式

一共有2种AAC头格式,一种是StreamMuxConfig,另一种是AudioSpecificConfig 1、AudioSpecificConfig 读写header的代码参考    ffmpeg libavcodecaacenc.c put_audio_specific_config()     ffmpeg libavcodecmpeg4audi...

从0开始编译安卓 9.0

手机是Google Pixel XL 编译环境的准备 google 9月更新了地址 https://source.android.com/setup/build/initializinghttps://source.android.com/setup/build/building ubuntu 16.0.4 x64 需要安装的软件包 看上面 的网址 经过测...

码片速率的含义

1.符号速率 符号速率*扩频因子=码片速率,符号速率=码片速率/扩频因子 如: WCDMA, 码片速率= 3.84 MHz ,扩频因子=4 ,则符号速率=960kbps. CDMA 1X, 码片速率=1.2288MHz,扩频因子=64,则符号速率=19.2kbps. 符号速率=(业务速率+校验码)*信道编码*打孔率 如: WCDMA ,业务速率=384kb...

比特币的锁定脚本与解锁脚本

锁定脚本:这笔钱发送给A(包含A的共钥); 解锁脚本:我是A,这笔钱是我的; 锁定脚本:我要验证你的身份; 解锁脚本:这个是我用我的私钥签名的上一笔交易信息的签名; 矿工: 1、使用解锁脚本关联的公钥的地址的hash信息与锁定脚本的地址hash比较; 2、如果一致; 3、获取共钥,使用公钥+上一笔交易信息+解锁脚本的私钥签名结果进行验签; 4、验签通过,说...

解决Deepin每次打开Chome都提示解锁登录密钥环的麻烦

密钥环是linux系统用于安全保存程序私密数据的模块,可以用于加密保存密码、证书、密钥等安全数据。chrome的密钥环用于保存本地访问站点密码或缓存从google服务器同步下来的访问站点的密码。 Deepin系统的chrome会默认会把密码放在登录密钥环里,之所以会提示解锁登录密钥环是因为你的登陆密钥环被锁定了,只要把你的登陆密钥环解锁就可以了。 安装se...

PLsql/Oracle数据库中没有scott账户,如何创建并解锁

当然首先要装好Oracle 11g 然后还要有sqlplus,这个在Oracle11g的时候应该都会配上的 进入正题,如果oracle/plsql没scott账户,如何创建 先找到Oracle安装目录下的soctt.sql 我的是在: E:app91959product11.2.0dbhome_1admin 如果没有soctt.sql,先建立一个txt文件...