[译] 使用 TheGraph 完善Web3 事件数据检索

这篇文章主要介绍了[译] 使用 TheGraph 完善Web3 事件数据检索 ,文中通过代码以及文档配合进行讲解,很详细,它对在座的每个人的研究和工作具有很经典的参考价值。 如果需要,让我们与区块链资料网一起学习。

https://www.interchains.cc/17967.html

[译] 使用 TheGraph 完善Web3 事件数据检索是很好的区块链资料,他说明了区块链当中的经典原理,可以给我们提供资料,[译] 使用 TheGraph 完善Web3 事件数据检索学习起来其实是很简单的,

不多的几个较为抽象的概念也很容易理解,之所以很多人感觉[译] 使用 TheGraph 完善Web3 事件数据检索比较复杂,一方面是因为大多数的文档没有做到由浅入深地讲解,概念上没有注意先后顺序,给读者的理解带来困难

[译] 使用 TheGraph 完善Web3 事件数据检索

  • TheGraph
  • 数据存储
  • 事件订阅

使用 TheGraph 进行事件存款及检索服务

  • 原文链接:https://soliditydeveloper.com/thegraph 作者:MarkusWaas
  • 译文出自:登链翻译计划
  • 译者:Tiny 熊
  • 本文永久链接:learnblockchain.cn/article…

为什么我们需要TheGraph以及如何使用它

以前我们看过Solidity的大图和create-eth-app,它们之前已经提到过TheGraph。这次,我们将仔细研究TheGraph,它在去年已成为开发Dapps的标准堆栈的一部分。

但首先让我们看看传统方式下如何开发…

没有TheGraph时…

因此,让我们来看一个简单的示例,以进行说明。我们都喜欢游戏,所以想象一个简单的游戏,用户下注:

pragma solidity 0.7.1;  contract Game {     uint256 totalGamesPlayerWon = 0;     uint256 totalGamesPlayerLost = 0;     event BetPlaced(address player, uint256 value, bool hasWon);      function placeBet() external payable {         bool hasWon = evaluateBetForPlayer(msg.sender);          if (hasWon) {             (bool success, ) = msg.sender.call{ value: msg.value * 2 }('');             require(success, "Transfer failed");             totalGamesPlayerWon++;         } else {             totalGamesPlayerLost++;         }          emit BetPlaced(msg.sender, msg.value, hasWon);     } }

现在让我们在Dapp中说,我们要显示输/赢的游戏总数,并在有人再次玩时更新它。该方法将是:

  1. 获取totalGamesPlayerWon
  2. 获取totalGamesPlayerLost
  3. 订阅BetPlaced事件。

如下代码所示,我们可以监听Web3中的事件,但这需要处理很多情况。

GameContract.events.BetPlaced({     fromBlock: 0 }, function(error, event) { console.log(event); }) .on('data', function(event) {     // event fired }) .on('changed', function(event) {     // event was removed again }) .on('error', function(error, receipt) {     // tx rejected });

现在,对于我们的简单示例来说,这还是可以的。但是,假设我们现在只想显示当前玩家输/赢的赌注数量。好吧,我们不走运,你最好部署一个新合约来存储这些值并获取它们。现在想象一个更复杂的智能合约和Dapp,事情会很快变得混乱。

[译] 使用 TheGraph 完善Web3 事件数据检索

你可以看到以上方案不是最佳的选择:

  • 不适用于已部署的合约。
  • 存储这些值需要额外的 gas 费用。
  • 需要额外的调用来获取以太坊eth节点的数据。

[译] 使用 TheGraph 完善Web3 事件数据检索

现在让我们看一个更好的解决方案。

让我向你介绍GraphQL

首先让我们谈谈最初由Facebook设计和实现的GraphQL,。你可能熟悉传统的Rest API 模型.,现在想像一下,你可以为所需的数据编写查询:

[译] 使用 TheGraph 完善Web3 事件数据检索

[译] 使用 TheGraph 完善Web3 事件数据检索

这两个图像几乎包含了GraphQL的本质。通过第二个图的查询,我们可以准确定义所需的数据,因此可以在一个请求中获得所有内容,仅此而已。GraphQL服务器处理所有所需数据的提取,因此前端消费者使用起来非常容易。如果你有兴趣对服务器如何精确地处理查询,这里有一个很好的解释。

现在有了这些知识,让我们最终进入区块链blockchain部分和TheGraph。

什么是TheGraph?

区块链blockchain是一个去中心化的数据库,但是与通常的情况相反,我们没有该数据库的查询语言。检索数据的解决方案是痛苦或完全不可能的。TheGraph是用于索引和查询区块链blockchain数据的去中心化协议。你可能已经猜到了,它使用GraphQL作为查询语言。

[译] 使用 TheGraph 完善Web3 事件数据检索

示例始终是最好的理解方法,因此让我们在游戏合约示例中使用TheGraph。

如何创建Subgraph

定义如何为数据建立索引,称为Subgraph。它需要三个组件:

  1. Manifest 清单(subgraph.yaml)
  2. Schema 模式(schema.graphql)
  3. Mapping 映射(mapping.ts)

清单(subgraph.yaml)

清单是我们的配置文件,它定义:

  • 要索引哪些智能合约(地址,网络,ABI…)
  • 监听哪些事件
  • 其他要监听的内容,例如函数调用或块
  • 被调用的映射函数(请参见下面的mapping.ts)

你可以在此处定义多个合约和处理程序。一个典型的设置是Truffle/Buidler项目代码库中有一个subgraph文件夹。然后,你可以轻松引用到ABI。

为了方便起见,你可能还需要使用mustache之类的模板工具,然后创建一个subgraph.template.yaml并根据​​最新部署插入地址。有关更高级的示例设置,请参见例如:Aave sub graph repo.

完整的文档可以在这里找到:https://thegraph.com/docs/define-a-subgraph#the-subgraph-manifest。

specVersion: 0.0.1 description: Placing Bets on Ethereum repository: - Github link - schema:   file: ./schema.graphql dataSources:   - kind: ethereum/contract     name: GameContract     network: mainnet     source:       address: '0x2E6454...cf77eC'       abi: GameContract       startBlock: 6175244     mapping:       kind: ethereum/events       apiVersion: 0.0.1       language: wasm/assemblyscript       entities:         - GameContract       abis:         - name: GameContract           file: ../build/contracts/GameContract.json       eventHandlers:         - event: PlacedBet(address,uint256,bool)           handler: handleNewBet       file: ./src/mapping.ts

模式(schema.graphql)

模式是GraphQL数据定义。它将允许你定义存在的实体及其类型。TheGraph支持的类型有

  • Bytes(字节)

  • ID

  • String(字符串)

  • Boolean(布尔值)

  • Int(整型)

  • BigInt(大整数)

  • BigDecimal(大浮点数)

还可以使用实体作为类型来定义关系。在我们的示例中,我们定义了从玩家到下注的一对多关系。表示该值不能为空。完整的文档可以在这里找到:https://thegraph.com/docs/define-a-subgraph#the-graphql-schema。

type Bet @entity {   id: ID!   player: Player!   playerHasWon: Boolean!   time: Int! }  type Player @entity {   id: ID!   totalPlayedCount: Int   hasWonCount: Int   hasLostCount: Int   bets: [Bet]! }

映射(mapping.ts)

TheGraph中的映射文件定义了将传入事件转换为实体的函数。它用TypeScript的子集AssemblyScript编写。这意味着可以将其编译为WASM(WebAssembly),以更高效,更便携式地执行映射。

你将需要定义subgraph.yaml文件中命名的每个函数,因此在我们的例子中,我们只需要一个函数:handleNewBet。我们首先尝试从发起人地址作为ID加载为为Player实体。如果不存在,我们将创建一个新实体,并用起始值填充它。

然后,我们创建一个新的Bet实体。此ID为event.transaction.hash.toHex() + “-” + event.logIndex.toString(),确保始终为唯一值。仅使用哈希是不够的,因为有人可能在一次交易中会多次调用智能合约的placeBet函数。

最后我们可以更新Player实体的所有数据。不能将数组直接压入,而需要按如下所示进行更新。我们使用ID来代表下注。最后需要.save()来存储实体。

完整的文档可以在这里找到:https://thegraph.com/docs/define-a-subgraph#writing-mappings。你还可以将日志输出添加到映射文件中,请参阅这里。

import { Bet, Player } from '../generated/schema'; import { PlacedBet }     from '../generated/GameContract/GameContract';  export function handleNewBet(event: PlacedBet): void {   let player = Player.load(     event.transaction.from.toHex()   );    if (player == null) {     // create if doesn't exist yet     player = new Player(event.transaction.from.toHex());     player.bets = new Array<string>(0);     player.totalPlayedCount = 0;     player.hasWonCount = 0;     player.hasLostCount = 0;   }    let bet = new Bet(     event.transaction.hash.toHex()         + '-'         + event.logIndex.toString()   );   bet.player = player.id;   bet.playerHasWon = event.params.hasWon;   bet.time = event.block.timestamp;   bet.save();    player.totalPlayedCount++;   if (event.params.hasWon) {     player.hasWonCount++;   } else {     player.hasLostCount++;   }    // update array like this   let bets = player.bets;   bets.push(bet.id);   player.bets = bets;    player.save(); }

在前端使用

使用类似ApolloBoost的东西,你可以轻松地将TheGraph集成到ReactDapp(或Apollo-Vue)中,尤其是当使用React hooks和Apollo时,获取数据就像编写单个代码一样简单的在组件中进行GraphQl查询,典型的代码如下所示:

// See all subgraphs: https://thegraph.com/explorer/ const client = new ApolloClient({   uri: "{{ subgraphUrl }}", });  ReactDOM.render(   <ApolloProvider client={client}>     <App />   </ApolloProvider>,   document.getElementById("root"), );
const { loading, error, data } = useQuery(myGraphQlQuery);  React.useEffect(() => {     if (!loading && !error && data) {         console.log({ data });     } }, [loading, error, data]);

现在,我们可以编写例如这样的查询。这将带给我们

  • 当前用户赢得了多少次
  • 当前用户输了多少次
  • 他之前所有下注的时间戳列表

仅需要对GraphQL服务器进行一个请求。

const myGraphQlQuery = gql`     players(where: { id: $currentUser }) {       totalPlayedCount       hasWonCount       hasLostCount       bets {         time       }     } `;

[译] 使用 TheGraph 完善Web3 事件数据检索

但是,我们错过了最后一个难题,那就是服务器。你可以自己运行它,也可以使用托管服务。

Graph服务器

GraphExplorer:托管服务

最简单的方法是使用托管服务。按照此处的说明部署subgraph。对于许多项目,你实际上可以在资源管理器中找到现有的subgraph,网址为https://thegraph.com/explorer/.

[译] 使用 TheGraph 完善Web3 事件数据检索

运行自己的节点

或者,你可以运行自己的节点:https://github.com/graphprotocol/graph-node#quick-start。这样做的原因之一可能是使用托管服务不支持的网络。当前仅支持主网,Kovan,Rinkeby,Ropsten,Goerli,PoA-Core,xDAI和Sokol。

去中心化的未来

GraphQL还为新进入的事件进行“流”支持。TheGraph尚未完全支持,但即将发布。

缺少的一方面仍然是权力下放。TheGraph未来计划具有最终成为完全去中心化协议。这两篇很棒的文章更详细地说明了该计划:

  • https://thegraph.com/blog/the-graph-network-in-depth-part-1
  • https://thegraph.com/blog/the-graph-network-in-depth-part-2

两个关键方面是:

  1. 用户将向索引器支付查询费用。
  2. 索引器将使用Graph通证(GRT)。

[译] 使用 TheGraph 完善Web3 事件数据检索


本翻译由 Cell Network 赞助支持。

  • 发表于 1小时前
  • 阅读 ( 13 )
  • 学分 ( 231 )
  • 分类:以太坊eth

部分转自网络,侵权联系删除www.interchains.cchttps://www.interchains.cc/17967.html

区块链毕设网(www.interchains.cc)全网最靠谱的原创区块链毕设代做网站 部分资料来自网络,侵权联系删除! 最全最大的区块链源码站 !
区块链知识分享网, 以太坊dapp资源网, 区块链教程, fabric教程下载, 区块链书籍下载, 区块链资料下载, 区块链视频教程下载, 区块链基础教程, 区块链入门教程, 区块链资源 » [译] 使用 TheGraph 完善Web3 事件数据检索

提供最优质的资源集合

立即查看 了解详情