前一篇文章我详细讲解了基本的 P2PKH 比特币地址,也是中本聪的原始设计,本篇就继续讲解另外一种交易类型的比特币地址,也是比特币的重要扩展之一 P2SH

再来看看表格

比特币地址类型

类型 版本前缀(hex) 编码类型 编码后的前缀
Pay-to-PublicKey-Hash Address 0x00 Base58 1
Bitcoin Testnet Address 0x6F Base58 m or n
Pay-to-Script-Hash Address 0x05 Base58 3
BIP-32 Extended Public Key 0x0488B21E Base58 xpub
segwit no version prefix Bech32 bc1

私钥类型

类型 版本前缀(hex) Base58 编码后的前缀
Private key (WIF, uncompressed pubkey) 0x80
Private key (WIF, compressed pubkey) 0x80(加上后缀0x01) K, or L
Testnet Private key (WIF, uncompressed pubkey) 0xEF 9
Testnet Private key (WIF, compressed pubkey) 0xEF c
BIP32 Extended Private Key 0x0488ADE4 xprv
BIP-38 Encrypted Private Key 0x0142 6P

# 0X01 P2SH

第一阶段
redeemScript: <pubkey OP_CHECKSIG> 
redeemScript hash = Hash160(redeemScript) = RIPEMD160(SHA256(redeemScript))
​
scriptSig: 0 <signature> redeemScript
scriptPubKey: OP_HASH160 <redeemScript hash> OP_EQUAL
​
redeemScript hash=OP_HASH160(redeemScript)
OP_EQUAL(redeemScript hash, <redeemScript hash>)
第一步成功!
​
第二阶段:
执行 <signature> redeemScript
反序列化 redeemScript=>
<signature> pubkey OP_CHECKSIG
这里是不是很熟悉了,p2pkh的验证脚本最后一步:
OP_CHECKSIG(Sig, PubKey)==TRUE
​
更复杂例子:2选1多人签名:
redeemScript: <1 <pubkey1> <pubkey2> 2 OP_CHECKMULTISIG> 
=>
scriptSig: 0 <signature1> <1 <pubkey1> <pubkey2> 2 OP_CHECKMULTISIG> 
scriptPubKey: OP_HASH160 <redeemScript  hash> OP_EQUAL

Multisignature addresses and P2SH Currently, the most common implementation of the P2SH function is the multi-signature address script. As the name implies, the underlying script requires a minimum number of signatures to prove ownership and therefore spend funds. The bitcoin multi-signature feature is designed to require M signatures (also known as the “threshold”) from a total of N keys, known as an M-of-N multisig, where M is equal to or less than N. For example, Bob the coffee shop owner from [ch01_intro_what_is_bitcoin] could use a multisignature address requiring 1-of-2 signatures from a key belonging to him and a key belonging to his spouse, ensuring either of them could sign to spend a transaction output locked to this address. This would be similar to a “joint account” as implemented in traditional banking where either spouse can spend with a single signature. Or Gopesh, the web designer paid by Bob to create a website, might have a 2-of-3 multisignature address for his business that ensures that no funds can be spent unless at least two of the business partners sign a transaction.

We will explore how to create transactions that spend funds from P2SH (and multi-signature) addresses in [transactions].

# segwit 地址

https://bitcoincore.org/zh_TW/2015/12/21/%E7%B3%BB%E7%B5%B1%E6%93%B4%E5%B1%95%E5%B8%B8%E8%A6%8B%E5%95%8F%E9%A1%8C%E8%A7%A3%E7%AD%94/

https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki native segwit VS P2SH wrapped (P2WPKH P2WSH) https://bitcoin.stackexchange.com/questions/100434/what-is-the-difference-between-native-segwit-and-bech32

The witness program is Hash160(pubkey) for P2WPKH, and Hash256(witness_script) for P2WSH. For native segwit outputs the scriptPubKey is OP_0 <witness_program>;

for P2SH-wrapped segwit outputs the redeemScript is OP_0 <witness_program> (and thus the scriptPubKey is OP_HASH160 <Hash160(OP_0 <witness_script>)> OP_EQUAL. 包在P2SH里面,自然地址类型就是跟P2SH一样,否则就是

 std::string operator()(const WitnessV0KeyHash& id) const
{
        std::vector<unsigned char> data = {0};
        data.reserve(33);
        ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.begin(), id.end());
        return bech32::Encode(m_params.Bech32HRP(), data);
    }
​
    std::string operator()(const WitnessV0ScriptHash& id) const
{
        std::vector<unsigned char> data = {0};
        data.reserve(53);
        ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.begin(), id.end());
        return bech32::Encode(m_params.Bech32HRP(), data);
    }是

简单来说,就是将锁定脚本和解锁脚本挪动位置:

witness: <signature> <pubkey>
scriptSig: empty
scriptPubKey: OP_0 <20-byte-key-hash>
​
key hash 会转换成 标准的P2PKH scriptPubKey 脚本 
OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG 
从而跟 witness进行拼接验证

https://www.youtube.com/watch?v=nrYOMjVmqi8

bech32开头的地址

向后兼容:


A non-SegWit node can verify a SegWit transaction as any other transitional transactions.
A typical Bitcoin transaction looks like this:
Input:
Previous tx: f5d8ee39a430901c91a5917b9f2dc19d6d1a0e9cea205b009ca73dd04470b9a6
Index: 0
scriptSig: 304502206e21798a42fae0e854281abd38bacd1aeed3ee3738d9e1446618c4571d10
90db022100e2ac980643b0b82c0e88ffdfec6b64e3e6ba35e7ba5fdd7d5d6cc8d25c6b241501
Output:
Value: 5000000000
scriptPubKey: OP_DUP OP_HASH160 404371705fa9bd789a2fcd52d2c580b65d35549d
OP_EQUALVERIFY OP_CHECKSIG
There are two sections: Input and Output. Inside the output section, the “scriptPubKey” defines the steps to verify this spending. A couple of operators are included:
OP_DUP / OP_HASH160 / OP_EQUALVERIFY / OP_CHECKSIG
These operations will execute in sequence on top of a stack. Such a stack is formatted by combining scriptSig and scriptPubKey fields.
In the “scriptSig” field, it has two parts: <sig> <pubKey>

In a SegWit transaction, “scriptPubKey” and “scriptSig” are trimmed to save space for each block. However, to pass the verification steps listed above, SegWit modifies scriptSig and scriptPubKey fields like this:

scriptPubKey: Empty

scriptSig: OP_TRUE

There will be no execution to check public key, and the only and final operation will always return true because of the constant “OP_TRUE”.

When running a verification on transaction like this, a SegWit miner or node knows where to find the signature data for verification, and non-SegWit (Legacy) node will verify this in traditional way and let it go.

For non-SegWit nodes or miners, this is an ingenious trick. This transaction is a “non-standard” transaction, also called “anyone-can-spend outputs”. Such transactions are not relayed in the network. However, if a miner (SegWit miner) includes a nonstandard transaction in a block, such block will be valid and the transaction will be relayed.

https://medium.com/@BlockTalkChain/how-does-non-segwit-legacy-node-verify-segwit-transaction-c3bc0872842b

https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch07.asciidoc

https://academy.binance.com/zh/articles/a-beginners-guide-to-segretated-witness-segwit

钱包中如何使用隔离见证功能: https://bitcoinelectrum.com/creating-a-p2sh-segwit-wallet-with-electrum/

If the client is SegWit enabled, the full transaction including witness data can be stored in the same format as the transaction is received over the wire. There is no need for separate storage - it can all be included in the block.

If the client is not SegWit enabled, SegWit transactions are stripped of their witness and the witness marker/flag before sending/receiving, so these clients will not receive witness data, and therefore will not store it at all and will only use the legacy format.

https://bitcoin.stackexchange.com/questions/90106/witness-data-storage-localisation-in-the-blockchain

# 多层确定性钱包

https://bitcoin.stackexchange.com/questions/73344/bip-44-master-private-key-sign-tx/83865#83865

谈谈BIP

bip

种子助记词 私钥 地址】

多层确定性钱包

一个用处就是,增强隐私性,如果你使用过比较新的比特币钱包,会发现,收帐地址经常变换,就是通过上述方式可以很容易的更换地址而不会增加钱包的管理负担,避免用户经常使用同一个地址,暴露用户身份

另外一个用处就是实现冷热(冷温)钱包

系统如何在为用户生成比特币地址的时候可以不暴露私钥?

采用BIP32 Hierarchical deterministic key即分级确定性密钥来创建, 我们可以通过父节点的扩展公钥生成子节点的比特币地址,所以作为一个网站直接跟外部网络交互,可以基本不用担心安全问题,父节点的扩展公钥是无法生成子节点的私钥的,所以不会暴露私钥,但是尽可能不要把这里的扩展公钥当成普通公钥暴露在外面,还是要妥善保存好,原因如下:

Note:BIP32有normal key普通密钥和hardened key加强密钥,只有当父节点是普通密钥时,才可以通过其扩展公钥(实际上还要加上一个chain code)才可以生成子节点公钥和地址,另外需要特别小心的是,对于普通密钥节点,一旦黑客掌握了子节点的私钥和其父节点的扩展公钥可以反推出父节点的私钥,从而会推出该父节点下面所有子节点。

[Refer to https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki]

每个用户都会分配一个比特币地址,如何有效管理如此众多的比特币地址?

采用BIP44协议,可以比较规范的管理所有的比特币地址,比如按照BIP44,我们可以生成两个主账号: 外部账号(分配给用户): m/44'/0'/0'/0/address_index 内部账号(分配给内部): m/44'/0'/1'/0/address_index

通过父节点的扩展密钥和索引编号我们可以给用户和内部生成比特币地址,进一步在数据库中绑定用户ID和比特币地址信息(比特币地址,编号,创建日期),我们可以实现更多的复杂逻辑,比如通过交叉对比充值记录回收三个月内没有使用的比特币地址。

PS: 再补充介绍一类地址:Vanity Addresses

Vanity addresses are valid bitcoin addresses that contain human-readable messages. For example, 1LoveBPzzD72PUXLzCkYAtGFYmK5vYNR33 is a valid address that contains the letters forming the word "Love" as the first four Base58 letters. Vanity addresses require generating and testing billions of candidate private keys, until a bitcoin address with the desired pattern is found. Although there are some optimizations in the vanity generation algorithm, the process essentially involves picking a private key at random, deriving the public key, deriving the bitcoin address, and checking to see if it matches the desired vanity pattern, repeating billions of times until a match is found.

Once a vanity address matching the desired pattern is found, the private key from which it was derived can be used by the owner to spend bitcoin in exactly the same way as any other address. Vanity addresses are no less or more secure than any other address. They depend on the same Elliptic Curve Cryptography (ECC) and SHA as any other address. You can no more easily find the private key of an address starting with a vanity pattern than you can of any other address.

完整的比特币地址和私钥类型:

前缀 十六进制 Example use 前导字符 例子
0 00 Pubkey hash (P2PKH address) 1 17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem
5 05 Script hash (P2SH address) 3 3EktnHQD7RiAE6uzMj2ZifT9YgRrkSgzQX
128 80 Private key (WIF, uncompressed pubkey) 5 5Hwgr3u458GLafKBgxtssHSPqJnYoGrSzgQsPwLFhLNYskDPyyA
128 80 Private key (WIF, compressed pubkey) K or L L1aW4aubDFB7yfras2S1mN3bqg9nwySY8nkoLmJebSLD5BWv3ENZ
4 136 178 30 0488B21E BIP32 pubkey xpub xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3
zgtU6LBpB85b3D2yc8sfvZU521AAwdZafEz7mnzBBsz4wKY5e4cp9LB
4 136 173 228 0488ADE4 BIP32 private key xprv xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63o
StZzF93Y5wvzdUayhgkkFoicQZcP3y52uPPxFnfoLZB21Teqt1VvEHx
111 6F Testnet pubkey hash m or n mipcBbFg9gMiCh81Kj8tqqdgoZub1ZJRfn
196 C4 Testnet script hash 2 2MzQwSSnBHWHqSAqtTVQ6v47XtaisrJa1Vc
239 EF Testnet Private key (WIF, uncompressed pubkey) 9 92Pg46rUhgTT7romnV7iGW6W1gbGdeezqdbJCzShkCsYNzyyNcc
239 EF Testnet Private key (WIF, compressed pubkey) c cNJFgo1driFnPcBdBX8BrJrpxchBWXwXCvNH5SoSkdcF6JXXwHMm
4 53 135 207 043587CF Testnet BIP32 pubkey tpub tpubD6NzVbkrYhZ4WLczPJWReQycCJdd6YVWXubbVUFnJ5KgU5MDQrD9
98ZJLNGbhd2pq7ZtDiPYTfJ7iBenLVQpYgSQqPjUsQeJXH8VQ8xA67D
4 53 131 148 04358394 Testnet BIP32 private key tprv tprv8ZgxMBicQKsPcsbCVeqqF1KVdH7gwDJbxbzpCxDUsoXHdb6SnTPY
xdwSAKDC6KKJzv7khnNWRAJQsRA8BBQyiSfYnRt6zuu4vZQGKjeW4YF
Bech32 pubkey hash or script hash bc1 bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4
Bech32 testnet pubkey hash or script hash tb1 tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx

https://en.bitcoin.it/wiki/List_of_address_prefixes

https://en.wikipedia.org/wiki/SegWit