Bitcoin Transactions

Table of Contents

1 Transactions简介

交易(Transaction,简称Tx)是比特币系统的重要组成部分。而块(Block)就是将这些基础单元打包装箱,并链在一起。巨大算力保障了块的安全,也就保障了单个交易的安全。

可以把Tx简单地理解为转账,图 1 是一个简单的交易示意图,它描述了Alice向Bob转账的场景。这个Tx中,Input是Alice及其付出金额,而Output是Bob和Alice及其收到金额。为什么Output中也有Alice呢?这是因为, 如果不考虑交易手续费,则交易Input和Output的金额应该相等(一般来说,Input会略大于Output,差额是交易的手续费)。 比如,Alice手头有一个10元钱,想转账3元钱给Bob,则输出中还会包含转账7元给自己的条目。

bitcoin-tx-common-example.png

Figure 1: Common Transaction

2 是多个Input,一个Output的Tx场景。

bitcoin-tx-aggregating-example.png

Figure 2: Transaction aggregating funds

3 是一个Input,很多个Output的Tx场景。

bitcoin-tx-distributing-example.png

Figure 3: Transaction distributing funds

2 Tx细节

4 是通过Block explorer展示Tx信息的例子(假设场景为Alice使用了0.1 BTC,其中的0.015 BTC转账给了Bob用于购买咖啡,而0.0845 BTC退给了自己,0.0005 BTC是转账手续费,由打包者获得)。

bitcoin-tx-high-level.png

Figure 4: Alice's transaction to Bob's Cafe

4 是很high level的交易信息。使用比特币命令行操作 getrawtransactiondecoderawtransaction ,可以得到上面Tx的底层结构看起来像下面这样:

{
    "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",
        }
    ]
}

在上面信息中,为什么一眼看不出Alice和Bob的地址,也看不出Alice所花费的0.1 BTC呢?不着急,后文将对上面信息进行说明。

3 Unspent Transaction Output (UTXO)

比特币网络中Tx输出有两个重要信息:地址(公钥Hash)和value(比特币)。如果Tx的输出没有出现在其它Tx的输入中,则这个Tx的输出就称为Unspent Transaction Output (UTXO)。系统中所有UTXO之和就是比特币总和,把和某个地址关联的所有UTXO相加,就是这个地址的“余额”。

谁拥有UTXO中公钥对应的私钥,谁就可以使用(即花费)这个UTXO。创建普通Tx,建构Tx输入时,需要指定一个可用的UTXO。如前面例子中Tx的输入为:

    "vin": [
        {
            "txid": "7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18",
            "vout": 0,
            "scriptSig" : "3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813[ALL] 0484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adf",
            "sequence": 4294967295
        }
    ]

它表示这个Tx所花费的UTXO来自于另外一个Tx(其id为7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18)的第0个输出(一个Tx的输出可以有多个,索引从0开始编号),我们可以从历史Tx中查找出这个UTXO的value(比如为0.1),所以这个Tx中Alice花费了0.1 BTC,数值0.1不需要显式地写在Tx中,而是通过查找UTXO信息来得到的。

一旦这个Tx被提交,那么Tx(7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18)的第0个输出就不再是UTXO了。

这个Tx中,输出有两个条目,如下所示:

    "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,直到有另外的Tx把它们做为输入。

3.1 UTXO实例

下面假设一个这样的场景:张三挖到12.5枚比特币。过了几天,他把其中2.5枚支付给李四。又过了几天,他和李四各出资2.5比特币凑成5比特币付给王五。

上面场景,在比特币中产生的Tx如图 5 所示。交易#3001中的两个输出是目前系统中的UTXO。

bitcoin-tx-utxo.jpg

Figure 5: UTXO实例

本节的例子摘自:其实并没有什么比特币,只有UTXO

4 Transaction Script(scriptSig和scriptPubKey)

在Tx的输入中有个scriptSig(又称Unlocking Script)信息,输出中有个scriptPubKey(又称Locking Script)信息,它们分别是什么呢?他们其实是一种简单的基于栈的脚本语言,该语言比较简单,没有循环等结构,它不是图灵完备的。这里以Pay-to-Public-Key-Hash(P2PKH)类型的脚本为例进行说明。

输出中的scriptPubKey,主要包含转账的目标地址(公钥的Hash)。而输入中的scriptSig主要包含签名和公钥(这样,我们可以利用公钥验证签名,从而确定用户身份)。如图 6 所示。

bitcoin-tx-script.png

Figure 6: Combining scriptSig and scriptPubKey to evaluate a transaction script

打包节点验证Tx的合法性。在栈上执行脚本,如果执行完Unlocking Script,再执行Locking Script,如果最后栈中内容为TRUE,则认为它是合法的。具体执行细节如图 7 所示。

bitcoin-tx-script-example.png

Figure 7: Evaluating a script for a P2PKH transaction

5 交易手续费

交易手续费没有直接体现在Tx中,它等于Tx输入之和减去Tx输出之和。钱包客户端一般可以调整交易手续费。交易手续费不是强制的,但打包节点会优先打包手续费高的Tx,且没有手续费的Tx很可能不会被打包。

6 Tx加入到Ledger中的过程

Tx由钱包创建,钱包将Tx发送给一些节点。如果某个节点(命名为A)收到一个新的Tx,则节点A会把这个Tx发送给它连接的所有节点,这种传播方式称为flooding。

挖矿节点会验证Tx的合法性,并在成功挖到矿后,把合法的Tx打包为块。

7 钱包安全性

比特币钱包是公钥的Hash,如图 8 所示。

bitcoin-tx-address.png

Figure 8: Private key, public key, and bitcoin address

假设某一天椭圆公钥密码体系被攻破(即由公钥可以计算出私钥),你的比特币就一定不安全了吗?不一定,因为钱包地址是公钥的Hash, 如果某个钱包地址只收钱,而不转出钱,那么公钥是不会暴露的 ,只有当你转出钱时,你才要需要提供签名及公钥。如果你确实需要转出钱,那么你可以在转出钱的同时把余额全部转入到另外一个全新的地址(这个地址还没有过转出记录)。

8 参考

Mastering Bitcoin, 2nd Edition


Author: cig01

Created: <2018-05-27 Sun 00:00>

Last updated: <2018-07-23 Mon 16:31>

Creator: Emacs 25.3.1 (Org mode 9.1.4)