今天的越写越快乐系列为大家带来《精通比特币》读书笔记之交易章节的分享。
简介
比特币交易是比特币系统中最重要的部分。根据比特币系统的设计原理,系统中的任何其他的部分都是为了确保比特币交易可以被生成、能在比特币网络中得以传播和通过验证,并最终添加入全球比特币交易总账薄中。比特币的本质是数据结构
,这些数据结构含有比特币交易参与者价值转移的相关信息。比特币区块链是一本全球复式记账总账薄,每个比特币交易都是在比特币区块链上的一个公开记录。
没有交易,就没有价值转移,没有价值转移,那么就无法达成共识,没有共识何来的价值信任。
交易细节
Alice与Bob的交易摘要 - 图片来自简书App实际的交易看起来于典型的区块浏览器提供的交易非常不同。事实上,我们在各种比特币应用程序用户界面中看到的大多数高级结构实际上并不存在于比特币系统中。我们可以使用Bitcoin Core的命令行界面来检索Alice的“原始”交易,对其进行解码,并查看它包含的内容。
{
"version": 1,
"locktime": 0,
"vin": [
{
"txid":"7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18",
"vout": 0,
"scriptSig": "3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813[ALL] 0484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adf",
"sequence": 4294967295
}
],
"vout": [
{
"value": 0.01500000,
"scriptPubKey": "OP_DUP OP_HASH160 ab68025513c3dbd2f7b92a94e0581f5d50f654e7 OP_EQUALVERIFY OP_CHECKSIG"
},
{
"value": 0.08450000,
"scriptPubKey": "OP_DUP OP_HASH160 7f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8 OP_EQUALVERIFY OP_CHECKSIG",
}
]
}
有没有发现什么?或者针对现实中交易的双方是不是缺少一些
细节
?
交易的输入输出
比特币交易中的基础构建单元是交易输出
。交易输出是比特币不可分割的基本组合,记录在区块,并被整个网络识别为有效。比特币完整节点跟踪所有可找到的和可使用的输出,称为“未花费的交易输出”,即UTXO
。所有UTXO的集合被称为UTXO集,目前有数百万个UTXO。当新的UTXO被创建,UTXO集就会变大,当UTXO被消耗时,UTXO集就会缩小。每个交易都代表UTXO集的变化(状态转移)。
一笔交易会消耗先前的已被记录(存在)的UTXO,并创建新的UTXO以备未来的交易消耗。通过这种方式,一定量的比特币价值在不同所有者之间转移,并在交易链中消耗和创建UTXO。一笔比特币交易通过使用所有者的签名来解锁UTXO,并通过使用新的所有者的比特币地址来锁定并创建UTXO。
交易输出
UTXO在UTXO集(UTXOset)中被每一个全节点比特币客户端追踪。新的交易从UTXO集中消耗(花费)一个或多个输出。交易输出包含两部分:
- 一定量的比特币,面值为“聪”,是最小的比特币单位;
- 确定花费输出所需条件的加密难题;
这个加密难题也称为锁定脚本。现在,我们来看看 Alice 的交易,看看我们是否可以找到并识别输出。
"vout": [
{
"value": 0.01500000,
"scriptPubKey": "OP_DUP OP_HASH160 ab68025513c3dbd2f7b92a94e0581f5d50f654e7 OP_EQUALVERIFY
OP_CHECKSIG"
},
{
"value": 0.08450000,
"scriptPubKey": "OP_DUP OP_HASH160 7f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8 OP_EQUALVERIFY OP_CHECKSIG",
}
]
如您所见,交易包含两个输出。 每个输出都由一个值和一个加密难题来定义。 在 Bitcoin Core 显示的编码中,该值显示以 bitcoin 为单位,但在交易本身中,它被记录为以 satoshis 为单位的整数。 每个输出的第二部分是设定支出条件的加密难题。 Bitcoin Core 将其显示为 scriptPubKey,并向我们展示了一个可读的脚本表示。稍后将在脚本构造(Lock + Unlock)中讨论锁定和解锁UTXO的主题。 在 ScriptPubKey 中用于编辑脚本的脚本语言在章节Transaction Scripts(交易脚本)和Script Language(脚本语言)中讨论。 但在我们深入研究这些话题之前,我们需要了解交易输入和输出的整体结构。
交易输出的序列化格式 - 图片来自简书App大多数比特币函数库和架构不会在内部将交易存储为字节流,因为每次需要访问单个字段时,都需要复杂的解析。为了方便和可读性,比特币函数库将交易内部存储在数据结构(通常是面向对象的结构)中。
从交易的字节流表示转换为函数库的内部数据结构表示的过程称为反序列化或交易解析。转换回字节流以通过网络传输、哈希化(hashing)或存储在磁盘上的过程称为序列化。大多数比特币函数库具有用于交易序列化和反序列化的内置函数。
交易输入
交易输入将UTXO(通过引用)标记为将被消费,并通过解锁脚本提供所有权证明。要构建一个交易,一个钱包从它控制的UTXO中选择足够的价值来执行被请求的付款。有时一个UTXO就足够,其他时候不止一个。对于将用于进行此付款的每个UTXO,钱包将创建一个指向UTXO的输入,并使用解锁脚本解锁它。
让我们更详细地看一下输入的组件。输入的第一部分是一个指向UTXO的指针,通过指向UTXO被记录在区块链中所在的交易的哈希值和序列号来实现。 第二部分是解锁脚本,钱包构建它用以满足设定在UTXO中的支出条件。 大多数情况下,解锁脚本是一个证明比特币所有权的数字签名和公钥,但是并不是所有的解锁脚本都包含签名。 第三部分是序列号,稍后再讨论。考虑我们在之前交易幕后章节提到的例子。交易输入是一个名为 vin 的数组:
"vin": [
{
"txid": "7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18",
"vout": 0,
"scriptSig" : "3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813[ALL] 0484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adf",
"sequence": 4294967295
}
]
如您所见,列表中只有一个输入(因为一个UTXO包含足够的值来完成此付款)。 输入包含四个元素:
- 一个交易ID,引用包含正在使用的UTXO的交易
- 一个输出索引(vout),用于标识来自该交易的哪个UTXO被引用(第一个为零)
- 一个 scriptSig(解锁脚本),满足放置在UTXO上的条件,解锁它用于支出
- 一个序列号(稍后讨论)
输出索引是0(即由该交易创建的第一个UTXO)。解锁脚本由Alice的钱包构建,首先检索引用的UTXO,检查其锁定脚本,然后使用它来构建所需的解锁脚本以满足此要求。
仅仅看这个输入,你可能已经注意到,除了对包含它引用的交易之外,我们无从了解这个UTXO的任何内容。我们不知道它的价值(多少satoshi金额),我们不知道设置支出条件的锁定脚本。要找到这些信息,我们必须通过检索整个交易来检索被引用的UTXO。请注意,由于输入的值未明确说明,因此我们还必须使用被引用的UTXO来计算在此交易中支付的费用(参见后面交易费用章节)。
不仅仅是Alice的钱包需要检索输入中引用的UTXO。一旦将该交易广播到网络,每个验证节点也将需要检索交易输入中引用的UTXO,以验证该交易。
当交易被序列化以在网络上传输时,它们的输入被编码成字节流,如下表所示
交易输入的序列化格式 - 图片来自简书App
交易费
大多数交易包含交易费(矿工费),这是为了确保网络安全而给比特币矿工的一种补偿。费用本身也作为一个安全机制,使经济上不利于攻击者通过交易来淹没网络。
交易费作为矿工打包(挖矿)一笔交易到下一个区块中的一种激励;同时作为一种抑制因素,通过对每一笔交易收取小额费用来防止对系统的滥用。成功挖到某区块的矿工将得到该区内包含的矿工费, 并将该区块添加至区块链中。
交易费是基于交易的千字节规模来计算的,而不是比特币交易的价值。总的来说,交易费是根据比特币网络中的市场力量确定的。矿工会依据许多不同的标准对交易进行优先级排序,包括费用,他们甚至可能在某些特定情况下免费处理交易。但大多数情况下,交易费影响处理优先级,这意味着有足够费用的交易会更可能被打包进下一个挖出的区块中;反之交易费不足或者没有交易费的交易可能会被推迟,基于尽力而为的原则在几个区块之后被处理,甚至可能根本不被处理。交易费不是强制的,而且没有交易费的交易最终也可能会被处理,但是,交易费将提高处理优先级。
随着时间的推移,交易费的计算方式以及在交易处理优先级上的影响已经产生了变化。起初,交易费是固定的,是网络中的一个固定常数。渐渐地,随着网络容量和交易量的不断变化,并可能受到来自市场力量的影响,收费结构开始放松。自从至少2016年初以来,比特币网络容量的限制已经造成交易之间的竞争,从而导致更高的费用,免费交易彻底成为过去式。零费用或非常低费用的交易鲜少被处理,有时甚至不会在网络上传播。
把交易费加入交易
交易的数据结构没有交易费的字段。相替代地,交易费是指输入和输出之间的差值。从所有输入中扣掉所有输出之后的多余的量会被矿工作为矿工费收集走:
交易费即输入总和减输出总和的余量:交易费 = 求和(所有输入) - 求和(所有输出)
正确理解交易比较困难,但又尤为重要。因为如果你要构建你自己的交易,你必须确保你没有因疏忽在交易中添加一笔大量交易费而大大减少了输入的可花费额。这意味着你必须计算所有的输入,如有必要则加上找零, 不然的话,结果就是你给了矿工一笔相当可观的劳务费!
交易费可以看作现实生活中的手续费。
个人感想
交易作为比特币系统中的核心组成,结合交易脚本和比特币函数库可以完成交易的整个过程,包括交易发起。交易签名、交易验证,最后加入到区块链账本中。交易脚本类似于计算机中的汇编语言,可以直接执行计算机的指令,也就是说可以直接在比特币系统中执行交易脚本而不需要进行额外的处理和解析。那么对于UTXO的不断增加和消耗就伴随着比特币价值在不同所有者之间的转移。到目前为止,比特币系统没出现过大的系统漏洞和安全事件,这就说明对于底层比特币系统的构建和设计来说是一次非常成功的区块链应用。并且对于其他基于区块链技术的区块链平台也是一次有意义的实践。我相信这仅仅是开始,接下来会出现更多的区块链平台去承载更加丰富的区块链应用场景,引入更多的技术解决生活中的痛点,让更多的人意识到区块链技术带给我们的便利。我相信越来越多的人会加入到这场伟大的变革当中,只有大家起来才能繁荣和推广这项一直在成熟的技术。若是我的文章对你有所启发,那将是我莫大的荣幸。
网友评论