区块链技术迅猛发展,新想法、新概念、新名词层出不穷。万向区块链因此推出“技术研究报告”专栏,定期与大家分享在区块链行业创新及热门技术方面的研究成果,带领大家第一时间研究学习新技术,紧跟技术发展趋势,探索发掘技术的应用价值。
本期技术研究将带大家了解区块链数据索引及查询协议The Graph。
本文作者:万向区块链通用架构技术部 杜超
一、概念
1.1、什么是 The Graph
The Graph是一个去中心化的协议,用于索引和查询区块链的数据,从以太坊开始。它使查询难以直接查询的数据成为可能。
The Graph网络对Web3的查询层和API层进行了去中心化,消除了dApp开发者目前面临的取舍难题:到底是开发一个高性能应用,还是开发一个完全去中心化的应用。
目前,开发者可以在自己的基础架构上运行一个Graph节点,也可以在我们的托管服务上开发一个。其中,开发者构建和部署从Web3数据源提取数据并为其编制索引的子图。目前已经有许多领先的以太坊项目创建了子图,包括Uniswap、ENS、DAOstack、Synthetix和Moloch等。在The Graph网络中,任何索引器都能够通过抵押Graph代币(GRT)参与到网络中,并在提供查询服务的过程赚取费用和通货膨胀奖励。
用户则按照使用次数进行付费,使用日益增长的索引器,此做法证明了供需规律也适用于该协议提供的服务。
Graph可以让数据查询变得简单易 *** 作。任何人都可以构建和发布开放的API,使数据易于访问。
1.2 、The Graph网络中的协议角色
协议中包括以下角色:
Consumers: 用户向索引器支付查询费用。他们通常是终端用户,但也可能是集成The Graph的网络服务或中间件。 Indexers: 检索人是The Graph的运行节点。其动力是赚取财务奖励。 Curators: 策展人使用GRT代币来指明哪些子图值得索引。他们通常是开发者,也可能是支持他们在使用服务的终端用户,或者纯粹出于经济动机的一种角色。策展人通过自己手中的GRT代码为某些subgraph投票,也叫信号标记,使这些子图更容易被搜索到。 Delegators: 委托人向某个Indexer质押GRT代币,赚取一部分通货膨胀奖励和费用,他们无需亲自运行一个Graph节点。这类角色主要出于经济动机。 Fisherman: 执法者时刻检查查询响应是否正确,以此保护网络。渔夫动机是利他的,因此The Graph将率先为网络提供执法者服务。 Arbitrator: 在争议解决期间,仲裁员决定是否对索引器进行罚没。他们可能出于经济或利他动机。 前四种是网络中利己的,是比较市场化的角色。后两种是利他的,一般由The Graph负责或引入其它机制。为了鼓励索引器为新子图建立索引,策展人必须介入并发出信号标记,表明新子图值得索引。
1.3、Graph代币在协议中主要用途
索引器质押:索引器质押Graph代币,以便自身被查询市场所发现,同时在执行工作过程中提供经济安全。 策展人信号:策展人将Graph代币质押到策展市场中,预测哪些API对网络具备价值,他们因为正确预测而获得奖励。二、工作原理
2.1、 GRAPH是如何工作的
Graph基于子图描述索引以太坊数据的内容和方法,称为子图清单。子图描述定义了子图相关的智能合约,这些合约中所定义的事件,以及如何将事件数据映射到The Graph将存储在其数据库中的数据。
下图给出了关于数据流的更多细节,一旦一个子图清单被部署,将转化为处理以太坊事务。
Transactions:去中心化应用程序通过智能合约上的交易向以太坊添加数据。 Events: 智能合约在处理交易时发出一个或多个事件。 Graph node: 图节点持续扫描以太坊的新块和它们可能包含的子图数据。 Mapping: 图节点在这些块中为你的子图找到以太坊事件,并运行你提供的映射处理程序。映射是一个WASM模块,用于创建或更新Graph Node存储的数据实体,以响应以太坊事件。 Store: 通过映射的数据被保存到节点上 Queries: 分散的应用程序使用节点的GraphQL端点向Graph Node查询从区块链索引的数据。2.2、The Graph 架构
The Graph网络包含以太坊上的智能合约,以及链下运行的各种其他服务和客户端。
三、如何索引合约事件
3.1、合约代码部署
JavaScript // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract GravatarRegistry { event NewGravatar(uint id, address owner, string displayName, string imageUrl); event UpdatedGravatar(uint id, address owner, string displayName, string imageUrl); struct Gravatar { address owner; string displayName; string imageUrl; } Gravatar[] public gravatars; mapping (uint => address) public gravatarToOwner; mapping (address => uint) public ownerToGravatar; function createGravatar(string memory _displayName, string memory _imageUrl) public { require(ownerToGravatar[msg.sender] == 0); gravatars.push(Gravatar(msg.sender, _displayName, _imageUrl)); uint id = gravatars.length - 1; gravatarToOwner[id] = msg.sender; ownerToGravatar[msg.sender] = id; emit NewGravatar(id, msg.sender, _displayName, _imageUrl); } function updateGravatarName(string memory _displayName) public { require(ownerToGravatar[msg.sender] != 0); require(msg.sender == gravatars[ownerToGravatar[msg.sender]].owner); uint id = ownerToGravatar[msg.sender]; gravatars[id].displayName = _displayName; emit UpdatedGravatar(id, msg.sender, _displayName, gravatars[id].imageUrl); } } |
部署合约:
网络: Rinkeby network
合约地址:0x0a89E2093d371A1AC387346C63b462BE3aD40F00
3.2、the graph注册subgraph
the graph studio
Bash # 1、INSTALL GRAPH CLI USING NPM npm install -g @graphprotocol/graph-cli # OR USING YARN yarn global add @graphprotocol/graph-cli # 2、INITIALIZE SUBGRAPH graph init --studio kktest # 3、AUTHENTICATE IN CLI graph auth --studio d2a22d5c11******b7ef6 # 4、BUILD SUBGRAPH cd kktest graph codegen && graph build # 5、DEPLOY SUBGRAPH graph deploy --studio kktest |
3.3、初始化subgraph配置
TheGraph中定义如何为数据建立索引,称为Subgraph,它包含三个组件:
Manifest 清单(subgraph.yaml) - 定义配置项 Schema 模式(schema.graphql) - 定义数据 Mapping 映射(mapping.ts) - 定义事件到数据的转换在kktest目录下会生成 subgraph.yaml 文件和 schema.graphq 文件
subgraph.yaml
YAML specVersion: 0.0.1 schema: file: ./schema.graphql dataSources: - kind: ethereum name: GravatarRegistry network: rinkeby source: address: "0x0a89E2093d371A1AC387346C63b462BE3aD40F00" abi: GravatarRegistry mapping: kind: ethereum/events apiVersion: 0.0.5 language: wasm/assemblyscript entities: - NewGravatar - UpdatedGravatar abis: - name: GravatarRegistry file: ./abis/GravatarRegistry.json eventHandlers: - event: NewGravatar(uint256,address,string,string) handler: handleNewGravatar - event: UpdatedGravatar(uint256,address,string,string) handler: handleUpdatedGravatar file: ./src/mapping.ts |
3.4、 定义模式(schema.graphql)
编写自己的模式 schema.graphql,模式是GraphQL数据定义。允许我们定义实体及其类型,这里我们在schema.graphql定义一个Gravatar实体:
Haskell type Gravatar @entity { id: ID! owner: Bytes! displayName: String! imageUrl: String! } |
3.5、定义映射(mapping.ts)
TheGraph中的映射文件定义了如何将传入事件转换为实体的函数。它用TypeScript的子集AssemblyScript编写。因此可以将其编译为WASM(WebAssembly),以更高效,更便携式地执行映射。
需要定义subgraph.yaml文件中每个handler函数,因此在我们的例子中,我们需要实现函数:handleNewGravatar 及 handleUpdatedGravatar。
graph codegen 可以生成解析事件的代码及模式实体代码,生成代码src/mapping.ts。
TypeScript import { NewGravatar, UpdatedGravatar } from '../generated/Gravity/Gravity' import { Gravatar } from '../generated/schema' export function handleNewGravatar(event: NewGravatar): void { let gravatar = new Gravatar(event.params.id.toHex()) gravatar.owner = event.params.owner gravatar.displayName = event.params.displayName gravatar.imageUrl = event.params.imageUrl gravatar.save() } export function handleUpdatedGravatar(event: UpdatedGravatar): void { let id = event.params.id.toHex() let gravatar = Gravatar.load(id) if (gravatar == null) { gravatar = new Gravatar(id) } gravatar.owner = event.params.owner gravatar.displayName = event.params.displayName gravatar.imageUrl = event.params.imageUrl gravatar.save() } |
在handler函数,我们使用事件的ID 创建Gravatar实体。并使用相应的字段填充数据,最后需要.save()来存储实体。
3.6、部署 Subgraph
Bash graph deploy \ --debug \ --node https://api.thegraph.com/deploy/ \ --ipfs https://api.thegraph.com/ipfs/ \ kktest |
3.7、DAPP查询数据
JavaScript import { createClient } from 'urql' const APIURL = 'https://api.thegraph.com/subgraphs/name/username/subgraphname' const tokensQuery = ` query { tokens { id tokenID contentURI metadataURI } } ` const client = createClient({ url: APIURL, }) const data = await client.query(tokensQuery).toPromise() |
四、FAQ
the graph 网络上一个indexer最小需要质押要求?一个indexer最小质押数设置为100K GRT。
indexer的收来源是什么?查询费用回扣 —— 为网络上的查询提供服务的费用。
索引奖励 —— 通过每年3%的协议膨胀产生,索引奖励被分配给索引人员,他们正在为网络的子图部署进行索引。
五、参考文档
the graph官网 the graph studio define a subgraph 如何索引合约事件 深入理解Graph (上) 深入理解Graph(下) The Graph Network in Depth欢迎分享,转载请注明来源:内存溢出
评论列表(0条)