8 分
Arweaveでのサブグラフ構築
Arweave support in Graph Node and on Subgraph Studio is in beta: please reach us on Discord with any questions about building Arweave Subgraphs!
このガイドでは、Arweaveブロックチェーンのインデックスを作成するためのサブグラフの構築とデプロイ方法について学びます。
Arweaveとは?
Arweave プロトコルは、開発者がデータを永久に保存することを可能にし、それが Arweave と IPFS の主な違いです。IPFSは永続性に欠ける一方、Arweaveに保存されたファイルは変更も削除もできません。
Arweaveは既に、さまざまなプログラミング言語でプロトコルを統合するための多数のライブラリを構築しています。詳細については、次を確認できます。
Arweaveサブグラフとは?
The Graph allows you to build custom open APIs called “Subgraphs”. Subgraphs are used to tell indexers (server operators) which data to index on a blockchain and save on their servers in order for you to be able to query it at any time using GraphQL.
Graph Node is now able to index data on Arweave protocol. The current integration is only indexing Arweave as a blockchain (blocks and transactions), it is not indexing the stored files yet.
Arweave サブグラフの作成
Arweaveのサブグラフを構築し展開できるようにするためには、2つのパッケージが必要です。
@graphprotocol/graph-cli
above version 0.30.2 - This is a command-line tool for building and deploying Subgraphs. Click here to download usingnpm
.@graphprotocol/graph-ts
above version 0.27.0 - This is library of Subgraph-specific types. Click here to download usingnpm
.
サブグラフのコンポーネント
There are three components of a Subgraph:
1. Manifest - subgraph.yaml
対象のデータ ソースとその処理方法を定義します。 Arweave は新しい種類のデータ ソースです。
2. Schema - schema.graphql
ここでは、GraphQL を使用してサブグラフにインデックスを付けた後にクエリできるようにするデータを定義します。これは実際には API のモデルに似ており、モデルはリクエスト本文の構造を定義します。
The requirements for Arweave Subgraphs are covered by the existing documentation.
3. AssemblyScript Mappings - mapping.ts
これは、リスニングしているデータソースと誰かがやりとりするときに、データをどのように取得し、保存するかを決定するロジックです。データは変換され、あなたがリストアップしたスキーマに基づいて保存されます。
During Subgraph development there are two key commands:
1$ graph codegen # generates types from the schema file identified in the manifest2$ graph build # generates Web Assembly from the AssemblyScript files, and prepares all the Subgraph files in a /build folder
サブグラフマニフェストの定義
The Subgraph manifest subgraph.yaml
identifies the data sources for the Subgraph, the triggers of interest, and the functions that should be run in response to those triggers. See below for an example Subgraph manifest for an Arweave Subgraph:
1specVersion: 1.3.02description: Arweave Blocks Indexing3schema:4 file: ./schema.graphql # link to the schema file5dataSources:6 - kind: arweave7 name: arweave-blocks8 network: arweave-mainnet # The Graph only supports Arweave Mainnet9 source:10 owner: 'ID-OF-AN-OWNER' # The public key of an Arweave wallet11 startBlock: 0 # set this to 0 to start indexing from chain genesis12 mapping:13 apiVersion: 0.0.914 language: wasm/assemblyscript15 file: ./src/blocks.ts # link to the file with the Assemblyscript mappings16 entities:17 - Block18 - Transaction19 blockHandlers:20 - handler: handleBlock # the function name in the mapping file21 transactionHandlers:22 - handler: handleTx # the function name in the mapping file
- Arweave Subgraphs introduce a new kind of data source (
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データソースは 2 種類のハンドラーをサポートしています:
blockHandlers
- Run on every new Arweave block. No source.owner is required.transactionHandlers
- Run on every transaction where the data source’ssource.owner
is the owner. Currently an owner is required fortransactionHandlers
, if users want to process all transactions they should provide "" as thesource.owner
Source.owner は、所有者のアドレスまたは公開鍵にすることができます。
トランザクションはArweave permawebの構成要素であり、エンドユーザーによって作成されるオブジェクトです。
Note: Irys (previously Bundlr) transactions are not supported yet.
スキーマ定義
Schema definition describes the structure of the resulting Subgraph database and the relationships between entities. This is agnostic of the original data source. There are more details on the Subgraph schema definition here.
AssemblyScript マッピング
The handlers for processing events are written in AssemblyScript.
Arweave indexing introduces Arweave-specific data types to the AssemblyScript API.
1class Block {2 timestamp: u643 lastRetarget: u644 height: u645 indepHash: Bytes6 nonce: Bytes7 previousBlock: Bytes8 diff: Bytes9 hash: Bytes10 txRoot: Bytes11 txs: Bytes[]12 walletList: Bytes13 rewardAddr: Bytes14 tags: Tag[]15 rewardPool: Bytes16 weaveSize: Bytes17 blockSize: Bytes18 cumulativeDiff: Bytes19 hashListMerkle: Bytes20 poa: ProofOfAccess21}2223class Transaction {24 format: u3225 id: Bytes26 lastTx: Bytes27 owner: Bytes28 tags: Tag[]29 target: Bytes30 quantity: Bytes31 data: Bytes32 dataSize: Bytes33 dataRoot: Bytes34 signature: Bytes35 reward: Bytes36}
Block handlers receive a Block
, while transactions receive a Transaction
.
Writing the mappings of an Arweave Subgraph is very similar to writing the mappings of an Ethereum Subgraph. For more information, click here.
Deploying an Arweave Subgraph in Subgraph Studio
Once your Subgraph has been created on your Subgraph Studio dashboard, you can deploy by using the graph deploy
CLI command.
1graph deploy --access-token <your-access-token>
Arweaveサブグラフのクエリ
The GraphQL endpoint for Arweave Subgraphs is determined by the schema definition, with the existing API interface. Please visit the GraphQL API documentation for more information.
サブグラフの例
Here is an example Subgraph for reference:
FAQ
Can a Subgraph index Arweave and other chains?
No, a Subgraph can only support data sources from one chain/network.
保存されたファイルをArweaveでインデックス化することはできますか?
現在、The Graph は Arweave をブロックチェーン (ブロックとトランザクション) としてのみインデックス化しています。
Can I identify Bundlr bundles in my Subgraph?
現在はサポートされていません。
トランザクションを特定のアカウントにフィルターするにはどうすればよいですか?
Source.ownerには、ユーザの公開鍵またはアカウントアドレスを指定することができます。
現在の暗号化フォーマットは?
Data is generally passed into the mappings as Bytes, which if stored directly is returned in the Subgraph in a hex
format (ex. block and transaction hashes). You may want to convert to a base64
or base64 URL
-safe format in your mappings, in order to match what is displayed in block explorers like Arweave Explorer.
The following bytesToBase64(bytes: Uint8Array, urlSafe: boolean): string
helper function can be used, and will be added to graph-ts
:
1const base64Alphabet = [2 "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",3 "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",4 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",5 "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",6 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"7];89const base64UrlAlphabet = [10 "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",11 "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",12 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",13 "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",14 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-", "_"15];1617function bytesToBase64(bytes: Uint8Array, urlSafe: boolean): string {18 let alphabet = urlSafe? base64UrlAlphabet : base64Alphabet;1920 let result = '', i: i32, l = bytes.length;21 for (i = 2; i < l; i += 3) {22 result += alphabet[bytes[i - 2] >> 2];23 result += alphabet[((bytes[i - 2] & 0x03) << 4) | (bytes[i - 1] >> 4)];24 result += alphabet[((bytes[i - 1] & 0x0F) << 2) | (bytes[i] >> 6)];25 result += alphabet[bytes[i] & 0x3F];26 }27 if (i === l + 1) { // 1 octet yet to write28 result += alphabet[bytes[i - 2] >> 2];29 result += alphabet[(bytes[i - 2] & 0x03) << 4];30 if (!urlSafe) {31 result += "==";32 }33 }34 if (!urlSafe && i === l) { // 2 octets yet to write35 result += alphabet[bytes[i - 2] >> 2];36 result += alphabet[((bytes[i - 2] & 0x03) << 4) | (bytes[i - 1] >> 4)];37 result += alphabet[(bytes[i - 1] & 0x0F) << 2];38 if (!urlSafe) {39 result += "=";40 }41 }42 return result;43}