← 返回文章

比特币学习之交易的基本结构

介绍 上节,我们学习了比特币钱包中的原理,这节我们继续学习比特币交易中的原理,比特币是一种电子货币,它主要

介绍

上节,我们学习了比特币钱包中的原理,这节我们继续学习比特币交易中的原理,比特币是一种电子货币,它主要的目的就是交易,从一个用户手中转移到另一个用户手中。而转移的记录就保存在比特币的 Transaction 中,Transaction 中最主要的就是 inputs 和 outputs。 举一个例子解释 inputs 和 outputs :假设A用户有两个5块钱,要向给B用户6块钱换一个东西,最后A还剩4块钱。那么这个交易中inputs有两个5块的input(其中有A用户的信息),同时outputs中有两个output:一个output中有6块钱(其中有B用户的信息),另一个有4块钱(其中有A用户的信息)。

UTXO 模型

在交易中output被用完后,就不能再使用了,所以一个花费了的output就像一具尸体。 但是,没有被使用过的output仍然存在,它们可以用于新的交易(只要我们可以解锁它)。 在上述例子中,两张5块钱就相当于被使用过的output,我们之后将无法再次使用它们。A用户的4块钱就类似于没有花费的output,之后这个钱还可以使用。

我们可以使用UTXO模型做什么

  1. 验证交易 节点将检查其输入是否已经花费来验证其接收的交易。 所以,如果我们想要创建比特币交易的话,必须要在输入中使用utxos:

    如果我们要使用已经在另一个交易中使用过的输出的话,交易将会被节点拒绝。

  2. 查询地址余额 如果我们想要算出一个地址的余额,把所有锁定到该地址的所有的未用output求和。

UTXO数据库

在区块链中是没有UTXO模型的,但是又因为节点需要用它去验证交易,所以,每个节点自己在本地数据库存放着UTXO模型。

以下是UTXO数据库的统计信息

以下是比特币中的utxo数据库的结构

{
  "height": 454974,
  "bestblock": "000000000000000001afbfe1209aee1882e8a8930bc1e020c4a37d98f72640d7",
  "transactions": 17707300,
  "txouts": 45845906,
  "bytes_serialized": 1791822745,
  "hash_serialized": "ed1bdcca4e08eb8270800d08b2f9dd7ce926f4ff9b1d7304b71c7a075a69098c",
  "total_amount": 16187023.59866495
}

交易ID(TXID)

交易ID 是对交易整个数据的一个哈希

交易ID 是比特币交易中的标识符,是由32个字节(或者64字符)或者16进制组成的

  • 创建一个交易ID 我们通过将交易数据(transcation data)进行两次 SHA-256 哈希就可以得到 TXID。如下方表示:
0100000001c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd3704000000004847304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901ffffffff0200ca9a3b00000000434104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac00286bee0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000

169e1e83e930853391bc6f35f605c6754cfead57cf8387639d3b4096c54f18f4 

注意:如果我们刚刚哈希了一些交易数据,同时想要在区块链中使用 TXID 搜索,必须要使用相反的字节顺序搜索它。

txid (original):  169e1e83e930853391bc6f35f605c6754cfead57cf8387639d3b4096c54f18f4
txid (searching): f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16

为什么要使用相反的字节顺序搜索它呢?因为历史原因,比特币核心使用的tx和block哈希就是字节翻转的。换句话说,这是比特币早期发展过程中的一个小小的疏忽,现在已经成为了一种标准。

  • 交易ID在什么时候使用

    当我们刚刚做了一笔交易,同时想要在区块链中找到这笔交易,就可以用到 TXID 。例如:

bitcoin-cli getrawtransaction 0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098

如果我们的比特币钱包给了我们一个 txid ,它就很有可能是"可搜索"的格式了。(已经进行了字节翻转)

当我们使用一个现存的 output 要当做一个新交易的 inpit 时,也需要 TXID

因为 TXID 是一个交易的唯一标识

inputs

inputs 是一个数组,包含一个以上的 input

input 中常用的结构如下:

| Field | 描述 | | -------------- | ----------------------------------- | | TXID | 引用现存的交易 | | VOUT | 作为input的这个output在交易中的索引 | | ScriptSig Size | 显示接下来解锁码的大小 | | ScriptSig | 解锁input的锁定脚本的解锁码 |

input如何工作

  • 选择一个output作为input

    我们如果要使用output作为交易的input时,需要指定花费哪一个output。

    每一个交易都有唯一的txid,每一个output在交易中也有特定的索引,因此我们可以引用区块链上的所有output

  • 解锁

    虽然我们可以引用区块链上的任意output,但是这个output必须我们要可以解锁才行(只能花费自己资金)。我们需要提供一个解锁脚本。

outputs

outputs 也是一个数组,包含一个以上的 output

每个output都有一个锁,意味着在未来的交易中被能够解锁的人用做input

output 中常用的结构如下:

| Field | 描述 | | ----------------- | ------------------------ | | Value | output 的值 | | ScriptPubKey Size | 显示接下来锁定代码的大小 | | ScriptPubKey | 对output锁定的脚本 |

output如何工作

  1. 给它一个值

    每个output都有一个值

  2. 给它一把锁

    在创建output时 ,我们需要对它进行锁定。这些锁定脚本是为了防止其他人在未来的交易中将这个output作为input。

    锁定代码称作:ScriptPubKey

ScriptPubKey

在上文中我们用到了ScriptPubKey这个锁定代码,虽然之后我们会详细学习锁定脚本以及解锁脚本它们的原理以及工作方式,这里我们简单的学习一下 ScriptPubKey。

ScriptPubKey 的作用之前也提到过,将它放入 output 中防止其他人花费。

比特币中常见的几种 ScriptPubKey:

  • P2PKH(Pay to PubKey Hash)(这是最常用的,同时也是标准比特币交易时的默认锁定脚本。)
OP_DUP OP_HASH160 fde0a08625e327ba400644ad62d5c571d2eec3de OP_EQUALVERIFY OP_CHECKSIG

注:
    锁定脚本: DUP HASH160 <PubKHash> EQUALVERIFY CHECKSIG (存储的是一些操作指令)
    DUP 操作符: 复制堆栈的置顶项
    HASH160 操作符: 对堆栈置顶项进行 PIREMD16(SHA256( 某一值 )) 的运算,并将结果推送至堆栈顶部
    EQUALVERIFY 操作符: 对堆栈中的前两项进行比较,如果一致,则都移除。
    CHECKSIG 操作符: 检查签名<sig>是否与公钥的<sig>匹配,如果一致,显示 TRUE
  • P2PK(Pay To PubKey)
04a9d6840fdd1497b3067b8066db783acf90bf42071a38fe2cf6d2d8a04835d0b5c45716d8d6012ab5d56c7824c39718f7bc7486d389cd0047f53785f9a63c0c9d OP_CHECKSIG

注: P2PK 是 P2PKH 的简化版
  • P2M(Pay to Multisig)
OP_1 0378ee11c3fb97054877a809ce083db292b16d971bcdc6aa4c8f92087133729d8b 1283b5fbf5cc62d4399dfa1025c3e306295264494722c5085ceadadf1291f68125 a31752c9f17c628edc4c69c4c0846f8d814b21e046eabe06f9968a037ce0741c74 OP_3 OP_CHECKMULTISIG

注:
    锁定脚本: M <Public Key 1> <Public Key 2> ... <Public Key N> N OP_CHECKMULTISIG 
    M是要求激活交易的最少公钥数,N是存档公钥总数。
  • P2SH(Pay to Script Hash)
OP_HASH160 10b0ed2d1698ff0f0ea151cf41988d05b728746a OP_EQUAL

注:  
    P2SH 是 MS 的简化版

交易数据(Transaction Data)

比特币交易就是代表了比特币运动的一堆数据,它接收 inputs,同时创造 outputs.

  • 交易数据结构
01000000017967a5185e907a25225574544c31f7b059c1a191d65b53dcc1554d339c4f9efc010000006a47304402206a2eb16b7b92051d0fa38c133e67684ed064effada1d7f925c842da401d4f22702201f196b10e6e4b4a9fff948e5c5d71ec5da53e90529c8dbd122bff2b1d21dc8a90121039b7bcd0824b9a9164f7ba098408e63e5b7e3cf90835cceb19868f54f8961a825ffffffff014baf2100000000001976a914db4d1141d0048b1ed15839d0b7a4c488cd368b0e88ac00000000

交易ID:c1b4e695098210a31fe02abffe9005cffc051bbe86ff33e173155bcbdc5821e3

交易数据结构中的各个十六进制数字表示如下:(交易中的所有数据都是十六进制的)

  • 流程

上图已经非常清楚的解释了一个交易结构中主要模块的作用:

  • 2.1 inputs 中的txid和vout 可以唯一锁定区块链上之前交易中的 output
  • 2.2 inputs 中的signature 是可以解开2.1中 output 的解锁脚本
  • 2.3 outputs 中 amount 是指转移比特币的数量
  • 2.4 outputs 中 lockingscript 将 2.3 中的比特币锁定,以供未来使用。

交易费用(Fee)

我们创建的交易需要矿工将交易写入到区块链中,交易费用就是激励矿工将交易包含到他们的候选区块中。

同时交易费用是按字节收取的,原因如下:

  • 比特币的区块大小限制为1MB
  • 交易数据要占据区块的空间
  • 矿工希望最大化他们可以收取的费用

END