https://blog.csdn.net/jerry81333/article/details/56824166
交易标准
比特币的区块链社区主要支持以下五种交易标准:P2PKH、P2PK、MS(限15个**)、P2SH和OP_Return。
OP_Return将不会介绍,因为其存储的是信息(或者说只是字节),并非比特币货币。
P2PKH(Pay-to-Public-Key-Hash):
现在的比特币网络上,大部分交易都是以P2PKH的方式进行的,以下是P2PKH的锁定脚本与解锁脚本:
<sig>表示签名,<PubK>表示Public Key,具体操作步骤如下:
可以看出,主要验证两个验证,第一是Public Key是否能够转换成正确的地址,第二是Signature是否正确,也就是证明你是否是这个Public Key的主人。
Signature签名:
签名内容主要是此交易摘要(也就是交易信息的Hash)与私钥进行运算。验证的话,将签名与公钥进行运算,如果能正确的得到交易摘要,则成功。
P2PK(Pay-to-Public-Key)
P2PK锁定版脚本形式如下:
<Public Key A> OP_CHECKSIG
用于解锁的脚本是一个简单签名:
<Signature from Private Key A>
经由交易验证软件确认的组合脚本为:
<Signature from Private Key A> <Public Key A> OP_CHECKSIG
根据上方的规则去运行就可以发现,此规则比P2PKH要简单的多,只有一步验证,少了上方的地址验证。其实,P2PKH被创建主要目的一方面为使比特币地址更简短,使之更方便使用,核心内容还是P2PK的。
MS(Multiple Signatures)多重签名
通用的M-N多重签名锁定脚本形式为:
M <Public Key 1> <Public Key 2> ... <Public Key N> N OP_CHECKMULTISIG
其中,N是存档公钥总数,M是要求**交易的最少公钥数。
例如,2-3多重签名条件:
2 <Public Key A> <Public Key B> <Public Key C> 3 OP_CHECKMULTISIG
上述锁定脚本可由含有签名和公钥的脚本予以解锁:
OP_0 <Signature B> <Signature C>
OP_0为占位符,没啥实际意义。
两个脚本组合将形成一个验证脚本:
OP_0 <Signature B> <Signature C> 2 <Public Key A> <Public Key B> <Public Key C> 3 OP_CHECKMULTISIG
P2SH(Pay-to-Script-Hash)
P2SH是MS多重签名的简化版本,如果使用P2SH进行和上方相同的2-3多重签名条件,步骤如下:
锁定脚本:
2 <Public Key A> <Public Key B> <Public Key C> 3 OP_CHECKMULTISIG
对锁定脚本,首先采用SHA256哈希算法,随后对其运用RIPEMD160算法。20字节的脚本为:
8ac1d7a2fa204a16dc984fa81cfdf86a2a4e1731
于是锁定脚本变为:
OP_HASH160 8ac1d7a2fa204a16dc984fa81cfdf86a2a4e1731 OP_EQUAL
此锁定脚本要比原先使用MS的锁定脚本要简短的多,当接收方要使用此交易中的UTXO时,需要提交解锁脚本(这里又可称为赎回脚本):
<Sig1> <Sig2> <2 PK1 PK2 PK3 PK4 PK5 5 OP_CHECKMULTISIG>
与锁定脚本相结合:
<Sig1> <Sig2> <2 PK1 PK2 PK3 PK4 PK5 5 OP_CHECKMULTISIG> OP_HASH160 8ac1d7a2fa204a16dc984fa81cfdf86a2a4e1731 OP_EQUAL
使用逆波兰表达式运算,就能很明显的得知,验证过程分两步,首先验证的是接收方附上的赎回脚本是否符合发送方的锁定脚本,如果是,便执行该脚本,进行多重签名的验证。
P2SH的特点是,将制作脚本的责任给了接收方,好处是可以暂缓节点存储的压力。
交易过程及校验
https://blog.csdn.net/wen294299195/article/details/80220651
交易格式:[nVersion] [nInputCount] [txInputs] [nOutputCount] [txOutputs] [nLockTime]
Input格式:[preTXID] [preOutputIndex] [scriptSig] [0xffffffff]
Output格式:[amount] [scriptPubKey]
-----------------------------------------------------------------------------------------------------------------------
scriptPubKey:通常翻译成锁定脚本(数学谜题)
scriptSig:通常翻译成解锁脚本(谜题的答案)
scriptPubKey 格式:OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
scriptSig 格式:<sig> <pubkey>
普通P2SH:
scriptPubKey :OP_HASH160 <Hash160(哈希原文)> OP_EQUAL
scriptSig :<哈希原文>
哈希原文格式(redeemScript) :没有固定格式
redeemScript :
通常翻译成赎回脚本,即为哈希原文,如果原文也是一段比特币脚本,那么验证机制除了验证哈希原文与哈希值的匹配性之外,还会验证原文记录的脚本的正确性,这就给了P2SH很大的可扩展性,多重签名就是其最重要一个扩展应用
基于P2SH的 m-n 的 多重签名:
scriptPubKey :OP_HASH160 <Hash160(redeemScript)> OP_EQUAL
scriptSig : OP_0 <A sig> [B sig] [C sig...] <redeemScript>
redeemScript:<m> <A pubkey> <B pubkey> <C pubkey...> <n> OP_CHECKMULTISIG
-----------------------------------------------------------------------------------------------------------------------
P2PKH: Base58(0x00 + Hash160(Public Key)) Pubkey为根据bip39、bip32、bip44规则生成的公钥
P2SH(with multiSig):Base58(0x05 + Hash160(m + pubkey1 + pubkey2 + pubkey3 +…+ n + OP_CHECKMULTISIG)) pubkey1、pubkey2、pubkey3 为所有参加签名的用户的公钥,在生成地址之初就需要各个参与方拿到所有的参与主公钥,然后根据统一的bip45规则生成地址
1、2、3为各个主公钥的语义顺序
P2PKH的地址永远为1开头,如1BG139BaR2gB15xFwu46WtfMgaL8yXdtz
P2SH的地址永远为3开头,如3KwBcdVqYCD13UMsavxGJ8nP8C7UxLxEAe
-----------------------------------------------------------------------------------------------------------------------
未签名交易:
Inputs里面不包含scriptSig,以0x00占位,
[preTXID] [preOutputIndex] [0x00][0xffffffff]
签名原文(preimage):
Inputs里面不包含scriptSig,但是包含preOutput的scriptPubKey
[preTXID] [preOutputIndex] [preOutput_ScriptPubKey] [0xffffffff]
已签名交易:
前面提到的交易格式,为最终的已签名的交易,记录到区块链上的均为此种交易
[preTXID] [preOutputIndex] [scriptSig] [0xffffffff]
比特币隔离验证交易(SegWit)
交易格式: [nVersion] [marker] [flag] [nInputCount] [txins] [nOutputCount] [txouts] [witness] [nLockTime]
wTXID: 根据上面交易格式序化后,计算Hash,其中marker固定为0x00,flag为0x01
Witness Program:
WitnessProgram在交易中所处的位置就是原标准交易中的scriptPubKey(锁定脚本)
他有固定的格式,他的格式是[nVersion][Data]
验证交易时,根据nVersion来指定验证逻辑,nVerion预留了0x00-0x10共16个逻辑
现阶段只实现0x00一种验证逻辑
根据Data的长度,又分为P2WPKH与P2WSH
当Data的长度为0x14 (20)时,其为公钥的Hash160,交易为P2WPKH
当Data的长度为0x20 (32)时,其为哈希原文的sha256,交易为P2WSH
在0x00的验证逻辑中,witness分为两部分,第一部分为签名,如果是P2WPKH,则第二部为公钥;如果是P2WSH则第二部为哈希原文(witness script)
P2WPKH的交易格式:
交易格式: [nVersion] [marker] [flag] [nInputCount] [txins] [nOutputCount] [txouts] [witness] [nLockTime]
Input: [preTXID] [preOutputIndex] [0x00] [0xffffffff]
scriptPubKey(锁定脚本):[0x00] [0x14] [Hash160(pubkey)]
scriptSig(解锁脚本):无
Witness:[signature][pubkey]
P2WSH(多重签名)的交易格式:
交易格式: [nVersion] [marker] [flag] [nInputCount] [txins] [nOutputCount] [txouts] [witness] [nLockTime]
Input:[preTXID] [preOutputIndex] [0x00] [0xffffffff]
scriptPubKey:[0x00] [0x20] [SHA256(witness script)]
scriptSig(解锁脚本):无
Witness :{[signature1] [signature2]} [witness script] (以2-3的多重签名为例)
Witness script: [0x02] [pubkey1] [pubkey2] [pubkey3] [0x03] [OP_CHECKMULTISIG]
P2WPKH nested in P2SH的交易格式
官方说P2WPKH nested in P2SH是将P2WPKH与P2SH结合,旧的客户端可以当做一个标准的P2SH交易进行处理
但其实是思想按p2sh设计, 但是交易结构是按照隔离验证来的。。。
交易格式:[nVersion] [marker] [flag] [nInputCount] [txins] [nOutputCount] [txouts] [witness] [nLockTime]
scriptPubKey:OP_HASH160 [Hash160(redeemScript)] OP_EQUAL
scriptSig:0x16 + reedemScript
reedemScript:0x00 + 0x14 + [Hash160(pubkey)]
Witness:[signature][pubkey]
将P2WPKH的锁定脚本做为P2SH的哈希谜题的原文,先验证P2SH,再结合witness验证原文记录的P2WPKH脚本
P2WSH nested in P2SH的交易格式
交易格式:[nVersion] [marker] [flag] [nInputCount] [txins] [nOutputCount] [txouts] [witness] [nLockTime]
scriptPubKey:OP_HASH160 [Hash160(redeemScript)] OP_EQUAL
scriptSig:0x22 + reedemScript
reedemScript:0x00 + 0x20 + [Hash256(Witness Script)]
Witness:{[signature1] [signature2]} [witness script]
Witness Script:[0x02] [pubkey1] [pubkey2] [pubkey3] [0x03] [OP_CHECKMULTISIG]
与P2WPKH nested in P2SH 的思路基本相同,先验证P2SH,再结合witness验证原文记录的P2WSH脚本
隔离验证的地址生成格式
编码格式从Base58修改成Bech32
格式为:人可读的“bc” + 分隔符“1”+ bench32(data)
P2WPKH: “bc” + “1” + bech32([1-byte witness program version] [20-byte-hash] )
P2WSH: “bc” + “1” + bech32([1-byte witness program version] [32-byte-hash] )
地址在主网上以”bc1”开头
P2SH(P2WPKH)与P2SH(P2WSH)遵循原标准比特币交易规则,以3开头
https://en.bitcoin.it/wiki/Script
到 https://blockchair.com/bitcoin/
上随便找比交易,点击 Raw transaction 对比着自己解析raw 试试吧!
01000000 nVersion
01 nInputCount
2a5c9a94fcde98f5581cd00162c60a13936ceb75389ea65bf38633b424eb4031 preTXID (65)
00000000 preOutpuIndex (0)
6c scriptSigLen (108)
49 signatureLen (73)
3046022100a82bbc57a0136751e5433f41cf000b3f1a99c6744775e76ec764fb78c54ee100022100f9e80b7de89de861dc6fb0c1429d5da72c2b6b2ee2406bc9bfb1beedd729d98501 signature (73*2+1)
21 pubKeyLen (33)
02e61d176da16edd1d258a200ad9759ef63adf8e14cd97f53227bae35cdb84d2f6 pubKey (33*2+1)
ffffffff nSequence
01 OutputCount
40420f0000000000 amount 0f4240 =====>1000000
19 scriptPubKeyLen (25) ===========> 76A914230ac37834073a42146f11ef8414ae929feaafc388ac (25*2+1)
76A9 OP_DUP OP_HASH160
14 hashLen (20)
230ac37834073a42146f11ef8414ae929feaafc3 pubkeyHash (20*2+1)
88ac OP_EQUALVERIFY OP_CHECKSIG
00000000 nLockTime