比特币分析之交易、脚本

在此之前,我们已经对比特币有了一个大体上的了解,总的来说它就是一个分布式账本。上个文章中我们只是按照通俗的说法讲解了比特币,这篇文章我们更加细致的看下比特币中交易是如何完成的。我们日常的每笔交易是这样的:张三账上减¥200,李四账上加¥200。在比特币区块链中,交易不是这么简单,交易实际是通过脚本来完成,以承载更多的功能。

未花费的交易输出(UTXO)

先引入一个概念:未花费的交易输出——UTXO(Unspent Transaction Output)

比特币及其许多衍生品,都将用户的余额信息存储在UTXO结构中,系统的整个状态由一系列的“有效的输出”组成(可以将这些“有效的输出”想象成钱币)。每个UTXO都有拥有者和自身的价值属性。一笔交易在消费若干个UTXO同时也会生成若干个新的UTXO。比特币的交易都是基于UTXO上的,即交易的输入是之前交易未花费的输出,这笔交易的输出可以被当做下一笔新交易的输入。“有效的输出”中“有效”需满足下面几点约束:

1.每个被引用的输入必须有效,且未被使用过;
2.交易的签名必须与每笔输入的所有者签名匹配;
3.输入的总值必须等于或大于输出的总值。

因此,比特币系统中,用户的“余额”是该用户的私钥能够有效签名的所有UTXO的总和。

挖矿奖励属于一个特殊的交易(称为coinbase交易),可以没有输入。
UTXO是交易的基本单元,不能再分割。
在比特币没有余额概念,只有分散到区块链里的UTXO

随着钱从一个地址被移动到另一个地址的同时形成了一条所有权链,像这样:
own_chain

比特币脚本

比特币交易是首先要提供一个用于解锁UTXO(用私钥去匹配锁定脚本)的脚本(常称为解锁脚本:Signature script),这也叫交易输入,
交易的输出则是指向一个脚本(称为锁定脚本:PubKey script),这个脚本表达了:谁的签名(签名是常见形式,并不一定必须是签名)能匹配这个输出地址,钱就支付给谁。

每一个比特币节点会通过同时执行这解锁和锁定脚本(不是当前的锁定脚本,是指上一个交易的锁定脚本)来验证一笔交易,脚本组合结果为真,则为有效交易。

当解锁版脚本与锁定版脚本的设定条件相匹配时,执行组合有效脚本时才会显示结果为真

如最为常见类型的比特币交易脚本(支付到公钥哈希:P2PKH(Pay-to-Public-Key-Hash))组合是这样:
script

常见交易脚本验证过程

比特币交易脚本语言是一种基于逆波兰表示法的基于栈的执行语言。

比特币脚本语言包含基本算数计算、基本逻辑(比如if…then)、报错以及返回结果和一些加密指令,不支持循环。

脚本语言通过从左至右地处理每个项目的方式执行脚本。

下面用两个图说明下常见类型的比特币交易脚本验证执行过程:
script_run1
上图为解锁脚本运行过程(主要是入栈)
script_run2
上图为锁定脚本运行过程(主要是出栈),最后的结果为真,说明交易有效。

交易分析

实际上比特币的交易被设计为可以纳入多个输入和输出。

交易结构

我们来看看完整的交易结构,
img

交易的锁定时间定义了能被加到区块链里的最早的交易时间。在大多数交易里,它被设置成0,用来表示立即执行。
如果锁定时间不是0并且小于5亿,就被视为区块高度,意指在这个指定的区块高度之前,该交易不会被包含在区块链里。
如果锁定时间大于5亿,则它被当作是一个Unix纪元时间戳(从1970年1月1日以来的秒数),并且在这个指定时间之前,该交易不会被包含在区块链里。

交易的数据结构没有交易费的字段,交易费通过所有输入的总和,以及所有输出的总和之间的差来表示,即:

交易费 = 求和(所有输入) - 求和(所有输出)

交易输入结构

刚刚我们提过输入需要提供一个解锁脚本,现在来看看一个交易的输入结构:
img

我们结合整个交易的结构里看输入结构就是这样子:
img

交易输出结构

刚刚我们提过输出是指向一个解锁脚本,具体交易的输出结构为:
img
我们结合整个交易的结构里看输出结构就是这样子:
img

我们看一下通过比特币核心的 API 获得的真正的交易数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
{
"txid": "0627052b6f28912f2703066a912ea577f2ce4da4caa5a5fbd8a57286c345c2f2",
"size": 258,
"version": 1,
"locktime": 0,
"vin":
[
{
"txid":"7957a35fe64f80d234d76d83a2...8149a41d81de548f0a65a8a999f6f18",
"vout":0,
"scriptSig":
{
"asm":"3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1decc...",
"hex":"483045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1de..."
},
"sequence": 4294967295
}
],
"vout":
[
{
"value": 0.01500000,
"n": 0,
"scriptPubKey":
{
"asm": "OP_DUP OP_HASH160 ab68...5f654e7 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a914ab68025513c3dbd2f7b92a94e0581f5d50f654e788ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": ["1GdK9UzpHBzqzX2A9JFP3Di4weBwqgmoQA" ]
}
},
{
"value": 0.08450000,
"n": 1,
"scriptPubKey":
{
"asm": "OP_DUP OP_HASH160 7f9b1a...025a8 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a888ac", "reqSigs": 1,
"type": "pubkeyhash",
"addresses": ["1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK" ]
}
}
]
}

智能合约雏形 - 应用场景说明

由于交易是通过脚本来实现,脚本语言可以表达出无数的条件变种。

比特币的脚本目前常用的主要分为两种,一种是常见的P2PKH(支付给公钥哈希),另一种是P2SH(Pay-to-Script-Hash支付脚本哈希)。
P2SH支付中,锁定脚本被密码学哈希所取代,当一笔交易试图支付UTXO时,要解锁支付脚本,它必须含有与哈希相匹配的脚本。

这里不展开技术细节,下面说明一些应用场景,以便大家有更直观的认识。

  • 多重签名应用
    合伙经营中,如只有一半以上的的股东同意签名就可以进行支付,可为公司治理提供管控便利,同时也能有效防范盗窃、挪用和遗失。

    用于担保和争端调解,一个买家想和他不认识或不信任的某人交易,在一般情况交易正常进行时,买家不想任何第三方参与。那交易双方可以发起支付,但如果交易出现问题时,那第三方就可以根据裁定,使用自己的签名和裁定认可的一方共同签名来兑现这笔交易。

  • 保证合同
    保证合同是建造公众商品时的集资办法,公众商品是指一旦建成,任何人都可以免费享受到好处。标准的例子是灯塔,所有人都认同应该建造一个,但是对于个人航海者来说灯塔太贵了,灯塔同时也会方便其他航海者。
    一个解决方案是向所有人集资,只有当筹集的资金超过所需的建造成本时,每个人才真正付钱,如果集资款不足,则谁都不用付钱。

  • 依靠预言
    假如老人想让他孙子继承遗产,继承时间是在他死后或者在孙子年满18岁时(也是一个带锁定时间交易),无论哪个条件先满足,他的孙子都可以得到遗产。
    因为比特币节点可依靠预言对死亡条件进行判断,预言是指具有密钥对的服务器,当用户自定义的表达式被证明是真的,它能按照要求对交易签名。

相信随着区块链的普及,会对未来的交易模式和商业结构带来巨大的影响。不过由于比特币的脚本语言不是图灵完备的,交易模式依旧有限,以太坊就是为解决这一问题而出现,之后的文章我会介绍以太坊是什么。