---
title: 跨链之间交易验证
---

## 面临的问题

链间应用程序对于数字资产生态系统而言并不是新事物。 实际上，就用户和数量而言，即使是较小的集中式交换机也绝对使所有组合在一起的单链应用程序相形见绌。 他们估值巨大，并花费了数年时间为众多最终用户有效地优化了其核心产品。 但是，它们的基本都要求用户单方面信任其机制，通常很少或根本没有追索权或对意外损失的保护。 这导致更广泛的数字资产生态沿网络断裂，因为互操作性解决方案通常具有以下特点：

- 技术复杂，无法全面实施
- 网络规模激励机制不稳定
- 要求质押者之间保持一致和高级别合作

## 拟定的解决方案

简单付款验证\(SPV\) 是大多数主要区块链网络上的轻客户端使用的一系列不同方法的通用术语，用于验证网络状态的各个方面，而无需完全存储和维护链本身的负担。 在大多数情况下，这意味着要依靠某种哈希树的形式，通过与该区块标头中的根哈希值或等效值进行比较，来证明某个交易中存在给定交易的证据。 这允许轻量级客户端或钱包本身就链上事件达到概率的确定性级别，而对网络节点的信任度要求最低。

传统上，这些证明的组装和验证过程是由节点，钱包或其他客户端在链下执行的，但它也为链间状态验证提供了一种潜在的机制。 但是，通过将验证SPV证明作为智能合约在链上的功能转移到一边，同时又利用了区块链固有的存储属性，有可能构建一个系统来以编程方式检测和验证其他网络上的交易，而无需涉及任何类型的受信任预言机或复杂的多阶段共识机制。 此概念可广泛应用于具有SPV机制的任何网络，甚至可以在其他智能合约平台上双向操作，从而开辟了廉价、快速链间价值转移的可能性，而无需依赖抵押品，哈希锁或受信任的中介机构。

选择利用所有主要区块链已经通用的，建立良好且发展稳定的机制，可以使基于SPV的互操作性解决方案比精心设计的多阶段方法要简单得多。 为此，他们无需广泛同意的跨链通信标准，也不需要大型的多方组织来编写它们，而是支持一套离散的基于合约的服务，这些服务可以由主叫合约通过通用的抽象格式协议轻松地使用。 这将为广泛的应用程序和合约奠定基础，这些应用和合约能够在多样化的平台和每个成长中的平台生态中相互操作。

## 术语

SPV程序 - 链间SPV系统的面向客户端的界面，管理参与者的角色。 SPV引擎 - 验证交易证明，为SPV程序的子集。 客户 - SPV程序的调用者，通常是另一个solana合约。 证明者 - 生成交易证明并将其提交给SPV程序的一方。 交易证明 - 由Provers创建，包含商业证明，交易和区块头参考。 Merkle证明 - 基本的SPV证明，用于验证特定区块中交易的存在。 区块头 - 表示给定区块的基本参数和相对位置。 证明请求 - 客户下达的由证明人验证(一笔或多笔) 交易的订单。 区块头存储 - 一种数据结构，用于存储和引用证明中区块头的范围。 客户请求 - 从客户到SPV程序的交易，以触发创建证明请求。 子帐户 - 另一个合约帐户拥有的Solana帐户，没有自己的私钥。

## 服务

SPV程序通过部署在Solana网络上的合约形式运行，并维护着SPV证明的公开市场，允许任何一方提交证明请求以及根据请求进行验证。 在任何给定时间，将有多个SPV程序实例处于活动状态，每个连接的外部网络至少有一个实例，并且每个网络可能有多个实例。 SPV程序实例的高级API和功能集将相对一致，并且货币平台\(Bitcoin, Litecoin\) 和智能合约平台之间会有一些差异，这是由于可以验证网络状态的变化，而不仅仅是交易本身。 在任何情况下，无论使用哪种网络，SPV程序都依赖于称为SPV引擎的内部组件，以提供对实际SPV证明的无状态验证，并以此为基础构建面向高级客户端的功能和api。 SPV引擎需要针对特定网络实施，但支持执行该实施并将其放入标准SPV程序中进行部署的任何团队，都可以轻松扩展较大的链间生态。

在Proof Request中，请求者被称为程序客户端， 在大多数情况下，如果不是所有情况下都是另一份Solana合约。 客户可以选择提交与特定交易有关的请求，也可以选择更广泛的过滤器，该过滤器可以应用于交易的一系列参数中的任何一个，包括其输入，输出和金额。 例如，客户可以在一定时间后提交从给定地址A发送到地址B且金额为X的任何交易的请求。 此结构可用于多种应用程序，例如在原子交换的情况下验证特定的预期付款或检测贷款的抵押资产的变动。

提交客户请求后，假设已成功验证该请求，则SPV程序将创建一个证明请求帐户，以跟踪请求的进度。 证明者使用该帐户指定他们打算填写其提交以供验证的证明的请求，这时SPV程序会验证这些证明，如果成功，则将其保存到请求帐户的账户数据中。 客户可以通过查询请求帐户的帐户数据来监视其请求的状态，并查看所有适用的交易以及其证明。 在以后的迭代中，如果得到Solana的支持，则可以通过合约发布事件来简化此过程，而不需要如上所述的投票过程。

## 执行情况

Solana链间SPV机制由以下组件和参与者组成：

### SPV 引擎

部署在Solana上的合约，可以为呼叫者无状态验证SPV证明。 它需要以下参数来验证：

- 与程序关联的区块链格式正确的SPV证明
- 引用相关的(一个或多个) 区块头来比较这个证明和
- 验证交易的必要参数

  如果成功验证了相关证明，则SPV程序将保存证明

  验证到请求帐户中，调用者可以将其保存到

  其帐户数据或根据需要进行其他处理。 SPV程序也暴露在

  表示和验证标头的实用程序和结构，

  逐个链地进行交易，哈希等。

### SPV 程序

部署在Solana上的合约，用于协调和中介客户与证明者之间的交互，并管理请求、标头、证明等的验证。 这是客户合约访问链间的主要访问点。 SPV机制。 它提供以下核心功能：

- 提交证明请求 - 允许客户提出特定证明或一组证明的请求
- 取消证明请求 - 允许客户使待处理请求无效
- 填写证明请求 - 由证明人提交与给定证明请求相对应的证明，用于验证

  SPV程序会维护有效的待处理证明的公开列表

  向其证明者的利益请求其帐户数据，

  监督者对此进行监视并将对目标请求的引用及其提交的证据括起来。

### 证明请求

客户端发送到SPV引擎的消息，表示请求特定交易或一组交易的证明。 证明请求可以通过其哈希值手动指定特定交易，也可以选择提交与多个交易或交易类别匹配的过滤器。 例如，匹配“从地址xxx到地址yyy的任何交易”的过滤器可用于检测债务的支付或链间合约的结算。 同样，与“来自地址xxx的任何交易”相匹配的过滤器可以由贷款或合成代币铸造合约使用，以监视抵押品的变化并对变化做出反应。 证明请求是有偿发送的，一旦与请求相匹配的证明经过验证，SPV引擎合约会将其支付给合适的证明者。

### 请求表

可供证明者填写或客户取消有效的、开放的验证请求的公开列表。 大致类似于交易所中的订单簿，但具有单一类型的列表，而不是两个分开的双方。 它存储在SPV程序的帐户数据中。

### 证明

所涉及的区块链中存在给定交易的证明。 证明包括实际的Merkle证明和对有效顺序块头链的(一个或多个) 引用。 它们是由证明者根据SPV程序请求书上托管的可公开获得的证明请求的规范构造和提交的。 验证后，它们将保存到相关证明请求的帐户数据中，客户可以使用该数据来监视请求的状态。

### 客户

交易证明请求的发起者。 客户通常会成为其他合约，作为应用程序或特定金融产品（如贷款、掉期、托管等）的组成部分。 在任何给定的验证过程周期中，客户最初都会提交一个ClientRequest，传达参数和费用，如果成功通过验证，则结果是通过SPV程序创建证明请求帐户。 客户也可以提交一个取消请求，该取消请求引用了一个有效的证明请求，表示无效的证明。

### Prover（证明者）

填写Proof Request请求的提交人。 证明者监视SPV程序的请求书中是否有未决的证明请求，并生成匹配的证明，然后将其提交给SPV程序进行验证。 如果证据被接受，则与咨询中的Proof Request相关的费用将支付给证明者。 证明者通常充当Solana区块节点，它们也可以访问比特币节点，用于构造证明和访问区块头。

### 区块头存储

一种基于帐户的数据结构，用于维护头部区块，以便通过引用区块头部存储帐户，将其包含在提交的证明中。 区块头存储可以由独立的实体维护，因为标头区块链验证是SPV程序证明验证机制的组成部分。 请求证明所支付的费用在默认证明的提交者和提交证明中引用的标头存储之间分配。 由于当前无法增加已经分配的帐户数据容量，因此用例需要一种可以无限增长而无需重新平衡的数据结构。 子帐户是SPV程序拥有的帐户，没有其自己的私钥，这些私钥用于通过将区块头分配到其帐户数据来进行存储。 采用多种可能的办法来实施标头存储是可行的：

将区块头存储在由公共地址索引的程序子账户中：

- 每个子账户都有一个头部指针，且有一个公钥匹配的区块哈希
- 每次验证需要与确认相同数量的帐户数据
- 通过最大交易数据上限来限制确认数量\(15-20\)
- 单个区块头在网络范围内不重复

多个子帐户存储标头的链接列表：

- 维护存储帐户的顺序索引，每个存储帐户有多个标头
- 最多进行2次帐户数据查询，以进行大于&gt;99.9％的验证(大多数情况下为1)
- 紧凑的顺序数据地址格式，允许任意数量的确认和快速查找
- 促进网络范围内的区块标头复制效率低下问题
