比特币交易(Bitcoin Transactions)

栏目:比特币高阶 作者:btcer 评论:0 点击: 2,566 次

本文译自比特币WIKI:https://en.bitcoin.it/wiki/Transaction

https://en.bitcoin.it/wiki/Transaction_Malleability

译者:申屠青春 深圳大学ATR国防科技重点实验室博士 新浪微博 @我看比特币

注意:本文可随意转发,请留下译者信息,如果觉得本文对你有用,请给译者捐赠,以便翻译更多比特币的核心资料。捐赠地址:1faVxBp2KmST98p3tJjx2MQP98JLLnF2Q

译者前言

比特币在国内已经众所周知,但是技术研究并未有效开展,大部分人处于知道和了解程度,目前比特圈中许多人对比特币能做什么,同样了解不多。一个重要原因是大多数比特币核心资料都是英文,很少有人能静心看完如此繁杂的英文资料。本人博士论文的研究方向是比特币,在研究其英文技术的同时,拟对一些重要资料进行翻译,让更多的圈内人对比特币有更多的理解。

本文主题是比特币交易,交易是整个比特币体系的核心,没有交易就没有比特币,同时也说明了交易可塑性的原理。

正文

交易是签过名的数据块,该数据块在网络中广播,并且被收集到中。它引用以前的交易,从该交易中发送特定数据的比特币到一个或多个公钥中(即比特币地址),交易未被加密(比特币体系中没有加密任何数据)。

块链浏览器是指一个网站,在该网站上可以浏览到被包含在块链中的每一个交易,有助于理解交易操作的技术细节,对支付验证也很有用。

1比特币交易的一般格式(在一个块中)

数据项

描述

大小

版本号

目前为 1

4字节

输入数量

正整数 VI = VarInt

1 – 9字节

输入列表

每块的第一个交易的第一个输入叫做 “coinbase” (早期版本中内容被忽略)

<in-counter>-许多输入

输出数量

正整数 VI = VarInt

1 – 9字节

输出列表

块中的第一个交易的输出是花掉挖矿得到的比特币

<out-counter>-许多输出

锁定时间

lock_time

如果非0并且序列号小于

0xFFFFFFFF ,是指块序号;如果交易已经终结,则是指时间戳

4字节

2带有1个输入和1个输出的比特币交易的例子

2.1数据

Input:

Previous tx: f5d8ee39a430901c91a5917b9f2dc19d6d1a0e9cea205b009ca73dd04470b9a6

Index: 0

scriptSig: 304502206e21798a42fae0e854281abd38bacd1aeed3ee3738d9e1446618c4571d10

90db022100e2ac980643b0b82c0e88ffdfec6b64e3e6ba35e7ba5fdd7d5d6cc8d25c6b241501

Output:

Value: 5000000000

scriptPubKey: OP_DUP OP_HASH160 404371705fa9bd789a2fcd52d2c580b65d35549d

OP_EQUALVERIFY OP_CHECKSIG

2.2解释

该交易的输入从交易f5d8ee39a430901c91a5917b9f2dc19d6d1a0e9cea205b009ca73dd04470b9a6的0号输出中导入了50个比特币,其输出发送了50个比特币到一个比特币地址(这里用十六进制表示:404371705fa9bd789a2fcd52d2c580b65d35549d,而非正常的base58表示)。如果接收者想花掉这些钱,他首先创建自己的交易B,再引用该交易A的0号输出作为B交易的输入。

2.2.1输入

一个输入是对其他交易的输出的引用,多个输入通常列在一个交易中。所有被引用的输出值相加,该总和值在该交易A的输出中用到。Previous tx是以前交易的HASH值,Index是被引用的交易的特定输出号,ScriptSig是一个脚本的前一半(脚本将在后续详细讨论)

脚本包含两个部分,一个签名和一个公钥,公钥属于交易输出的赎回者,并且证明交易创建者被允许赎回输出值,另一个部分是ECDSA签名,是通过对简化交易的HASH值进行ECDSA签名而得到。签名和公钥一起,证明原地址的真正所有者创建了该支付交易,许多指标定义了是如何简化,并且可以用来创建不同类型的支付。

2.2.2输出

一个输出包含发送比特币的指令,Value是以聪(Satoshi,1BTC=100,000,000聪)为单位的数值,当该输出被赎回时,这个数值是非常有价值的。ScriptPubKey是脚本的另一半(在后面讨论),还可以有多于一个输出,他们共享了输入的总和值。因为一个交易的每个输出只能被后来的交易当成输入引用一次。如果你不想丢币,需要把所有输入值的总和值发送到一个输出地址,如果输入是50BTC,但你仅想发送25BTC,比特币将创建2个25BTC的输出:一个发往目标地址,另一个回到你的地址(称之为“找零”,即使你是发送给自己了)。任何输入的作为交易费的比特币不能被赎回,将被生成这个块的矿工得到。studybtc.com

2.2.3验证

为了验证某个交易的输入已经被授权,可以收集被引用的输出中的所有币值,比特币体系使用了一个类似于Forth脚本系统,输入的scriptSig和被引用的输出scriptPubKey会被评估(按顺序),评估scriptPubKey时会使用scriptSig留在堆栈里的值。 如果scriptPubKey返回真,则输入被授权。通过脚本系统,发送者可以创建非常复杂的条件,人们为了赎回输出值则必须满足这些条件。举个例子,可以创建一个能被任何人赎回而无需授权的输出,也可以创建一个需要10个不同签名的输入,或者无需公钥仅由密码赎回的输出。 比特币客户端

3交易类型

比特币目前创建两个不同的scriptSig/scriptPubKey对,描述如下。

创建更复杂的交易类型并且把他们关联成密码学加强的合同,这是完全可能的,我们称之为合同

3.1支付到公钥HASH地址

scriptPubKey: OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG

scriptSig: <sig> <pubKey>

一个比特币地址只是一个HASH值,因而发送者无法在scriptPubKey中提供完整的公钥,当要赎回已经被发送到一个比特币地址的比特币时,接收者需同时提供签名和公钥,脚本会验证公钥的HASH确实与scriptPubKey中的HASH值匹配,还会检查公钥和签名是否匹配。检查过程如下:

堆栈

脚本

描述

<sig> <pubKey> OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG

scriptSig和scriptPubKey 联合

<sig> <pubKey>

OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG

遇到常数,压入堆栈

<sig> <pubKey> <pubKey>

OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG

复制栈顶元素

<sig> <pubKey> <pubHashA>

<pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG

HASH栈顶元素

<sig> <pubKey> <pubHashA> <pubKeyHash>

OP_EQUALVERIFY OP_CHECKSIG

遇到常数,压入堆栈

<sig> <pubKey>

OP_CHECKSIG

检查两个栈顶元素是否相等

true

Empty.

用两个栈顶元素,检查签名是否正确。

3.2支付到脚本HASH

内容为空。

3.3比特币生成交易

生成交易只有一个输入,该输入有一个”coinbase”参数没有scriptSig,在”coinbase”中的数据可以是任意内容,它不会被使用。比特币把压缩的当前HASH目标值和任意精确度的”外加随机数”存贮在这儿, 块头中的Nonce每次溢出,它们都会增长。输出可以是任何内容,但比特币创建了一个准确的类似于IP地址的交易。extraNonce有助于扩大工作量证明函数的范围,矿工很容易修改Nonce(4个字节)、时间戳和extraNonce(2-100字节)。

译者按:(1)当前HASH目标值解释如下,挖矿软件随机生成一个随机数,放到正在生成的块里,对块进行HASH,使得该HASH值小于或等于当前HASH目标值,就代表挖矿成功;如果不成功则重新生成外加随机数,再次HASH) (2) Nonce溢出:是指在对一个块进行HASH时,Nonce从0开始,每计算一次HASH都要增长一次,因而有可能会超过数值范围的情况,extraNonce就要相应增长以存贮Nonce。

4交易的每一个输入的一般格式(在块内)-Txin

数据项

描述

大小

以前交易的HASH

以前交易的两次SHA256HASH值

32 字节

以前 交易的

Txout-index

非负整数,用来索引被引用的交易的输出

4字节

Txin-script 长度

非负整数VI = VarInt

1 – 9字节

Txin-script /

scriptSig

Script 脚本

<in-script length>-许多字节

序列号

sequence_no

正常是 0xFFFFFFFF; 当交易的lock_time 大于0时有意义

4字节

输入充分描述了去哪里拿到要赎回的币、以及怎么拿到。如果这个输入是块中的第一个交易的第一个输入,我们称之为生产交易,它的输入和内容完全被忽略。(一般情况,以前的交易HASH是0,以前的Txout-index为-1)

5交易的每一个输出的一般格式(在块内)-Txout

数据项

描述

大小

输出值

非负整数,以Satoshi聪为单位的数值,表示要被发送的币数量

8字节

Txout- script长度

非负整数

1 – 9字节VI = VarInt

Txin-script/ scriptPubKey

Script 脚本

<out-script length>-许多字节

在输出中设置以后释放这些比特币数量的条件,第一个交易的输出值的总和,等于被矿工挖到的该块比特币数量加上块中其他交易的交易费。

6交易可塑性

当交易被签名时,该签名并没有覆盖交易中的所有数据。因而,在非正常情况下,一个网络节点可以使得HASH无效来改变你发送的交易。注意:这样只是改变了HASH值,交易的输出没有改变,比特币会被发送到先前指定的地址。然而,这并不意味着,例如,在任何条件下接受未确认的交易是不安全的,因为后续的交易要依赖以前交易的HASH值,这些HASH值可以被改变,直到它们在一个块中被确认后,才不会再改变。(如果块链重组,有可能要等到一个确认以后才不会再改变)。另外,钱包必须经常扫描与它相关的交易,如果是因为钱包创建了txout而假定该txout一定存在,这是不安全的。

6.1签名可塑性

可塑性的第一个形式是签名本身,每个签名仅有一个DER编码的ANS.1的8进制表示,但是openssl并不强制要求,如果签名本身不是特别奇特,一般都会被接受。另外,对于每个ECDSA签名(r,s),签名(r, -s (mod N))是对相同信息的有效签名。

正在努力使得比特币节点不转播非标准签名,最终达到完全不许它们被包括进新块。

6.2 scriptSig可塑性

比特币中的签名算法,未把任何scriptSig包括在内,因为要对签名本身签名,这是不可能的。这就意味着可以把其他数据加入到交易中,附加的数据优先于签名和公钥,被压入堆栈。类似地,可以把OP_DROP加入到脚本中,以便堆栈恢复scriptPubKey操作之前的状态。

正在考虑阻止scriptSig可塑性,当前的交易,如果在scriptSig中有数据入栈之外的任何操作,都被认为是非标准交易,并且不会被转发,最终该无规则会强化到:在脚本执行完成后,堆栈中只能有一个项。然后,这样做可能影响到比特币后续扩展性。



0

声明: 本文由( btcer )原创编译,转载请保留链接: 比特币交易(Bitcoin Transactions)

比特币交易(Bitcoin Transactions):等您坐沙发呢!

发表评论


    分享到:
11.5K

若觉得本站内容对您有用,欢迎随手打赏

地址 1EwvVKfHm34h8bzKTx8NjT8nHjsRrjGhvm

比特币常用网址:
交易查询(国外):http://blockchain.info/
交易查询(国内):http://qukuai.com
中文维基:https://zh-cn.bitcoin.it/
BTC客户端:http://bitcoin.org/en/choose-your-wallet
行情汇总:http://z.btc123.com/

"In computing we trust."
我们信任计算

什么是比特币?比特币™ (BitCoin)是一种P2P形式的虚拟货币。点对点的传输意味着一个去中心化的支付系统。比特币不依靠特定货币机构发行,它通过特定算法的大量计算产生,比特币经济使用整个P2P网络中众多节点构成的分布式数据库来确认并记录所有的交易行为。P2P的去中心化特性与算法本身可以确保无法通过大量制造比特币来人为操控币值。基于密码学的设计可以使比特币只能被真实的拥有者转移或支付。这同样确保了货币所有权与流通交易的匿名性。