今天了解了下比特币的支付方式,发现以前的了解太麻烦了,今天就多查了查资料弄明白点。

前言

首先我要吐槽下,比特币的国内相关资料真的是很无奈,全是互相抄,而且有的内容就像机翻,完全理解不了啥意思。

简介

首先我们解释几个常见的词。 P2PKH:Pay-to-Public-Key-Hash,就是指向一个公钥哈希付款。 用户的公钥地址具体的计算方式不做介绍了,是通过多次哈希计算最后编码得到的。当然,每个用户的地址最前面是一个1,是因为加了一个0x00的前缀编码出来的。 MultiSig:多重签名。也就是说一笔交易需要好几个人来共同确认才能使用。 P2SH:Pay-to-Script-Hash,就是指向一个脚本付款。 这个的含义可以理解成原来向一个人转账,只要那个人证明他是他,就可以收到了。情况太简单,无法满足复杂的逻辑,因此复杂的需求可以使用本方式进行支付。

P2PKH

前面我们简单介绍了下P2PKH,现在我们详细介绍下P2PKH的工作原理。 粗略了解支付方式的人都知道,这种支付方式是小王说给小宁转10块钱,小宁拿出来她身份证,证明了她是她,就可以把钱拿走了。 可是具体的工作流程呢? 第一步,小王转账,不能随便让人取走,有一个对钱的锁定脚本

1
DUP HASH160 PUSHDATA(目标公钥哈希) EQUALVERIFY CHECKSIG

第二步,小宁要取钱,需要把这个脚本解锁

1
PUSHDATA(签名) PUSHDATA(公钥)

如果一切都正确,小宁就可以取走钱了。 接下来是具体的工作流程

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
//先运行解锁脚本
[] //初始状态,栈为空
[小宁签名] //PUSHDATA(签名),小宁用自己的私钥获得一个自己身份的签名
[小宁签名,小宁公钥] //PUSHDATA(公钥),小宁把自己的公钥放入栈
//开始执行锁定脚本的内容
[小宁签名,小宁公钥,小宁公钥] //DUP复制一遍公钥,栈里面两个公钥了
[小宁签名,小宁公钥,小宁公钥哈希] //HASH160取出小宁的公钥,计算出哈希放入栈
[小宁签名,小宁公钥,小宁公钥哈希,目标公钥哈希] //PUSHDATA(目标公钥哈希),将小王在转账的时候指定的用户地址放入栈
[小宁签名,小宁公钥,True] //EQUALVERIFY,对比验证了下,小宁的公钥地址没错
[True] //CHECKSIG 对比了小宁刚来的时候提供的私钥签名和公钥内容,发现一致
[] //结束,小宁获得了10块钱

看着挺简单,但是很有效。小宁花钱让人相信,可是小王花钱就有问题啦。 小宁给小王转账的时候发现,小王总是拿着钱偷偷的买吃的,没有其他人看着他。P2PKH就不够用了。

MultiSig

小宁想,如果小王在取钱的时候,需要其他几个人一块来通过,才能取到钱,就好了。所以,以后小王每次取钱都拉着大脸猫等人一块去了。

P2SH

P2SH是在MultiSig之后提出的,可以实现它的功能,当然,还支持更多的功能。在这,我们继续以转账为例子。 首先,小宁跟小王商量好了,小王取钱,必须得找到懒熊,大脸猫等人一块才行。

1
HASH160 PUSHDATA(目标脚本哈希) EQUAL

当然,具体商量的内容小宁不用单独提供,就提供个哈希就好了。小王想取钱,商量的内容拿出来。

1
2 PUSHDATA(公钥A) PUSHDATA(公钥B) PUSHDATA(公钥C) 3 CHECKMULTISIG

这个就是小宁小王商量好的内容,小王要拿出来才能取钱。小王这次准备拿出来自己的签名以及大脸猫的签名一块来取钱。

1
0 PUSHDATA(签名D) PUSHDATA(签名E) PUSHDATA(脚本)

接下来是具体的执行内容

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
//先执行解锁脚本
[] //初始化,栈为空
[0] //将数字0入栈,当然,这个0没有什么实际用处
[0 小王签名] //PUSHDATA(签名D) 小王将自己的签名放入栈
[0 小王签名 大脸猫签名] //PUSHDATA(签名E) 拉着大脸猫一块来背锅,将大脸猫的身份证明放入栈
[0 小王签名 大脸猫签名 脚本] //将脚本内容放入堆栈
[0 小王签名 大脸猫签名 脚本哈希] //HASH160取出脚本,计算脚本哈希
[0 小王签名 大脸猫签名 脚本哈希 目标脚本哈希] //PUSHDATA(目标脚本哈希) 小宁和小王商量好的目标脚本哈希值放入栈
[0 小王签名 大脸猫签名 True] //EQUAL验证脚本内容是商量好的内容,正确的话执行脚本的内容
[0 小王签名 大脸猫签名 2] //脚本中的数字2入栈 表示有两个签名
... //脚本执行,数据入栈
[0 小王签名 大脸猫签名 2 小王公钥 大脸猫公钥 懒熊公钥 3] // 已经全部入栈,3表示有3个公钥
[0 小王签名 大脸猫签名 2 小王公钥 大脸猫公钥 懒熊公钥] //CHECKMULTISIG执行,取出3,下一步取出3个公钥
[0 小王签名 大脸猫签名 2] //取出2,下一步取出两个签名
[0] //进行签名和公钥的验证,决定是否符合条件
[] //CHECKMULTISIG的bug,会多读取一个数字,0取出,结束

这么一看,转账灵活了许多,可以使用多重签名来转账,也可以实现一些其他的转账交易。

区别

这两个支付方式的名称实际取得很形象,一个相当于直接转给了公钥地址,一个是没有直接转给一个人,而是转给了脚本,需要执行了脚本才能取出钱

结束

本文为了方便理解,使用例子的方式介绍,其中名称均为化名,请勿猜测实际含义。

参考文献 1. P2PKH脚本验证 2. P2SH地址与MultiSig 3. Pay_to_script_hash 4. Bitcoin multisig the hard way: