比特币开发指南 - 交易Transactions
交易Transactions
“交易”是用户使用比特币的过程。每个交易由几个部分构成,一个交易即可以是简单的直接支付,也可以是复杂的交易。本小节会描述交易的每一个部门,而且说明怎样把各个部分合起来构建成一个完整的交易。
为了简单起便,本小节假设
coinbase transactions
不存在。
coinbase transactions
只能被矿机创建并且这些交易是下面很多规则的例外。与其一一指出
coinbase transactions
交易的例外,我们更加建议读者阅读本指南”区块链”一章里面关于
coinbase transactions
的内容。
上面的图标说明了比特币交易的核心部分。每个交易至少由一个input和一个output。每个input 使用上一个oupt的比特币作为输入。每个output作为未花费的output【Unspent Transaction
Output
(
UTXO
)】等待着,直到一个最近的inptut使用这个output。当你的比特币钱包告诉你余额有10BTC时,它真正的意思是说你有10BTC在一个或者多少UTXOs等待被花费出去。
每个交易的前缀由四个字节的“交易版本序号”组成,这可以让比特币节点和矿工知道本交易适用于哪些规则。这也方便开发者未来开发出的新规则和旧规则能相兼容。
下面的图帮助你了解交易的一些特点,图示的工作流是ALICE发送了一个交易给BOB,稍后BOB又把这个交易发送出去。ALICE和BOB使用的都是最常见的标准交易类型,Pay-To-Public-Key-Hash (
P2PKH
)。
P2PKH
让ALICE可以把比特币发送到一个典型的比特币地址上,然后又让BOB可以进一步通过简单的密钥对把比特币发送出去。
在ALICE创建第一笔交易前,Bob必须先生成公钥/私钥对。标准的比特币私钥是长度为256b的随机字符串。一份私钥的数据,最后会经过变成而成“公钥”。因为那个变形可以在稍后重复进行,所以公钥并不需要保存。
接着公钥将加密并未得哈希值。公钥的哈希值同样也可以再次求出来,所以也不需要保存。哈希值比较短,而且也经过混淆,使得手工抄写比较简单,而且也提供了对抗未知问题的安全性,这些未知问题如允许在往后的日子里面通过公钥重新构造成私钥。
BOB把公钥的哈希值提供给ALICE。公钥哈希就是大家所熟知的编码过的比特币地址,编码采用的base58进行,里面包含了一个版本序号、哈希值以及一个用来校验错误的值。比特币地址可能通过任何介质传播,当然也包括单向的介质,这样可以切断发款人和收款人的联系,比特币地址还可以被进一步编码成其它的格式,比如包括”bitcoion:”的二维码地址。
只要ALICE拿到地址,而且解码还原为原来的标准哈希值,她就可以创建第一笔交易了。她创建了一个标准的P2PKH交易输出,里面包括了可以让任何人花费这笔输出的“说明”,只这他能证明他拥有与BOB的公钥对应的私钥。那些说明,称为“script”。
ALICE广播那一笔交易并且把它添加到区块链。比特币网络会收集这一笔交易,并把它作为未花费的交易【Unspent Transaction
Output
(
UTXO
),】,并在bob的钱包软件显示为可以使用的余额。
未来,如果bob决定把那个UTXO用出去,他必须创建一个引用了ALICE创建的交易的哈希值(这个哈希值被称为交易标识(txid)),而且还要引用ALICE使用过的那一笔的输出索引。BOB必须创建一个“
scriptSig
”,
scriptSig
是指一个包括满足ALICE之前那笔交易设置的条件的数据集合。
Bob并不需要和ALICE进行沟通,BOB只要简单地在比特币点对点网络上证明,他可以满足那些script指定的条件就可恼。对于P2PKH类型的输出,BOB的
scriptSig
只需要包含下面两个条件即可:
1. 他提供的完整公钥(未经过哈希运算),以便于 script 可以通过重新求得哈希值来验 证 ALICE 提供的哈希值是否一致。
2.
一个用bob提供私钥采用
ECDSA
加密算法计算出的包含确定的交易数据的签名。这个签名用来验证BOB是否拥有那个生成公钥的私钥。
Bob的签名不仅仅是证明BOB拥有他的私钥,签名同时还保证了BOB的签名不被篡改,这样就可以在比特币P2P网络安全地进行广播。
如上图所示,bob的签名包括了txid和前一个交易的输出索引、前一个交易的
script
、bob创建的可以让下一个接收者花费它这个output的
script
、总共要转给下一具接者的比特币数量。本质上来说,整个交易都被签名除了
scriptSigs
,因为
scriptSigs
持有了公钥以及相关的
signatures
。
把他的
signature
和公钥放到
scriptSig
后,BOB通过P2P网络广播这一笔交易给比特币矿机。在进一步广播以及被包含进区块链之前,每一个节点和矿机都独立地验证这一笔交易。
P2PKH Script Validation
验证的过程需要重新评估
script
。在一个P2PKH类型的output里面,
script
如下:
OP_DUP OP_HASH160
发送者的
scriptSig
是经过验证的,而且也是
script
的开头部分。在一个标准的
P2PKH
交易中,
scriptSig
包含了一个
signature
以及一个完整公钥创建的字符串连接:
script
语言是一种类似Forth的基于堆栈的语言,它是故意设计成与状态无关且是”图灵不完备”(Turing complete 图灵完备)的。与其它状态无关保证了只要交易一写入到区块链,就没有其它条件可以把使其永远不可以花费出去。”图灵不完备”可以使得
script
语言少了些灵活性,而且预测性更加地好,这极大简化了安全模块。
为了测试一个交易是否合法,一次只把一个
scriptSig
和
script
的参数推入到堆栈里面去,从bob的
scriptSig
开始,以Alice的
script
结束。下面的图展示了怎样检验一个标准的
P2PKH
script
;图示下面是这个过程的描述。
·
signature
(由BOB的
scriptSig
生成)被添加到一个空栈里面。因为只是一些数据,所以只是简单地把这些数据添加到栈,并没有做其它东西。公钥(同样也从
scriptSig
获得)被添加到
signature
的上面。
·
从ALICE的
script
里面,操作
OP_DUP
被添加到堆栈。
OP_DUP
用下一层的数据把自己替换掉,这样就把BOB提供的公钥复制了一次。
·
接着继续操作一下个,
OP_HASH160
,用下一层的数据(也就是BOB的公钥)把自己替换掉。这样就创建了BOB公钥的哈希值。
·
接着Alice的
script
把从她和BOB的第一笔交易得到的公钥哈希添加到堆栈里面。这样,堆栈顶部就有两份BOB的公钥哈希了。
现在事情变得有趣起来:Alice’的
script
把
OP_EQUALVERIFY
添加到堆栈里面,
OP_EQUALVERIFY
可以展开为
OP_EQUAL
和
OP_VERIFY
(隐性地)。
OP_EQUAL
(隐性地)检查它下面的两个值;在这个例子里,它会检查BOB提供的完整公钥生成的公钥哈希是否和ALICE创建的交易#1相等。
OP_EQUAL
接着比较的结果:0(false)或者1(true)替换掉。
OP_VERIFY
(隐性地)马上检查它下面的值。如果值为false,则马上停止堆栈内的检查,宣告交易检验失败。否则,它会把自己以及true值抛出栈外。
·
最后,ALICE的
script
把
OP_CHECKSIG
压入堆栈,用以对BOB提供的
signature
和BOB提供的当前经过验证的公钥进行校验。如果
signature
符合公钥,
OP_CHECKSIG
会被 替换成true;
P2SH脚本
输出脚本由支付者创建,他们(钱花出去之后)不怎么关心他们消费的比特聪的长期安全或者对别人是否有用。收款人则关心输出脚本指定的条件。如果收款人愿意,他们可以请求支付者使用某种特定脚本。遗憾的是,定制的脚本没有短小的比特币地址方便,也不像P2PKH的公钥哈希方案(
P2PKH
pubkey hashes
)那样容易保护。
为了解决这些问题,“支付到脚本哈希”(P2SH)交易在2012年被创建,它让支付者创建一个输出脚本,里边包含另一个脚本的哈希,另一个脚本称为“认领脚本”。
下图是基本的P2SH流程图,它看起来几乎与P2PKH流程一模一样。Bob随心所欲创建一个认领脚本,计算它的哈希,并把这个哈希值发给Alice。Alice创建一个P2SH风格的输出,其中包含Bob的认领脚本的哈希值。
当Bob想花费这个输出时,他把他的签名和完整的(序列化的)认领脚本放在输入的scriptSig域。比特币网络会确认,认领脚本被哈希后,得到的值与Alice输出里放的脚本哈希相同。然后网络会像处理原生脚本(即由Alice提供的脚本)那样,处理认领脚本,如果返回值为真,则允许Bob花费这个输出。
认领脚本的哈希和公钥哈希有相同的属性(主要指长度和范围),所以它可以被转换为标准的比特币地址格式,除了加上一点点小的变化,把它和标准地址区分开。这让接收P2SH风格的地址就像接收P2PKH风格的地址一样简单。哈希过程也混淆了认领脚本里的所有公钥,这使得P2SH脚本和P2PKH公钥哈希一样安全。
标准交易
必须小心避免非标准的输出脚本。按照比特币核心版本0.9,标准的脚本类型包括:
公钥哈希(P2PKH)
P2PKH是最常见的脚本形式,用于把交易发至一个或多个比特币地址。
script: OP_DUP OP_HASH160
脚本哈希(P2SH)
P2SH用于把交易发至一个脚本哈希。每一种标准脚本都可以用在P2SH认领脚本里。但实践中,只有多重签名(multisig)脚本是有意义的,除非以后有更多的交易类型变成标准的。
Bitcoin Price Consolidates Below Resistance, Are Dips Still Supported?
Bitcoin Price Consolidates Below Resistance, Are Dips Still Supported?
XRP, Solana, Cardano, Shiba Inu Making Up for Lost Time as Big Whale Transaction Spikes Pop Up
XRP, Solana, Cardano, Shiba Inu Making Up for Lost Time as Big Whale Transaction Spikes Pop Up
Justin Sun suspected to have purchased $160m in Ethereum
Justin Sun suspected to have purchased $160m in Ethereum