Jacky Gu

Solana开发笔记: Subgraph与substream的使用

01 Jan 2025 Share to

Subgraph与substream的使用

为什么要用subgraph? 因为这是链上数据和前端之间的接口,链上数据需要按账号调用,但是帐号却无法按一定逻辑进行排序和检索,所以需要通过subgraph,把不同链上账号的数据保存在graph中,一次性调用所有数据。

与以太坊可以直接使用subgraph不同,Solana需要通过substreams整理链上数据,然后才能部署到subgraph上使用。

substreams使用方法

文档:https://thegraph.com/docs/zh/sps/triggers-example/

1- 在github的Codespaces中使用substreams

  • 进入githubcodespaces:https://github.com/streamingfast/substreams-starter。
  • 使用命令:substreams init,创建一个项目。需要准备好idl内容,程序program id,以及部署程序的区块高度。 如果已经创建,打开 https://github.com/codespaces 即可看到程序空间,点击进入。
  • 建议在本地vscode中打开创建好的CodeSpaces项目
  • 修改自动创建的program.proto和程序lib.rs,因为自动创建的程序无法直接build,需要做如下修改
    • program.proto中重复定义的message删掉
    • lib.rs中,把EventInstruction中的内容补全(一般只用到Event)
    • 在补全过程中,如果遇到stateevent的定义中引用复杂类型,会在自动生成的lib.rs最底部有解析的方法,直接调用即可。
    • Cargo.comlsubstreams.yaml中,把package的名字改成所需要的,如果不改,默认my_project
    • 执行:substreams build,如果不出错误,会在当前目录下生成一个.so的目标文件
    • 执行:substreams auth,浏览器会打开subgraph授权网页,根据提示,创建一个key,该文件保存在.substreams.env中(如果重新编译,不需要重复授权)
    • 测试:substreams gui,会在命令行中打开一个UI界面,可以使用一些常用命令快捷键,查看交易内容

2- Subgraph部分

当编译并生成.so文件后,即可开始subgraph的操作:

  • 执行:substreams codegen subgraph,生成subgraph代码
  • 执行:cd subgraph,进入生成的subgraph目录
  • 执行:npm install 安装相关库
  • 执行:npm run generate,生成AssemblyScript and Protobuf bindings
  • 执行:graph build 查看编译是否有问题

3- 自定义subgraph程序

  • 编辑scheme.graphql文件,定义需要加载到subgraph中的数据结构,如:
    type InitializeTokenEventEntity @entity {
    id: ID!
    admin: String!
    tokenId: BigInt!
    mint: String!
    configAccount: String!
    mintStateAccount: String!
    metadataAccount: String!
    tokenName: String!
    tokenSymbol: String!
    tokenUri: String!
    targetEras: BigInt!
    epochesPerEra: BigInt!
    targetSecondsPerEpoch: BigInt!
    reduceRatio: BigDecimal!
    initialMintSize: BigDecimal!
    initialTargetMintSizePerEpoch: BigDecimal!
    feeRate: BigInt!
    liquidityTokensRatio: BigDecimal!
    }
    
  • 运行npm run codegen,在generated/scheme.ts中会根据scheme.graphql文件生成配置文件
  • src/mappings.ts中定义数据加载规则
  • 运行graph build

4- 部署到subgraph studio

  • 打开https://thegraph.com/studio,在subgraph studio上创建一个新的项目。
  • auth(只要操作一次)
    graph auth --studio deploy_key
    
  • 编译代买
    graph codegen && graph build
    
  • 上传,上传时需要输入版本号
    graph deploy --studio proof_of_mint
    

获得endpoint的地址,即可用于前端调用。

程序升级后,subgraph需要重新部署的Checklist

如果程序升级未设计到数据结构的变化,比如state和event的数据结构,可以参考以下项目升级subgraph:

  • 更新Solana程序,使用anchor build编译,并使用anchor deploy部署
  • 将新的idl文件复制到substreams工作区的idls/program.json中
  • 更新substreams工作区的proto/program.proto文件,新增或更改数据类型message,执行substreams build,生成pb目录下文件。这时可能src/lib.rs会编译出错,不用管
  • 更新substreams工作区的src/lib.rs文件,新增或更改实现逻辑
  • 运行substreams build,编译substreams程序,直到通过编译
  • 保存之前版本subgraph中的/src/mappings.ts和scheme.graphql两个文件,然后删除之前版本的subgraph目录(或更改目录名)
  • 执行substreams codegen subgraph,生成新的subgraph项目目录
  • 进入subgraph目录,执行npm install or yarn,安装库。(之后操作都在subgraph目录中操作)
  • 执行:yarn generate,生成/src/pb/目录下的文件,以及/generated/scheme.ts
  • 将保存的之前版本的/src/mappings.ts和scheme.graphql复制到新的subgraph目录中相应位置
  • 编辑scheme.graphql,执行yarn generate,升级数据类型/generated/scheme.ts
  • 编辑/src/mappings.ts,使之符合新的scheme.graphql数据抓取
  • 执行: yarn protogen && graph codegen && graph build
  • 执行: graph deploy –studio proof_of_mint,更新部署
  • 在thegraph中查看数据是否同步成功,并在playground中测试新的数据
  • 在前端更新idl和合约地址

如果程序升级设计到数据结构的变化,则建议生成新的ProgramId,然后重新部署substreams/subgraph。因为手动升级很容易出错。

创建本地substreams/subgraph开发环境

  • 参考:https://docs.substreams.dev/documentation/consume/installing-the-cli,安装需要的工具。

  • 执行:yarn add global @graphprotocol/graph-cli,安装subgraph

本地开发的好处:

  • 可以用到AI辅助开发,尤其是对rustprotocol buffer不太熟悉的开发者;
  • 低延迟,开发快,bash命令可以得到提示;
  • 可以更方便的在github上做版本管理