在 Arweave 上构建子图
Reading time: 9 min
Arweave support in Graph Node and on Subgraph Studio is in beta: please reach us on with any questions about building Arweave subgraphs!
在本指南中,您将学习如何构建和部署子图以索引Arweave区块链。
Arweave 协议允许开发者永久存储数据,这是 Arweave 和 IPFS 的主要区别,IPFS 没有这个特性,永久性和存储在 Arweave 上的文件不能被更改或删除。
Arweave 已经构建了许多库,用于将协议集成到许多不同的编程语言中。更多信息可以查看:
Graph 允许您构建称为“子图 ”的自定义开放 API。子图用于告诉索引人(服务器操作员) 在区块链上索引哪些数据,并保存在他们的服务器上,以便您能够在任何时候使用 查询它。
现在能够在 Arweave 协议上索引数据。当前的集成只是索引 Arweave 作为一个区块链(区块和交易) ,它还没有索引存储的文件。
为了能够构建和部署 Arweave 子图,您需要两个包:
@graphprotocol/graph-cli
高于0.30.2版本-这是一个用于构建和部署子图的命令行工具。下载使用npm
。@ graph protocol/graph-ts
0.27.0以上版本-这是子图特定类型的库。下载使用npm
。
一个子图有三个组成部分:
定义感兴趣的数据源,以及如何处理它们。Arweave是一种新型数据源。
在这里,您可以定义在使用 GraphQL 索引子图之后希望能够查询的数据。这实际上类似于 API 的模型,其中模型定义了请求主体的结构。
这种逻辑决定了当有人与您正在监听的数据源进行交互时,应该如何检索和存储数据。数据将被翻译并根据您列出的模式进行存储。
在子图开发过程中,有两个关键命令:
$ graph codegen # 从清单中标识的模式文件生成类型$ graph build # 从 AssemblyScript 文件生成 Web Assembly,并在 /build 文件夹中准备所有子图文件
子图清单subgraph.yaml
标识子图的数据源、感兴趣的触发器以及应该响应这些触发器而运行的函数。下面是 Arweave 子图的子图清单示例:
specVersion: 0.0.5description: Arweave Blocks Indexingschema:file: ./schema.graphql # link to the schema filedataSources:- kind: arweavename: arweave-blocksnetwork: arweave-mainnet # The Graph only supports Arweave Mainnetsource:owner: 'ID-OF-AN-OWNER' # The public key of an Arweave walletstartBlock: 0 # set this to 0 to start indexing from chain genesismapping:apiVersion: 0.0.5language: wasm/assemblyscriptfile: ./src/blocks.ts # link to the file with the Assemblyscript mappingsentities:- Block- TransactionblockHandlers:- handler: handleBlock # the function name in the mapping filetransactionHandlers:- handler: handleTx # the function name in the mapping file
- Arweave子图引入了一种新的数据源(
arweave
) - The network should correspond to a network on the hosting Graph Node. In Subgraph Studio, Arweave's mainnet is
arweave-mainnet
- Arweave 数据源引入了一个可选的 source. owner 字段,它是 Arweave 钱包的公钥
Arweave 数据源支持两种类型的处理程序:
blockHandlers
在每个新的 Arweave 区块上运行,不需要 source. owner。transactionHandlers
- 在数据源的source.owner
是所有者的每个交易上运行。目前,transactionHandlers
需要一个所有者,如果用户想要处理所有交易,他们应该提供""作为source.owner
Source.Owner 可以是所有者的地址,也可以是他们的公钥。
交易是 Arweave permaweb 的构建区块,它们是终端用户创建的对象。
数据查询结构定义描述了生成的子图数据库的结构以及实体之间的关系,无需与原始数据源有关。有关于子图模式定义的更多细节。
Arweave 索引向 引入了特定于 Arweave 的数据类型。
class Block {timestamp: u64lastRetarget: u64height: u64indepHash: Bytesnonce: BytespreviousBlock: Bytesdiff: Byteshash: BytestxRoot: Bytestxs: Bytes[]walletList: BytesrewardAddr: Bytestags: Tag[]rewardPool: BytesweaveSize: BytesblockSize: BytescumulativeDiff: ByteshashListMerkle: Bytespoa: ProofOfAccess}class Transaction {format: u32id: ByteslastTx: Bytesowner: Bytestags: Tag[]target: Bytesquantity: Bytesdata: BytesdataSize: BytesdataRoot: Bytessignature: Bytesreward: Bytes}
区块处理程序接收Block
,而交易接收Transaction
.。
写 Arweave 子图的映射与写 Etherum 子图的映射非常相似。了解更多信息,请点击。
Once your subgraph has been created on your Subgraph Studio dashboard, you can deploy by using the graph deploy
CLI command.
graph deploy --studio --access-token <your-access-token>
Arweave 子图的 GraphQL 端点由模式定义和现有的 API 接口决定。有关更多信息,请访问 。
下面是一个子图的例子,以供参考:
不,子图只能支持来自一个链/网络的数据源。
目前,Graph 只是将 Arweave 索引为区块链(它的区块和交易)。
目前还不支持。
Source.owner可以是用户的公钥或账户地址。
数据通常以字节的形式传递到映射中,如果直接存储字节,则以十六进制
格式(例如,区块和和交易hashes)返回。您可能希望在映射中转换为 base64
或 base64 URL
安全格式,以便与 等区块浏览器中显示的内容相匹配。
可以使用以下 bytesToBase64(字节: Uint8Array,urlSafe: boolean): string
辅助函数,并将其添加到 graph-ts
:
const base64Alphabet = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M","N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z","a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m","n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z","0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"];const base64UrlAlphabet = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M","N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z","a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m","n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z","0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-", "_"];function bytesToBase64(bytes: Uint8Array, urlSafe: boolean): string {let alphabet = urlSafe? base64UrlAlphabet : base64Alphabet;let result = '', i: i32, l = bytes.length;for (i = 2; i < l; i += 3) {result += alphabet[bytes[i - 2] >> 2];result += alphabet[((bytes[i - 2] & 0x03) << 4) | (bytes[i - 1] >> 4)];result += alphabet[((bytes[i - 1] & 0x0F) << 2) | (bytes[i] >> 6)];result += alphabet[bytes[i] & 0x3F];}if (i === l + 1) { // 1 octet yet to writeresult += alphabet[bytes[i - 2] >> 2];result += alphabet[(bytes[i - 2] & 0x03) << 4];if (!urlSafe) {result += "==";}}if (!urlSafe && i === l) { // 2 octets yet to writeresult += alphabet[bytes[i - 2] >> 2];result += alphabet[((bytes[i - 2] & 0x03) << 4) | (bytes[i - 1] >> 4)];result += alphabet[(bytes[i - 1] & 0x0F) << 2];if (!urlSafe) {result += "=";}}return result;}