Substreams-powered subgraphs
Reading time: 8 min
は、StreamingFastがThe Graph Networkのために開発した、ブロックチェーンのデータを処理するための新しいフレームワークである。サブストリームモジュールは、サブグラフエンティティと互換性のあるエンティティの変更を出力することができます。サブグラフはこのようなサブストリームモジュールをデータソースとして使用することができ、サブストリームのインデックス作成速度と追加データをサブグラフ開発者にもたらします。
This cookbook requires , , and the latest version of Graph CLI (>=0.52.0):
npm install -g @graphprotocol/graph-cli
グラフ初期化 --from-example substreams-powered-subgraph
Substreamsパッケージは、型(として定義される)、モジュール(Rustで記述される)、および型を参照し、モジュールがどのようにトリガーされるかを指定するsubstreams.yaml
ファイルで構成されます。してください。また、やを参照してください。
問題の Substreams パッケージは、メインネット イーサリアム上のコントラクトのデプロイメントを検出し、新しくデプロイされたすべてのコントラクトの作成ブロックとタイムスタンプを追跡します。これを行うには、/proto/example.proto
に専用の Contract
タイプがあります ():
syntax = "proto3";package example;message Contracts {repeated Contract contracts = 1;}message Contract {string address = 1;uint64 blockNumber = 2;string timestamp = 3;uint64 ordinal = 4;}
Substreams パッケージのコア ロジックは、lib.rs
の map_contract
モジュールです。これは、すべてのブロックを処理し、元に戻されなかった Create 呼び出しをフィルタリングして、Contracts
を返します。
#[substreams::handlers::map]fn map_contract(block: eth::v2::Block) -> Result<Contracts, substreams::errors::Error> {let contracts = block.transactions().flat_map(|tx| {tx.calls.iter().filter(|call| !call.state_reverted).filter(|call| call.call_type == eth::v2::CallType::Create as i32).map(|call| Contract {address: format!("0x{}", Hex(&call.address)),block_number: block.number,timestamp: block.timestamp_seconds().to_string(),ordinal: tx.begin_ordinal,})}).collect();Ok(Contracts { contracts })
Substreams パッケージは、互換性のあるエンティティの変更を出力するモジュールを持っている限り、サブグラフで使用できます。サンプルの Substreams パッケージには、「lib.rs」内に追加の「graph_out」モジュールがあり、グラフ ノードで処理できる「substreams_entity_change::pb::entity::EntityChanges」出力を返します。
「substreams_entity_change」クレートには、エンティティの変更を単純に生成するための専用の「Tables」関数もあります ([)。生成されたエンティティ変更は、対応するサブグラフの subgraph.graphql
で定義された schema.graphql
エンティティと互換性がある必要があります。
#[substreams::handlers::map]pub fn graph_out(contracts: Contracts) -> Result<EntityChanges, substreams::errors::Error> {// hash map of name to a tablelet mut tables = Tables::new();for contract in contracts.contracts.into_iter() {tables.create_row("Contract", contract.address).set("timestamp", contract.timestamp).set("blockNumber", contract.block_number);}Ok(tables.to_entity_changes())}
これらの型とモジュールは substreams.yaml
にまとめられています。
specVersion: v0.1.0package:name: 'substreams_test' # the name to be used in the .spkgversion: v1.0.1 # the version to use when creating the .spkgimports: # dependenciesentity: https://github.com/streamingfast/substreams-entity-change/releases/download/v0.2.1/substreams-entity-change-v0.2.1.spkgprotobuf: # specifies custom types for use by Substreams modulesfiles:- example.protoimportPaths:- ./protobinaries:default:type: wasm/rust-v1file: ./target/wasm32-unknown-unknown/release/substreams.wasmmodules: # specify modules with their inputs and outputs.- name: map_contractkind: mapinputs:- source: sf.ethereum.type.v2.Blockoutput:type: proto:test.Contracts- name: graph_outkind: mapinputs:- map: map_contractoutput:type: proto:substreams.entity.v1.EntityChanges # this type can be consumed by Graph Node
substreams chart
を実行することで、ブロックから map_contract
、graph_out
までの全体的な「フロー」を確認できます。
この Substreams パッケージをサブグラフで使用できるように準備するには、次のコマンドを実行する必要があります。
yarn substreams:protogen # generates types in /src/pbyarn substreams:build # builds the substreamsyarn substreams:package # packages the substreams in a .spkg file# alternatively, yarn substreams:prepare calls all of the above commands
基礎となるサブストリーム コマンドを理解したい場合は、これらのスクリプトは「package.json」ファイルで定義されます。
これにより、「substreams.yaml」のパッケージ名とバージョンに基づいて「spkg」ファイルが生成されます。 「spkg」ファイルには、グラフ ノードがこのサブストリーム パッケージを取り込むために必要なすべての情報が含まれています。
Substreams パッケージを更新する場合、加えた変更に応じて、spkg
を最新にするために上記のコマンドの一部またはすべてを実行する必要がある場合があります。
サブストリームによって動作するサブグラフは、新しい "substreams" というデータソースの kind を導入します。このようなサブグラフは、ただ1つのデータソースのみを持つことができます
このデータ ソースは、インデックス付きネットワーク、相対的なファイルの場所としての Substreams パッケージ (spkg
)、およびサブグラフ互換のエンティティ変更を生成するその Substreams パッケージ内のモジュール (この場合は、上記の Substreams パッケージからの map_entity_changes
) を指定する必要があります。マッピングは指定されていますが、単にマッピングの種類 (「サブストリーム/グラフ エンティティ」) と apiVersion を識別するだけです。
Currently, Subgraph Studio and The Graph Network support Substreams-powered subgraphs which index mainnet
(Mainnet Ethereum).
specVersion: 0.0.4description: Ethereum Contract Tracking Subgraph (powered by Substreams)repository: https://github.com/graphprotocol/graph-toolingschema:file: schema.graphqldataSources:- kind: substreamsname: substream_testnetwork: mainnetsource:package:moduleName: graph_outfile: substreams-test-v1.0.1.spkgmapping:kind: substreams/graph-entitiesapiVersion: 0.0.5
subgraph.yaml
もスキーマ ファイルを参照します。このファイルの要件は変更されていませんが、指定されたエンティティは、subgraph.yaml
で参照される Substreams モジュールによって生成されるエンティティの変更と互換性がある必要があります。
type Contract @entity {id: ID!"The timestamp when the contract was deployed"timestamp: String!"The block number of the contract deployment"blockNumber: BigInt!}
上記を考慮すると、サブグラフ開発者は Graph CLI を使用して、このサブストリームを利用したサブグラフをデプロイできます。
yarn install # install graph-cliyarn subgraph:build # build the subgraphyarn subgraph:deploy # deploy the subgraph
それでおしまい!サブストリームを利用したサブグラフを構築してデプロイしました。
サブストリームを利用したサブグラフを提供するには、チェーン ヘッドを追跡するための Firehose または RPC だけでなく、関連するネットワークのサブストリーム プロバイダーを使用してグラフ ノードを構成する必要があります。これらのプロバイダーは、「config.toml」ファイル経由で設定できます。
[chains.mainnet]shard = "main"protocol = "ethereum"provider = [{ label = "substreams-provider-mainnet",details = { type = "substreams",url = "https://mainnet-substreams-url.grpc.substreams.io/",token = "exampletokenhere" }},{ label = "firehose-provider-mainnet",details = { type = "firehose",url = "https://mainnet-firehose-url.grpc.firehose.io/",token = "exampletokenhere" }},]