スマート コントラクトを作成する場合、状態の変化は通常、イベントのトリガーによって表現されます。Graph はブロックチェーン イベントをキャプチャし、イベントをクエリするための GraphQL インターフェイスを提供するため、データの変更を簡単に追跡できます。実際、多くの DEFI プロトコルと The Graph はクエリ データに基づいています。
https://thegraph.academy/developers/local-development/
このチュートリアルをベースにいくつか追加していきます。
ツールの準備:nodejs、yarn、docker、truffle、graph-cli
1. 受託開発および導入
-
受託開発環境構築
npm install -g truffle ganache-cli
-
コントラクトの作成
このコントラクトは手書きのテスト コントラクトであり、主に 2 つのイベント、PairCreated と AddLiquidity を定義します。thegarph を使用して次のイベントをリッスンします。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Pair{
string private _name;
uint private _liquidity;
constructor(string memory name){
_name = name;
}
function addLiquidity(uint amount) public {
_liquidity+=amount;
}
function getLiquidity() public view returns(uint){
return _liquidity;
}
function getName() public view returns(string memory){
return _name;
}
}
contract Dex {
address private _owner;
uint private _index = 0;
mapping(address => Pair) private _pairs;
mapping(uint => address) private _indexs;
modifier onlyOwner(){
require(msg.sender == _owner,"must be owner");
_;
}
event PairCreated(string name, address pairAddress);
event AddLiquidity(address pairAddress, uint liquidity);
function createPair(string memory name) public {
Pair pair = new Pair(name);
_pairs[address(pair)] = pair;
_indexs[_index] = address(pair);
_index++;
emit PairCreated(name, address(pair));
}
function addLiquidity(address pairAddress,uint liquidity) public {
_pairs[pairAddress].addLiquidity(liquidity);
emit AddLiquidity(pairAddress,liquidity);
}
function getCount() public view returns(uint){
return _index;
}
function pairAddress(uint index) public view returns(address){
return _indexs[index];
}
function getPairName(address pairAddress) public view returns(string memory){
return _pairs[pairAddress].getName();
}
function getLiquidity(address pairAddress) public view returns(uint liquidity){
return _pairs[pairAddress].getLiquidity();
}
}
-
トリュフを介して自己構築ガナッシュブロックチェーンにデプロイ
truffle migrate
-
リミックスを通じてデータを書き込み、イベントをトリガーするコントラクトを呼び出します。
2. インデックスデータのサブグラフを作成する
TheGraph は、サブグラフと呼ばれるデータのインデックス付け方法を定義します。サブグラフは、次の 3 つのコンポーネントで構成されます。
- マニフェスト リスト (subgraph.yaml) - 構成アイテムを定義します
specVersion: 0.0.1
description: study
repository: https://github.com/graphprotocol/example-subgraph
schema:
file: ./schema.graphql
dataSources:
- kind: ethereum/contract
name: study
network: mainnet
source:
address: '0xf80e65c3c1B49626bae2ECE7e67A3e1AdBD480C2'
abi: Dex
mapping:
kind: ethereum/events
apiVersion: 0.0.5
language: wasm/assemblyscript
entities:
- Pairs
abis:
- name: Dex
file: ./build/contracts/Dex.json
eventHandlers:
- event: PairCreated(string,address)
handler: handleNewPairCreated
- event: AddLiquidity(address,uint256)
handler: handleAddLiquidity
file: ./src/mapping.ts
- スキーマ スキーマ (schema.graphql) - データを定義します。
type Pair @entity {
id: ID!
displayName: String!
liquidity: Int!
}
-
コードを生成する
graph codegen
-
マッピング マッピング (mapping.ts) - イベントからデータへの変換を定義します。
import {AddLiquidity, PairCreated} from '../generated/study/Dex'
import {Pair} from '../generated/schema'
export function handleNewPairCreated(event: PairCreated): void {
let pair = new Pair(event.params.pairAddress.toHexString())
pair.displayName = event.params.name
pair.liquidity = 0
pair.save()
}
export function handleAddLiquidity(event: AddLiquidity): void {
let id = event.params.pairAddress.toHexString()
let pair = Pair.load(id)
if (pair == null) {
return
}
pair.liquidity += event.params.liquidity.toI32()
pair.save()
}
3. Subgraph を TheGraph にデプロイしてデータのインデックス作成を実装する
- ローカルノードの構築を例として、graph-node を実行します。
git clone https://github.com/graphprotocol/graph-node/
cd graph-node/docker
docker compose up
- プロジェクトの依存関係をインストールし、グラフ ノードにデプロイします
yarn && yarn codegen
yarn create-local
yarn deploy-local
4.graphqlでデータをクエリする
query{
pairs(first:10){
id,
displayName,
liquidity
}
}
表示結果は以下の通り
5. ステッピングピットガイド
- Graph ノード http://127.0.0.1:8020/ へのデプロイに失敗しました: Ethereum ネットワークはレジストラ: mainnet でサポートされていません。
ローカルでプレイしている ganache ブロックチェーン ネットワークが原因で、graph-node がコンテナ IP でホストを見つけることができません、docker/docker-compose.yml の設定イーサリアムを変更しました: 'mainnet:http://docker.for.mac.host.internal:8545'