比特币系统中最重要的部分是比特币交易,其他部分都是为了确保比特币交易的生成、能够在比特币网络中得以传播和通过验证,最终添加到全球比特币交易总账簿。
比特币交易的基础构建单元是交易输出,记录在区块上,被整个网络识别为有效。比特币完整节点跟踪所有可找到的和可使用的输出,称为UTXO(unspent transaction outputs)。UTXO只记录未花费的比特币输出,每次交易花费的是之前的某一个或多个输出。比特币存储的实际是一笔又一笔的交易,最后永远只有未花费过的交易输出,也就是UTXO。
用户钱包收到比特币时,是钱包检测到了可用的UTXO。通过钱包控制的密钥可以把UTXO花出去。因此,用户的比特币“余额”是指用户钱包中可用的UTXO总和,可能分散在数百个交易和区块中。比特币钱包通过扫描区块链统计所有属于该用户的UTXO来计算该用户的余额。
一个UTXO可以是1“聪”(satoshi)的任意整数倍,比特币可以被分割成八位小数的“聪”。UTXO一旦被创建出来就不可分割,一个UTXO只能在一次交易中作为一个整体被消耗。
有一种特殊的交易,称为Coinbase交易,即矿工挖出的比特币,该交易没有输入,只有输出。
交易输出包含两个部分:
1.一定量的比特币,面值为“聪”,是最小的比特币单位
2.确定花费输出所需条件的加密难题,加密难题也被称为locking script, witness script或scriptPubKey
交易输入将UTXO标记为将被消费,通过解锁脚本提供所有权证明。
要构建一个交易,一个钱包从它控制的UTXO中选择足够的价值来执行被请求的付款。有时一个UTXO足够,有时不止一个。对于将用于此付款的每个UTXO,钱包将创建一个指向UTXO的输入,并使用解锁脚本解锁。
输入包括两个主要部分去下:
1.指向UTXO的指针,通过指向UTXO被记录在区块链中所在的交易的哈希值和序列号实现。
2.解锁脚本,大部分情况下,解锁脚本是一个证明比特币所有权的数字签名和公钥。
交易数据格式
比特币交易数据解码网站:https://blockchain.info/decode-tx
示例:
播报数据HEX格式
01000000024a2989e933ed9875f83776ddb4ee105a3ee7363e60e0f53db8a682f82aa52303010000006b483045022071e572d11357a0801ce69741ffde20de49099cd4ddeac19d4ad6697ca766c5fc022100835d7dabdc674e78ca523f09811b7178b3c31d08735909a28975721c6a2d2e34012103be47f412d8e23a3baf591bbe42c5859062b5b0b168567ecd8746ddc1948103fdffffffff0bcdf46d36a33c8d768e25be6b185bc9efad8aca7fad55b5180c9475afe6718f000000006c493046022100ae57aeb9711a6879bc7ddd363feb62aa5aa42b0dca6aa81e1eafc533e4cce0c4022100db46f11ac362e0fe494c65d24fb702c92ebc554690a7447365d38e7aa3613a740121030b7979840ce44d7318f5883aed9d8f5a3c0778326beae0c2117ea8712c7de5aaffffffff0108880200000000001976a9148c2cbf83f9b3034007456580a9072a9304684a4988ac00000000
解码如下:
HEX字段解析:
01000000 //verison
02 //输入交易个数
//第一组输入交易
4a2989e933ed9875f83776ddb4ee105a3ee7363e60e0f53db8a682f82aa52303 //交易ID,前向交易HASH值,反转字节顺序序列化,小端
01000000 //输出索引,要花费的UTXO的索引号
6b //签名的长度, 0x6b = 107字节, 107字节长度的签名,含有两个部分:公钥+签名
48 //签名长度,0×48 = 72字节
3045022071e572d11357a0801ce69741ffde20de49099cd4ddeac19d4ad6697ca766c5fc022100835d7dabdc674e78ca523f09811b7178b3c31d08735909a28975721c6a2d2e3401 //签名序列化(DER)
0x30 //表示DER序列的开始
0x45 //序列的长度
0x02 //一个整数值
0x20 //整数的长度
R-71e572d11357a0801ce69741ffde20de49099cd4ddeac19d4ad6697ca766c5fc
0x02 //接下来是一个整数
0x21 //整数的长度
S-00835d7dabdc674e78ca523f09811b7178b3c31d08735909a28975721c6a2d2e34
后缀(0x01)指示使用的哈希的类型(SIGHASH_ALL)
21 //公钥长度
03 //公钥压缩格式
be47f412d8e23a3baf591bbe42c5859062b5b0b168567ecd8746ddc1948103fd //公钥
ffffffff // sequence
//第二组输入交易,格式同上
0bcdf46d36a33c8d768e25be6b185bc9efad8aca7fad55b5180c9475afe6718f000000006c493046022100ae57aeb9711a6879bc7ddd363feb62aa5aa42b0dca6aa81e1eafc533e4cce0c4022100db46f11ac362e0fe494c65d24fb702c92ebc554690a7447365d38e7aa3613a740121030b7979840ce44d7318f5883aed9d8f5a3c0778326beae0c2117ea8712c7de5aaffffffff
01 //输出地址的个数
0888020000000000 // 输出的币值,8个字节。字节序需翻转,~= 0x0000000000028808 = 165896 satoshi
19 // 输出目的地址字节数, 0×19 = 25字节,由一些操作码与数值构成
76 //OP_DUP(stack ops)
a9 //OP_HASH160(crypto)
14 //长度,0×14 = 20字节
8c2cbf83f9b3034007456580a9072a9304684a49 // 地址的HASH160值,20字节
88 //OP_EQUALVERIFY(bit logic)
ac //OP_CHECKSIG(crypto)
00000000 // lock_time,固定4字节
由于一个交易的输入、输出都可能具有多个,那么签名也具有多种类型,目前共三类:SIGHASH_ALL, SIGHASH_NONE, SIGHASH_SINGLE。
SIGHASH_ALL
该签名类型为默认类型,也是目前绝大部分交易采用的,顾名思义即签名整单交易。首先,组织所有输出、输入,就像上文分解Hex过程一样,每个输入都对应一个签名,暂时留空,其他包括sequence等字段均须填写,这样就形成了一个完整的交易Hex(只缺签名字段)。然后,每一个输入均需使用私钥对该段数据进行签名,签名完成后各自填入相应的位置,N个输入N个签名。简单理解就是:对于该笔单子,认可且只认可的这些输入、输出,并同意花费我的那笔输入。
SIGHASH_NONE
该签名类型是最自由松散的,仅对输入签名,不对输出签名,输出可以任意指定。某人对某笔币签名后交给你,你可以在任意时刻填入任意接受地址,广播出去令其生效。简单理解就是:我同意花费我的那笔钱,至于给谁,我不关心。
SIGHASH_SINGLE
该签名类型其次自由松散,仅对自己的输入、输出签名,并留空sequence字段。其输入的次序对应其输出的次序,比如输入是第3个,那么签名的输出也是第三个。简单理解就是:我同意花费我的那笔钱,且只能花费到我认可的输出,至于单子里的其他输入、输出,我不关心。
交易签名
对每个输入交易都需要单独计算签名,以上广播数据有两个输入交易,签名数据组织如下:
第一个签名数据是将第一个交易签名位置替换为上一个交易的锁定脚本,第二个交易签名置空,数据组织如下:
0100000002
4a2989e933ed9875f83776ddb4ee105a3ee7363e60e0f53db8a682f82aa5230301000000
1976a9143f120b35b8d25b30a4fd405a9d5bada5a959033588ac //第一个交易签名就处替换为上一个交易(要花出去的)的锁定脚本
ffffffff 0bcdf46d36a33c8d768e25be6b185bc9efad8aca7fad55b5180c9475afe6718f00000000
00 //第二个交易签名置为空
ffffffff
0108880200000000001976a9148c2cbf83f9b3034007456580a9072a9304684a4988ac0000000001000000
第二个签名数据将第二个交易签名替换为上一个交易的锁定脚本,第一个交易签名置空,数据如下:
01000000024a2989e933ed9875f83776ddb4ee105a3ee7363e60e0f53db8a682f82aa5230301000000
00 //第一个交易签名处置空
ffffffff
0bcdf46d36a33c8d768e25be6b185bc9efad8aca7fad55b5180c9475afe6718f00000000
1976a91492c2ad259239543f1723982621bdb8625b609b2588ac //第二个交易签名处替换为上一个交易(要花出去的)的锁定脚本
ffffffff
0108880200000000001976a9148c2cbf83f9b3034007456580a9072a9304684a4988ac0000000001000000
对交易数据进行双哈希运算sha256(sha256(空白交易))得出哈希值,以上两个输入的哈希结果如下:
3517704667f173e73c381494b78b67f35d615132ccc4d9273b56261d8f199e6a
5a643c0c7a68960a29d6e08d4b865ddeffba0358013fb7923b6f4257060be2b0
对哈希结果再进行签名,填入空白交易,得到完整的交易即可发布。