越写越快乐之《精通比特币》读书笔记之交易下优质

65次浏览 | 2024-07-16 11:16:49 更新
来源 :互联网
最佳经验

简要回答

精通比特币 - 图片来自简书App

今天的越写越快乐系列为大家带来《精通比特币》读书笔记之交易章节的下半部分的分享。

前情回顾

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

类比现实生活中你去商场买鞋,然后看中一双鞋,亲自试了试,觉得合适,然后付款,拿着鞋离开商场,而交易就大致这么个过程,只是交易的渠道和媒介不太一样罢了

比特币交易脚本和脚本语言

比特币交易脚本,是一种类似Forth的逆波兰表达式的基于堆栈的执行语言。放置在UTXO上的锁定脚本和解锁脚本都以此脚本语言编写。当一笔交易被验证时,每一个输入值中的解锁脚本与其对应的锁定脚本同时(互不干扰,相互隔离)执行,以确定这笔交易是否满足支付条件。

如今,大多数经比特币网络处理的交易是以“Alice付给Bob”的形式存在,并基于一种称为“P2PKH”脚本。但是比特币交易不局限于“支付给Bob的比特币地址”的脚本。事实上,锁定脚本可以被编写成表达各种复杂的情况。

比特币交易验证并不基于静态模式,而是通过脚本语言的执行来实现的。这种语言允许表达几乎无限的各种条件,这也是比特币作为一种“可编程货币”所拥有的力量。

图灵非完备性

比特币脚本语言包含许多操作码,但都故意限定为一种重要的模式——除了有条件的流控制以外,没有任何循环或者复杂流控制能力。这样就保证了脚本语言的图灵非完备性,这就意味着脚本有限的复杂性和可预见的执行次数。

图灵非完备性是不能解决所有的可计算性问题的通用物理机器或编程语言。

去中心化验证

由于比特币系统是去中心化的,因此没有任何一个节点可以控制其他节点的交易脚本的执行,那么对于脚本的执行,只有包含执行脚本的所有信息,执行脚本才能顺利地完成执行。这样的话,同一个执行脚本可以在任意一个节点上执行,得到相同的执行结果。

可以联想到函数的幂等性,也就是函数的执行结果和其执行的次数无关。具体有关幂等性的解释,请参考理解HTTP幂等性

脚本构建

比特币的交易验证引擎依赖于两类脚本来验证比特币交易:锁定脚本和解锁脚本。锁定脚本是一个放置在输出上面的花费条件:它指定了今后花费这边输出必须满足的条件。解锁脚本是一个“解决”或满足被锁定脚本在一个输出上设定的花费条件的脚本,它允许输出被消费。解锁脚本是每一个比特币交易输入的一部分,而且往往含有一个由用户的比特币钱包(通过私钥)生成的数字签名。

每一个比特币验证节点会通过同时执行锁定脚本和解锁脚本来验证一笔交易。每一个输入都包含一个解锁脚本,并引用了之前存在的UTXO。验证软件将复制解锁脚本,检索输入引用的UTXO,并从该UTXO复制锁定脚本。然后依次很自信解锁和锁定脚本。如果解锁脚本满足锁定脚本条件,则输入有效。所有的输入都是独立验证的,作为交易总体验证的一部分。

脚本执行堆栈

脚本执行堆栈用于执行操作脚本,也就是由操作数和操作码构成的操作表达式。堆栈是一个非常简单的数据结构,可以被视为一叠卡片。栈允许两个操作:push和pop。Push(推送)在堆栈顶部添加一个项目。Pop(弹出)从堆栈中删除最顶端的一个项目。栈的操作只能作用于栈的顶端项目。

脚本语言通过从左到右处理每个项目来执行脚本。先把操作数推倒堆栈,然后操作码从堆栈中推送或者弹出一个或多个参数,对其进行操作,并可能将结果推送到堆栈上。

从左到右的执行顺序有没有让你想到哪种计算机编程语言呢?

这种操作数和操作码的方式可以联想到计算机的汇编语言,汇编语言的简单入门,请参考阮一峰老师的汇编语言入门。

脚本语言可以看作比特币系统中一段可以自动执行的程序,该程序用在比特币系统中的大部分场合,结合本书附录的第二部分脚本语言操作费、常量和符号,我相信你对交易脚本会有一个比较深入的认识。

脚本一个简单脚本示例

锁定脚本如下

3 OP_ADD 5 OP_EQUAL

解锁脚本如下

2

锁定和解锁脚本组合,其结果脚本如下

2 3 OP_ADD 5 OP_EQUAL

上述脚本的含义是操作数2和3进行相加操作,然后OP_EQUAL操作码验证相加的结果是否为5。当脚本执行后,如果执行结果是OP_TRUE,则说明交易有效。不仅该笔的输出锁定脚本有效,同时UTXO也能被任何知晓这个运算技巧的人所使用。

每次脚本执行完成后都会查看栈顶的结果是否为TRUE,如果堆栈顶部的结果显示为FALSE,或者脚本执行被操作码明确禁止,或有条件终止,则交易无效。有没有联想到以太坊的溢出安全问题,其实就是没有充分考虑软件执行条件的边界问题,当然以太坊的安全漏洞不是我说的这么简单。交易执行结果脚本请参考相关章节内容。

解锁和锁定脚本的单独执行

可以看作你向朋友转账时,需要验证双方的有效身份并检索账户余额,然后发起转账操作。

将解锁和锁定脚本分别传递给堆栈执行引擎,具体的执行过程如下:首先,使用堆栈执行引擎执行解锁脚本,如果解锁脚本在执行过程中未报错,则负责主堆栈,并执行锁定脚本。如果从解锁脚本中复制过来的堆栈数据执行锁定脚本的结果为“TRUE”,那么解锁脚本就成功地满足了锁定脚本所设置的条件。因此该输入是一个能使用该UTXO的有效授权。如果在合并脚本后的结果不是“TRUE”以外的任何结果,输入都是无效的,因为它不满足UTXO中所设置的使用该笔资金的条件。

可以看作在转账的过程中验证不通过,可能出现的问题有余额不足、身份欺诈、网络不通畅等。

P2PKH(Pay-to-Public-Key-Hash)

比特币网络处理的大多数交易花费的都是“付款至公钥哈希”脚本锁定的输出,这些输出都含有一个锁定脚本,将输入锁定为一个公钥哈希值,即我们常说的比特币地址。由P2PKH脚本锁定的输出可以通过提供一个公钥和由相应私钥创建的数字签名来解锁。例如,我们可以再次回顾一下Alice向Bob咖啡馆支付的案例。Alice下达了向Bob咖啡馆的比特币地址支付了0.015比特币的支付指令,该笔交易的输出内容为以下形式的锁定脚本:

OP_DUP OP_HASH160  OP_EQUALVERIFY OP_CHECKSIG

脚本中的Cafe Public Key Hash 即为咖啡馆的比特币地址,但该地址不是基于Base58Check编码。事实上,大多数比特币地址的公钥哈希值都显示为十六进制码,而不是大家所熟知的以1开头的基于Base58Check编码的比特币地址。上述锁定脚本相应的解锁脚本是:

 

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

  OP_DUP OP_HASH160
 OP_EQUALVERIFY OP_CHECKSIG

只有当解锁脚本与锁定脚本的设定条件相匹配时,执行组合验证脚本才会显示结果为TRUE。换句话说,只有当解锁脚本得到了咖啡馆的有效签名,交易执行结果才会被通过,该有效签名是从与公钥哈希相匹配的咖啡馆的私钥中所获取的。

其实就是验证接收者的签名是否与发送者给定的转账地址匹配,简单的理解就是《林海雪原》中的那句天王盖地虎,宝塔镇河妖。

数字签名

比特币中石油的数字签名算法是椭圆曲线数字签名算法(ECDSA)。ECDSA是用于基于椭圆曲线私钥/公钥对的数字签名算法。ECDSA用于脚本函数OP_CHECKSIG,OP_CHECKSIGVERIFY,OP_CHECKMULTISIG和OP_CHECKMULTISIGVERIFY。每当你锁定脚本看到这些脚本函数式,解锁脚本都必须包含一个ECDSA签名。

数字签名在比特币中的用途:

数字签名如何工作

数字签名是一种由两部分组成的数学方案:第一部分是使用私钥从消息(交易)创建签名的算法;第二部分是允许任何人验证签名的算法,给定消息和公钥。

在比特币的ECDSA算法的实现中,被签名的“消息”是交易,或更确切地说是交易中特定数据子集的哈希值。签名密钥是用户的私钥,结果是签名,公式如下:

((Sig = F{sig}(F{hash}(m), dA)))。

公式中的字母含义如下:

ECDSA数学运算的更多细节可以在ECDSA Math章节中找到。函数Fsig 产生由两个值组成的签名Sig,通常称为R和S:Sig = (R, S)。现在已经计算了两个值R和S,它们就序列化为字节流,使用一种称为“分辨编码规则”(Distinguished Encoding Rules)或 DER的国际标准编码方案。

接下来我们看看签名序列化,也就是DER的过程,我们来看看Alice创建的交易。 在交易输入中有一个解锁脚本,其中包含Alice的钱包中的以下DER编码签名:

3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e381301

该签名是Alice的钱包生成的R和S值的序列化字节流,证明她拥有授权花费该输出的私钥。 序列化格式包含以下9个元素:

看看您是否可以使用此列表解码 Alice 的序列化(DER编码)签名。 重要的数字是R和S; 数据的其余部分是DER编码方案的一部分。

验证签名

要验证签名,必须有签名(R和S)、序列化交易和公钥(对应于用于创建签名的私钥)。本质上,签名的验证意味着“只有生成此公钥的私钥的所有者,才能在此交易上产生此签名。”

签名验证算法采用消息(交易或其部分的哈希值)、签名者的公钥和签名(R和S值),如果签名对该消息和公钥有效,则返回 TRUE 值。

签名哈希类型(SIGHASH)

比特币签名具有指示交易数据的哪一部分包含在使用 SIGHASH 标志的私钥签名的哈希中的方式。 SIGHASH 标志是附加到签名的单个字节。每个签名都有一个SIGHASH标志,该标志在不同输入之间也可以不同。具有三个签名输入的交易可以具有不同SIGHASH标志的三个签名,每个签名签署(承诺)交易的不同部分。

记住,每个输入可能在其解锁脚本中包含一个签名。因此,包含多个输入的交易可以拥有具有不同SIGHASH标志的签名,这些标志在每个输入中承诺交易的不同部分。还要注意,比特币交易可能包含来自不同“所有者”的输入,他们在部分构建(和无效)的交易中可能仅签署一个输入,继而与他人协作收集所有必要的签名后再使交易生效。许多SIGHSASH标志类型,只有在你考虑到由许多参与者在比特币网络之外共同协作去更新仅部分签署了的交易,才具有意义。

有三个SIGHASH标志:ALL,NONE和SINGLE,如下表所示。

SIGHASH类型和意义 - 图片来自简书App

另外还有一个修饰符标志SIGHASH_ANYONECANPAY,它可以与前面的每个标志组合。 当设置ANYONECANPAY时,只有一个输入被签名,其余的(及其序列号)打开以进行修改。 ANYONECANPAY的值为0x80,并通过按位OR运算,得到如下所示的组合标志:

带修饰符的SIGHASH类型及其含义 - 图片来自简书App

SIGHASH标志在签名和验证期间应用的方式是建立交易的副本和删节其中的某些字段(设置长度为零并清空),继而生成的交易被序列化,SIGHASH标志被添加到序列化交易的结尾,并将结果哈希化 ,得到的哈希值本身即是被签名的“消息”。 基于SIGHASH标志的使用,交易的不同部分被删节。 所得到的哈希值取决于交易中数据的不同子集。 在哈希化前,SIGHASH作为最后一步被包含在内,签名也会对SIGHASH类型进行签署,因此不能更改。

ECDSA数学

签名算法首先生成一个 ephemeral(临时)私公钥对。 在涉及签名私钥和交易哈希的变换之后,该临时密钥对用于计算R和S值。临时密钥对基于随机数k,用作临时私钥。 从k,我们生成相应的临时公钥P。数字签名的R值则是临时公钥P的x坐标。从那里,算法计算签名的S值,使得:

计算S值 - 图片来自简书App

其中:

验证是签名生成函数的倒数,使用R,S值和公钥来计算一个值P,该值是椭圆曲线上的一个点(签名创建中使用的临时公钥):

计算P值 - 图片来自简书App

其中:

如果计算点P的x坐标等于R,则验证者可以得出结论,签名是有效的。

随机性在签名中的重要性

如我们在ECDSA Math中所看到的,签名生成算法使用随机密钥k作为临时私有-公钥对的基础。 k 的值不重要,只要它是随机的。如果使用相同的值 k 在不同的消息(交易)上产生两个签名,那么签名私钥可以由任何人计算。在签名算法中重用相同的 k 值会导致私钥的暴露。

比特币地址、余额和其他摘要

一笔交易 - 图片来自简书App

在上图中表示的是最近发生的一笔交易,该交易在区块链浏览器上的交易记录。在交易的左侧,区块链浏览器将比特币地址18T6vFXeCr7evfXCNz6bfqeJ7QiPi3AZi7显示为“发送者”,其实这个信息本身并不在交易中。当区块链接到浏览器检索到交易时,它还检索在输入中引用的先前交易,并从该旧交易中提取第一个输出。在该输出内是一个锁定脚本,将UTXO锁定到某个人的公钥哈希(P2PKH脚本)。块链浏览器提取公钥哈希,并使用Base58Check编码对其进行编码,以生成和显示表示该公钥的比特币地址。同样,在右侧则显示了接收者的比特币地址,该地址也是区块链浏览器从每个输出中提取锁定脚本,将其识别为P2PKH脚本,并从内部提取公钥哈希,最后块链浏览器重新编码了使用Base58Check的公钥哈希生成和显示比特币地址。

某个比特币地址的余额 - 图片来自简书App

对于一个比特币地址的余额,比特币系统中没有余额的概念,这里显示的余额是通过以下步骤来显示在区块链浏览器上的:

通过计算UTXO集,区块链浏览器总结了引用账户X的公钥哈希的所有未使用的值,并产生向用户显示的“最终余额”数目。

引用个人感想

通过对《精通比特币》交易章节的梳理,我们知道了比特币交易过程中数字签名和交易脚本是如何保证交易的执行和确认的,也让我联想到了现实生活中从最初的银行转账汇款、到后来的ATM取现、到现在的手机银行转账,随着支付渠道的兴起和支付手段的便捷,让我们更加意识到了资金安全的重要性,也让我们知道了比特币是如何解决我们生活中的需求痛点的,对于跨国结账和跨行结算业务有了不一样的处理渠道,我相信科技和金融的关系会更加地紧密,也让我对金融科技的理解更进一步。当然每个国家对于数字货币以及以数字货币为媒介的数字资产的监管政策不同,也诞生了许多数字货币相关的业务和行业创新,我相信这对于区块链行业的发展,或者说对于金融行业和科技行业的深度整合提供了不一样的视角和维度。我更坚信区块链技术重构了生产关系这句话深信不疑。虽然我对经济学、金融学的了解很粗浅,但是我有兴趣去了解和探索生产关系的改变是如何影响大家的生活和工作的。我更是知道技术是第一生产力,更是改变你我生活质量的利器,要是加以合理利用,我相信会为我们打开一个更有想象力的世界。相信你对比特币中的交易脚本和数字签名有了一定的了解,接下来我会继续为大家带来区块链其它章节的分享,敬请期待。若是我的文章对你有所启发,那将是我莫大的荣幸和巨大的鼓舞。

本文地址:https://www.huajie.net.cn/btc/43795.html

发布于 2024-07-16 11:16:49
收藏
分享
海报
65
上一篇:《精通比特币》 下一篇:非法取得比特币不愿还 法院判决应全部归还或折价赔偿

推荐阅读

0 条评论

本站已关闭游客评论,请登录或者注册后再评论吧~

忘记密码?

图形验证码