Substreams-drivna subgrafer
Reading time: 5 min
är en ny ramverk för att behandla blockkedjedata som utvecklats av StreamingFast för The Graph Network. Ett Substreams-modul kan generera ändringar i entiteter som är kompatibla med Subgraph-entiteter. En subgraf kan använda en sådan Substreams-modul som en datakälla och därmed ta del av Substreams indexeringshastighet och ytterligare data för subgrafutvecklare.
This cookbook requires , , and the latest version of Graph CLI (>=0.52.0):
npm install -g @graphprotocol/graph-cli
graph init --from-example substreams-powered-subgraph
En Substreams-paket består av typer (definierade som ), moduler (skrivna i Rust) och en substreams.yaml
-fil som refererar till typerna och specificerar hur modulerna utlöses. , och kolla in och för fler exempel.
Substreams-paketet i fråga upptäcker kontraktsdistributioner på Mainnet Ethereum, spårar skapandeblocket och tidsstämpeln för alla nyligen distribuerade kontrakt. För att göra detta finns det en dedikerad "kontrakt"-typ i "/proto/example.proto" ():
syntax = "proto3";package example;message Contracts {repeated Contract contracts = 1;}message Contract {string address = 1;uint64 blockNumber = 2;string timestamp = 3;uint64 ordinal = 4;}
Kärnlogiken i Substreams-paketet är en map_contract
-modul i lib.rs
, som bearbetar varje block, filtrerar efter Skapa-anrop som inte återgick, returnerar 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 })}
Ett Substreams-paket kan användas av en subgraf så länge det har en modul som matar ut kompatibla enhetsändringar. Exemplet på Substreams-paketet har en extra graph_out
-modul i lib.rs
som returnerar en substreams_entity_change::pb::entity::EntityChanges
-utdata, som kan bearbetas av Graph Node.
"substreams_entity_change"-lådan har också en dedikerad "Tables"-funktion för att helt enkelt generera entitetsändringar (). Entitetsändringarna som genereras måste vara kompatibla med "schema.graphql"-entiteterna som definieras i "subgraph.graphql" i motsvarande subgraf.
#[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())}
Dessa typer och moduler dras ihop i 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
Du kan kontrollera det övergripande "flödet" från ett block, till map_contract
till graph_out
genom att köra substreams graph
:
För att förbereda detta Substreams paket för konsumtion av en subgraf måste du köra följande kommandon:
yarn substreams:protogen # genererar typer i /src/pbyarn substreams:build # bygger substreamsyarn substreams:package # paketerar substreams i en .spkg-fil# alternativt anropar yarn substreams:prepare alla ovanstående kommandon
Dessa skript definieras i filen package.json
om du vill förstå de underliggande substreams-kommandona
Detta genererar en spkg
-fil baserat på paketnamnet och versionen från substreams.yaml
. spkg
-filen har all information som Graph Node behöver för att mata in detta Substreams-paket.
Om du uppdaterar Substreams-paketet, beroende på de ändringar du gör, kan du behöva köra några eller alla ovanstående kommandon så att spkg
är uppdaterad.
Substreams-drivna subgrafer introducerar en ny "typ" av datakälla, "substreams". Sådana subgrafer kan bara ha en datakälla.
Denna datakälla måste ange det indexerade nätverket, Substreams-paketet ("spkg") som en relativ filplats och modulen i det Substreams-paketet som producerar subgrafkompatibla entitetsändringar (i detta fall "map_entity_changes", från Substreams-paketet ovan). Mappningen är specificerad, men identifierar helt enkelt mappningstypen ("substreams/graph-entities") och 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
refererar också till en schemafil. Kraven för denna fil är oförändrade, men de angivna entiteterna måste vara kompatibla med entitetsändringarna som produceras av Substreams-modulen som refereras till i subgraph.yaml
.
type Contract @entity {id: ID!"Tidsstämpeln när kontraktet implementerades"timestamp: String!"Blocknummer för kontraktsimplementeringen"blockNumber: BigInt!}
Med tanke på ovanstående kan subgraf utvecklare använda Graph CLI för att distribuera denna Substreams-drivna subgraf.
yarn install # install graph-cliyarn subgraph:build # bygg subgrafenyarn subgraph:deploy # deploy the subgraph
Det är allt! Du har byggt och distribuerat en Substreams-drivna subgraf.
För att kunna betjäna Substreams-drivna subgrafer måste Graph Node konfigureras med en Substreams-leverantör för det relevanta nätverket, samt en Firehose eller RPC för att spåra kedjehuvudet. Dessa leverantörer kan konfigureras via en config.toml
-fil:
[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" }},]