Graph-node: create a new subgraph

Graph-node: create a new subgraph

1. Contract source code (take TetherToken as an example)

TetherToken

2. Develop subgraphs

​ As a subgraph developer, you define what blockchain data The Graph is indexing and how it is stored. Here are the three files included in the subgraph definition:

  • subgraph.yaml: The central YAML file that stores the list of subgraphs .
  • schema.graphql: Define what data to store and how to query it via GraphQL.
  • AssemblyScript Mappings: used to convert blockchain event data into entities defined by the developer schema (mapping.ts in this tutorial)

2.1 Create a subgraph

2.1.1 Create a subgraph from an existing contract

​ You can use existing smart contracts to bootstrap your new subgraph. If you have already deployed your smart contract to Ethereum or a testnet, please follow this part of the instructions.

First, we will create a subgraph that indexes all events of an existing smart contract. The subgraph will try to get the contract ABI from Etherscan. If unsuccessful, it falls back to requesting a local file path. If any optional parameters are missing, an interactive form will guide you through the process.

graph init \
  --from-contract <CONTRACT_ADDRESS> \
  [--network <ETHEREUM_NETWORK>] \
  [--abi <FILE>] \
  <GITHUB_USER>/<SUBGRAPH_NAME> [<DIRECTORY>]
  • GITHUB_USER: the name of your organization or GitHub user
  • SUBGRAPH_NAME: the name you want to give your subplot
  • DIRECTORY: (optional) - Defines graph initthe directory where submap manifests are stored.

​ Example:

graph init \
  --from-contract 0xdAC17F958D2ee523a2206206994597C13D831ec7 \
  --network mainnet \
  --abi TetherToken.json \
  github_user/subgraph

​ Press Enter according to the options shown in the figure below

insert image description here

​ The generated submap file directory is as follows. Among them, network.js, tsconfig.jsoncan be deleted if not used temporarily.

insert image description here

​ Replace the content in package.json with:

{
    
    
  "name": "example",
  "version": "0.1.0",
  "repository": "xxx",
  "license": "MIT",
  "scripts": {
    
    
    "build-contract": "solc contracts/TetherToken.sol --abi -o abis --overwrite && solc contracts/TetherToken.sol --bin -o bin --overwrite",
    "create": "graph create example --node https://api.thegraph.com/deploy/",
    "create-local": "graph create example --node http://127.0.0.1:8020",
    "codegen": "graph codegen",
    "build": "graph build",
    "deploy": "graph deploy example --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/",
    "deploy-local": "graph deploy example --ipfs http://127.0.0.1:5001 --node http://127.0.0.1:8020"
  },
  "devDependencies": {
    
    
    "@graphprotocol/graph-cli": "^0.30.2",
    "@graphprotocol/graph-ts": "^0.27.0"
  },
  "dependencies": {
    
    
    "babel-polyfill": "^6.26.0",
    "babel-register": "^6.26.0",
    "truffle": "^5.0.4",
    "truffle-contract": "^4.0.5",
    "truffle-hdwallet-provider": "^1.0.4"
  }
}

2.1.2 Creating a subgraph using the example subgraph

graph init --from-example graphprotocol/example-subgraph

2.2 Create a contract

​ Initialize the contract project

cd subgraph
truffle init

insert image description here

​ Copy the TetherToken.sol file into the contracts folder. Since the sloc version used by this contract is 0.4.17, the version in Migrations.sol and truffle-config.js needs to be modified accordingly

insert image description here

​ By the way, you also need to configure the network in truffle-config.js, and modify the networks as follows (note the port number):

  networks: {
    
    
    development: {
    
    
      host: '127.0.0.1',
      port: 7545,
      network_id: '*',
    },
    ropsten: {
    
    
      provider: function() {
    
    
        return new HDWalletProvider(
          process.env.MNEMONIC,
          `https://ropsten.infura.io/v3/${
      
      process.env.ROPSTEN_INFURA_API_KEY}`
        )
      },
      network_id: '3',
    },
  }

​ Create a new 2_deploy_contract.js file in the migrations folder and enter the following content:

const TetherToken = artifacts.require('./TetherToken.sol')

module.exports = async function(deployer) {
    
    
  // 创建一个新的token
  await deployer.deploy(TetherToken,'100','TokenName','TokenSymbol','5')
}

2.3 Create subgraph list (subgraph.yaml)

specVersion: 0.0.4
description: TetherToken for Ethereum
repository: xxx
schema:
  file: ./schema.graphql
dataSources:
  - kind: ethereum/contract
    name: TetherToken
    network: mainnet
    source:
      address: '0x5630081330A00a85833Af27D1e7bD015fe2FF05b'
      abi: TetherToken
    mapping:
      kind: ethereum/events
      apiVersion: 0.0.5
      language: wasm/assemblyscript
      entities:
        - Token
        - Transfer
      abis:
        - name: TetherToken
          file: ./abis/TetherToken.json
      eventHandlers:
        - event: NewTetherToken(uint256,string,string,uint256)
          handler: handleNewTetherToken
        - event: TetherTokenTransfer(address,uint256)
          handler: handleTransfer
      file: ./src/mapping.ts
  • dataSources.source.addressIt is the contract address, truffle migrateand then replace it with the contract address of 2_deploy_contract
  • dataSources.source.abiIt needs to correspond to dataSources>abis>namethe value
  • dataSources.mapping.entities: This entry defines which entities the data source writes to storage. schema.graphqlDefine the schema for each entity.
  • dataSources.mapping.eventHandlers: Use this entry to define the smart contract events your subgraph responds to. This is also where you define handlers in the map that translate smart contract events to entities in the store. In our example case, this is the ./src/mapping.ts.

​ Next, several attributes in the subgraph list are introduced in detail:

2.3.1 eventHandlers

NewTetherToken​With TetherTokenTransferthe events spit out during the contract call, the subgraph of this project will monitor and analyze these two events, which are defined in TetherToken.sol as follows:

// Called if new token is created
event NewTetherToken(uint _initialSupply, string _name, string _symbol, uint _decimals);

// Called if new Transfer is created
event TetherTokenTransfer(address _to, uint _value);

​ Spit out events in TetherToken(uint _initialSupply, string _name, string _symbol, uint _decimals)methodsNewTetherToken

insert image description here

​ Spit out events in transfer(address _to, uint _value)methodsTetherTokenTransfer

insert image description here

2.3.2 entities

entities​In Token, Transferis the entity generated after parsing the above two events, which will be introduced more specifically in later chapters, and can be ignored here.

2.4 Define entities (schema.graphql)

type Token @entity {
  id: ID!
  symbol: String!
}

type Transfer @entity {
  id: ID!
  value: String!
}

2.4.1 Built-in scalar types

type meaning
Bytes Byte array, represented as a hexadecimal string. Typically used for Ethereum hashes and addresses.
ID Stored as a string.
String A scalar of string values. Null characters are not supported and are automatically removed.
Boolean A scalar of boolean values.
Int The GraphQL specification defines an Int as having a size of 32 bytes.
BigInt The GraphQL specification defines an Int as having a size of 32 bytes.
BigDecimal BigDecimal High-precision decimals represented as significand and exponent. The exponent range is -6143 to +6144. Rounded to 34 significant figures.

2.5 Installation dependencies

​ Run yarnthe dependencies needed to add the contract

// yarn install速度慢的话可以修改源
// yarn config set registry 'https://registry.npm.taobao.org'
yarn

​ then run

yarn codegen

​ Then run truffle compilethe compile contract, copy the generated json file into the abis folder, and delete the original .json in abis

truffle compile

2.6 Writing a mapping

// event
import { NewTetherToken, TetherTokenTransfer} from '../generated/TetherToken/TetherToken'
// entity
import { Token, Transfer} from '../generated/schema'

export function handleNewTetherToken(event: NewTetherToken): void {
  let token = new Token(event.params._name)
  token.symbol = event.params._symbol
  token.save()
}

export function handleTransfer(event: TetherTokenTransfer): void {
  let transfer = new Transfer(event.params._to.toString());
  transfer.value = event.params._value.toString()
  transfer.save()
}

​:handleNewTetherToken When an event is spit out during the contract call NewTetherToken, the subgraph will call a method to store handleNewTetherTokenthe generated token as an entity.Token

​:handleTransfer When TetherTokenthe transfer function in the contract is called, the corresponding TetherTokenTransferevent will be spit out, and the subgraph will call handleTransferthe method after listening to the event, and store the transfer information in Transferthe entity.

2.7 run

See (43 messages) Graph-node: deployment and testing_I don't want to be bald blog-CSDN blog_graphnode

Guess you like

Origin blog.csdn.net/cacique111/article/details/126146779