区块链自问自答 day3
比特币的交易是如何完成的?
交易类型最常见的有两种:接收地址为公钥散列的交易(P2PKH,Pay-to-Public-Key-Hash),以及接收地址为脚本散列的交易(P2SH,Pay-to-Script-Hash),这两种交易统称为标准交易类型。
什么是P2PKH?
比特币网络上的大多数交易是P2PKH,这类交易的输出是给公钥散列,也就是我们常说的比特币地址。
什么是P2SH?
P2SH在2012年作为一种能大大简化复杂交易脚本的交易类型而引入。此类交易的输出是脚本S经过Hash160处理后的值。S是ReedeemScript,这是一种可兑现脚本,这个脚本本身也可实现一些功能,如多重签名。多重签名的接收地址不是通常意义的地址,而是一个合成地址。若花费时需要提供m个签名中的n个,那么这种方式叫做n-of-m类型。可以说,P2SH交易类型的引入,使比特币系统可以实现一些简单的智能合约,增强了它的图灵性。
在引入隔离见证(Segregated Witness)后,比特币的交易类型增加了P2WPKH(Pay-to-Witness-Public-Key-Hash)和P2WSH(Pay-to-Witness-Script-Hash)这两种。
比特币的交易记录的结构是什么样的?
# 交易记录的完整结构
class 交易数据结构:
版本号 = 4 byte # 明确这笔交易参照的规则
输入个数 = 1~9 byte # 被包含的输入数量
输入列表 = 不定 # 一个或多个交易输入(块中第一块交易也叫Coinbase交易)
class 输入字段数据结构:
上一个交易的散列值(使用交易的散列值) = 32 byte # 对交易进行双重散列(SHA256)指向交易包含的被花费UTXO的散列指针
输出索引 = 4 byte # 被花费UTXO的索引号,第一个是0
解锁脚本长度 = 1~9 byte # 用字节表示后面的解锁脚本长度
输入(解锁)脚本 = 变长 # 一个达到UTXO锁定脚本中条件的脚本
序列号 = 4 byte # 一般是0xFFFFFFFF,除非lock_time>0
输出个数 = 1~9 byte # 被包含的输出数量
输出列表 = 不定 # 一个或多个交易输入(块中第一块交易的输出是挖矿奖励)
class 输出字段数据结构:
输出值 = 8 byte # 以聪为单位表示比特值
锁定脚本长度 = 1~9 byte # 用字节表示后面的锁定脚本长度
输出(锁定)脚本 = 变长 # 一个定义了支付输出所需条件的脚本
锁定时间 = 4 byte # 如果锁定时间不为0且小于0xFFFFFFFF,那么可以设定交易的解锁条件,如块高度或时间
使用bitcoin-core的getrawtransaction命令查看交易数据,以下是getrawtransaction命令返回数据的格式和数据含义。
{
"hex":"data", (string) The serialized, hex-encoded data for 'txid'
"txid":"id", (string) The transaction id (same as provided)
"hash":"id", (string) The transaction hash (differs from txid for witness transactions)
"size":n, (numeric) The serialized transaction size
"vsize":n, (numeric) The virtual transaction size (differs from size for witness transactions)
"weight":n, (numeric) The transaction's weight (between vsize*4-3 and vsize*4)
"version":n, (numeric) The version
"locktime":ttt, (numeric) The lock time
"vin":[ (array of json objects)
{
"txid":"id", (string) The transaction id
"vout":n, (numeric)
"scriptSig":{ (json object) The script
"asm":"asm", (string) asm
"hex":"hex", (string) hex
},
"sequence":n, (numeric) The script sequence number
"txinwitness":["hex", ...] (array of string) hex-encoded witness data (if any)
}
,...
],
"vout":[ (array of json objects)
{
"value":x.xxx, (numeric) The value in " + CURRENCY_UNIT + "
"n":n, (numeric) index
"scriptPubKey":{ (json object)
"asm":"asm", (string) the asm
"hex":"hex", (string) the hex
"reqSigs":n, (numeric) The required sigs
"type":pubkeyhash, (string) The type, eg 'pubkeyhash'
"addresses":[ (json array of string)
"adress" (string) bitcoin address
,...
]
}
}
,...
],
"blockhash":"hash", (string) the block hash
"confirmations":n, (numeric) The confirmations
"time":ttt, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT)
"blocktime":ttt (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)
通过028cfae228f8a4b0caee9c566bd41aed36bcd237cdc0eb18f0331d1e87111743这个交易ID分析交易的结构
# ~ bitcoind getrawtransaction 028cfae228f8a4b0caee9c566bd41aed36bcd237cdc0eb18f0331d1e87111743 1
{
"hex" : # (字符串)序列化的16进制编码的交易'txid'数据
"0100000003c9f3b07ebfca68fd1a6339d0808fbb013c90c6095fc93901ea77410103489ab7000000008a473044022055bac1856ecbc377dd5e869b1a84ed1d5228c987b098c095030c12431a4d5249022055523130a9d0af5fc27828aba43b464ecb1991172ba2a509b5fbd6cac97ff3af0141048aefd78bba80e2d1686225b755dacea890c9ca1be10ec98173d7d5f2fefbbf881a6e918f3b051f8aaaa3fcc18bbf65097ce8d30d5a7e5ef8d1005eaafd4b3fbeffffffffc9f3b07ebfca68fd1a6339d0808fbb013c90c6095fc93901ea77410103489ab7010000008a47304402206b993231adec55e6085e75f7dc5ca6c19e42e744cd60abaff957b1c352b3ef9a022022a22fec37dfa2c646c78d9a0753d56cb4393e8d0b22dc580ef1aa6cccef208d0141042ff65bd6b3ef04253225405ccc3ab2dd926ff2ee48aac210819698440f35d785ec3cec92a51330eb0c76cf49e9e474fb9159ab41653a9c1725c031449d31026affffffffc98620a6c40fc7b3a506ad79af339541762facd1dd80ff0881d773fb72b230da010000008b483045022040a5d957e087ed61e80f1110bcaf4901b5317c257711a6cbc54d6b98b6a8563f02210081e3697031fe82774b8f44dd3660901e61ac5a99bff2d0efc83ad261da5b4f1d014104a7d1a57e650613d3414ebd59e3192229dc09d3613e547bdd1f83435cc4ca0a11c679d96456cae75b1f5563728ec7da1c1f42606db15bf554dbe8a829f3a8fe2fffffffff0200bd0105000000001976a914634228c26cf40a02a05db93f2f98b768a8e0e61b88acc096c7a6030000001976a9147514080ab2fcac0764de3a77d10cb790c71c74c288ac00000000",
"txid" : # (字符串)交易索引(和传入的一样)
"028cfae228f8a4b0caee9c566bd41aed36bcd237cdc0eb18f0331d1e87111743",
"version" : 1, # (数字)版本
"locktime" : 0, # (数字)锁定时间
"vin" : [ # (json对象数组)
{
# (字符串)交易索引
"txid" : "b79a4803014177ea0139c95f09c6903c01bb8f80d039631afd68cabf7eb0f3c9",
# (数字)
"vout" : 0,
# (json对象)脚本
"scriptSig" : {
# (字符串)脚本公钥和签名
"asm" : "3044022055bac1856ecbc377dd5e869b1a84ed1d5228c987b098c095030c12431a4d5249022055523130a9d0af5fc27828aba43b464ecb1991172ba2a509b5fbd6cac97ff3af01 048aefd78bba80e2d1686225b755dacea890c9ca1be10ec98173d7d5f2fefbbf881a6e918f3b051f8aaaa3fcc18bbf65097ce8d30d5a7e5ef8d1005eaafd4b3fbe",
# (字符串)16进制公钥
"hex" : "473044022055bac1856ecbc377dd5e869b1a84ed1d5228c987b098c095030c12431a4d5249022055523130a9d0af5fc27828aba43b464ecb1991172ba2a509b5fbd6cac97ff3af0141048aefd78bba80e2d1686225b755dacea890c9ca1be10ec98173d7d5f2fefbbf881a6e918f3b051f8aaaa3fcc18bbf65097ce8d30d5a7e5ef8d1005eaafd4b3fbe"
},
"sequence" : 4294967295 # (数字)脚本序列号,4294967295=0xffffffff
},
{
"txid" : "b79a4803014177ea0139c95f09c6903c01bb8f80d039631afd68cabf7eb0f3c9",
"vout" : 1,
"scriptSig" : {
"asm" : "304402206b993231adec55e6085e75f7dc5ca6c19e42e744cd60abaff957b1c352b3ef9a022022a22fec37dfa2c646c78d9a0753d56cb4393e8d0b22dc580ef1aa6cccef208d01 042ff65bd6b3ef04253225405ccc3ab2dd926ff2ee48aac210819698440f35d785ec3cec92a51330eb0c76cf49e9e474fb9159ab41653a9c1725c031449d31026a",
"hex" : "47304402206b993231adec55e6085e75f7dc5ca6c19e42e744cd60abaff957b1c352b3ef9a022022a22fec37dfa2c646c78d9a0753d56cb4393e8d0b22dc580ef1aa6cccef208d0141042ff65bd6b3ef04253225405ccc3ab2dd926ff2ee48aac210819698440f35d785ec3cec92a51330eb0c76cf49e9e474fb9159ab41653a9c1725c031449d31026a"
},
"sequence" : 4294967295
},
{
"txid" : "da30b272fb73d78108ff80ddd1ac2f76419533af79ad06a5b3c70fc4a62086c9",
"vout" : 1,
"scriptSig" : {
"asm" : "3045022040a5d957e087ed61e80f1110bcaf4901b5317c257711a6cbc54d6b98b6a8563f02210081e3697031fe82774b8f44dd3660901e61ac5a99bff2d0efc83ad261da5b4f1d01 04a7d1a57e650613d3414ebd59e3192229dc09d3613e547bdd1f83435cc4ca0a11c679d96456cae75b1f5563728ec7da1c1f42606db15bf554dbe8a829f3a8fe2f",
"hex" : "483045022040a5d957e087ed61e80f1110bcaf4901b5317c257711a6cbc54d6b98b6a8563f02210081e3697031fe82774b8f44dd3660901e61ac5a99bff2d0efc83ad261da5b4f1d014104a7d1a57e650613d3414ebd59e3192229dc09d3613e547bdd1f83435cc4ca0a11c679d96456cae75b1f5563728ec7da1c1f42606db15bf554dbe8a829f3a8fe2f"
},
"sequence" : 4294967295
}
],
"vout" : [
{
"value" : 0.84000000, # (数字)以BTC为单位的金额
"n" : 0, # (数字)索引/序号
"scriptPubKey" :
{
"asm" : "OP_DUP OP_HASH160 634228c26cf40a02a05db93f2f98b768a8e0e61b OP_EQUALVERIFY OP_CHECKSIG",
"hex" : "76a914634228c26cf40a02a05db93f2f98b768a8e0e61b88ac",
"reqSigs" : 1,
"type" : "pubkeyhash",
"addresses" : [
"1A3q9pDtR4h8wpvyb8SVpiNPpT8ZNbHY8h"
]
}
},
{
"value" : 156.83000000,
"n" : 1,
"scriptPubKey" : { (json对象)
# (字符串)脚本公钥
"asm" : "OP_DUP OP_HASH160 7514080ab2fcac0764de3a77d10cb790c71c74c2 OP_EQUALVERIFY OP_CHECKSIG",
# (字符串)16进制公钥
"hex" : "76a9147514080ab2fcac0764de3a77d10cb790c71c74c288ac",
"reqSigs" : 1, # (数字)需要的签名
"type" : "pubkeyhash", # (字符串)类型,例‘pubkeyhash’
"addresses" : [ # (json字符串数组)
"1Bg44FZsoTeYteRykC1XHz8facWYKhGvQ8" # (字符串)比特币地址
]
}
}
],
# (字符串)区块哈希
"blockhash" : "0000000000007c639f2cbb23e4606a1d022fa4206353b9d92e99f5144bd74611",
"confirmations" : 147751, # (数字)确认数
"time" : 1301705313, # (数字)从格林尼治时间 1970-01-01 00:00:00 开始以秒为单位的交易时间
"blocktime" : 1301705313 # (数字)从格林尼治时间 1970-01-01 00:00:00 开始以秒为单位的区块创建时间
}
什么是UTXO?
比特币交易中的“花费”是未经使用的一个交易输出,称作UTXO(Unspend Transaction Output)。
比特币中没有账户的概念,使用类似交易流水的方式记录比特币的去向。如果要知道一个地址目前有多少比特币可以用,就要查找过去所有交易中转入这个地址的UTXO然后相加。并且任何一笔UTXO只能使用一次,在使用的过程中会花费一个或多个UTXO,同时也会产生一个或多个UTXO。
如果Alice的地址存在两个UTXO,一个UTXO是Calor转入的3BTC,一个是Dave转入的2BTC。这时Alice想向Bob转入4.5BTC,那么Alice构造的交易中input就包括两笔交易的txid,这两笔是Calor和Dave转给Alice BTC所产生的。两笔交易加在一起就有5BTC的输入,但是Alice只需要给Bob转4.5BTC,这时Alice构造的交易就有两笔output,一笔给Bob的4.5BTC,一笔给自己的0.5BTC。
完成转账后Alice使用过的两个UTXO就消耗掉了,因为矿工在挖矿时会验证UTXO是否之前被使用过。但是也生成了新的一笔转给Alice 0.5BTC的UTXO。