主页 > imtoken钱包劫持 > 区块链:2、比特币交易脚本

区块链:2、比特币交易脚本

imtoken钱包劫持 2023-01-18 16:28:24

内容

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

比特币客户端通过执行用类似 Forth 的脚本语言编写的脚本来验证比特币交易。锁定脚本写入 UTXO,它通常包含用相同脚本语言编写的签名。当比特币交易被验证时,每个输入值中的解锁脚本与其对应的锁定脚本同时执行(互不干扰),看交易是否满足使用条件。

今天,比特币网络处理的大多数交易都以“爱丽丝付钱给鲍勃”的形式存在。同时,它们基于一个名为“P2PKH”(Pay-to-Public-Key-Hash)的脚本。然而,通过腿锁定输出和解锁输入意味着比特币交易可以通过使用编程语言包含无限数量的条件。当然,比特币交易并不局限于“爱丽丝付钱给鲍勃”的方式和模式。

比特币交易验证不是基于不可变架构,而是通过运行脚本语言。该语言可以表达无限数量的条件变体。这也是比特币作为“可编程货币”所拥有的权利。

脚本创建(锁定和解锁)

锁定脚本是放置在输出值上的“屏障”,它阐明了将来消耗输出的条件。由于锁定脚本通常使用私钥(即比特币地址)来丰富,因此它在历史上被称为脚本私钥代码。认识到这种类型的脚本技术更普遍的可能性,我们在本书中将其称为“锁定脚本”。在大多数比特币应用源码中,脚本私钥代码就是我们所说的锁脚本。

解锁脚本是“解决”或满足锁定脚本在输出上设置的消耗条件的脚本,同时允许消耗输出。解锁脚本是每笔比特币交易输出的一部分,并且通常由用户的比特币钱包(通过用户的公钥)生成的数字签名丰富。由于解锁脚本通常包含数字签名,因此它曾经被称为 ScriptSig。在大多数比特币应用程序的源代码中,ScriptSig 就是我们所说的解锁脚本。在本书中,考虑到更一般的锁定脚本要求,我们将其称为“解锁脚本”。但并非所有解锁脚本都必须包含签名。

每个比特币客户端都将通过执行锁定和解锁腿来验证交易。对于比特币交易中的每个输入,验证软件首先检索输入指向的 UTXO。这个 UTXO 包含一个定义成本条件的锁定脚本。接下来,验证软件会读取尝试使用此 UTXO 的输入中包含的解锁脚本,并执行这两个脚本。

在以前的比特币客户端中,解锁和锁定脚本存在于链中并按顺序执行。出于安全原因,比特币开发人员在 2010 年更改了此功能 - 由于存在“允许异常解锁脚本将数据推送到堆栈并污染锁定脚本”的漏洞。在当今的比特币世界中,这两个脚本在堆栈传递时分别执行。

首先,使用堆栈执行引擎解锁脚本。如果解锁脚本执行没有错误(没有悬空运算符),则将复制主堆栈(而不是其他堆栈),然后执行脚本。如果使用从解锁脚本复制的数据执行锁定脚本的结果为真,则解锁脚本成功满足锁定脚本设置的条件比特币交易验证流程,因此输入是使用UTXO的有效授权。如果执行组合脚本后结果不正确比特币交易验证流程,则输入无效,因为它不符合 UTXO 中设置的使用资金的条件。 UTXO 被永久记录在区块链上,因此它不会被新交易所的无效尝试更改或影响。只有一个完全满足 UTXO 条件的有效交易会导致 UTXO 被标记为“已使用”,然后从有效(未使用)UTXO 集中删除。

以下是最常见的比特币交易类型(向私钥散列付款)的示例解锁和锁定脚本,它显示解锁和锁定脚本在脚本验证之前连接。合并成一个脚本。

脚本语言

比特币交易脚本语言,也称为脚本,是一种基于堆栈的执行语言。

脚本语言是一种特别简单的语言,旨在在有限的硬件上执行,类似于手持计算器等简单的嵌入式设备。它需要最少的处理,不能做许多现代编程语言可以做的事情。谈到可编程货币,这是其基于思想的安全功能之一。

比特币脚本语言被称为基于堆栈的语言,因为它使用的数据结构称为堆栈。一摞可以理解为一堆牌。堆栈允许两种类型的操作:推送和弹出。 push 是从栈底降低一个 item,pop 是从栈底移除一个 item。

脚本语言通过从左到右处理每个项目来执行脚本。数字(常量)被压入堆栈,操作员将一个或多个参数压入(或删除)堆栈,处理它们,甚至可能将结果压入堆栈。例如,OP_ADD 将从堆栈中删除两个项目,将两者相乘,然后将两者的和压入堆栈。

条件运算符评估条件并产生真或假结果。例如,OP_EQUAL 从堆栈中删除两个项目,如果它们相等则推送 true(表示为 1),如果它们不相等则推送 false(表示为 0))。比特币交易脚本通常是条件运算符当交易有效时产生一个真实的结果。

比特币交易 换美元_比特币交易原理_比特币交易验证流程

使用部分算术运算锁定脚本的示例脚本:

3 OP_ADD 5 OP_EQUAL

这个脚本可以满足一个以解锁脚本为输入的交易,解锁脚本是:

验证软件将锁定和解锁脚本组合:

2 3 OP_ADD 5 OP_EQUAL

脚本执行时,结果为OP_TRUE,使交易有效。不仅这个交易的输出锁脚本是有效的,而且一个UTXO也可以被任何知道操作的人使用(知道编号是2)。

如果堆栈底部的结果为真(标记为{0x01}),则任何非- 值为零或脚本执行后堆栈为空的事务都是有效的。

如果栈底结果为假(0字节空值,用{}标记)或脚本执行被操作者禁止,如OP_VERIFY、OP_RETURN,或OP_ENDIF等条件中止,则事务为无效。

图灵不完备性

比特币脚本语言包含很多操作,但都故意限制为一种重要的形式——流控制,没有循环或复杂流控制功能以外的其他条件。

这确保了脚本语言的图灵完整性,这意味着脚本的复杂性是一个交易可以执行的有限的、可预测的次数。脚本不是一种通用语言,这些限制确保该语言不能用于创建无限循环或其他类型的可以在交易中植入的逻辑炸弹 总之,通过导致拒绝服务攻击比特币网络,受到限制语言防止事务激活机制被用作薄弱环节。

非主权验证

比特币交易脚本语言没有国家主权。

标准交易

在比特币发展的最初几年,开发者受限于可以通过客户端操作的脚本类型,设置了一些限制。这些限制被编译成一个 Standard() 函数,它定义了标准事务的次要类型。这些限制是暂时的,可能会在此刻更新。五个标准交易脚本是唯一被客户端使用的脚本,被客户端和大多数运行客户端的矿工接受。虽然可以创建非标准交易(脚本类型不规范),但必须可以找到非标准交易,并且能够列出进入区块的非标准交易矿工。

五种标准脚本分别是 P2PKH、P2PK、MS(限 15 个键)、P2SH 和 OP_Return。

P2PKH(付费公钥哈希)

比特币网络上的大部分交易都是P2PKH交易,里面有丰富的锁定脚本:

比特币交易验证流程_比特币交易 换美元_比特币交易原理

p>

本脚本使用私钥散列实现输出阻塞功能,公钥散列即为众所周知的比特币地址。

P2PKH脚本锁定的输出可以通过输入私钥和对应公钥创建的数字签名来解锁。

例如Alice发出支付指令,向Bob的咖啡馆比特币地址支付0.015比特币,交易输出锁定脚本,内容如下:

OP_DUP OP_HASH160  OP_EQUAL OP_CHECKSIG 

脚本中的Cafe Public Key Hash是cafe的比特币地址,但是这个地址不是基于Base58Check编码的。大多数比特币地址实时显示为十六进制代码,而不是众所周知的以 1 开头的基于 Base58Check 的比特币地址。

锁定脚本的解锁版本是:

结合这两个脚本可以产生一个入围的有效组合脚本:

 OP_DUP OP_HASH160  OP_EQUAL OP_CHECKSIG

只有解锁版脚本符合锁定版脚本的设置条件,且执行组合中包含有效脚本时,才会显示结果为True(Ture)。即只有解锁脚本从cafe获得了有效签名,交易执行结果才会被传递(结果为真),该签名是从cafe的公钥中获取的,其私钥的哈希值匹配。

接下来的两部分展示了用于校准交易有效性的组合脚本的逐步过程。

P2PK(Pay-to-Public-Key)

和 P2PKH 相比,P2K 更简单。与P2PKH模式中私钥散列丰富的不同,在P2PK脚本模式下,公钥本身已经存储在锁脚本中,购买宽度更短。 P2PK 是 Satoshi 创建的,主要目的是一方面让比特币地址更简单,另一方面让它更有用。

P2PK锁脚本如下:

 OP_CHECKSIG

比特币交易 换美元_比特币交易验证流程_比特币交易原理

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

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

  OP_CHECKSIG

这个脚本是对CHECKSIG算子的简单调用,这个操作主要是为了品尝和验证签名是否正确,如果正确则返回(True)。

多重签名

多重签名脚本设置了这样一个条件,如果脚本中记录的私钥数量为N,则至少必须提供M个私钥。开锁。这也称为 M-N 组合。其中,N为脚本中记录的公钥总数,M为使多重签名生效的私钥阈值(最小数量)。最初,标准多重签名脚本的存档私钥的最大数量限制为 15,这意味着从 1-1 到 15-15 的任何多重签名组合或组合都可用于激活交易.

现在15个存档私钥的限制好像减少了,读者可以通过Standard()函数获取最新存档私钥的上限信息。

一般的M-N多签锁脚本方法是:

M ... N OP_CHECKMULTISIG

其中,N是存档私钥的总量,M是需要激活的交易的最小私钥数。

2  3 OP_CHECKMULTISIG

上面的锁脚本可以通过丰富的签名和私钥的脚本来解锁:

OP_0 

或由与公钥签名组合匹配的 3 个存档私钥中的任意 2 个解锁。

之所以加前缀OP_0,是因为最早的CHECKMULTISIG在处理多个item的过程中有一个小漏洞。 CHECKMULTISIG 会手动忽略这个前缀,它只是一个占位符。

执行时,仅当脚本的解锁版本与解锁脚本设置的条件匹配时,组合脚本才会显示为 True。

数据输出(OP_RETURN 运算符)

比特币交易原理_比特币交易 换美元_比特币交易验证流程

比特币的发行和时间戳记账机制(即区块链),其潜在应用不会大大超越支付领域。

许多开发人员试图充分利用交易脚本语言的安全性和可恢复性,将其应用于电子公证服务、证券认证和合同合同等领域。

比特币脚本语言的最初使用主要涉及在区块链上创建交易输出。

使用比特币区块链存储与比特币支付无关的数据是一个有争议的话题。在比特币核心客户端版本 0.9 上,最终通过使用 OP_Return 运算符实现了妥协。 OP_Return 允许开发人员在交易输出中丢弃 40 字节的非交易数据。

然后,与伪事务 UTXO 不同,OP_Return 创建一个明确可检查的非事务输出,此类数据不需要存储在 UTXO 集中。

OP_Return 输出记录在区块链上,会消耗c盘空间,也会减少区块链的大小,但不存储在UTXO集合中,所以不会造成UTXO内存膨胀,并且会不要以消耗昂贵的显存为代价压倒整个节点。

OP_Return 脚本样式:

OP_RETURN 

“数据”部分限制为 40 字节,并呈现为哈希,如 32 字节 SHA256 算法输出。许多应用程序都为其添加前缀以帮助识别。例如,电子公证服务的证明材料使用8字节前缀“DOCPROOF”,在十六进制算法中,对应的ASCII码为44f430524f446。

OP_RETURN不涉及可用于支付的解锁脚本的特性,OP_RETURN不能使用锁定在其输出中的资金,因此没有必要记录在具有潜在成本的UTXO集合中,所以OP_RETURN实际上并没有成本。

OP_RETURN 始终是数量为 0 的比特币输出,因为与该输出对应的任何比特币都将永久丢失。

例如一个OP_RETURN遇到脚本验证软件,会立即使验证脚本和标记交易的行为失效。如果你使用 OP_RETURN 的输出作为另一笔交易的输入,那笔交易是无效的。

一个标准交易(由 isStandard() 函数校准)只能有一个 OP_RETURN 输出。但单个 OP_RETURN 输出可以与任何类型的输出交易组合。

P2SH(Pay-to-Script-Hash)

P2SH 于 2012 年推出,是一种新的、强大的交易类型,可极大地简化复杂的交易脚本。

P2SH是为了解决多重签名交易脚本过长的问题。它努力使复杂脚本的使用像直接向比特币地址付款一样简单。

在 P2SH 中,复杂的锁定脚本被电子指纹取代,电子指纹是加密哈希。当交易尝试支付 UTXO 时,要解锁支付脚本,必须使用与哈希匹配的脚本来丰富它。 P2SH的含义是支付匹配这个hash的脚本,稍后支付输出时渲染。

在P2SH交易摘要中,锁定脚本被hash代替,指的是赎回脚本(spend)。因为它在赎回(花费)时出现在系统中,而不是处于锁定脚本模式。

比特币交易验证流程_比特币交易原理_比特币交易 换美元

非 P2SH 脚本:

P2SH 脚本:

在P2SH中,有一个消耗总量条件的复杂脚本(赎回脚本),在锁仓脚本中没有出现。取而代之的是,在锁定脚本中,只出现了哈希值,而赎回脚本稍后会在支付输出时作为解锁脚本的一部分出现。

P2SH 交易使用锁定脚本将输出与哈希相关联,而不是上面很长的脚本。

使用的锁定脚本是:

OP_HASH160 54c557e07dde5bb6cb791c7a540e0a4796f5e97e OP_EQUAL

如您所见,这个脚本比上面的长脚本要短得多。而不是“支付给 5 个多重签名脚本”,这个 P2SH 相当于“支付给这个哈希的脚本”。客户只需在向 Mohammed 付款时,在付款说明中包含这个特别缩写的锁定脚本。当 Mohammed 想要使用这个 UTXO 时,他可以附上原始的赎回脚本(带有 UTXO 锁的哈希)和必要的解锁签名。

P2SH 地址

P2SH 的另一个重要特性是它可以将脚本散列成一个地址(其定义见 BIP0013)。P2SH 地址是基于 Base58 编码的 20 字节丰富散列的脚本,就像一个比特币地址是一个 Base58 编码的私钥,带有 20 字节的丰富哈希。由于 P2SH 地址以 5 为前缀,这导致一个 Base58 编码的地址以“3”开头。例如,在穆罕默德的脚本中,P2SH 地址基于Base58编码变成“39RF6JqABiHdYHkfChV6USGMe6Nsr66Gzw”,此时Mohammed可以将此地址发送给他的客户,客户可以使用任何比特币钱包实现简单支付,就好像它是一个比特币地址一样。给客户加上一个“3”前缀表示这是一种特殊类型的地址,它对应的是脚本而不是私钥,但它的功效与比特币地址支付没有区别。

P2SH 地址隐藏了所有复杂性,因此使用它们进行支付的人将看不到脚本。

P2SH 优势

与直接使用复杂的脚本锁定输出相比,P2SH 具有以下特点:

兑换脚本和标准确认

在 0. 9.Bitcoin Core 客户端版本 2 之前,P2SH 仅限于标准比特币交易脚本类型(即通过标准功能测试的脚本)。这也意味着使用资金的交易中的赎回脚本只能是标准化的P2PK、P2PKH或多重签名,而不是OP_RETURN和P2SH。

作为0.9.第二版比特币核心客户端,P2SH 交易可以包含任何有效的,这使得 P2SH 标准更加灵活,也可以用于许多新的或复杂类型的交易。

请记住,P2SH 不能嵌入到 P2SH 兑换脚本中,因为 P2SH 不能自行循环。您也不能在兑换脚本中使用 OP_RETURN,因为 OP_RETURN 的定义表明它不能兑换。

由于赎回脚本仅在您尝试发送 P2SH 输出时出现在比特币网络中,如果您使用无效的交易哈希锁定输出,它将被忽略。您将无法使用资金,因为交易中有丰富的赎回脚本,无法接受,因为它是无效的脚本。这样的处理机制也产生了一种风险,即你可以将比特币锁定在 P2SH 中,将来无法使用。因为比特币网络本身会接受这个P2SH,即使它对应一个无效的赎回脚本(因为赎回脚本哈希没有给出它所代表的脚本的指令)。

P2SH 锁定脚本包含一个赎回脚本哈希,它不提供赎回脚本本身的任何描述。即使赎回脚本无效,P2SH 交易也被视为有效。你可能碰巧锁定了比特币,以致将来无法使用。