主页 > imtoken钱包app下载链接 > 比特币交易中如何保证每个地址发送比特币的合法性

比特币交易中如何保证每个地址发送比特币的合法性

imtoken钱包app下载链接 2023-09-10 05:11:36

内容

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

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

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

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

脚本创建(锁定和解锁)

锁定脚本是放置在输出值上的“屏障”,它指定了将来使用输出的条件。由于锁定脚本通常包含一个公钥(即比特币地址),因此它在历史上被称为脚本公钥代码。认识到这种脚本技术的更广泛的可能性,我们在本书中将其称为“锁定脚本”。在大多数比特币应用程序源代码中,脚本公钥代码就是我们所说的锁脚本。

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

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

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

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

以下是最常见类型的比特币交易(向公钥哈希支付)的示例解锁和锁定脚本,它显示了在脚本验证之前连接解锁和锁定脚本的组合脚本。

脚本语言

比特币交易脚本语言,也称为脚本,是一种基于反向波兰表示法的基于堆栈的执行语言。

脚本语言是一种非常简单的语言,旨在在有限的硬件上执行,例如手持计算器等简单的嵌入式设备。它需要最少的处理,不能做许多现代编程语言可以做的事情。谈到可编程货币,这是其经过深思熟虑的安全功能之一。

比特币脚本语言被称为基于堆栈的语言,因为它使用的数据结构称为堆栈。一摞可以理解为一堆牌。堆栈允许两种类型的操作:推送和弹出。push 将一个项目添加到堆栈的顶部,并且 pop 从堆栈的顶部删除一个项目。

脚本语言通过从左到右处理每个项目来执行脚本。数字(常量)被压入堆栈,操作员将一个或多个参数压入(或删除)堆栈,处理它们,甚至可能将结果压入堆栈。例如,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等条件终止,则交易无效。

图灵不完备

比特币脚本语言包含许多操作,但它们都被有意限制在一个重要的方式上——没有循环或其他条件的流量控制,而不是复杂的流量控制功能。

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

非主权核查

比特币交易脚本语言是无状态的。

标准交易

在比特币开发的最初几年,开发人员对可以通过客户端操作的脚本类型设置了一些限制。这些限制被编译成一个 Standard() 函数,该函数定义了五种类型的标准事务。这些限制是暂时的,可能会在此时更新。五个标准交易脚本是唯一被客户端和大多数运行客户端的矿工接受的脚本。虽然可以创建非标准交易(脚本类型非标准化),但必须可以找到不遵循标准的矿工,并且可以将非标准交易包含在区块中。

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

P2PKH(付费公钥哈希)

比特币网络上的大多数交易都是 P2PKH 交易,其中包含一个锁定脚本:

该脚本通过公钥哈希实现阻塞输出功能,也就是众所周知的比特币地址。

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

例如,Alice 向 Bob 的咖啡馆的比特币地址订购了 0.015 个比特币加密货币交易合法吗,该地址输出了如下形式的锁定脚本:

OP_DUP OP_HASH160  OP_EQUAL OP_CHECKSIG 

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

锁定脚本的解锁版本为:

组合这两个脚本会产生一个有效的组合脚本:

 OP_DUP OP_HASH160  OP_EQUAL OP_CHECKSIG

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

接下来的两节展示了组合脚本验证交易有效性的分步过程。

P2PK(付费公钥)

与 P2PKH 相比,P2K 更简单。与包含公钥哈希的 P2PKH 模式不同,在 P2PK 脚本模式下,公钥本身已经存储在锁定脚本中,购买长度也更短。P2PK 是由 Satoshi 创建的,其主要目的是一方面使比特币地址更短,另一方面更通用。

P2PK 锁定脚本具有以下形式:

 OP_CHECKSIG

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

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

  OP_CHECKSIG

脚本知道一个简单的CHECKSIG算子调用,主要是为了味蕾验证签名是否正确,如果正确则返回(True)。

多重签名

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

现在可能会增加15个归档公钥的上限,读者可以通过Standard()函数获取最新归档公钥的上限信息。

MN多签锁定脚本的一般形式为:

M ... N OP_CHECKMULTISIG

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

2  3 OP_CHECKMULTISIG

上面的锁定脚本可以通过包含签名和公钥的脚本来解锁:

OP_0 

或者它可以通过 3 个已归档公钥的任意 2 个匹配的私钥签名组合来解锁。

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

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

数据输出(OP_RETURN 运算符)

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

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

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

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

然后,与伪事务性 UTXO 不同,OP_Return 创建了一个显式的、可审查的、非事务性的输出,不需要存储在 UTXO 集中。

OP_Return 输出记录在区块链上,它们消耗磁盘空间,也导致区块链的大小增加,但它们不存储在 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 的意思是,支付一个与该哈希匹配的脚本,稍后在支付输出时呈现该脚本。

在 P2SH 交易聚合中,锁脚本被哈希替换,哈希是指赎回脚本(spend)。因为它在赎回(花费)时出现在系统中,而不是在锁定脚本模式下。

非 P2SH 脚本:

P2SH 脚本:

在 P2SH 中,有一个复杂的脚本来花费支付的条件(赎回脚本),这在锁定脚本中是不存在的。取而代之的是,在锁定脚本中,只出现了哈希值,而赎回脚本稍后会在支付输出时作为解锁脚本的一部分出现。

P2SH 交易使用锁定脚本将输出与哈希相关联,而不是与之前特别长的脚本相关联。

使用的锁定脚本是:

OP_HASH160 54c557e07dde5bb6cb791c7a540e0a4796f5e97e OP_EQUAL

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

P2SH地址

P2SH 的另一个重要特性是它可以将脚本哈希编译成地址(其定义参见 BIP0013)。P2SH 地址是具有 20 字节哈希的 Base58 编码脚本,如比特币地址是Base58编码的公钥有20个字节。由于P2SH地址以5为前缀,这导致Base58编码的地址以“3”开头。例如Mohammed的脚本,基于Base58编码的P2SH地址变为“39RF6JqABiHdYHkfChV6USGMe6Nsr66Gzw”。此时,Mohammed 可以将此地址发送给他的客户,他们可以使用任何比特币钱包进行简单的支付,就好像它是一个比特币地址。前缀为“3”这是对客户的一个提示,这是一种特殊类型的地址,对应于脚本而不是公钥,但它与比特币地址支付的效果相同。

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

P2SH的优势

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

赎回脚本和标准确认

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

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

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

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

P2SH 锁定脚本包含一个赎回脚本哈希,它不提供赎回脚本本身的描述。即使赎回脚本无效,P2SH 交易也被视为有效。你可能会不小心以某种方式锁定比特币,使其将来无法使用。