一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

散列消息认证码生成方法与流程

2022-10-26 15:19:49 来源:中国专利 TAG:


1.本公开涉及一种使用区块链事务生成消息的散列消息认证码(hmac)的方法。


背景技术:

2.区块链是指一种分布式数据结构形式,其中在点对点(p2p)网络中的多个节点中的每个节点处维护区块链副本。区块链包括一系列数据区块,其中每个区块包括一个或更多个事务(transaction)。每个事务都可以回指序列中的先前事务,其可以扩展一个或更多区块。事务可以通过提交到网络包括在新区块中。新区块的创建过程称为“挖掘”,该过程涉及多个挖掘节点中的每个挖掘节点争相执行“工作量证明”,即基于等待包括在区块中的未决事务池解决加密难题。
3.区块链中的事务通常用于传递数字资产,即用作价值储存手段的数据。但是也可利用区块链实现区块链上的分层附加功能。例如,区块链协议可允许在事务输出中存储附加用户数据。现代区块链在单一事务中可储存的最大数据容量在不断增加,从而能够并入更复杂的数据。例如,这可用于在区块链中存储电子文档,甚至音频或视频数据。
4.网络中的每个节点可以具有以下三个角色中的任何一个、两个或全部:转发、挖掘和存储。转发节点在整个网络节点中传播事务。挖掘节点将事务挖掘到区块中。存储节点各自对区块链中的已挖掘区块存储自己的副本。为了将事务记录在区块链中,一方将该事务发送到网络中的节点中的一个节点进行传播。接收该事务的挖掘节点可以争相将该事务挖掘到新区块中。每个节点被配置为遵守相同的节点协议,该协议将包括用于确认事务有效的一个或更多个条件。无效事务将不会传播或挖掘到区块中。假定事务已经核实有效,从而在区块链上被接受,则该事务(包括任何用户数据)将因此作为不可改变的公共记录,继续存储在p2p网络中的各个节点处。
5.成功解决工作量证明难题以创建最新区块的矿工通常被奖励一个称为“区块创始事务”的新事务,该事务会生成新的数字资产数额。工作量证明激励矿工不要欺骗系统,在他们的区块中包括双重花费事务,因为挖掘区块需要大量计算资源,而包括试图双重花费的区块很可能不会被其他节点接受。
6.在“基于输出的”模型(有时称为基于utxo的模型)中,给定事务的数据结构包括一个或更多个输入以及一个或更多个输出。任何可花费输出包括指定数字资产数额的元素,有时称为utxo(“未花费的事务输出”)。该输出还可以包括指定用于赎回该输出的条件的锁定脚本。每个输入包括指向先前事务中的此类输出的指针,并且还可以包括解锁脚本以用于解锁指向输出的锁定脚本。因此,考虑一对事务,将其称为第一事务和第二事务(或“目标”事务)。第一事务包括指定数字资产数额的至少一个输出,并且包括定义解锁该输出的一个或更多个条件的锁定脚本。第二事务(目标事务)包括至少一个输入和解锁脚本,该至少一个输入包括指向第一事务的输出的指针;该解锁脚本用于解锁第一事务的输出。
7.在此类模型中,当第二事务(目标事务)被发送到p2p网络以在区块链中传播和记录时,在每个节点处应用的有效性准则之一将是:解锁脚本满足在第一事务的锁定脚本中
定义的一个或更多个条件中的所有条件。另一条件将是:第一事务的输出尚未被另一早期有效事务赎回。根据这些条件中的任何一个条件发现目标事务无效的任何节点都不会传播该事务,也不会包括该事务以便挖掘到要记录在区块链中的区块中。
8.散列消息认证码(hmac)(有时也称为密钥散列消息认证码)是一种涉及加密散列函数和秘密加密密钥的消息认证码(mac)。
9.使用验证所接收消息完整性的消息认证算法来生成消息的hmac。假设第一方(例如,爱丽丝)想要向第二方(例如,鲍勃)发送消息。爱丽丝对消息进行加密,然后将加密后的消息与消息的hmac(可以用共享密钥签名)一起发送给鲍勃。如果鲍勃可以验证爱丽丝发送给他的hmac等同于hmac的本地计算,则他明白该消息在传输过程中没有被泄露,并且确实是爱丽丝发送的。
10.给定hmac密钥k
hmac
,密文消息(ciphertext message)的hmac被定义为
[0011][0012]
其中,h是散列函数或散列函数的某种组合。此外,opad和opad是以十六进制表示的常数,其长度取决于散列函数输入的长度(也称为区块大小)。介绍hmac的原始论文(m.bellare、r.canetti和h.krawczyk,"keying hash functions for message authentication",in annual international cryptology conference,1996,pp.1-15(“用于消息身份验证的密钥散列函数”,国际密码讨论年会,1996年,第1-15页)中定义了opad和ipad。ipad被定义为字节0x36,opad被定义为字节0x5c,这两者重复执行以匹配给定散列函数h的区块大小。例如,使用sha-256时,输入大小为512位,因此填充重复64次。opad和ipad是任意选择的,选择的唯一限制条件为它们不是相同的常数。包含这些填充是为了使hmac函数比其前身在加密方面更安全。


技术实现要素:

[0013]
区块链的一个主要安全特征是,在给定公钥的情况下计算私钥在计算上是不可行的。所述私钥用作控制区块链事务的输出的手段,难以绕过,并且可以链接到拥有所述私钥的一方的身份。正因为如此(即,难以仅从所述公钥获得私钥),给定事务的锁定输出可以仅由拥有私钥-公钥对的一方解锁。为了解锁使用某个公钥的散列值锁定的锁定脚本(也称为输出脚本),必须提供使用对应的私钥创建的签名。所述事务中与这些锁定脚本和解锁脚本对应的字段是采用脚本语言编写的。例如,一种特定的区块链协议使用一种称为“脚本”(大写s)的特定语言。
[0014]
通常,消息的hmac由发送方(例如,爱丽丝)计算并与消息本身一起发送给接收方(例如,鲍勃)。需要使用区块链(即,使用区块链的事务)来生成消息的hmac。这样可以将hmac永久、不可变地记录在区块链上,以供任何一方检查和验证。
[0015]
根据本文公开的一个方面,提供了一种使用区块链事务生成消息的散列消息认证码(hmac)的计算机实现的方法,其中所述方法由第一方执行并且包括:生成第一区块链事务的输出脚本,其中所述输出脚本包括hmac脚本,所述hmac脚本被配置为在与第二区块链事务的输入脚本一起执行时基于输入值生成所述消息的所述hmac,其中所述输入值包含在所述第二区块链事务的所述输入脚本中;以及使所述第一区块链事务传输到区块链网络的一个或更多个节点以使所述第一区块链事务包含在所述区块链中。
[0016]
所述第一方生成所述第一事务的所述输出脚本。所述第一方还可以生成所述第一事务;或者,所述第一方可以获取所述第一事务,即所述第一事务可以是事务模板,所述第一方可以向所述事务模板添加附加输出(在一些示例中,添加附加输入)。所述输出脚本(下文也称为锁定脚本)包括称为“hmac脚本”的脚本的一部分。应当注意的是,这仅仅是被配置为执行所定义函数的所述输出脚本的一部分的标签。所述输出脚本可以包括除所述hmac脚本之外的脚本的一个或更多个附加部分。所述第一方生成所述hmac脚本,使得当向所述hmac脚本提供来自第二(即,后一个)事务的输入脚本的输入时,所述hmac脚本将生成消息的hmac。然后,所述第一方将所述第一事务传输到所述区块链网络,或者将所述第一事务转发给一方以传输到所述区块链网络。应当注意的是,在生成并传输所述第一区块链时,所述第二事务尚未传输到所述区块链网络。
[0017]
所述第一方可以生成所述hmac脚本,使得所述hmac脚本被配置为需要特定输入(包含在所述第二事务的所述输入脚本中)以生成所述hmac。例如,所述hmac脚本可以被配置为要求所述输入是(秘密)hmac密钥。或者,可以要求所述输入是所述消息本身,即所述hmac脚本被配置为将任何消息作为输入并生成该消息的hmac。又或者,为了保护所述消息的隐私度,所述hmac脚本可以被配置为要求所述输入至少是所述消息的散列值。
[0018]
本发明在脚本中生成所述hmac,使得可以使用所述区块链事务的输出(锁定)和输入(解锁)字段来完成hmac函数的计算。所述脚本可以采用所述脚本语言编写,所述脚本语言由称为操作码的预定义函数组成。
[0019]
所述hmac的使用方式也可以类似于常规p2pkh脚本,在所述脚本中,必须提供来自私钥的签名才能解锁事务的输出。通过使用所述hmac,可以“锁定”输出,所述输出只能通过所述hmac的正确原像解锁。
附图说明
[0020]
为了帮助理解本公开的实施例并示出如何实施此类实施例,现将仅通过举例的方式参考附图进行说明,其中:
[0021]
图1是一种用于实现区块链的系统的示意性框图;
[0022]
图2示意性地示出了可记录在区块链中的事务的一些示例;
[0023]
图3是另一种用于实现区块链的系统的示意性框图;
[0024]
图4a是客户端应用程序的示意性框图;
[0025]
图4b是可由图4a的客户端应用程序表示的示例性用户界面的示意性模型;
[0026]
图5示出了用于处理事务的一些节点软件的示意性框图;
[0027]
图6示意性地示出了用于使用区块链的事务来生成消息的hmac的系统;
[0028]
图7示意性地示出了用于使用区块链的事务来生成公钥的系统;
[0029]
图8示意性地示出了分层确定性密钥集;
[0030]
图9示出了用于转换为二进制表示的示例性脚本;
[0031]
图10示出了用于执行点标量乘法的示例性脚本;
[0032]
图11示出了用于执行逆模计算的示例性脚本;
[0033]
图12示出了用于对两个不同的点执行点加法的示例性脚本;
[0034]
图13示出了用于对两个相同的点执行点加法的示例性脚本;
[0035]
图14示出了用于对两个点执行点加法的示例性脚本;以及
[0036]
图15示出了用于将数据转换为压缩密钥格式的示例性脚本。
具体实施方式
[0037]
示例性系统概述
[0038]
图1示出了一种用于实现区块链150的示例性系统100。系统100包括分组交换网络101,通常是诸如互联网的广域互联网。分组交换网络101包括多个节点104,该多个节点被设置成在分组交换网络101内形成点对点(p2p)覆盖网络106。每个节点104包括对等体的计算机设备,不同的节点104属于不同的对等体。每个节点104包括含一个或更多个处理器的处理装置,例如一个或更多个中央处理单元(cpu)、加速器处理器、特定应用程序处理器和/或现场可编程门阵列(fpga)。每个节点还包括存储器,即采用非暂时性计算机可读介质形式的计算机可读存储器。存储器可包括一个或更多个存储器单元,其采用一个或更多个存储器介质,例如诸如硬盘等的磁介质、诸如固态硬盘(ssd)、闪存或电可擦可编程只读存储器(eeprom)等的电子媒介和/或诸如光盘驱动器等的光学介质。
[0039]
区块链150包括一系列数据区块151,其中在p2p网络160中的多个节点中的每个节点处维护相应的区块链150副本。区块链中的每个区块151均包括一个或更多个事务152,其中该上下文中的事务是指一种数据结构。数据结构的性质将取决于用作事务模型或计划的一部分的事务协议类型。给定的区块链通常全程使用一个特定的事务协议。在一种常见的事务协议中,每个事务152的数据结构至少包括一个输入和至少一个输出。每个输出指定一个数额,该数额表示属于输出被加密锁定的用户103的数字资产值(需要该用户的签名进行解锁,从而进行赎回或花费)。每个输入指向先前事务152的输出,从而链接这些事务。
[0040]
节点104中的至少一些节点扮演转发节点104f的角色,这些节点转发并因此传播事务152。节点104中的至少一些节点扮演挖掘区块151的矿工104m的角色。节点104中的至少一些节点扮演存储节点104s(有时也称为“完整副本”节点)的角色,每个存储节点均在相应的存储器中存储相同区块链150的相应副本。每个矿工节点104m还维护等待挖掘到区块151中的事务152的池154。给定节点104可以是转发节点104、矿工104m、存储节点104s或其中两个节点或所有节点的任意组合。
[0041]
在给定的当前事务152j中,输入(或每个输入)包括指针,该指针引用事务序列中先前事务152i的输出,指定该输出将在当前事务152j中被赎回或“花费”。通常,当前事务可以是池154或任何区块151中的任何事务。尽管为了确保当前事务有效,将需要存在先前事务152i并核实其有效,但是在创建当前事务152j甚至向网络106发送当前事务152j时,不必存在先前事务152i。因此,在本文中,“先前”是指由指针链接的逻辑序列中的前任,而不一定是时间序列中的创建时间或发送时间,因此,不一定排除无序创建或发送事务152i、152j的情况(参见下面关于孤立事务的讨论)。先前事务152i同样可以称为先行事务或前任事务。
[0042]
当前事务152j的输入还包括先前事务152i的输出被锁定到的用户103a的签名。反过来,当前事务152j的输出可以加密锁定到新用户103b。因此,当前事务152j可将先前事务152i的输入中定义的数额转移到当前事务152j的输出中定义的新用户103b。在某些情况下,事务152可具有多个输出,以在多个用户间分割输入数额(其中一个可以是原始用户
103a,以便进行变更)。在某些情况下,一事务还可以具有多个输入,以将一个或更多个先前事务的多个输出中的数额汇总在一起,并重新分配到当前事务的一个或更多个输出。
[0043]
上述可称为“基于输出的”事务协议,有时也称为未花费的事务输出(utxo)的协议(其中输出称为utxo)。用户的总余额不是用区块链中存储的任何一个数字定义的;相反,用户需要特殊“钱包”应用程序105,以整理该用户的所有utxo值,这些utxo值分散在区块链151的许多不同事务152中。
[0044]
作为基于账户的事务模型的一部分,另一种类型的事务协议可称为“基于账户的”协议。在基于账户的情况下,每个事务均不通过参考过去事务序列中先前事务的utxo来定义转移的数额,而是通过参考绝对账户余额进行定义。所有账户的当前状态由矿工单独存储到区块链中,并不断更新。在此类系统中,事务使用账户的运行事务记录(也称为“头寸”)进行排序。该值由发送者签名作为其加密签名的一部分,并作为事务引用计算的一部分进行哈希处理。此外,可选的数据字段也可以在事务中签名。例如,如果数据字段中包含先前事务的id,则该数据字段可指向先前事务。
[0045]
无论采用何种类型的事务协议,当用户103希望执行新事务152j时,其希望将新事务从其计算机终端102发送至p2p核实网络106的节点104中的一个(现在通常是服务器或数据中心,但原则上可以是其他用户终端)。此节点104根据在节点104中的每个节点处应用的节点协议检查事务是否有效。节点协议的详细信息将与相关区块链150中使用的事务协议类型相对应,一起形成整个事务模型。节点协议通常要求节点104检查新事务152j中的加密签名是否与预期签名相匹配,这取决于事务152的有序序列中的先前事务152i。在基于输出的情况下,这可包括检查新事务152j的输入中包含的用户加密签名是否与新事务花费的先前事务152i的输出中定义的条件相匹配,其中该条件通常包括至少检查新事务152j的输入中的加密签名是否解锁新事务的输入所指向的先前事务152i的输出。在一些事务协议中,条件可至少部分地由输入和/或输出中包含的自定义脚本定义。或者,这可仅由节点协议单独确定,或可通过其组合确定。无论采用哪种方式,如果新事务152j有效,当前节点会将其转发到p2p网络106中的一个或更多个其他节点104。这些节点104中的至少一些节点还作为转发节点104f,根据相同的节点协议应用相同的测试,从而将新事务152j转发到一个或更多个进一步的节点104,依此类推。通过这种方式,新事务在节点104的整个网络中进行传播。
[0046]
在基于输出的模型中,给定输出(例如,utxo)是否花费的定义是,根据节点协议,其是否通过另一个随后事务152j的输入有效赎回。事务有效的另一个条件是其试图花费或赎回的先前事务152i的输出尚未被另一个有效事务花费/赎回。同样,如果无效,事务152j将不会在区块链中传播或记录。这可防止重复花费,即花费者对同一个事务的输出花费超过一次。另一方面,基于账户的模型通过保持账户余额防止重复花费。因为同样存在定义的事务顺序,账户余额在任何时候均具有单一定义的状态。
[0047]
除核实之外,节点104m中的至少一些节点在称为挖矿的过程中争先创建事务区块,该过程以“工作量证明”为基础。在挖矿节点104m处,将新事务添加到区块中尚未出现的有效事务的池中。然后,矿工争相通过尝试解决加密难题来组装事务池154中事务152的新的有效区块151。通常情况下,这包括搜索“随机数”值,从而当随机数与事务池154并置且进行哈希处理时,哈希值的输出满足预定条件。例如,预定条件可以是哈希值的输出具有某个
预定义的前导零数。哈希函数的特性是,相对于其输入,其具有不可预测的输出。因此,该搜索只能通过强力执行,从而在试图解决难题的每个节点104m处消耗大量的处理资源。
[0048]
解决难题的第一矿工节点104m在网络106上宣布难题解决,提供解决方案作为证明,然后网络中的其他节点104则可以轻松检查该解决方案(一旦给出哈希值的解决方案,就可以直接检查该解决方案是否使哈希值的输出满足条件)。基于已在每个此类节点处检查获胜者的已宣布解决方案,获胜者已为其解决该难题的事务池154之后由充当存储节点104s的节点104中的至少一些节点记录在区块链150中作为新区块151。区块指针155还分配给指向区块链中先前创建的区块151n-1的新区块151n。工作量证明有助于降低重复花费的风险,因为创建新区块151需要大量工作,并且由于包含重复花费的任何区块都可能被其他节点104拒绝,因此挖矿节点104m受到激励,不允许在其区块中包含双重花费。一旦创建,则不可修改区块151,因为其根据相同的协议在p2p网络106中的存储节点104s中的每个存储节点进行识别和维护。区块指针155还向区块151施加顺序。由于事务152记录在p2p网络106中每个存储节点104s处的有序区块中,因此提供了事务的不可变公共分类账。
[0049]
应当注意的是,在任何给定时间争相解决难题的不同矿工104m可能会根据任何给定时间的未挖掘事务池154的不同快照执行该操作,具体取决于他们何时开始搜索解决方案。解决相应难题的人员首先定义新区块151n中包含的事务152,并更新当前未挖掘事务池154。然后,矿工104m继续争相从新定义的未完成池154中创建区块,依此类推。此外,还存在解决可能出现的任何“分叉”的协议,其中两名矿工104m彼此在很短的时间内解决难题,从而传播区块链的冲突视图。简言之,分叉方向最长的成为最终区块链150。
[0050]
在大部分区块链中,获胜矿工104m会自动获得特殊类型的新事务作为奖励,该新事务创建新的数字资产值(与将数字资产数额从一个用户转移至另一个用户的正常事务截然相反)。因此,获胜节点被视为已“挖掘”一定数量的数字资产。这种特殊类型的事务有时称为“生成”事务,其自动形成新区块151n的一部分。该奖励可激励矿工104m争相参与工作量证明。通常情况下,常规(非生成)事务152还将在其输出中的一个输出中指定附加事务费用,以进一步奖励创建其中包含事务的区块151n的获胜矿工104m。
[0051]
由于挖掘中涉及的计算资源,通常至少矿工节点104m中的每个矿工节点采用服务器的形式,该服务器包括一个或更多个物理服务器单元,甚至整个数据中心。每个转发节点104m和/或存储节点104s还可采取服务器或数据中心的形式。但是,原则上来说,任何给定节点104均可采用一个用户终端或联网在一起的一组用户终端的形式。
[0052]
每个节点104的存储器均存储被配置为在节点104的处理装置上运行的软件,以根据节点协议执行其相应的角色并处理事务152。应当理解的是,在本文中归因于节点104的任何动作均可通过在相应计算机设备的处理装置上运行的软件执行。节点软件可以在应用层的一个或更多个应用中实现,或者在诸如操作系统层或协议层的较低层中实现,或者在这些层的任何组合中实现。此外,在本文中使用的“区块链”一词是指一般技术类型的通用术语,不限于任何特定专有区块链、协议或服务。
[0053]
扮演消费用户角色的多方103中的每一方的计算机设备102也连接到网络101。他们充当事务中的支付者和收受者,但不一定代表其他方参与挖掘或传播事务。他们不一定运行挖矿协议。出于说明目的,示出了双方103及其相应的设备102:第一方103a及其相应的计算机设备102a,以及第二方103b及其相应的计算机设备102b。应当理解的是,更多此类当
事方103及其相应的计算机设备102可能存在并参与系统,但为了方便起见,未进行说明。每一方103均可以是个人或组织。仅出于说明目的,在本文中,第一方103a称为爱丽丝(alice),第二方103b称为鲍勃(bob),但应当理解的是,这并不仅限于爱丽丝或鲍勃,且本文对爱丽丝或鲍勃的任何引用均可分别用“第一方”和“第二方”替换。
[0054]
每一方103的计算机设备102包括相应的处理装置,其包括一个或更多个处理器,例如一个或更多个cpu、图形处理单元(gpu)、其他加速器处理器、特定应用程序处理器和/或fpga。每一方103的计算机设备102还包括存储器,即采用非暂时性计算机可读介质形式的计算机可读存储器。该存储器可包括一个或更多个存储器单元,其采用一个或更多个存储器介质,例如诸如硬盘等磁介质、诸如ssd、闪存或eeprom等电子媒介和/或诸如光盘驱动器等的光学介质。每一方103的计算机设备102上的存储器存储软件,其包括被设置为在处理装置上运行的至少一个客户端应用程序105的相应实例。应当理解的是,在本文中归因于给定方103的任何行动均可通过在相应计算机设备102的处理装置上运行的软件执行。每一方103的计算机设备102包括至少一个用户终端,例如台式或笔记本电脑、平板电脑、智能手机或诸如智能手表等的可穿戴设备。给定方103的计算机设备102还可包括一个或更多个其他网络资源,诸如通过用户终端访问的云计算资源。
[0055]
客户端应用程序105最初可通过例如从服务器下载的适当计算机可读存储介质,或通过诸如可移动ssd、闪存密钥、可移动eeprom、可移动磁盘驱动器、软盘或磁带等的可移动存储设备、诸如cd或dvd rom等的光盘或可移动光驱等提供至任何给定方103的计算机设备102。
[0056]
客户端应用程序105至少包括“钱包”功能。这有两个主要功能。其中一个功能是使相应的用户方103创建、签名和发送拟在节点104的整个网络中传播的事务152,并因此包含在区块链150中。另一个功能是向相应方汇报其目前拥有的数字资产数额。在基于输出的系统中,该第二功能包括整理分散在区块链150中属于相关方的各种事务152的输出中定义的数额。
[0057]
注意:虽然各种客户端功能可以描述为集成到给定客户端应用105中,但这不一定是限制性的,相反,在本文中所描述的任何客户端功能可以在由两个或更多个不同应用组成的套件中实现,例如经由api进行接口连接或一个应用作为另一个应用的插件。更通俗地说,客户端功能可以在应用层或诸如操作系统的较低层或这些层的任意组合实现。下面将根据客户端应用105进行描述,但应当理解的是,这不是限制性的。
[0058]
每个计算机设备102上的客户端应用程序或软件105的实例可操作地耦合到p2p网络106的转发节点104f中的至少一个转发节点。这可以启用客户端105的钱包功能,以将事务152发送至网络106。客户端105还可联系一个、一些或所有存储节点104,以在区块链150中查询相应方103作为接收者的任何事务(或实际上在区块链150中检查其他方的事务,因为在实施例中,区块链150是在某种程度上通过其公开可见性提供事务信任的公共设施)。每个计算机设备102上的钱包功能被配置为根据事务协议制定和发送事务152。每个节点104运行软件,其被配置为根据节点协议核实事务152有效的软件,并且在转发节点104f的情况下转发事务152,以在整个网络106中传播此类事务。事务协议和节点协议相互对应,给定事务协议和给定节点协议一起实现给定的事务模型。区块链150中的所有事务152均采用相同的事务协议(尽管事务协议可允许其内存在不同的事务子类型)。网络106中的所有节
点104采用相同的节点协议(尽管其可根据针对该子类型定义的规则区分处理不同的事务子类型,并且不同的节点还可扮演不同的角色,从而实现协议的不同对应方面)。
[0059]
如上所述,区块链150包括一系列区块151,其中每个区块151包括通过如前所述的工作量证明过程创建的一个或更多个事务152的集合。每个区块151还包括区块指针155,其指向区块链中先前创建的区块151,以定义区块151的顺序。区块链150还包括有效事务池154,其等待通过工作量证明过程包含在新的区块中。每个事务152(除了一生成事务)包括指向先前事务的指针,以定义事务序列的顺序(注:事务152的序列可进行分支)。区块151的区块链一直追溯到创始区块(gb)153,该创始区块是区块链中的第一区块。区块链150中早期的一个或更多个原始事务152指向创始区块153,而非先前事务。
[0060]
当给定方103(比方说爱丽丝)希望发送拟包含在区块链150中的新事务152j时,她将根据相关事务协议(使用其客户端应用程序105中的钱包功能)制定新事务。然后,她将事务152从客户端应用程序105发送至其连接的一个或更多个转发节点104f中的一个。例如,这可以是与爱丽丝的计算机102最近或最佳连接的转发节点104f。当任何给定节点104接收新事务152j时,其将根据节点协议及其相应的角色进行处理。这包括首先检查新接收的事务152j是否满足变为“有效”的特定条件,具体示例稍后将详细讨论。在一些事务协议中,有效条件可通过事务152中包含的脚本在每个事务的基础上进行配置。或者,条件可仅仅是节点协议的内置功能,或通过组合脚本和节点协议进行定义。
[0061]
如果新接收的事务152j通过有效性测试(即:“有效”的条件下),接收事务152j的任何存储节点104s将向在该节点104s处维护的区块链150的副本中的池154中添加新有效事务152。进一步地,接收事务152j的任何转发节点104f随后将有效事务152传播至p2p网络106中的一个或更多个其他节点104。由于每个转发节点104f应用相同的协议,因此假定事务152j有效,这意味着事务很快将在整个p2p网络106中传播。
[0062]
一旦进入在一个或更多个存储节点104处维护的区块链150的副本中的池154中,矿工节点104m将开始竞相解决包括新事务152的池154的最新版本方面的工作量证明难题(其他矿工104m可继续尝试基于池154的旧视角解决难题,但首先解决难题的矿工将定义下一个新区块151的结束位置和新池154的开始位置,最终将有人解决包括爱丽丝的事务152j的池154的一部分的难题)。一旦包括新事务152j的池154完成工作量证明,其将不可变地成为区块链150中区块151中的一个区块的一部分。每个事务152包括指向早前事务的指针,因此事务的顺序也被不可变地记录下来。
[0063]
不同的节点104可以首先接收给定事务的不同实例,并且因此在一个实例被挖掘到区块150中之前具有关于哪个实例“有效”的冲突视图,此时所有节点104同意所挖掘的实例是唯一的有效实例。如果节点104接受一个实例为有效实例,然后发现第二实例已记录在区块链150中,则该节点104必须接受这一点,并将丢弃(即视为无效)其最初接受的未挖掘实例。
[0064]
基于utxo的模型
[0065]
图2示出了示例性事务协议。这是基于utxo的协议的示例。事务152(简称“tx”)是区块链150的基本数据结构(每个区块151包括一个或更多个事务152)。下面将通过参考基于输出或基于“utxo”的协议进行描述。但这并不限于所有可能的实施例。
[0066]
在基于utxo的模型中,每个事务(“tx”)152包括数据结构,其包括一个或更多个输
入202和一个或更多个输出203。每个输出203可包括未花费的事务输出(utxo),其可用作另一新事务的输入202的来源(如果utxo尚未赎回)。utxo指定数字资产数额。它还可包含其来源事务的事务id以及其他信息。事务数据结构还可包括头部201,其可包括输入字段202和输出字段203的大小指示符。头部201还可包括事务的id。在实施例中,事务id是事务数据(不含事务id本身)的哈希值,且存储在提交至矿工104m的原始事务152的头部201中。
[0067]
比方说,爱丽丝103a希望创建转移相关数字资产数额至鲍勃103b的事务152j。在图2中,爱丽丝的新事务152j标记为“tx
1”。该新事务获取在序列中先前事务152i的输出203中锁定至爱丽丝的数字资产数额,并至少将此类数额中的一部分转移至鲍勃。在图2中,先前事务152i标记为“tx
0”。tx0和tx1只是任意的标记,其不一定意味着tx0指区块链151中的第一事务且tx1指池154中的下一个事务。tx1可指向仍具有锁定至爱丽丝的未花费输出203的任何先前(即先行)事务。
[0068]
当爱丽丝创建其新事务tx1时,或至少在她将该新事务发送至网络106时,先前事务tx0可能已经有效并包括在区块链150中。该事务此时可能已包括在区块151中的一个区块中,或者可能仍在池154中等待,在这种情况下,该事务将很快包括在新区块151中。或者,tx0和tx1可以创建并一起发送至网络102;或者,如果节点协议允许缓冲“孤立”事务,tx0甚至可以在tx1之后发送。本文事务序列上下文中使用的“先前”和“后续”一词是指由事务中指定的事务指针定义的序列中的事务顺序(哪个事务指向哪个其他事务等等)。它们同样可以替换为“前任”和“继任”、“先行”和“后代”或“父项”和“子项”等。这不一定指其创建、发送至网络106或到达任何给定节点104的顺序。然而,指向先前事务(先行事务或“父事务”)的后续事务(后代事务或“子事务”)不会有效除非父事务有效。在父事务之前到达节点104的子事务被视为孤立事务。根据节点协议和/或矿工行为,其可被丢弃或缓冲一段时间,以等待父事务。
[0069]
先前事务tx0的一个或更多个输出203中的一个包括特定的utxo,标记为utxo0。每个utxo包括指定utxo表示的数字资产数额的值以及锁定脚本,该锁定脚本定义后续事务的输入202中的解锁脚本必须满足的条件,以使后续事务有效,从而成功赎回utxo。通常情况下,锁定脚本将数额锁定至特定方(该数额的事务的受益人)。即,锁定脚本定义解锁条件,该解锁条件通常包括以下条件:后续事务的输入中的解锁脚本包括先前事务被锁定到的一方的加密签名。
[0070]
锁定脚本(亦称scriptpubkey)是节点协议识别的域特定语言中写入的一段代码。此类语言的特定示例称为“脚本(script)”(s大写)。锁定脚本指定花费事务输出203所需的信息,例如爱丽丝签名的要求。解锁脚本出现在事务的输出中。解锁脚本(亦称scriptsig)是提供满足锁定脚本准则所需信息的域特定语言中写入的一段代码。例如,其可包含鲍勃的签名。解锁脚本出现在事务的输入202中。
[0071]
因此在示出的示例中,tx0的输出203中的utxo0包括锁定脚本[checksig pa],该锁定脚本需要爱丽丝的签名sig pa,以赎回utxo0(严格来说,是为了使试图赎回utxo0的后续事务有效)。[checksig pa]包含爱丽丝的公私密钥对中的公钥pa。tx1的输入202包括向回指向tx1的指针(例如,通过其事务id(txid0),其在实施例中是整个事务tx0的哈希值)。tx1的输入202包括在tx0中标识utxo0的索引,以在tx0的任何其他可能输出中对其进行标识。tx1的输入202进一步包括解锁脚本《sig pa》,该解锁脚本包括爱丽丝的加密签名,该签名由爱
丽丝通过将其密钥对中的私钥应用于预定的部分数据(有时在密码学中称为“消息”)创建。爱丽丝需要签名以提供有效签名的数据(或“消息”)可通过锁定脚本、节点协议或其组合进行定义。
[0072]
当新事务tx1到达节点104时,该节点应用节点协议。这包括一起运行锁定脚本和解锁脚本,以检查解锁脚本是否满足锁定脚本中定义的条件(其中该条件可包括一个或更多个准则)。在实施例中,这涉及并置两个脚本:
[0073]
《sig pa》《pa》||[checksig pa]
[0074]
其中“||”表示并置,“《

》”表示将数据放在堆栈上,“[

]”表示由解锁脚本组成的函数(在该示例中指基于堆栈的语言)。同样,脚本可以使用公共堆栈一个接一个地运行,而不是并置脚本。无论采用哪种方式,当一起运行时,脚本使用爱丽丝的公钥pa(包括在tx0的输出的锁定脚本中),以认证tx1的输入中的锁定脚本是否包含爱丽丝签名预期部分的数据时的签名。预期的部分数据本身(“消息”)也需要包括在tx0中,以便执行此认证。在实施例中,签名的数据包括整个tx0(因此不需要包括一个单独的元素来明文指定签名的部分数据,因为其本身便已存在)。
[0075]
本领域技术人员将熟悉通过公私密码进行认证的细节。基本上而言,如果爱丽丝已通过使用其私钥加密签署消息,则给定爱丽丝的公钥和明文中的消息(未加密消息),诸如节点104等其他实体可认证加密版本的消息必须已经由爱丽丝签名。签署通常包括对消息进行散列,签署哈希值和将此标记到消息的明文版本作为签名,从而使公钥的任何持有者能够认证签名。因此,应当注意的是,在实施例中,在本文中对签名特定数据片段或事务部分等的任何引用可以意味着对该数据片段或事务部分的哈希值进行签名。
[0076]
如果tx1中的解锁脚本满足tx0的锁定脚本中指定的一个或更多个条件(因此,在所示示例中,如果在tx1中提供了爱丽丝的签名并进行认证),则节点104认为tx1有效。如果是挖矿节点104m,这意味着其将添加至等待工作量证明的事务154池。如果是转发节点104f,则其将事务tx1转发到网络106中的一个或更多个其他节点104,从而将在整个网络中传播。一旦tx1有效并包括在区块链150中,这将把tx0中的utxo0定义为已花费。请注意,tx1仅在花费未花费的事务输出203时才有效。如果试图花费另一事务152已经花费的输出,则即使满足所有其他条件,tx1也将无效。因此,节点104还需要检查先前事务tx0中引用的utxo是否已经花费(已经形成另一有效事务的有效输入)。这是为何区块链150对事务152施加定义的顺序很重要的原因之一。在实践中,给定节点104可维护单独的数据库,标记已花费事务152的utxo 203,但最终定义utxo是否已花费取决于是否在区块链150中形成了另一有效事务的有效输入。
[0077]
如果给定事务152的所有输出203中指定的总数额大于其所有输入202所指向的总数额,则这是大多数事务模型中的另一失效依据。因此,此类事务将不会传播或挖掘到区块151中。
[0078]
请注意,在基于utxo的事务模型中,给定utxo需要作为一个整体使用。不能“留下”utxo中定义为已花费的一部分数额,而同时又花费另一部分。但utxo的数额可以在下一个事务的多个输出之间分割。例如,tx0的utxo0中定义的数额可以在tx1中的多个utxo之间分割。因此,如果爱丽丝不想将utxo0中定义的所有数额都给鲍勃,她可以使用剩余部分在tx1的第二输出中自己找零,或者支付给另一方。
[0079]
在实践中,爱丽丝通常还将需要包括获胜矿工的费用,因为现在仅靠区块创始事务的奖励币通常不足以激励挖掘。如果爱丽丝未包括矿工的费用,tx0可能会被矿工节点104m拒绝,因此,尽管技术上有效,但仍然不会传播并包括在区块链150中(如果矿工104m不愿意,矿工协议不会强制他们接受事务152)。在一些协议中,挖掘费不需要其自身的单独输出203(即不需要单独的utxo)。相反,给定事务152中输入202所指向的总数额与输出203所指定的总数额之间的任何差额都将自动提供给获胜矿工104。例如,假设指向utxo0的指针是tx1的唯一输入,而tx1只有一个输出utxo1。如果utxo0中指定的数字资产的数额大于utxo1中指定的数额,则该差额将自动提供给获胜矿工104m。替代地或附加地,这不一定排除可以在其自身事务152的其中一个utxo 203中明确指定矿工费用。
[0080]
爱丽丝和鲍勃的数字资产由区块链150中任何位置的任何事务152中的锁定至他们的未花费utxo组成。因此,通常情况下,给定方103的资产分散在整个区块链150的各种事务152的utxo中。区块链150中的任何位置均未存储定义给定方103的总余额的一个数字。客户端应用程序105的钱包功能的作用是将锁定至相应方且在其他随后事务中尚未花费的各种utxo值整理在一起。通过查询在任何存储节点104s(例如,与相应方的计算机设备102最近或最佳连接的存储节点104s)处存储的区块链150副本,可以实现这一点。
[0081]
请注意,脚本代码通常用示意图表示(即非精确语言)。例如,可写入[checksig pa]表示[checksig pa]=op_dup op_hash160《h(pa)》op_equalverify op_checksig。“op_...”是指脚本语言的特定操作码。op_checksig(又称“checksig”)是脚本操作码,其取两个输入(签名和公钥),并使用椭圆曲线数字签名算法(ecdsa)验证签名的有效性。在运行时,移除脚本中任何出现的签名(

sig’),但在由

sig’输入验证的事务中仍保留附加要求,诸如哈希难题。再如,op_return是脚本语言操作码,用于创建事务的不可花费输出,其可以将元数据储存在事务中,从而将元数据不可变地记录在区块链150中。例如,元数据可包括需存储在区块链中的文件。
[0082]
签名pa是数字签名。在实施例中,这基于使用椭圆曲线secp256k1的ecdsa。数字签名对特定的数据段进行签名。在实施例中,对于给定事务,签名将对部分事务输入以及全部或部分事务输出进行签名。对输出的特定部分进行签名取决于sighash标志。sighash标志是包含在签名末尾的4字节代码,用于选择签名的输出(并因此在签名时固定)。
[0083]
锁定脚本有时称为“scriptpubkey”,指其包括相应事务被锁定到的当事方的公钥。解锁脚本有时称为“scriptsig”,指其提供相应的签名。但是更通俗地说,在区块链150的所有应用中,utxo赎回的条件并不一定包括对签名进行认证。更通俗地说,脚本语言可用于定义任何一个或更多个条件。因此,可以优选更为通用的术语“锁定脚本”和“解锁脚本”。
[0084]
可选的侧信道
[0085]
图3示出了用于实现区块链150的另一系统100。除了附加的通信功能外,该系统100与图1所示的内容基本相同。爱丽丝和鲍勃的每台计算机设备102a、120b上的客户端应用程序分别包括附加通信功能。也就是说,这可使爱丽丝103a建立与鲍勃103b分离的侧信道301(在任何一方或第三方的鼓动下)。侧信道301能够独立于p2p网络实现数据交换。此等通信有时候被称为“链下”通信。比如,当交换爱丽丝与鲍勃之间的事务152时不想将该事务(仍未)发布到p2p网络106或挖掘到区块150,可以采用此等通信,直到其中一方选择将该事务广播到网络106。替代地或附加地,该侧信道301可以用于交换任何其他的事务相关数据,
例如密钥、协商的数额或条款、数据内容、等等。
[0086]
通过与p2p覆盖网络106相同的分组交换网络101可建立侧信道301。此外/或者,通过诸如移动蜂窝网络等不同网络、或者诸如本地无线网络等局域网、或者甚至爱丽丝和鲍勃的设备102a、102b之间的直接有线或无线连接可以建立侧信道301。一般而言,本文所指的侧信道301可包括经由一种或更多种联网技术或者通信介质的任何一个或更多个链路,用于“链下”(即独立于p2p覆盖网络106)交换数据。在多个链路被使用的情况下,整个链下链路的捆绑或集合才可以被称为侧信道301。因此,需要注意的是,虽然爱丽丝和鲍勃通过侧信道301对特定的信息或数据片段或者诸如此类进行交换,但这并不一定意味着所有这些数据片段必须通过相同的链路或甚至同一类型网络进行发送。
[0087]
客户端软件
[0088]
图4a示出了用于实现本公开方案的实施例的客户端应用程序105的示例性实施方式。客户端应用程序105包括事务引擎401和用户界面(ui)层402。根据上文讨论的方案以及稍后将进一步详细讨论的内容,事务引擎401被配置为实现客户端105的基础事务相关功能,诸如制定事务152,通过侧信道301接收和/或发送事务和/或其他数据,和/或发送事务以通过p2p网络106传播。根据本文公开的实施例,每个客户端105的事务引擎401包括函数403,函数403被配置为生成事务的输出脚本,其中输出脚本包括hmac脚本。例如,函数403可以被配置为基于一个或更多个用户输入(诸如hmac密钥或消息)生成hmac脚本,以包括一个或更多个用户输入。
[0089]
该ui层402被配置为通过相应用户的计算机设备102的用户输入/输出(i/o)方式呈现用户界面,包括通过设备102的用户输出方式向相应用户103输出信息,和通过设备102的用户输入方式接收来自相应用户103的输入。例如,用户输出方式可包括提供视觉输出的一个或显示多个屏(触摸或非触摸屏)、提供音频输出的一个或更多个扬声器、和/或提供触觉输出的一个或更多个触觉输出设备等。用户输入方式可包括例如一个或更多个触摸屏的输入阵列(可与用于输出方式的那个/那些相同或不同);一个或更多个基于光标的设备,诸如鼠标、轨迹板或轨迹球;一个或更多个麦克风和语音或声音识别算法,用于接收语音或声音输入;一个或更多个基于手势的输入设备,用于接收手动或身体手势形式的输入;或者一个或更多个机械按钮、开关或控制杆等。
[0090]
注:虽然本文中的各种功能可以被描述为集成到同一客户端应用程序105中,但这并不一定构成限制,相反,它们可以在两个或更多个不同应用程序组成的一套程序中实现,例如一个应用程序作为另一个应用程序的插件或经由api(应用程序编程接口)进行接口。比如,事务引擎401的功能可以在单独的应用程序中实现,而不是在ui层402中实现,或者诸如事务引擎401的给定模块的功能可以在多个应用程序之间分割。同时,也不排除部分或全部描述的功能可以在比如操作系统层实现。在本文任何位置引用单个或给定应用程序105或诸如此类的情况下,应当理解的是这只是作为示例,并且更通俗地说,所描述的功能可以在任何形式的软件中实现。
[0091]
图4b给出了用户界面(ui)400的示例的模型,该ui可由客户端应用程序105a的ui层402在爱丽丝的设备102a上呈现。应当理解的是,类似的ui可以由客户端105b在鲍勃的设备102b或任何其他方的设备上呈现。
[0092]
通过图示的方式,图4b从爱丽丝的角度示出了ui 400。ui 400可包括一个或更多
个ui元素411、412、413,该一个或更多个ui元素通过用户输出方式呈现为不同的ui元素。
[0093]
例如,ui元素可包括一个或更多个用户可选择的元素411,这些元素可以是屏幕上的不同按钮、菜单中的不同选项或者诸如此类。用户输入方式被设置成使用户103(在这种情况下为爱丽丝103a)能够选择或以其它方式操作其中一个选项,诸如通过点击或触摸屏幕上的ui元素,或者说出所需选项的名称(注:本文使用的“手动”一词仅用于与自动进行对比,而不一定限于用手执行操作)。这些选项使用户(爱丽丝)能够指定hmac脚本的要求,例如,hmac脚本被配置为需求一输入,以生成该hmac。
[0094]
替代地或附加地,ui元素可以包括一个或更多个数据输入字段412,通过数据输入字段412,用户可以(例如)手动输入hmac脚本或手动输入hmac脚本的部分,例如密文。这些数据进入字段通过用户输出方式呈现,例如屏幕上,并且数据可通过用户输入方式进入到字段中,例如键盘或触摸屏。或者,数据可以例如基于语音识别口头地接收。
[0095]
替代地或附加地,ui元素可包括向用户输出信息的一个或更多个信息元素413。例如,这/这些可以在屏幕上呈现或可听见。
[0096]
应当理解的是,呈现各种ui元素、选择选项和输入数据的特定方式并不重要。这些ui元素的功能稍后将进行更详细地讨论。还应当理解的是,图4b中示出的ui 400只是一个图示模型,在实践中,它可包括一个或更多个进一步的ui元素,为了简洁起见,未对其进行说明。
[0097]
节点软件
[0098]
图5示出了在基于utxo或基于输出的模型的示例中,在p2p网络106的每个节点104上运行的节点软件500的示例。节点软件500包括协议引擎501、脚本引擎502、堆栈503、应用级决策引擎504以及一个或更多个区块链相关功能模块的集合505。在任何给定节点104处,这些模块可以包括以下三个模块中的任何一个、两个或全部:挖掘模块505m、转发模块505f和存储模块505s(取决于该节点的一个或更多个角色)。协议引擎501被配置为识别事务152的不同字段,并根据节点协议处理此类字段。当接收到具有指向另一先前事务152i(tx
m-1
)的输出(例如,utxo)的输入的事务152j(txj)时,协议引擎501标识txj中的解锁脚本并将其传递给脚本引擎502。协议引擎501还基于txj的输入中的指针来标识和检索txi。如果txi尚未在区块链150上,则可以从相应节点自身的未决事务池154中检索txi;或者,如果txi已在区块链150上,则可以从存储在相应节点或另一节点104处的区块链150中的区块151的副本中检索。无论采用哪种方式,脚本引擎502都会标识txi的指向输出中的锁定脚本,并将其传递给脚本引擎502。
[0099]
因此,脚本引擎502具有txi的锁定脚本和来自txj的相应输入的解锁脚本。例如,图2中示出的标记为的tx0和tx1的事务,但同样可以应用于任何事务对。如前所述,脚本引擎502同时运行两个脚本,这将包括根据正在使用的基于堆栈的脚本语言(例如,脚本)将数据放置到堆栈503上并从该堆栈中检索数据。
[0100]
通过同时运行脚本,脚本引擎502确定解锁脚本是否满足锁定脚本中定义的一个或更多个标准,即解锁脚本是否对包括锁定脚本的输出进行解锁?脚本引擎502将该确定的结果返回给协议引擎501。如果脚本引擎502确定解锁脚本确实满足在相应的锁定脚本中指定的一个或更多个标准,则返回结果“true”。否则,返回结果“false”。
[0101]
在基于输出的模型中,来自脚本引擎502的结果“true”是事务有效性的条件之一。
通常,还必须满足由协议引擎501评估的一个或更多个进一步协议级条件;例如,txj的输出中所指向的数字资产的总数额不超过其输入指定的总数额,并且txi的指向输出尚未被另一有效事务花费。协议引擎501评估来自脚本引擎502的结果以及一个或更多个协议级条件,并且只有当它们都为true时,协议引擎501才核实事务txj有效。协议引擎501将事务是否有效的指示输出到应用级决策引擎504。只有在txj确实核实有效的条件下,决策引擎504才可以选择控制挖掘模块505m和转发模块505f中的一个或两个来执行它们涉及txj的相应区块链相关函数。这可以包括:挖掘模块505m,该挖掘模块将txj添加到节点的相应池154以挖掘到区块151中;和/或转发模块505f,该转发模块将txj转发到p2p网络106中的另一节点104。然而,应当注意的是,在实施例中,虽然决策引擎504不会选择转发或挖掘无效事务,相反,这并不一定意味着,仅因为事务有效,该决策引擎就必须触发该事务的挖掘或转发。可选地,在实施例中,应用级决策引擎504可以在触发这些函数中的一个或两个函数之前应用一个或更多个附加条件。例如,如果节点是挖掘节点104m,则决策引擎可以仅在事务有效且预留足够挖掘费用的条件下选择挖掘该事务。
[0102]
此外,还应当注意的是,在本文中,术语“true”和“false”不一定限于返回仅以单个二进制数(位)形式表示的结果,尽管这确实是一种可能的实现方式。更通俗地说,“true”可以指指示成功或肯定结果的任何状态,而“false”可以指指示不成功或不肯定结果的任何状态。例如,在基于账户的模型(图5中未示出)中,可以通过节点104对签名的隐式协议级核实和智能合约的附加肯定输出的组合来指示结果为“true”(如果两个单独的结果均为true,则认为总体结果为true)。
[0103]
脚本中的hmac
[0104]
图6示意性地示出了用于使用区块链150的事务来生成消息的hmac的系统。该系统包括第一方(爱丽丝)103a和第二方(鲍勃)103b以及他们的相应计算机设备102a和102b(未示出)。应当注意的是,描述为由爱丽丝103a或鲍勃103b执行的动作是指由爱丽丝或鲍勃的相应计算机设备执行的动作。爱丽丝103a生成第一区块链事务tx1的输出脚本。输出脚本包括hmac脚本。hmac脚本是输出脚本的一部分,该输出脚本被配置为执行特定函数(将在下面描述)。输出脚本包含在第一事务的输出中。第一事务tx1可以包括一个或更多个附加输出,每个附加输出具有相应的输出脚本。在一些示例中,一个、一些或全部附加输出各自包括包含相应hmac脚本的输出脚本。根据区块链协议的要求,第一事务tx1包括一个或更多个输入。在图6的示例中,爱丽丝103a生成第一事务tx1并将第一事务tx1传输到区块链网络106。如果第一事务tx1被视为有效事务,则它将被记录在区块链150的区块151中。在其他示例中,例如,在将一个或更多个附加输入和/或一个或更多个附加输出添加到第一事务tx1之后,爱丽丝103a可以将第一事务tx1传输到负责将第一事务tx1传输到区块链网络106的第三方(未示出)。
[0105]
一旦第一事务tx1被传输到区块链网络106,鲍勃就可以生成包括输入的第二事务tx2。第二事务tx2的输入引用第一事务tx1的输出(即,包括hmac脚本的输出),并且包括输入脚本,该输入脚本包括hmac输入值。图6中的虚线箭头示出了引用第一事务tx1的输出的第二事务tx2的输入。如果第一事务tx1包括多个输出,每个输出包括相应的hmac脚本,则第二事务tx2的输入引用这些输出中的一个输出。当第一事务tx1的输出脚本与第二事务tx2的输入脚本一起执行时,hmac脚本被配置为对hmac输入值进行运算。应当注意的是,一些区块链
协议首先执行第二事务tx2的输入脚本,然后执行第一事务tx1的输出脚本。
[0106]
爱丽丝103a生成的hmac脚本被配置为基于hmac输入值生成消息的hmac。也就是说,根据hmac脚本生成的hmac将根据hmac输入值的特定值而变化。hmac脚本可以包括一个或更多个函数,每个函数被配置为执行特定操作。
[0107]
例如,hmac脚本可以包括一个或更多个操作代码(操作码)(即,指令),每个操作码被映射到特定的相应操作(每个执行脚本的节点104上的脚本引擎被配置为在脚本中执行该操作码的实例时执行相应的操作)。从这个意义上来说,脚本是以操作码的形式记录在事务的输入或输出中的指令列表。一般而言,操作码可以执行以下一个或更多个操作:(a)将元素输出到存储器;(b)从存储器中检索元素;或(c)对存储器中的元素进行运算;以及(d)从存储器中移除元素。对元素进行运算可以包括对该元素执行数学运算。
[0108]
具体举例来说,hmac脚本可以采用基于堆栈的脚本语言编写。上文已结合图5描述了基于堆栈的脚本语言的示例。在这种语言中,给定操作码被映射到以下一个或更多个操作:(a)将元素放置在堆栈503上;(b)从堆栈503中检索元素;(c)对堆栈503上的元素进行运算;以及(d)从堆栈中移除元素。一些基于堆栈的语言可以允许将数据存储在两个堆栈(例如,主堆栈和备用堆栈)上。
[0109]
在一些示例中,hmac脚本可以被配置为使所生成的消息的hmac输出到存储器(例如,堆栈503)。也就是说,在hmac脚本执行期间的某个阶段,所生成的hmac可以输出到存储器(例如,堆栈503)。所生成的hmac可以作为执行hmac脚本和/或输出脚本的最终结果输出。或者,所生成的hmac可以在hmac脚本和/或输出脚本的中间步骤中输出。
[0110]
由上可知,给定hmac密钥k
hmac
,密文的hmac的通用公式(“hmac公式”)被定义为
[0111][0112]
其中,h是散列函数或散列函数的某种组合。爱丽丝103a生成的hmac脚本可以采用几种形式中的一种,具体取决于爱丽丝103a是否需要鲍勃103b的hmac输入。
[0113]
在一些实施例中,hmac脚本被配置为基于hmac密钥k
hmac
生成消息的hmac。也就是说,hmac脚本被配置为将hmac密钥k
hmac
作为来自第二事务tx2的输入脚本的输入,并生成hmac。这使得鲍勃103b能够指定要用作hmac密钥k
hmac
的值。在一些示例中,k
hmac
是以十六进制表示的爱丽丝103a和鲍勃103b共享的密钥。在这些实施例中,hmac输入是hmac密钥k
hmac
,或者至少包括hmac密钥k
hmac
。参考上述hmac公式,计算hmac时也需要该消息。因此,在这些实施例中,hmac脚本包括消息(例如,密文)。
[0114]
例如,如果爱丽丝103a要求解锁脚本中的hmac输入是《k
hmac
》,则hmac脚本可以采用以下形式:
[0115]
[hmacscript]
(1)
=op_dup《ipad》op_xor《message》op_cat op_sha256op_swap《opad》op_xor op_swap op_cat op_sha256
[0116]
在替代实施例中,hmac脚本被配置为基于消息(例如,密文)生成消息的hmac。也就是说,hmac脚本被配置为将消息作为来自第二事务tx2的输入脚本的输入,并生成hmac。这使得鲍勃103b能够指定要用作消息的值。换言之,鲍勃103b可以生成任何所需消息的hmac。在这些实施例中,hmac输入是消息,或者至少包括该消息。参考上述hmac公式,计算hmac时也需要hmac密钥k
hmac
。因此,在这些实施例中,hmac脚本包括hmac密钥k
hmac

[0117]
例如,如果爱丽丝103a要求解锁脚本中的hmac输入是《message》,则hmac脚本可以
采用以下形式:
[0118][0119]
在替代实施例中,hmac脚本被配置为基于加密形式的消息(密文)生成消息的hmac。也就是说,hmac脚本被配置为至少将消息的散列值作为来自第二事务tx2的输入脚本的输入,并生成hmac。这使得鲍勃103b能够在区块链150上生成该密文的hmac,而不暴露该消息。换言之,鲍勃103b可以生成任何所需消息的hmac,而无需任何第三方查看该消息。在这些实施例中,hmac输入至少是消息的散列值,或者至少包括消息的散列。参考上述hmac公式,计算hmac时也需要hmac密钥k
hmac
。因此,在这些实施例中,hmac脚本包括hmac密钥k
hmac

[0120]
例如,如果爱丽丝103a和/或鲍勃103b要求隐藏消息,则解锁脚本中的hmac输入可以是hmac公式中内部散列函数的结果,即《然后,hmac脚本可以采用以下形式:
[0121][0122]
技术人员应该熟悉上述示例性hmac脚本中使用的操作码及其相关操作。应当理解的是,可以在不影响hmac脚本本身结果的情况下对示例性脚本进行某些细微改变,例如,包括在结果中加上数字1,然后从结果中减去数字1的操作码。包括《ipad》和《opad》是可选的,并且将取决于散列函数输入的长度。示例性hmac脚本使用sha-256散列函数。然而,可以替代地使用任何散列函数或散列函数的组合,例如sha-512。
[0123]
在一些示例中,爱丽丝103a可以将消息(以明文和/或密文的形式)发送给鲍勃103b。例如,在hmac脚本采取[hmac script]
(2)
形式的实施例中,爱丽丝103a可以将明文消息或密文消息传输给鲍勃103b,以便鲍勃103b提供该消息作为hmac输入。
[0124]
上述各实施例允许在脚本中计算消息的hmac。在一些场景中,爱丽丝103a可能想要利用预先计算的hmac来验证作为鲍勃的输入的结果而生成的hmac。为此,第一事务tx1的输出脚本可以包括“hmac验证脚本”。对于hmac脚本,hmac验证脚本是包括以执行预定函数(例如,由操作码序列定义)的脚本的一部分的标签。在这些实施例中,hmac验证脚本包括消息的预先计算的(即,预定)hmac。然后,hmac验证脚本被配置为将预先计算的hmac与使用hmac脚本(来自第一事务tx1的输出脚本)和hmac输入(来自第二事务tx2的输入脚本)生成的hmac进行比较,并确定它们是否彼此对应,例如它们是否相同。
[0125]
例如,如果爱丽丝103a想要比较预先计算的hmac的结果,则hmac验证脚本可以采用以下形式:
[0126]
[hmac verification script]=[hmac in script](i)《hmac》op_equalverify,
[0127]
其中,(i)索引指定上面给出的示例性hmac脚本之一,并且
[0128][0129]
是hmac的预先计算的结果。
[0130]
hmac验证脚本可以被配置为输出指示预先计算的hmac是否与新生成的hmac的结果对应的结果。例如,指示可以输出到存储器(例如,堆栈503)。例如,如果两个结果匹配,则“1”或“true”的表示可以输出到堆栈503。又如,如果预先计算的hmac与新生成的hmac不对应,则hmac验证脚本可以被配置为使第二事务tx2被标记为无效事务。这可以通过上述示例
性脚本中的op_equalverify操作码来实现。
[0131]
在一些实施例中,根据hmac脚本生成的hmac可以用于生成公钥。也就是说,所生成的公钥是作为hmac的函数生成的。在这些实施例中,第一事务tx1的输出包括“公钥导出脚本”,即被配置为执行预定义函数的脚本的一部分,在这种情况下,该预定义函数基于hmac生成新公钥。公钥导出脚本可以被配置为使新公钥输出到存储器(例如,堆栈503)。
[0132]
例如,公钥导出脚本可以被配置为对hmac执行点标量乘法,从而将hmac乘以生成值。例如,如果新公钥需要是椭圆曲线数字签名算法(ecdsa)所需的公钥,则生成值可以是椭圆曲线基点(即,椭圆曲线上的点)。在这种情况下,生成值根据椭圆曲线上的两个坐标定义。
[0133]
例如,公钥导出可以被配置为执行以下计算:
[0134]
p
child
=hmac(k
hmac
,message)
·g[0135]
其中,p
child
是新公钥,g是生成点,hmac(k
hmac
,ciphertext)是根据hmac脚本生成的hmac。下面提供了用于执行点标量乘法(
·
)的示例性脚本。
[0136]
在一些实施例中,新公钥可以基于先前公钥生成,即新公钥(例如,子公钥)可以根据hmac和先前公钥(例如,父公钥)生成。公钥导出脚本被配置为对hmac执行点加法(转换为公钥后,例如通过与生成点相乘),从而将hmac添加到先前公钥。
[0137]
例如,公钥导出可以被配置为执行以下计算:
[0138]
p
child
=p
parent
hmac(k
hmac
,ciphertext)
·g[0139]
其中,p
parent
是先前公钥。下面提供了用于执行点加法( )的示例性脚本。
[0140]
在一些示例中,hmac脚本用于计算hmac的消息可以包括公钥。公钥可以是上述先前公钥,也可以是其他公钥。该消息还可以包括先前公钥的索引。附加地或替代地,hmac脚本用于计算hmac的hmac密钥k
hmac
可以包括链码。
[0141]
公钥可以分层确定性方式彼此链接。换言之,每个公钥可以存在于各层级公钥的层级结构内的相应层级。层级结构内第n 1个层级中的公钥链接到层级结构内第n个层级中的一个或更多个公钥。公钥的相应层级由链码表示。给定层级可以包括一个或更多个公钥的序列。公钥在序列中的相应位置由索引表示。
[0142]
图8示出了分层确定性(hd)密钥集(也称为hd钱包)的示例。在本文中,主密钥是基于种子生成的。每个子密钥集中的子密钥都是基于主密钥生成的。每个相应孙密钥集中的孙密钥都是基于相应子密钥集生成的。在该示例中,主密钥是父密钥。然而,标签“父”和“子”可用于指代第n个层级中的公钥和第n 1个层级中的公钥,其中第n 1个层级中的公钥是基于第n个层级中的公钥生成的。
[0143]
在一些示例中,公钥导出可以被配置为执行以下计算:
[0144]
p
child
=p
parent
hmac(c
parent
,p
parent
||index)
·
g,
[0145]
其中,c
parent
是先前公钥的链码,index是新公钥的索引。换言之,hmac脚本被配置为生成先前公钥的hmac,并且公钥导出脚本被配置为使用该结果来生成新公钥。在这些实施例中,消息(例如,密文)等同于先前公钥p
parent
和索引index(如果存在)。
[0146]
在一些实施例中,hmac脚本被配置为基于链码c
parent
生成消息的hmac。也就是说,hmac脚本被配置为将链码c
parent
作为来自第二事务tx2的输入脚本的输入,并生成hmac。这使得鲍勃103b能够指定用作链码c
parent
的值,即新公钥在各层级公钥的层级结构内所处的
层级。在这些实施例中,hmac输入是链码c
parent
。参考上述hmac公式,计算hmac时也需要消息(现在等同于p
parent
||index)。因此,在这些实施例中,hmac脚本包括p
parent
||index,其中该索引是可选的。然后,公钥导出脚本被配置为基于所生成的hmac和先前公钥p
parent
生成新公钥p
child
。新公钥可以输出到存储器(例如,堆栈503)。
[0147]
在替代实施例中,hmac脚本被配置为基于先前公钥p
parent
生成消息的hmac。也就是说,hmac脚本被配置为将先前公钥p
parent
作为来自第二事务tx2的输入脚本的输入,并生成hmac。这使得鲍勃103b能够指定用作先前公钥(例如,主公钥)的公钥。在这些实施例中,hmac输入是先前公钥p
parent
,并且在一些示例中是索引。参考上述hmac公式,计算hmac时也需要hmac密钥k
hmac
,(现在等同于链码c
parent
)。因此,在这些实施例中代码,hmac脚本包括链码c
parent
。然后,公钥导出脚本被配置为基于所生成的hmac和先前公钥p
parent
生成新公钥p
child
。新公钥p
child
可以输出到存储器(例如,堆栈503)。
[0148]
在替代实施例中,hmac脚本被配置为基于加密形式的先前公钥p
parent
生成消息的hmac。也就是说,hmac脚本被配置为至少将先前公钥的散列值作为来自第二事务tx2的输入脚本的输入,并生成hmac。这使得鲍勃103b能够在区块链150上生成先前公钥p
parent
的hmac,而不暴露先前公钥p
parent
。换言之,鲍勃103b可以生成任何所需公钥的hmac,而无需任何第三方查看先前公钥p
pare
。在这些实施例中,hmac输入至少是先前公钥p
parent
的散列值。在一些示例中,hmac输入是先前公钥p
parent
和索引的散列值。参考上述hmac公式,计算hmac时也需要链码c
parent
。因此,在这些实施例中代码,hmac脚本包括链码c
parent
。然后,公钥导出脚本被配置为基于所生成的hmac和先前公钥p
parent
生成新公钥p
child
。新公钥p
child
可以输出到存储器(例如,堆栈503)。
[0149]
最佳做法是不针对从公钥导出的区块链事务重复使用支付地址。为免需要存储与这些公钥对应的多个随机生成的私钥,分层确定性(hd)钱包从一个种子计算多个密钥,从而确保轻松存储和重新生成密钥。在一个特定的区块链钱包协议中,用于从父公钥计算子公钥的等式如上文所示,即:
[0150]
p
child
=p
parent
hmac-sha512
l
(c
parent
,p
parent
||index)
·
g,
[0151]
其中,hmac-sha512
l
是使用sha-512散列函数的hmac函数结果的左侧256位。在一些示例中,hmac脚本被配置为输出hmac结果的预定位数,例如左侧256位。显然,该hmac函数的等式如下:
[0152][0153]
并且在子公钥计算中仅使用该结果的左侧256位。右侧256位将对应于子密钥c
child
的链码,该链码将用于导出孙密钥。
[0154]
父链码用于导出子密钥,其中c
parent
是与父公钥p
parent
对应的链码。显然,
[0155]cparent
=hmac-sha512r(c
grandparent
,p
grandparent
||index
parent
),
[0156]
其中,下标r表示hmac计算结果的右侧256位。使用链码导出子密钥只是为了在计算中引入熵。
[0157]
然后,0≤index《2
31
是与子密钥对应的索引。应当注意的是,该索引从0开始。引入索引,以便可以从单个父项中导出多个子密钥。然后,可以将每个子密钥用作父密钥,并为每个子密钥导出多个孙密钥。
[0158]
最后,应当注意的是,针对p
child
的等式中给出的g是椭圆曲线上的点,该点可由secp256k1椭圆曲线指定。由于hmac-sha512
l
(c,p
parent
||index)会产生整数结果,因此p
child
计算中的第二项是将该点g与其自身相加该hmac结果指定次数的记数。
[0159]
在链上显式导出密钥的一个好处在于,用户可以证明他们拥有的两个公钥之间的链接,因此存在关于该证明的不可变记录。这在公钥基础设施(pki)的上下文中将尤其有用,其中可以对单个公钥进行认证。然后,借助关于链接位于链上的该证明,可以通过扩展对相关公钥进行认证。
[0160]
在脚本中计算子密钥的另一个好处在于,该子密钥可以用于签署事务,但从不显式存储在链上。因此,如果攻击者搜索包含给定子公钥的事务,他们不会找到使用该方法的事务。这会增加用户使用该方法的隐私度。
[0161]
脚本中的公钥导出
[0162]
图7示意性地示出了用于使用区块链150的事务来生成公钥的系统。该系统包括第一方(爱丽丝)103a和第二方(鲍勃)103b的相应计算机设备102a和102b(未示出)。应当注意的是,描述为由爱丽丝103a或鲍勃103b执行的动作是指由爱丽丝或鲍勃的相应计算机设备执行的动作。爱丽丝103a生成第一区块链事务tx1的输出脚本。输出脚本包括公钥导出(pkd)脚本。pkd脚本是输出脚本的一部分,该输出脚本被配置为执行特定函数(将在下面描述)。输出脚本包含在第一事务的输出中。第一事务tx1可以包括一个或更多个附加输出,每个附加输出具有相应的输出脚本。在一些示例中,一个、一些或全部附加输出各自包括输出脚本,该输出脚本包含相应pkd脚本。根据区块链协议的要求,第一事务tx1包括一个或更多个输入。在图7的示例中,爱丽丝103a生成第一事务tx1并将第一事务tx1传输到区块链网络106。如果第一事务tx1被视为有效事务,则它将被记录在区块链150的区块151中。在其他示例中,例如,在将一个或更多个附加输入和/或一个或更多个附加输出添加到第一事务tx1之后,爱丽丝103a可以将第一事务tx1传输给鲍勃103b或负责将第一事务tx1传输到区块链网络106的第三方(未示出)。
[0163]
一旦第一事务tx1被传输到区块链网络106,鲍勃就可以生成包括输入的第二事务tx2。第二事务tx2的输入引用第一事务tx1的输出(即,包括pkd脚本的输出),并且包括输入脚本,该输入脚本包括第一公钥pk1(下文也称为“父公钥”)。图7中的虚线箭头示出了引用第一事务tx1的输出的第二事务tx2的输入。如果第一事务tx1包括多个输出,每个输出包括相应的hmac脚本,则第二事务tx2的输入引用这些输出中的一个输出。当第一事务tx1的输出脚本与第二事务tx2的输入脚本一起执行时,pkd脚本被配置为对第一公钥pk1进行运算。应当注意的是,一些区块链协议首先执行第二事务tx2的输入脚本,然后执行第一事务tx1的输出脚本。
[0164]
应当注意的是,在一些示例中,同一方实际上可以同时生成第一事务tx1和第二事务tx2。换言之,在前述段落中描述为由鲍勃103b执行的一些或全部动作可以由爱丽丝103a执行。
[0165]
爱丽丝103a生成的pkd脚本被配置为使用第一公钥pk1来生成第二公钥pk2(下文也被称为“子公钥”)。也就是说,第二公钥pk2基于第一公钥pk1。pkd脚本可以包括一个或更多个函数,每个函数被配置为执行特定操作。
[0166]
例如,pkd脚本可以包括一个或更多个操作代码(操作码)(即,指令),每个操作码
映射于特定的操作。从这个意义上来说,脚本是以操作码的形式记录在事务的输入或输出中的指令列表。一般而言,操作码可以执行以下一个或更多个操作:(a)将元素输出到存储器;(b)从存储器中检索元素;或(c)对存储器中的元素进行运算;以及(d)从存储器中移除元素。对元素进行运算可以包括对该元素执行数学运算。
[0167]
具体举例来说,pkd脚本可以采用基于堆栈的脚本语言编写。上文已结合图5描述了基于堆栈的脚本语言的示例。在这种语言中,给定操作码被配置为执行以下一个或更多个操作:(a)将元素放置在堆栈503上;(b)从堆栈503中检索元素;(c)对堆栈503上的元素进行运算;以及(d)从堆栈中移除元素。一些基于堆栈的语言可以允许将数据存储在两个堆栈(例如,主堆栈和备用堆栈)上。
[0168]
在一些示例中,pkd脚本可以被配置为使所生成的第二公钥pk2输出到存储器(例如,堆栈503)。也就是说,在pkd脚本执行期间的某个阶段,第二公钥pk2可以输出到存储器(例如,堆栈503)。第二公钥pk2可以作为执行pkd脚本和/或输出脚本的最终结果输出。或者,第二公钥pk2可以在pkd脚本和/或输出脚本的中间步骤中输出。
[0169]
一般而言,pkd脚本被配置为计算以下公式:
[0170]
pk2=f(pk1)
[0171]
其中,f()是由pkd脚本定义的函数,用于对第一公钥pk1进行运算。第二公钥pk2被描述为链接到第一公钥pk1,因为第二公钥基于第一公钥pk1,例如,第一公钥和第二公钥之间存在数学联系。
[0172]
在一些实施例中,pkd脚本可以包括“散列脚本”。散列脚本是被配置为执行预定函数(例如,由操作码序列定义)的脚本的一部分的标签。散列脚本被配置为至少对第一公钥pk1应用散列函数(例如,sha-256、sha-512)以生成散列结果。在一些示例中,应用散列函数可以包括多次应用相同的散列函数(例如,应用sha-512函数两次),或应用一个或更多个不同的散列函数(例如,应用sha-512函数,然后应用sha-256函数),或两者的组合(例如,应用sha-256函数两次,然后应用sha-512函数)。在一些示例中,散列脚本可以被配置为仅对第一公钥应用散列函数。在其他示例中,散列函数可以对第一公钥pk1以及一个或更多个其他数据项应用散列函数。一个或更多个数据项可以包含在散列脚本中,也可以包含在第二事务的输入脚本中。在一些示例中,一个或更多个数据项可以包含在散列脚本中,一个或更多个不同的数据项可以包含在第二事务的输入脚本中。散列脚本可以被配置为使散列结果输出到存储器(例如,堆栈503)。
[0173]
一般而言,当pkd脚本包括散列脚本时,pkd脚本被配置为计算以下公式:
[0174]
pk2=f(pk1)
[0175]
其中,f()包括散列函数h,例如pk2=pk1 h(pk1)。
[0176]
在一些示例中,散列脚本可以是散列消息认证码(hmac)脚本,其中散列函数是hmac函数。散列脚本是被配置为执行预定函数(例如,由操作码序列定义)的脚本的一部分的标签。hmac脚本被配置为至少对所述第一公钥应用hmac函数以生成hmac。通常,如本领域已知的,hmac取自“消息”。在一些示例中,根据本发明的实施例,该消息可以包括第一公钥pk1。或者,该消息可以包括第一公钥pk1以及上文结合“散列函数”讨论的一个或更多个其他数据项。
[0177]
一般而言,当pkd脚本包括hmac脚本时,pkd脚本被配置为计算以下公式:
[0178]
pk2=f(pk1)
[0179]
其中,f()包括hmac函数h,例如pk2=pk1 hmac(pk1)。
[0180]
下面提供了替代hmac脚本的示例。pkd脚本的hmac脚本可以采用这些hmac脚本中的任何一个脚本的形式。又如,hmac脚本可以被配置为对第一公钥进行运算以生成以下hmac:
[0181][0182]
其中,p
parent
表示第一公钥,c
parent
定义了第一公钥pk1的链码,index定义了第二公钥的索引。链码和索引如下所述。也就是说,在这些示例中,hmac脚本被配置为对消息应用hmac函数,该消息包括链码、第一公钥pk1和索引。在一些示例中,该消息可以包括第一公钥pk1和链码,但不包括索引。在其他示例中,该消息可以包括第一公钥pk1和索引,但不包括链码。在一些示例中,链码和/或索引可以包含在hmac脚本本身中。在其他示例中,链码和/或索引可以包含在第二事务的输入脚本中。应当注意的是,sha-512函数可以替换为任何其他合适的散列函数。
[0183]
作为说明性示例,将父公钥《p
parent
》作为输入并计算hmac-sha512(c
parent
,p
parent
||index)的hmac脚本可以定义为
[0184][0185]
其中,op_sha512是被配置为弹出栈顶项并将其sha-512散列值返回到堆栈的操作码。
[0186]
在一些示例中,hmac函数生成的消息的hmac可能大于所需值,即消息的hmac的字节数可能超过所需数目。hmac脚本可以被配置为生成散列结果作为消息的hmac的预定字节数,例如,hmac的前导字节数可以保留为散列结果。例如,如果仅需32个字节(256位),则hmac脚本可以被配置为将hmac的前导32个字节输出到存储器(例如,堆栈503)。
[0187]
例如,hmac脚本可以包括以下操作码:
[0188]
[hmac-sha512]《0x20》op_split op_drop,
[0189]
其中,先前定义的hmac脚本之后的操作码被配置为丢弃函数[hmac-sha512]的结果的右侧32个字节。应当注意的是,《0x20》相当于以十进制表示的32。《0x20》可以替换为表示hmac函数要返回的所需字节数的任何数目。
[0190]
在一些实施例中,pkd脚本可以包括“点标量乘法(psm)脚本”。psm脚本是被配置为执行预定函数(例如,由操作码序列定义)的脚本的一部分的标签。psm脚本被配置为生成第二数据值,作为对第一数据值与椭圆曲线的预定生成点执行点标量乘法的结果。换言之,psm脚本被配置为执行椭圆曲线点乘法。例如,可能需要psm脚本将散列结果转换为公钥形式,例如以添加到第一公钥。椭圆曲线点乘法是沿椭圆曲线对一个点重复执行加法的运算。在本文中,生成点是椭圆曲线(例如,secp256k1椭圆曲线)上的一个点。对于某个标量(整数)r和曲线e(例如,e:y2=x3 ax b)上的点p=(x,y),椭圆曲线点乘法被定义为rp=p p p p

p。在该示例中,r是第一数据值,p是生成点。
[0191]
pkd脚本可以被配置为基于第一公钥pk1和第二数据值(基于生成点生成)生成第
二公钥。在一些示例中,第一数据值可以包含在第二事务的输入脚本中。在其他示例中,第一数据值可以包括根据散列脚本生成的散列结果。
[0192]
一般而言,当pkd脚本包括psm脚本时,pkd脚本被配置为计算第二值q
·
g,其中,q是第一数据值,g是生成点,
·
表示点乘法。
[0193]
例如,pkd脚本可以被配置为计算以下公式:
[0194]
pk2=pk1 h(pk1)
·
g,
[0195]
例如,pk2=pk1 hmac(pk1)
·g[0196]
psm脚本可以被配置为使第二数据值输出到存储器(例如,堆栈)。
[0197]
在示例中,第一数据值(例如,散列结果)可以二进制表示。在这些示例中,psm脚本被配置为生成第二数据作为椭圆曲线上的点,即指示椭圆曲线上的点的两个坐标。坐标可以十六进制或其他形式表示。
[0198]
在一些实施例中,pkd脚本可以包括“二进制转换脚本”。二进制转换脚本是被配置为执行预定函数(例如,由操作码序列定义)的脚本的一部分的标签。二进制转换脚本被配置为将数据项的十进制或十六进制表示转换为数据项的二进制表示。例如,二进制转换脚本可以被配置为将第一数据值(例如,散列结果)的十进制或十六进制表示转换为第一数据值的二进制表示。
[0199]
图9提供了使用操作码的示例性二进制转换脚本[hextobinary]。
[0200]
操作码周围的方括号的4l-2次方表示这些操作码应重复4l-2次,其中,n是要转换为二进制的字节数。例如,字节数可以是l=32。-2是考虑到第一轮和最后一轮,这两轮略有不同。应当注意的是,虽然该函数被标记为[hextobinary](“hex”是十六进制的缩写),但同一函数也可以用于将十进制表示转换为二进制表示。
[0201]
在一些实施例中,pkd脚本可以包括“点加法脚本”。点加法脚本是被配置为执行预定函数(例如,由操作码序列定义)的脚本的一部分的标签。点加法脚本被配置为对第一公钥pk1与第三公钥pk3执行点加法。在一些示例中,第一公钥与第三公钥的点加法的结果是第二公钥(即,根据pkd脚本生成的公钥)。椭圆曲线上的两个点相加(或一个点与其自身相加)将在椭圆曲线上产生第三点,其位置与前两个点的位置没有直接明显的关系。下面提供了点标量乘法脚本的特定示例。
[0202]
一般而言,当pkd脚本包括点加法脚本时,pkd脚本被配置为计算以下公式:
[0203]
pk2=f(pk1,pk3)
[0204]
其中,f()包括点加法函数,例如pk2=pk1 pk3,其中, 是点加法运算。
[0205]
第三公钥pk3可以包含在第二事务的输入脚本中。或者,第三公钥可以作为执行pkd脚本的结果生成。例如,第三公钥pk3可以是第二值,即根据psm脚本生成的值,即pk3=q
·
g。在该示例中,第二公钥pk2可以是pk2=pk1 q
·
g。又如,第三公钥pk3可以基于散列结果,例如pk3=h(pk1)
·
g。在该示例中,第二公钥pk2可以是pk2=pk1 h(pk1)
·
g,也可以是pk2=pk1 hmac(pk
21
)
·
g。
[0206]
执行点加法可以包括将两个不同的点相加,或者将相同的点与其自身相加,即点加倍。在将2个不同的点p和q相加的情况下,加法被定义为对曲线e与由点p和q定义的直线相交而产生的点进行的取反,从而得到点r。在点p和q重合(位于相同的坐标)的情况下,加法是相似的,区别在于没有界限分明的直线穿过p,因此使用极限情况(与曲线e相切)在p处
闭合运算。
[0207]
更详细地,假设一个椭圆曲线群其中e是点集(x,y),满足以下条件
[0208]
y2=(x3 ax b)modp,
[0209]
其中,a、b和p是根据给定方案设置的参数,满足4a3 27b2≠0,o被定义为无穷远点和群的单位元素,然后点加法 通过以下定义来定义:
[0210]
1.如果p=(x1,y1),o=(x2,y2),且x1≠x2,则p q=(x3,y3),其中
[0211]
x3=(y
2-y1)2(x
2-x1)-2-x
1-x2modp,
[0212]
y3=(y
2-y1)(x
2-x1)-1
(x
1-x3)-y1modp,
[0213]
其中运算是常用算术模p。
[0214]
2.如果p=(x1,y1),q=(x1,y1),且y1≠0,则p p=(x2,y2),其中
[0215][0216][0217]
其中运算同样是常用算术模p。
[0218]
3.如果p=(x1,y1),且q=(x1,-y1),则
[0219]
4.对于任何
[0220]
应当注意的是,在y1=0时执行点加倍的情况下,使用第三定义,其中p=q。
[0221]
点加法脚本可以被配置为首先确定第一公钥与第三公钥之间的关系(例如,它们是否为相同的公钥),并且响应于该确定应用若干预定义函数中的一个预定义函数。也就是说,如果第一公钥和第三公钥是相同的公钥,则点加法脚本可以被配置为通过应用点加法的第二定义来生成第二公钥pk2。如果第一公钥和第三公钥是不同的公钥,则点加法脚本可以被配置为通过应用点加法的第一定义(取决于第一公钥与第三公钥的不同之处)来生成第二公钥pk2。下面提供了用于执行点加法的示例性点加法脚本。
[0222]
点加法脚本可以被配置为通过生成第二公钥pk2的第一坐标(例如,x坐标)和第二公钥的第二坐标(例如,y坐标)来生成第二公钥pk2。点加法脚本可以进一步被配置为将第二公钥pk2的第一坐标和第二坐标输出到存储器(例如,堆栈503)。在一些示例中,点加法脚本可以被配置为组合(例如,级联concatenate)第一坐标和第二坐标并将结果输出到存储器(例如,堆栈503)。
[0223]
以下示例描述了如何使用公钥导出脚本从父密钥中导出hd钱包子密钥,该父密钥包含在第二事务的输入脚本中。应当理解的是,根据预期结果,一些或所有单个示例性脚本可以单独使用,也可以与少于所有单个脚本的脚本组合使用。此外,以下示例描述了根据bip32协议的子密钥的导出,该协议使用hmac函数作为特定形式的散列函数。应当理解的是,可以使用其他散列函数。
[0224]
pkd脚本可以被配置为实现用于从父公钥p
parent
(第一公钥)导出子公钥p
child
(第二公钥)的以下等式:
[0225]
p
child
=p
parent
hmac-shsa512
l
(c
parent
,p
parent
||index)
·
g,
[0226]
其中,hmac-sha512
l
是hmac-sha512函数的结果的左侧32个字节,c
parent
是与父密钥对应的链码,index是与子密钥对应的索引。
[0227]
然后,可以通过以下方式在脚本中完成此计算。解锁脚本是《p
parent
》(父公钥的未
压缩格式),没有指定该格式的前缀04。因此,x和y坐标级联。为了由此导出子密钥,可以使用以下锁定脚本:
[0228]
[p
chi
derivation]=op_dup《0x20》op_split op_swap op_rot[hmac-sha512]《0x20》op_left
[0229]
[hex to binary][point scalar multiplication][point addition],
[0230]
其中,每组方括号是执行给定描述的一组操作码。现在,对[p
chi
derivation]的每个函数进行详细说明。计算中包含的所有函数都已编写为可以彼此独立使用。
[0231]
由于在计算子密钥p
child
时需要使用父密钥两次,因此第一操作码op_dup《0x20》op_split op_swap op_rot复制输入的父密钥p
parent
。然后,它将副本拆分成其x和y坐标(分别对应于左侧和右侧32个字节),并将这些坐标置于堆栈底部,因为这是最终函数[point addition]所需的格式。执行这些操作码后,堆栈的状态如下:
[0232]
《p
parent
》《p
parent
(x)》《p
parent
(y)》
[0233]
现在,在脚本中计算hmac-sha512函数(即,hmac脚本)。函数[hmac-sha512]将父公钥《p
parent
》作为输入,并计算hmac-sha512(c
parent
,p
parent
||index)。该函数被定义为
[0234][0235]
其中,op_sha512是被配置为弹出栈顶项并将其sha-512散列值返回到堆栈的操作码。执行该hmac函数后,堆栈的状态如下:
[0236]
《hmac-sha512(c
parent
,p
parent
||index)》《p
parent
(x)》《p
parent
(y)》
[0237]
然后,后续操作码《0x20》op_split op_drop丢弃函数[hmac-sha512]的结果的右侧32个字节。此时,该点之后堆栈的状态如下:
[0238]
《hmac-sha512
l
(c
parent
,p
parent
||index)》《p
parent
(x)》《p
parent
(y)》
[0239]
然后,将产生的数字hmac-sha512
l
(c
parent
,p
parent
||index)从十六进制更改为二进制。接下来,为了计算[point scalar multiplication],函数的输入必须为二进制,因此定义了一个函数(即,二进制转换脚本),以将hmac的十六进制结果转换为字节,每个字节表示一个二进制数字。如上所述,图9中示出了[hex to binary]。
[0240]
以下是执行[hex to binary]函数时的说明性示例。在该示例中,十六进制《0x07》被转换为其二进制表示0111。在该示例中,n=1。白色的列表示堆栈,灰色的列表示备用堆栈(altstack)。堆栈先从左到右,然后从上到下流动。
[0241][0242][0243][0244][0245]
该函数将十六进制《0x07》转换为其二进制表示《0x00010101》,其中每个字节表示一位。应当注意的是,0x前缀表示其后面的字节是十六进制数字,因此《0x00010101》实际上不同于以二进制表示的0x07,但下一操作码读取该表示的方式会将视其为以二进制表示的该数字。如果完全按照编写方式读取,则《0x00010101》相当于以十进制表示的65793。执行函数[hex to binary]后的堆栈状态如下:
[0246]
《binary representation of hmac-sha512
l
(c
parent
,p
parent
||index)》《p
parent
(x)》《p
parent
(y)》
[0247]
函数[hex to binary]产生一个字符串,其中每个字节现在表示一位。对于该特定示例性pkd脚本,必须使用以下操作码将字符串拆分为数组:
[0248]
[op_1op_split op_swap]
256
[0249]
其中,方括号的次方表示应重复该操作的次数(在该示例中为256次)。这会产生长度为256的二进制数组,其中表示最低有效位的字节位于堆栈顶部。数组中的每个字节表示一位,并且是《0x01》或《0x00》。上述流程涉及在转换为二进制时级联二进制表示,然后将结果拆分为数组。进行该拆分的原因在于,要求采用低位优先格式的结果。该结果可以在不进行级联的情况下实现,但需要跟踪堆栈的深度,然后在保持顺序的同时不断地将堆栈项目置于顶部。将结果级联到一个字符串中,利用备用堆栈,然后进行拆分,就像上述根据脚本所实现的那样简单得多。
[0250]
下面举例说明如何在脚本中执行点标量乘法。[point scalar multiplication]函数(即,psm脚本)。[point scalar multiplication]函数将hmac函数结果(在一些示例中,仅hmac函数结果的左侧32个字节)作为二进制表示并返回hmac-sha512
l
(c,p
parent
||i)
·
g。为了便于表示,使用以下定义:q:=hmac-sha512
l
。然后,可以计算对应的点q
·
g:=hmac-sha512
l
·
g。要在脚本中计算q
·
g,首先要预先计算q0=20·
g,q1=21·
g,

,q
255
=2
255
.g。这样可以计算0≤q《2
256
的任何可能的q
·
g。这是因为,在将二进制表示作为输入的情况下,如果该二进制表示的第i个数字是1,则将对应的2i与q
·
g的计算的当前状态相加。如果第i个数字是0,则不会将对应的2i与q
·
g的计算的当前状态相加。图10中示出了用于实现这一点的示例性psm脚本。假设输入q采用低位优先二进制数组的形式,图10中的示例性脚本计算q
·
g,其中《qi(x)》表示2i·
g的x坐标,《qi(y)》表示2i·
g的y坐标。
[0251]
当q的对应位等于1时,该函数将点2i·
g与q
·
g的当前状态相加。该函数使用[point addition](即,点加法脚本),如下所述。[points calar multiplication]函数首先将《0x00》《0x00》推到堆栈中,此操作的目的是充当起始点(在该示例中,充当单位元素)。由于[pointaddition]将两个点作为输入,而不是最初将《0x00》《0x00》推到堆栈中,因此第一次执行时将只有一个输入,并且将导致错误。本质上,《0x00》《0x00》充当单位元素,因为[point addition]的定义方式如下:如果一个点是《0x00》《0x00》,则函数仅输出另一个点。应当注意的是,选择该记数作为单位元素是安全的,因为点(0,0)不是secp256k1椭圆曲线上的点。此时,该点处堆栈的状态如下:
[0252]
《(hmac-sha512
l
(c
parent
,p
parent
||index)
·
g)(x)》《(hmac-sha512
l
(c
parent
,p
parent
||index)
·
g)(y)》《p
parent
(x)》《p
parent
(y)》
[0253]
其中,最上面的两项是hmac-sha512
l
(c
parent
,p
parent
||index)
·
g的计算结果的x坐标和y坐标。
[0254]
[pointaddition]函数是在子密钥导出中使用的最终函数。这会产生[point scalar multiplication]的结果和p
parent
密钥(在函数[p
child
derivation]的前几个操作码中复制之后一直存储在堆栈底部),并将p
child
返回到堆栈。在定义完整函数之前,需要计算几个函数。其中包括:
[0255]
·
[inverse mod p]
[0256]
·
[different point addition]
[0257]
·
[same point addition]
[0258]
首先,描述脚本中模逆p的示例,它将用于对两个点执行加法。费马小定理指出m-1
=m
p-2
modp。假设输入p已知,则可以使用图11中所示的代码来对m模p进行求逆,即计算m
p-2
modp。《p
n-1
》《p
n-2


《p0》表示数组,其中该数组的每一项对应于(p-2)的二进制索引,即p

=p-2=p020 p121

p
n-12n-1
,其中图11中的操作码计算函数[inverse mod p],给定输入为《m》。
[0259]
在该示例中,n为256,这是p的二进制长度。在将p-2的二进制数组推到堆栈上后,与op_roll组合的操作码《(n 1)》将《m》置于堆栈顶部。在该点处将p-2推到堆栈中,以确保该逆函数是自包含的,因此可轻松用于其他情况。同样,方括号的次方的记数表示该代码的
重复次数。
[0260]
图12示出了用于执行点加法的示例性脚本。在该示例中,示例性脚本对两个不同的点执行点加法。对两个不同的点执行加法时,输入为《y2》《x2》《y1》《x1》,其中每个坐标是32个字节的十六进制坐标。然后,图12中的代码计算函数[different point addition],从而将《y3》《x3》返回到堆栈。下面示出了图12的代码中每行末尾的堆栈状态。堆栈状态从输入开始,然后依次执行每行示例性代码。
[0261][0262][0263][0264]
这就完成了在脚本中对不同的点执行加法的计算。
[0265]
图13示出了用于执行点加法的另一示例性脚本。在该示例中,示例性脚本对相同的点执行点加法。对两个相同的点执行加法时,输入为《y1》《x1》《y1》《x1》,其中每个坐标是32个字节的十六进制坐标。然后,图13中的代码计算函数[same point addition],从而将《y2》《x2》返回到堆栈。下面示出了图13的代码中每行末尾的堆栈状态。堆栈状态从输入开始,然后依次执行每行示例性代码。应当注意的是,a是由椭圆曲线定义的常数,在该示例中为secp256k1,因此a=7。
[0266][0267][0268][0269]
图14示出了用于执行点加法的另一示例性脚本。在该示例中,示例性脚本检查要对其执行加法的两个点是相同的点还是不同的点,并相应地执行操作。应当注意的是,图14中的粗体文本解释了该行代码正在执行的操作,数字(i)对应于上面给出的点加法的定义。假定输入采用《y2》《x2》《y1》《x1》形式,其中每个坐标是32个字节的十六进制坐标。
[0270]
第一行旨在检查第二个点是否为《0x00》《0x00》,在所选记数中,第二个点是无穷远点,因为已知该点不在secp256k1曲线上。如果第二个点是无穷远点,则第一个点《y1》《x1》返回到堆栈,这对应于点加法的定义(4)。应当注意的是,在示例性代码中,无穷远点仅显示为第二个点。
[0271]
然后,第一op_else中的第一行检查x坐标是否相等。如果相等,则检查y坐标是否也相等。如果相等,则检查y=0是否成立,在这种情况下,返回无穷远点,这对应于点加法的定义(3)。如果y≠0,则代码对一个点与该点自身执行点加法,即上文定义的函数[same point addition],这对应于点加法定义的定义(2)。接下来,如果y值不同,则这些点必须互逆,从而返回无穷远点,因此返回《0x00》《0x00》。这对应于点加法的定义(3)。最后,如果x值不同,则代码执行不同的点加法[different point addition],这对应于点加法的定义(1)。
[0272]
这就完成了脚本中点加法的计算,最终完成了脚本中子密钥的计算。此时,堆栈的最终状态如下:
[0273]
《p
child
(x)》《p
child
(y)》 [0274]
图15示出了用于将堆栈上的数据转换为压缩密钥格式的示例性脚本。该示例性函
数将密钥的x和y坐标作为输入,并返回压缩公钥格式。对于输入《p(y)》《p(x)》,图15中的操作码定义了函数[compressed key format]。前3个操作码检查子密钥的y坐标是偶数还是奇数。然后,后续操作码根据该结果在x坐标后附加正确的前缀。这会产生压缩子密钥,从而使堆栈的最终状态如下:
[0275]
《p
child

ꢀꢀ
[0276]
或者,如果实际上希望生成非压缩格式的结果,则可以使用以下函数:
[0277]
[uncompressed key format]=op_swap op_cat《0x04》op_swap op_cat。
[0278]
结论
[0279]
应当理解,上述实施例仅通过示例的方式进行描述。更通俗地说,可根据下述任何一个或更多个语句提供一种方法、装置或程序。
[0280]
语句1、一种使用区块链事务生成消息的散列消息认证码hmac的计算机实现的方法,其中所述方法由第一方执行并且包括:生成第一区块链事务的输出脚本,其中所述输出脚本包括hmac脚本,所述hmac脚本被配置为在与第二区块链事务的输入脚本一起执行时基于输入值生成所述消息的所述hmac,其中所述输入值包含在所述第二区块链事务的所述输入脚本中;以及,使所述第一区块链事务传输到区块链网络的一个或更多个节点以使所述第一区块链事务包含在所述区块链中。
[0281]
所述hmac脚本可以被配置为使所述消息的所述hmac输出到存储器。例如,所述hmac脚本可以采用基于堆栈的语言编写,并且可以使所述hmac输出到堆栈。
[0282]
所述消息可以是明文消息,也可以是密文消息。
[0283]
语句2、根据语句1所述的方法,其中所述hmac脚本包括所述消息,所述输入值是hmac密钥,所述hmac脚本被配置为基于所述hmac密钥生成所述消息的所述hmac,其中所述hmac密钥包含在所述第二区块链事务的所述输入脚本中。
[0284]
语句3、根据语句1所述的方法,其中所述hmac脚本包括hmac密钥,所述输入值是所述消息,所述hmac脚本被配置为基于所述消息生成所述消息的所述hmac,其中所述消息包含在所述第二区块链事务的所述输入脚本中。
[0285]
语句4、根据语句1所述的方法,其中所述hmac脚本包括hmac密钥,所述输入值是至少所述hmac密钥和所述消息的散列值,所述hmac脚本被配置为基于至少所述hmac密钥和所述消息的所述散列值生成所述消息的所述hmac,其中至少所述hmac密钥和所述消息的所述散列值包含在所述第二区块链事务的所述输入脚本中。
[0286]
语句5、根据前述任一项语句所述的方法,其中所述第二区块链事务由第二方生成,并且其中所述方法包括将所述消息传输给所述第二方。
[0287]
语句6、根据前述任一项语句所述的方法,其中所述消息是明文消息的加密。
[0288]
语句7、根据前述任一项语句所述的方法,其中所述输出脚本包括hmac验证脚本,所述hmac验证脚本包括所述hmac脚本和所述消息的预定hmac,所述hmac验证脚本被配置为确定所述消息的所述预定hmac是否对应于基于所述输入值生成的所述hmac,其中所述输入值包含在所述第二区块链事务的所述输入脚本中。
[0289]
语句8、根据语句7所述的方法,其中所述hmac验证脚本被配置为在与所述第二区
块链事务的所述输入脚本一起执行时,基于有关所述消息的所述预定hmac是否对应于基于所述输入值生成的所述hmac的所述确定来输出结果,所述结果指示所述预定hmac是否对应于基于所述输入值生成的所述hmac。
[0290]
所述hmac验证脚本可以被配置为将所述结果输出到所述存储器(例如,所述堆栈),所述结果指示所述预定hmac是否对应于基于所述输入值生成的所述hmac。
[0291]
语句9、根据语句7或8所述的方法,其中所述hmac验证脚本被配置为基于有关所述消息的所述预定hmac是否对应于基于所述输入值确定的所述hmac的所述确定,在所述预定hmac不对应于基于所述输入值确定的所述hmac的情况下使所述第二事务被标记为无效事务。
[0292]
语句10、根据前述任一项语句所述的方法,其中所述第一区块链事务的所述输出脚本包括公钥导出脚本,所述公钥导出脚本包括所述hmac脚本,所述公钥导出脚本被配置为在与所述第二区块链事务的所述输入脚本一起执行时至少基于所述消息的所述确定的hmac生成新公钥。
[0293]
所述公钥导出脚本可以被配置为使所述新公钥输出到存储器(例如,所述堆栈)。
[0294]
语句11、根据语句10所述的方法,其中所述hmac脚本包括所述消息,所述消息包括先前公钥,所述输入值是链码,所述链码定义所述先前公钥在各层级公钥的层级结构中的层级,所述hmac脚本被配置为基于所述链码生成所述消息的所述hmac,其中所述链码包含在所述第二区块链事务的所述输入脚本中,所述公钥导出脚本被配置为基于所述先前公钥以及基于所述链码生成的所述hmac来生成所述新公钥。
[0295]
语句12、根据语句10所述的方法,其中所述hmac脚本包括链码,所述链码定义先前公钥在各层级公钥的层级结构中的层级,所述输入值包括所述先前公钥,所述hmac脚本被配置为基于所述先前公钥生成所述消息的所述hmac,其中所述先前公钥包含在所述第二区块链事务的所述输入脚本中,所述公钥导出脚本被配置为基于所述先前公钥以及基于所述先前公钥生成的所述hmac来生成所述新公钥。
[0296]
语句13、根据语句10所述的方法,其中所述hmac脚本包括链码,所述链码定义先前公钥在各层级公钥的层级结构中的层级,所述输入值是至少所述链码和所述消息的散列值,所述消息包括所述先前公钥,所述hmac脚本被配置为基于至少所述链码和所述消息的所述散列值生成所述消息的所述hmac,其中至少所述链码和所述消息的所述散列值包含在所述第二区块链事务的所述输入脚本中,所述公钥导出脚本被配置为基于所述先前公钥以及基于所述先前公钥生成的所述hmac来生成所述新公钥。
[0297]
语句14、根据语句11至13中任一项所述的方法,其中各层级公钥的所述层级结构中的每个层级包括一个或更多个公钥的序列,所述消息包括所述先前公钥和索引,所述索引定义所述先前公钥在所述先前公钥的相应层级的相应公钥序列内的位置。
[0298]
语句15、根据从属于语句12或13的语句14所述的方法,其中所述输入值包括所述索引。
[0299]
语句16、一种计算机设备,所述计算机设备包括:存储器,所述存储器包括一个或更多个存储器单元;以及,处理装置,所述处理装置包括一个或更多个处理单元,其中所述存储器存储被设置在所述处理装置上运行的代码,所述代码被配置为当在所述处理装置上运行时,执行根据语句1至15中任一项所述的方法。
[0300]
语句17、一种计算机程序,所述计算机程序包含在计算机可读存储器上并且被配置为当在根据语句16所述的计算机设备上运行时,执行根据语句1至15中任一项所述的方法。
[0301]
语句18、一种包括输出脚本的第一区块链事务,其中所述输出脚本包括散列消息认证码hmac脚本,所述hmac脚本被配置为在与第二区块链事务的输入脚本一起执行时基于输入值生成消息的所述hmac,其中所述输入值包含在所述第二区块链事务的所述输入脚本中。
[0302]
语句19、一种计算机可读存储介质,其上存储有根据语句18所述的第一区块链事务。
[0303]
根据本文公开的另一方面,可提供一种方法,所述方法包括所述第一方和所述第二方的动作。所述方法还可以包括所述节点网络的动作。
[0304]
根据本文公开的另一方面,可提供一种系统,所述系统包括所述第一方的计算机设备和所述第二方的计算机设备。所述系统还可以包括所述节点网络的计算机设备。
[0305]
根据本文公开的另一个方面,可提供一组事务,所述一组事务包括所述第一区块链事务和/或所述第二区块链事务。
[0306]
一旦给出本文的公开内容,所公开技术的其他变体或用例对于本领域技术人员可能变得显而易见。本公开的范围不受所描述的实施例限制,而仅受随附权利要求限制。
再多了解一些

本文用于创业者技术爱好者查询,仅供学习研究,如用于商业用途,请联系技术所有人。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献