GASP — 图形智能同步协议
补丁候选人 1.3.10 更新打包的第一当事方运行时间或开发依赖范围。 此只使用元数据补丁保存了公共API,对等范围,有线格式和默认. 不需要额外的消费者或数据迁移;早期的迁移指南仍然适用.
这个 图形意识同步协议 (GASP)是两个或两个以上当事方之间同步BSV交易数据的强大协议. 与简单化的“UTXO列表”或“交易推进”机制不同,GASP允许每个参与者逐步建立一个 图表 交易的祖先和后代。 这确保:
- 合法性:缔约方只能通过使用Merkle证明、脚本评估以及SPV的其他规则来最后确定它们能够验证的数据.
- 完整性: 反之,每一方抽取证明正确性所需的投入——避免部分或 " 中断 " 交易数据.
- 效率:每个参与者只获取和传输数据 没有 已经有, 最小化带宽.
- 灵活性: 自定义存储、自定义远程机制, 单向 同步, 货币选项, 还有更多 .
目录
关键特性
- 递归同步: 只获取所需的交易输出和 递归 按需获取输入数据.
- 元数据支持:可选交换每笔交易或产出的元数据(如发票数据,说明,篮子或专题成员等).
- 证明安打:每次交易可附加默克勒证明,确保链上可核查.
- 单向: 如果需要, 您可以配置“ 仅推出” 模式, 即从远程获取数据, 但绝不按自己的模式 .
- 选择性货币: 使用边框平行取取取或相继取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取.
- 灵活融合编号:
GASPStorage财务报告和审定财务报表GASPRemote接口允许您与自己的存储逻辑或远程传输进行集成.
如何运作
- 初始请求:一个对等方发起请求,包括双方最后一次同步时的时间戳.
- 初步反应: 另一对等方返回自该时间戳以来观察到的一组UTXO, 加上一个“自”时间戳, 用于潜在“复制”
- 递归图形大楼数字 :
- 每一方都要求提供每个未知UTXO的交易数据(可选包括元数据).
- 每次新收到的交易可能包含更多未知输入,从而引发进一步获取.
- 最后敲定: 一旦获取所有所需的输入,每个对等端会将新验证的交易数据定稿到自己的存储中.
- 可选“补偿”: 在一个 双向 假设情况,第二对等方则采取同样做法,确保两者最终都有一套一致的数据.
如果你设置 GASP 到 单向,第5步被跳过:您的本地节点只是从远程提取数据,但从不发送数据.
双向父假设 : 五进制
submitNode(node)信件确实 不携带spentBy父关节。 被推倒的孩子的接收者必须 因此,父母已经有必要验证这一边缘。 如果是这样 而不是,它必须在随后的同步回合中请求父程序或 拒绝图表。 只拉模式避免了这种假设,因为请求者 已经知道它所要求的精确的父输入 。 永远不接受未知的 父母的边缘仅仅因为同伴提交孩子.
安装
npm i @bsv/gasp
或者,如果你用 yarn数字 :
yarn add @bsv/gasp
快速启动
下面是一个裸骨配方 让GASP起来运行.
1. 执行 GASPStorage 接口
这个 GASP 组合 界面是您的本地“ 数据库层 ”。 它控制您如何存储 UTXOs, 您如何获取它们, 以及如何处理部分交易图表 .
import { GASPNode, GASPNodeResponse, GASPStorage } from '@bsv/gasp'
export class MyCustomStorage implements GASPStorage {
async findKnownUTXOs(since: number) {
/* return an array of unspent TXID-outputIndices since `since` timestamp */
}
async hydrateGASPNode(graphID: string, txid: string, outputIndex: number, metadata: boolean) {
/* return the GASPNode with rawTx, proof, metadata, etc. */
}
async findNeededInputs(tx: GASPNode): Promise<GASPNodeResponse | void> {
/* optionally request more inputs if needed*/
}
async appendToGraph(tx: GASPNode, spentBy?: string) {
/* store the node in some temporary graph structure*/
}
async validateGraphAnchor(graphID: string) {
/* confirm the graph is anchored in the blockchain or otherwise valid*/
}
async discardGraph(graphID: string) {
/* if invalid, discard it */
}
async finalizeGraph(graphID: string) {
/* finalize the validated graph into local storage*/
}
}
2. 实施(或获取)a GASPRemote
A 类 GASP 读取 你是如何与一个 远程 GASP对等。 您可以执行自己的 HTTP 获取逻辑, 使用基于 WebSocket 的方法, 或甚至在同一过程中运行一切用于测试 .
import { GASPRemote, GASPNode, GASPInitialRequest, GASPInitialResponse } from '@bsv/gasp'
export class MyRemote implements GASPRemote {
async getInitialResponse(request: GASPInitialRequest): Promise<GASPInitialResponse> {
// Call remote peer and return their data
// ...
}
async getInitialReply(response: GASPInitialResponse) {
// Only needed if doing bidirectional sync
// ...
}
async requestNode(
graphID: string,
txid: string,
outputIndex: number,
metadata: boolean
): Promise<GASPNode> {
// Request a node from the remote
// ...
}
async submitNode(node: GASPNode) {
// In a bidirectional sync, we push our node to the remote
// ...
}
}
3. 初始化和同步
最后,创建 GASP 实例,并呼叫 sync()数字 :
import { GASP, LogLevel } from '@bsv/gasp'
// 1. Create your storage
const myStorage = new MyCustomStorage()
// 2. Create your remote (or re-use an existing GASP instance as the remote)
const myRemote = new MyRemote()
// 3. Instantiate GASP
const gasp = new GASP(
myStorage,
myRemote,
/* lastInteraction= */ 0,
/* logPrefix= */ '[GASP] ',
/* log= */ false, // legacy logging toggle
/* unidirectional= */ true, // choose pull-only when the receiver will not already have parents
/* logLevel= */ LogLevel.INFO,
/* sequential= */ false // if true, tasks run one-at-a-time rather than in parallel
)
// 4. Trigger the sync
gasp
.sync()
.then(() => console.log('GASP sync complete!'))
.catch(err => console.error('GASP sync error:', err))
实例
最小示例
如果您想要快速演示从远程提取数据, 您可以看到一个简短的例子 在我们的测试中。这个代码片段显示了一种超简单的方法:
import { GASP } from '@bsv/gasp'
// ...Suppose we have minimal storage and remote classes from above...
const aliceStorage = new MyCustomStorage()
const bobRemote = new MyRemote()
// Create GASP instance
const aliceGASP = new GASP(aliceStorage, bobRemote, 0, '[GASP] ', false, true)
// Run the sync
await aliceGASP.sync()
高级示例 : sequential 和日志级别
有时,执行过多的并行操作(例如写到数据库)会导致锁定问题. 另外,你也许想控制日志的动词.
import { GASP, LogLevel } from '@bsv/gasp'
const gasp = new GASP(
myStorage, // Implementation of GASPStorage
myRemote, // Implementation of GASPRemote
0, // lastInteraction timestamp
'[GASP Demo] ', // logPrefix
false, // old boolean log toggle, for backwards-compat
true, // choose pull-only when the receiver cannot assume parent availability
LogLevel.DEBUG, // Use DEBUG or WARN/ERROR
true // sequential? If true, GASP will do tasks in sequence
)
await gasp.sync()
单向拉动同步
GASP v1 支持只拉操作,这在SPV客户端使用中很常见.
过 true 明确表明,当接收者不得依赖已经拥有
用于在回复中按下半个节点的父进程 。 双向用户必须应用
以上描述的母假设.
// Alice sets unidirectional = true
// She only wants to receive data from Bob, not share her own data
const gaspAlice = new GASP(
aliceStorage,
bobRemote,
0,
'[GASP-Alice] ',
false,
true // unidirectional is set to true
)
await gaspAlice.sync()
// Alice's local store is updated with Bob's UTXOs, but Bob sees no new data from Alice
处理“深入”交易和元数据
收到新交易后,GASP会打电话给你 findNeededInputs(...) 方法。 如果您需要更多数据(例如验证脚本Sig或自定义元数据字段),只需返回 a requestedInputs 显示您需要的输入对象。 GASP会自动从遥控器中请求它们.
async findNeededInputs(tx: GASPNode): Promise<GASPNodeResponse | void> {
// Suppose any transaction with "magic" in the outputMetadata needs further inputs
if (tx.outputMetadata?.includes('magic')) {
return {
requestedInputs: {
// outpoint -> { metadata: boolean }
'some_txid.0': { metadata: true },
'some_txid.1': { metadata: false }
}
}
}
// If none needed, return undefined
}
您的远程端点 requestNode(...) 方法将交付这些缺失的棋子(如果存在的话),确保构建一个“深”交易图.
将每个远程响应视为不信任. 储存/运输执行 必须将每个节点的原始交易ID和输出索引绑定在请求中,验证 每个儿童都是其父母要求的实际投入,孤立临时 图表、绑定的图表字节和节点计数、拒绝循环/冲突开支,以及 只有在确定一个积极的主干和专题政策后才能定稿。 HTTP 密码 运输工具还必须使用经认证的公用HTTPS、拒绝重定向,以及 在字节和时间限制下对流响应.
有用链接
- 全面试验编号: 测试套件 覆盖从版本不匹配到复发边缘大小写的全部内容.
- 现实世界一体化: 见
OverlayGASPStorage财务报告和审定财务报表OverlayGASPRemote在此 生产适配器的工作空间.
发展与分配
运行软件包工作 ts-stack 带有 Node.js 24.11 或
较新的和pnpm 10:
pnpm install
pnpm --filter @bsv/gasp format:check
pnpm --filter @bsv/gasp lint
pnpm --filter @bsv/gasp typecheck
pnpm --filter @bsv/gasp test:coverage
pnpm --filter @bsv/gasp pack:check
覆盖门会扭曲声明、分支、功能和线条.
pack:check 在无害环境管理和普通JS中建立和安装准确的 npm 沥青球
消费者项目,然后核查出口和有条件的类型。 出版内容为
属于仓库发布工作流程; 本地检查不更改版本
或发表.
财务问题
-
GASP处理相互矛盾的交易吗?
GASP是,我们 不可知论 关于冲突。 由你决定GASPStorage执行决定如何处理双重开支或冲突国家. -
我如何只进行“SPV证明”验证? GASP 包括通过
proof字段。 狦validateGraphAnchor(...)检查他们,你得到有效的 SPV级验证. -
专门的元数据或政策如何? GASP曾经是 已建成 对于这个。 使用
txMetadata, (中文(简体) ),outputMetadata,或inputs存储并传播任何自定义数据。 如果需要, 您的代码可以收集额外的输入 . -
如果远程无法提供数据呢? GASP的复发停止。 如果您从未收到您要求的输入, 您就永远不会完成交易 。 这确保了连贯的部分或全部定稿.
许可证
当前 TS Stack 更改根据 Open BSV 许可证版本 6 获得许可; 参见
LICENSE.txt (英语)。该软件包还保留了统一前代码
在开放BSV许可证版本4下. 补给者必须保留
第三次议会 NoTICES.md 和适用的文本在
LICENSES/。 。 。 .
SDK4 热补丁对等要求
SDK4 对等替代开始于 @bsv/sdk ^4.0.1,恢复数字
钱包结果和遗留线条相容性。 现有的SDK2/3替代品和
下限不变。 SDK4 用户应安装 4. 0.1 个热补丁; 不
需要应用程序-wallet线或数据迁移.