背景图

比特币地址和脚本

这两天由于要做多签名的钱包的问题,所以一直在关注比特币钱包的知识,当我看到bitcoinj里面的知识时,发现了ScriptBuilder的类,也发现了bitcoinj文档中有提到怎么使用多签名的钱包,这里就简单带过吧,今天的主题还是要说明钱包的地址和脚本的一些知识。

地址

首先关于钱包地址大概有以下几种:

类型 版本前缀(hex) Base58结果的前缀
传统bitcoin地址 0x00 1
P2SH 0x05 3
比特币测试网络地址 0x6F m或者n
私钥WIF 0x80 5、K、L
BIP-38编码私钥 0x0142 6P
BIP-32编码私钥 0x0488B21E xpub

其实地址的类型和交易的解锁也是有很大的相关关系的。如果你创造了一种新的地址类型,并配置了相关的加密和解密脚本,那么这个地址是可以工作的,只是没有钱包支持,你需要提供能够利用这种地址类型,发送解密和加密脚本的客户端,这样你的地址就可以生效了,当然你也要兼容其他类型,如果发送的地址类型是其他的,那你的输出脚本要按照对应地址类型的要求来才行

比特币地址的生成规则如下:

传统的比特币地址脚本P2PKH

对于比特币脚本的语言介绍这里不提太多,比特币脚本其实就是一种基于堆栈的脚本语言,堆栈是一个非常简单的数据结构,可以被视为一叠卡片。栈允许两个操作:push和pop(推送和弹出)。

对于解锁脚本大概是这样的:

1
OP_DUP OP_HASH160 <Cafe Public Key Hash> OP_EQUALVERIFY OP_CHECKSIG

前面输出的锁定脚本是这样的:

1
<sig> <pubk>

那么整体的脚本是这样的:

P2SH

Gavin Andresen在bip16提出一种P2SH(pay to Script Hash)方法,主要目的有两个,一是容许发送者构造丰富的交易类型,二是将字节从A->B的output转移到B->C的input(A->B的output script中将是固定长度)。

对于解锁的脚本是

1
OP_HASH256 6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000 OP_EQUAL

我们可以理解成解数学中的难题,hash(x) = 6fe28c0ab6f1b372c1a6 我们只是提供一个x满足这个条件,就可以证明我可以花费这笔钱了。这里6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000不是简单的一个数字的hash,而是一段script的hash(简称redeemScript), 我们可以理解成只要你提供了一段script,它的二进制hash和目标匹配,那么你就可以花费这笔钱了,注意这里是前端脚本执行的输出是x就行了。.

请注意,虽然这样的交易很有趣,但它们并不安全,因为它们不包含任何签名,因此任何试图花费它们的交易都可以用将资金发送到其他地方,用不同的交易来替代

P2SH地址生成

可以使用 go-bitcoin-multisig 生成,Github地址

1
go-bitcoin-multisig keys --count 3 --concise

生成结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
--------------
KEY #1
Private key:
5JruagvxNLXTnkksyLMfgFgf3CagJ3Ekxu5oGxpTm5mPfTAPez3
Public key hex:
04a882d414e478039cd5b52a92ffb13dd5e6bd4515497439dffd691a0f12af9575fa349b5694ed3155b136f09e63975a1700c9f4d4df849323dac06cf3bd6458cd
Public Bitcoin address:
1JzVFZSN1kxGLTHG41EVvY5gHxLAX7q1Rh
--------------
--------------
KEY #2
Private key:
5JX3qAwDEEaapvLXRfbXRMSiyRgRSW9WjgxeyJQWwBugbudCwsk
Public key hex:
046ce31db9bdd543e72fe3039a1f1c047dab87037c36a669ff90e28da1848f640de68c2fe913d363a51154a0c62d7adea1b822d05035077418267b1a1379790187
Public Bitcoin address:
14JfSvgEq8A8S7qcvxeaSCxhn1u1L71vo4
--------------
--------------
KEY #3
Private key:
5JjHVMwJdjPEPQhq34WMUhzLcEd4SD7HgZktEh8WHstWcCLRceV
Public key hex:
0411ffd36c70776538d079fbae117dc38effafb33304af83ce4894589747aee1ef992f63280567f52f5ba870678b4ab4ff6c8ea600bd217870a8b4f1f09f3a8e83
Public Bitcoin address:
1Kyy7pxzSKG75L9HhahRZgYoer9FePZL4R
--------------

接着我们取出里面所有的Public key(hex格式)

1
2
3
4
5
6
Key A: 
04a882d414e478039cd5b52a92ffb13dd5e6bd4515497439dffd691a0f12af9575fa349b5694ed3155b136f09e63975a1700c9f4d4df849323dac06cf3bd6458cd
Key B:
046ce31db9bdd543e72fe3039a1f1c047dab87037c36a669ff90e28da1848f640de68c2fe913d363a51154a0c62d7adea1b822d05035077418267b1a1379790187
Key C:
0411ffd36c70776538d079fbae117dc38effafb33304af83ce4894589747aee1ef992f63280567f52f5ba870678b4ab4ff6c8ea600bd217870a8b4f1f09f3a8e83

然后就可以使用这三组Public key组合起来(A,B,C)进行多重签名:

1
go-bitcoin-multisig address --m 2 --n 3 --public-keys 04a882d414e478039cd5b52a92ffb13dd5e6bd4515497439dffd691a0f12af9575fa349b5694ed3155b136f09e63975a1700c9f4d4df849323dac06cf3bd6458cd,046ce31db9bdd543e72fe3039a1f1c047dab87037c36a669ff90e28da1848f640de68c2fe913d363a51154a0c62d7adea1b822d05035077418267b1a1379790187,0411ffd36c70776538d079fbae117dc38effafb33304af83ce4894589747aee1ef992f63280567f52f5ba870678b4ab4ff6c8ea600bd217870a8b4f1f09f3a8e83

接着就生成了P2SH地址:

1
2
3
4
5
6
7
8
9
10
---------------------
Your *P2SH ADDRESS* is:
347N1Thc213QqfYCz3PZkjoJpNv5b14kBd
Give this to sender funding multisig address with Bitcoin.
---------------------
---------------------
Your *REDEEM SCRIPT* is:
524104a882d414e478039cd5b52a92ffb13dd5e6bd4515497439dffd691a0f12af9575fa349b5694ed3155b136f09e63975a1700c9f4d4df849323dac06cf3bd6458cd41046ce31db9bdd543e72fe3039a1f1c047dab87037c36a669ff90e28da1848f640de68c2fe913d363a51154a0c62d7adea1b822d05035077418267b1a1379790187410411ffd36c70776538d079fbae117dc38effafb33304af83ce4894589747aee1ef992f63280567f52f5ba870678b4ab4ff6c8ea600bd217870a8b4f1f09f3a8e8353ae
Keep private and provide this to redeem multisig balance later.
---------------------

多重签名地址

在bitcoin bips历史上先有M-of-N Transaction(bip-11),然后才有Pay To Script Hash(bip-16)(简称P2SH). 按照这个顺序,其实比特币中实现多重签名有两种方法:

原始的方法(bip-11)

1
2
scriptPubKey : m {pubkey}...{pubkey} n OP_CHECKMULTISIG
scriptSig : OP_0 ...signatures...

可以查看一下实例:09dd94f2c85262173da87a745a459007bb1eed6eeb6bfa238a0cd91a16cf7790

用P2SH来实现

1
2
scriptSig: [signature] {[pubkey] OP_CHECKSIG}
scriptPubKey: OP_HASH160 [20-byte-hash of {[pubkey] OP_CHECKSIG} ] OP_EQUAL

这里{[pubkey] OP_CHECKSIG}就是我们提到redeemScript代码. 实例:3c9018e8d5615c306d72397f8f5eef44308c98fb576a88e030c25456b4f3a7ac

总结

  1. 首先P2SH和MultiSig是完全不同两码事,很多文章将P2SH表述成MultiSig,这是不恰当的。只不过现在可以用P2SH来实现MultiSig。
  2. 比特币的关键是认证,刚开始中本聪提供用私钥认证,后来人发明了用hash(redeemScript)认证.
  3. P2SH丰富了交易类型,简单易扩展

参考和引用

http://8btc.com/thread-23440-1-1.html

0%