精通比特币系列---交易

简介: 简介比特币交易是比特币系统中最重要的部分。根据比特币系统的设计原理,系统中任何其他的部分都是为了确保比特币交易可以被生成、能在比特币网络中得以传播和通过验证,并最终添加入全球比特币交易总账簿(比特币区块链)。

简介
比特币交易是比特币系统中最重要的部分。根据比特币系统的设计原理,系统中任何其他的部分都是为了确保比特币交易可以被生成、能在比特币网络中得以传播和通过验证,并最终添加入全球比特币交易总账簿(比特币区块链)。比特币交易的本质是数据结构,这些数据结构中含有比特币交易参与者价值转移的相关信息。比特币区块链是全球复式记账总账簿,每个比特币交易都是在比特币区块链上的一个公开记录。

在这一章,我们将会剖析比特币交易的多种形式、所包含的信息、如何被创建、如何被验证以及如何成为所有比特币交易永久记录的一部分。

比特币交易的生命周期
一笔比特币交易的生命周期起始于它被创建的那一刻,也就是诞生(origination)。 随后,比特币交易会被一个或者多个签名加密,这些签名标志着对该交易指向的比特币资金的使用许可。接下来,比特币交易被广播到比特币网络中。在比特币网络中,每一个节点(比特币交易参与者)验证、并将交易在网络中进行广播,直到这笔交易被网络中大多数节点接收。最终,比特币交易被一个挖矿节点验证,并被添加到区块链上一个记录着许多比特币交易的区块中。
一笔比特币交易一旦被记录到区块链上并被足够多的后续区块确认,便成为比特币总账簿的一部分,并被所有比特币交易参与者认可为有效交易。于是,被这笔交易分配到一个新所有者名下的比特币资金可以在新的交易中被使用——这使得所有权链得以延伸且再次开启一个新的比特币交易生命周期。

创建比特币交易
将一笔比特币交易理解成纸质支票或许有助于加深我们对它的理解。与支票相似,一笔比特币交易其实是一个有着货币转移目的的工具,这个工具只有在交易被执行时才会在金融体系中体现,而且交易发起人并不一定是签署该笔交易的人。

广播交易至比特币网络
首先,一笔交易需要传递至比特币网络,才能被传播,也才能加入区块链中。本质上,一笔比特币交易只是300到400字节的数据,而且它们必须被发送到成千上万个比特币节点中的任意一个。只要发送者能使用多于一个比特币节点来确保这笔交易被传播,那么发送者并不需要信任用来传播该笔交易的单一节点。相应地,这些节点不需要信任发送者,也不用建立发送者的“身份档案”。由于这笔交易是经过签名且不含任何机密信息、私钥或密码,因此它可被任何潜在的便利网络公开地传播。

比特币交易在比特币网络中的传播
一旦一笔比特币交易被发送到任意一个连接至比特币网络的节点,这笔交易将会被该节点验证。如果交易被验证有效,该节点将会将这笔交易传播到这个节点所连接的其他节点;同时,交易发起者会收到一条表示交易有效并被接受的返回信息。如果这笔交易被验证为无效,这个节点会拒绝接受这笔交易且同时返回给交易发起者一条表示交易被拒绝的信息。
比特币网络是一个点对点网络,这意味着每一个比特币节点都连接到一些其他的比特币节点(这些其他的节点是在启动点对点协议时被发现的)。整个比特币网络形成了一个松散地连接、且没有固定拓扑或任何结构的“蛛网”——这使得所有节点的地位都是同等的。比特币交易相关信息(包括交易和区块)被传播——从每一个节点到它连接的其他节点。一笔刚通过验证且并被传递到比特币网络中任意节点的交易会被发送到三到四个相邻节点,而每一个相邻节点又会将交易发送到三至四个与它们相邻的节点。以此类推,在几秒钟之内,一笔有效的交易就会像指数级扩散的波一样在网络中传播,直到所有连接到网络的节点都接收到它。
比特币网络被设计为能高效且灵活地传递交易和区块至所有节点的模式,因而比特币网络能抵御入侵。为了避免垃圾信息的滥发、拒绝服务攻击或其他针对比特币系统的恶意攻击,每一个节点在传播每一笔交易之前均进行独立验证。 一个异常交易所能到达的节点不会超过一个。

交易结构
一笔比特币交易是一个含有输入值和输出值的数据结构,该数据结构植入了将一笔资金从初始点(输入值)转移至目标地址(输出值)的代码信息。比特币交易的输入值和输出值与账号或者身份信息无关。你应该将它们理解成一种被特定秘密信息锁定的一定数量的比特币。只有拥有者或知晓这个秘密信息的人可以解锁。

image


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

交易的输出和输入
比特币交易的基本单位是未经使用的一个交易输出,简称UTXO。UTXO是不能再分割、被所有者锁住或记录于区块链中的并被整个网络识别成货币单位的一定量的比特币货币。比特币网络监测着以百万为单位的所有可用的(未花费的)UTXO。当一个用户接收比特币时,金额被当作UTXO记录到区块链里。这样,一个用户的比特币会被当作UTXO分散到数百个交易和数百个区块中。实际上,并不存在储存比特币地址或账户余额的地点,只有被所有者锁住的、分散的UTXO。“一个用户的比特币余额”,这个概念是一个通过比特币钱包应用创建的派生之物。比特币钱包通过扫描区块链并聚合所有属于该用户的UTXO来计算该用户的余额。
一个UTXO可以是一“聪”的任意倍。就像美元可以被分割成表示两位小数的“分”一样,比特币可以被分割成表示八位小数的“聪”。尽管UTXO可以是任意值,但只要它被创造出来了,就像不能被切成两半的硬币一样不可再分了。如果一个UTXO比一笔交易所需量大,它仍会被当作一个整体而消耗掉,但同时会在交易中生成零头。例如,你有20比特币的UTXO并且想支付1比特币,那么你的交易必须消耗掉整个20比特币的UTXO并且产生两个输出:一个是支付了1比特币给接收人,另一个是支付19比特币的找零到你的钱包。这样的话,大部分比特币交易都会产生找零。
类似的,一笔比特币交易可以有任意数值,但必须从用户可用的UTXO中创建出来。用户不能再把UTXO进一步细分,就像不能把一元纸币撕开而继续当货币使用一样。用户的钱包应用通常会从用户可用的UTXO中选取多个可用的个体来拼凑出一个大于或等于一笔交易所需的比特币量。
就像现实生活中一样,比特币应用可以使用一些策略来满足付款需要:组合若干小的个体,算出准确的找零;或者使用一个比交易值大的个体然后进行找零。所有这些复杂的、由可支付的UTXO完成的组合,都是由用户的钱包自动完成,并不为用户所见。只有当你以编程方式用UTXO来构建原始交易时,这些才与你有关。
被交易消耗的UTXO被称为交易输入,由交易创建的UTXO被称为交易输出。通过这种方式,一定量的比特币价值在不同所有者之间转移,并在交易链中消耗和创建UTXO。一笔比特币交易通过使用所有者的签名来解锁UTXO,并通过使用新的所有者的比特币地址来锁定并创建UTXO。
对于输出和输入链来说,有一个例外,它是一种特殊的交易类型,称为Coinbase交易。这是每个区块中的首个交易。这种交易存在的原因是作为对挖矿的奖励而产生全新的可用于支付的比特币给“赢家”矿工。这也就是为什么比特币可以在挖矿过程中被创造出来,后面会详细讲解。

交易输出
每一笔比特币交易创造输出,输出都会被比特币账簿记录下来。几乎所有的输出都能创造一定数量的可用于支付的比特币,也就是UTXO。这些UTXO被整个网络识别,并且所有者可在未来的交易中使用它们。给某人发送比特币实际上是创造新的UTXO,注册到那个人的地址,并且能被他用于新的支付。
UTXO被每一个全节点比特币客户端在一个储存于内存中的数据库所追踪,该数据库也被称为“UTXO集”或者“UTXO池”。新的交易从UTXO集中消耗(支付)一个或多个输出。
交易输出包含两部分:
▷ 一定量的比特币,被命名为“聪”,是最小的比特币单位; 一个锁定脚本,也被当作是“障碍”,提出支付输出所必须被满足的条件以“锁

住”这笔总额。
image

交易输入
简单地说,交易输入是指向UTXO的指针。它们指向特定的UTXO,并被交易哈希和在区块链中记录UTXO的序列号作为参考。若想支付UTXO,一个交易的输入也需要包含一个解锁脚本,用来满足UTXO的支付条件。解锁脚本通常是一个签名,用来证明对于在锁定脚本中的比特币地址拥有所有权。

当用户付款时,他的钱包通过选择可用的UTXO来构造一笔交易。比如说,要支付0.015比特币,钱包应用会选择一个0.01 UTXO和一个0.005 UTXO,使用它们加在一起来得到想要的付款额。

image

交易费
大多数交易包含交易费,这是为了在网络安全方面给比特币矿工一种补偿。在第8章中,对于挖矿、费用和矿工得到的奖励,有更详细的讨论。这一节解释交易费是如何被包含在日常交易中的。大多数钱包自动计算并计入交易费。但是,如果你编程构造交易,或者使用命令行接口,你必须手动计算并计入这些费用。
交易费可当作是为了包含(挖矿)一笔交易到下一个区块中的一种鼓励,也可当作是对于欺诈交易和任何种类的系统滥用,在每一笔交易上通过征收一笔小成本的税而造成的一种妨碍。交易费被挖出这个区块的矿工得到,并且记录在这个交易的区块链中。
交易费基于交易的尺寸,用千字节来计算,而不是比特币的价值。总的来说,交易费基于市场所设置,生效于比特币网络中。矿工依据许多不同的标准,按重要性对交易进行排序,这包括费用,并且甚至可能在某种特定情况下免费处理交易。交易费影响处理优先级,这意味着有足够费用的交易会更可能地被包含在下一个挖出的区块中;与此同时,交易费不足或者没有交易费的交易可能会被推迟,基于尽力而为的原则在几个区块之后被处理,甚至可能根本不被处理。交易费不是强制的,而且没有交易费的交易也许最终会被处理,但是,包含交易费将提高处理优先级。

把交易费加到交易中
交易的数据结构没有交易费的字段。相反地,交易费通过所有输入的总和,以及所有输出的总和之间的差来表示。从所有输入中扣掉所有输出之后的多余的量会被矿工收集走。
交易费被作为输入减输出的余量:

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

对于交易来说,这是一个很让人摸不着头脑的元素,但又是很重要的问题。因为如果你要构造你自己的交易,你必须确认你没有疏忽地包含了一笔少于输入的、量非常大的费用。这意味着你必须计算所有的输入,如果必要的话进行找零,不然的话,结果就是你给了矿工一笔可观的劳动费!
举例来说,如果你消耗了一个20比特币的UTXO来完成1比特币的付款,你必须包含一笔19比特币的找零回到你的钱包。否则,那剩下的19比特币会被当作交易费,并且会被挖出你的交易到一个区块中的矿工收走。尽管你会受到高优先级的处理,并且让一个矿工喜出望外,但这很可能不是你想要的。

交易链条和孤立交易
正如我们之前所看到的那样,交易形成一条链,这条链的形式是一笔交易消耗了先前的交易(父交易)的输出,并为随后的交易(子交易)创造了输出。有的时候组成整个链条的所有交易依赖于他们自己——比如父交易、子交易和孙交易——而他们又被同时创造出来,来满足复杂交易的工作流程。这需要在一个交易的父交易被签名之前,有一个合法的子交易被签名。举个例子,这是CoinJoin交易使用的一项技术,这项技术可以让多方同时加入交易,从而保护他们的隐私。
当一条交易链被整个网络传送时,他们并不能总是按照相同的顺序到达目的地。有时,子交易在父交易之前到达。在这种情况下,节点会首先收到一个子交易,而不能找到他参考的父交易。节点不会立即抛弃这个子交易,而是放到一个临时池中,并等着接收它的父交易,与此同时广播这个子交易给其他节点。没有父交易的交易池被称作孤立交易池。一旦接收到了父交易,所有与这个父交易创建的UTXO有关的孤块会从池中释放出来,递归地重新验证,然后整条交易链就会被交易池包括进去,并等待着被区块所挖走。交易链可以是任意长度并且可以被任意数量的批次同时传走。在孤立池中保留孤块的机制保证了其他合法的交易不会只是因为父交易被耽误了而被抛弃,并且无论接收顺序,最终整个链会以正确的顺序重新构造出来。
内存中储存的孤立交易数量是有限制的,这是为了防止针对比特币节点的拒绝服务攻击(DoS)。这个限制被定义在比特币涉及到的客户端的源代码中的MAX_ORPHAN_TRANSACTIONS。如果池中的孤立交易数量达到了MAX_ORPHAN_TRANSACTIONS,一个或多个的、被随机选出的孤立交易会被池抛弃,直到池的大小回到限制以内。

比特币交易脚本和脚本语言
比特币客户端通过执行一个用类Forth脚本语言编写的脚本验证比特币交易。锁定脚本被写入UTXO,同时它往往包含一个用同种脚本语言编写的签名。当一笔比特币交易被验证时,每一个输入值中的解锁脚本被与其对应的锁定脚本同时(互不干扰地)执行,从而查看这笔交易是否满足使用条件。
脚本创建(锁定与解锁)
比特币的交易验证引擎依赖于两类脚本来验证比特币交易:一个锁定脚本和一个解锁脚本。
锁定脚本是一个放在一个输出值上的“障碍”,同时它明确了今后花费这笔输出的条件。由于锁定脚本往往含有一个公钥(即比特币地址),在历史上它曾被称作一个脚本公钥代码。由于认识到这种脚本技术存在着更为宽泛的可能性,在本书中,我们将它称为一个“锁定脚本”。在大多数比特币应用源代码中,脚本公钥代码便是我们所说的锁定脚本。
解锁脚本是一个“解决”或满足被锁定脚本在一个输出上设定的花费条件的脚本,同时它将允许输出被消费。解锁脚本是每一笔比特币交易输出的一部分,而且往往含有一个被用户的比特币钱包(通过用户的私钥)生成的数字签名。由于解锁脚本常常包含一个数字签名,因此它曾被称作ScriptSig。在大多数比特币应用的源代码中,ScriptSig便是我们所说的解锁脚本。考虑到更宽泛的锁定脚本要求,在本书中,我们将它称为“解锁脚本”。但并非所有解锁脚本都一定会包含签名。
每一个比特币客户端会通过同时执行锁定和解锁脚本来验证一笔交易。对于比特币交易中的每一个输入,验证软件会先检索输入所指向的UTXO。这个UTXO包含一个定义了花费条件的锁定脚本。接下来,验证软件会读取试图花费这个UTXO的输入中所包含的解锁脚本,并执行这两个脚本。
在先前的比特币客户端中,解锁和锁定脚本是以连锁的形式存在的,并且是被依次执行的。出于安全因素考虑,在2010年比特币开发者们修改了这个特性——因为存在“允许异常解锁脚本推送数据入栈并且污染锁定脚本”的漏洞。在当今的比特币世界中,这两个脚本是随着堆栈的传递被分别执行的,后续将会详细介绍。
首先,使用堆栈执行引擎执行解锁脚本。如果解锁脚本在执行过程中未报错(没有悬空操作符),主堆栈(非其它堆栈)将被复制,然后脚本将被执行。如果采用从解锁脚本处复制而来的数据执行锁定脚本的结果为真,那么解锁脚本就成功地满足了锁定脚本所设置的条件,因而,该输入是一个能使用该UTXO的有效授权。如果在执行完组合脚本后的结果不是真,那么输入就不是有效的,因为它并未能满足UTXO中所设置的使用该笔资金的条件。注意,UTXO是永久性地记录在区块链中的,因此它不会因一笔新交易所发起的无效尝试而变化或受影响。只有一笔有效的能准确满足UTXO条件的交易才会导致UTXO被标记为“已使用”,然后从有效的(未使用)UTXO集中所移除。
图5-1是最为常见类型的比特币交易(向公钥哈希进行一笔支付)的解锁和锁定脚本样本,该样本展示了在脚本验证之前将解锁脚本和锁定脚本串联而成的组合脚本。

image

标准交易
在比特币最初几年的发展过程中,开发者对可以经由客户端进行操作的脚本类型设置了一些限制。这些限制被编译为一个Standard()函数,该函数定义了五种类型的标准交易。这些限制都是临时性的,当您阅读本书时或许已经更新。截至目前,五种标准交易脚本是仅有的被客户端和大多数运行客户端的矿工们所接受的脚本。虽然创设一个非标准交易(脚本类型非标准化)是有可能的,但前提是必须能找到一个不遵循标准而且能将该非标准交易纳入区块的矿工。
通过检索比特币核心客户端源代码,可以看到当前有哪些交易脚本是被认可的。
五大标准脚本分别为P2PKH、P2PK、MS(限15个密钥)、P2SH和OP_Return,后文将详细介绍这五大脚本。

P2PKH(Pay-to-Public-Key-Hash)
比特币网络上的大多数交易都是P2PKH交易,此类交易都含有一个锁定脚本,该脚本由公钥哈希实现阻止输出功能,公钥哈希即为广为人知的比特币地址。由P2PKH脚本锁定的输出可以通过键入公钥和由相应私钥创设的数字签名得以解锁。
例如,我们可以再次回顾一下Alice向Bob咖啡馆支付的案例。Alice下达了向Bob咖啡馆的比特币地址支付0.015比特币的支付指令,该笔交易的输出内容为以下形式的锁定脚本:

OP_DUP OP_HASH160 <Cafe Public Key Hash> OP_EQUAL OP_CHECKSIG

脚本中的Cafe Public Key Hash即为咖啡馆的比特币地址,但这个地址不是基于Base58Check编码的。事实上,大多数比特币地址都显示为十六进制码,而不是大家所熟知的以1开头的基于Bsase58Check编码的比特币地址。

锁定脚本的解锁版脚本是:

<Cafe Signature> <Cafe Public Key>

将两个脚本结合起来可以形成如下有效组合脚本:

<Cafe Signature> <Cafe Public Key> OP_DUP OP_HASH160
<Cafe Public Key Hash> OP_EQUAL OP_CHECKSIG

只有当解锁版脚本与锁定版脚本的设定条件相匹配时,执行组合有效脚本时才会显示结果为真(Ture)。即只有当解锁脚本得到了咖啡馆的有效签名,交易执行结果才会被通过(结果为真),该有效签名是从与公钥哈希相匹配的咖啡馆的私钥中所获取的。
图5-3和图5-4(分两部分)显示了组合脚本一步步检验交易有效性的过程。

image


image

P2PK(Pay-to-Public-Key)
与P2PKH相比,P2PK模式更为简单。与P2PKH模式含有公钥哈希的模式不同,在P2PK脚本模式中,公钥本身已经存储在锁定脚本中,而且代码长度也更短。P2PKH是由Satoshi创建的,主要目的一方面为使比特币地址更简短,另一方面也使之更方便使用。P2PK目前在Coinbase交易中最为常见,Coinbase交易由老的采矿软件产生,目前还没更新至P2PKH。
P2PK锁定版脚本形式如下:

<Public Key A> OP_CHECKSIG

用于解锁的脚本是一个简单签名:

<Signature from Private Key A>

经由交易验证软件确认的组合脚本为:

<Signature from Private Key A> <Public Key A> OP_CHECKSIG

该脚本只是CHECKSIG操作符的简单调用,该操作主要是为了验证签名是否正确,如果正确,则返回为真(Ture)。

多重签名
多重签名脚本设置了这样一个条件,假如记录在脚本中的公钥个数为N,则至少需提供其中的M个公钥才可以解锁。这也被称为M-N组合,其中,N是记录在脚本中的公钥总个数,M是使得多重签名生效的公钥数阀值(最少数目)。例如,对于一个2-3多重签名组合而言,存档公钥数为3个,至少同时使用其中2个或者2个以上的公钥时,才能生成激活交易的签名,通过验证后才可使用这笔资金。最初,标准多重签名脚本的最大存档公钥数被限定为15个,这意味着可采用1-1乃至15-15的任意多重签名组合,或者组合的组合来激活交易。15个存档公钥数的限制也许在本书出版时已有所增加,读者通过检索Standard()函数可以获得最新存档公钥数上限值的相关信息。
通用的M-N多重签名锁定脚本形式为:

M <Public Key 1> <Public Key 2> ... <Public Key N> N OP_CHECKMULTISIG

其中,N是存档公钥总数,M是要求激活交易的最少公钥数。
2-3多重签名条件:

2 <Public Key A> <Public Key B> <Public Key C> 3 OP_CHECKMULTISIG

上述锁定脚本可由含有签名和公钥的脚本予以解锁:

OP_0 <Signature B> <Signature C>

或者由3个存档公钥中的任意2个相一致的私钥签名组合予以解锁。
之所以要加上前缀OP_0,是因为最早的CHECKMULTISIG在处理含有多个项目的过程中有个小漏洞,CHECKMULTISIG会自动忽略这个前缀,它只是占位符而已。
两个脚本组合将形成一个验证脚本:

OP_0 <Signature B> <Signature C> 2 <Public Key A> <Public Key B> <Public Key C> 3 OP_CHECKMULTISIG

当执行时,只有当未解锁版脚本与解锁脚本设置条件相匹配时,组合脚本才显示得到结果为真(Ture)。上述例子中相应的设置条件即为未解锁脚本是否含有与3个公钥中的任意2个相一致的私钥的有效签名。

数据输出(OP_RETURN操作符)
//todo

P2SH(Pay-to-Script-Hash)
//todo

--摘自《精通比特币》

目录
相关文章
|
存储 人工智能 安全
区块链合约交易所源码新币币交易所USDT秒合约杠杆C2C法币交易
迄今为止,已经有相当多的服务提供加密货币兑换服务。虚拟货币的流行度只增不减,交易平台的需求量也越来越大。 并非所有知名交易所都是可靠和诚实的,因此利基市场仍然对新的和改进的公司开放。
区块链合约交易所源码新币币交易所USDT秒合约杠杆C2C法币交易
|
存储 算法 安全
区块链系列教程之:比特币的钱包与交易
区块链系列教程之:比特币的钱包与交易
区块链系列教程之:比特币的钱包与交易
|
区块链
区块链交易所:虚拟货币交易的5个技巧
  在虚拟货币交易市场里,经常混迹于币圈世界里的交易员通过长时间的交易经验积累,总结一套属于自己的交易技巧,以此来减少自己犯错误的成本。接下来由https://www.fgba.net/为你揭晓虚拟货币交易的6个技巧,希望您在区块链交易所交易过程中少走点弯路。
645 0
区块链交易所:虚拟货币交易的5个技巧
|
区块链
区块链每日一问丨比特币转账的手续费收取标准是什么?
手续费是公平的吗?手续费可以自定义吗?
1219 0
|
区块链 数据安全/隐私保护
区块链应用 | 以太坊网络交易量超 6 大币种总和
以太坊网络交易量超 6 大币种总和
1148 0