Docs
搜索⌘ K
  • 主页
  • 关于 The Graph
  • 支持的网络
  • 协议合约
  • 子图
    • 子流
      • 代币 API
        • AI Suite
          • 索引
            • 资源
              子图 > 最佳实践

              6 分钟

              子图最佳实践4-通过避免eth_calls提高索引速度

              TLDR

              eth_calls是可以从子图到以太坊节点进行的调用。这些调用需要大量时间来返回数据,从而减慢了索引速度。如果可能的话,设计智能合约来发出你需要的所有数据,这样你就不需要使用eth_calls`。

              为什么避免eth_calls是一种最佳实践

              子图经过优化,可以对智能合约发出的事件数据进行索引。子图也可以对来自eth_calls的数据进行索引,但是,这会大大减慢子图索引的速度,因为eth_call需要对智能合约进行外部调用。这些调用的响应性不依赖于子图,而是依赖于被查询的以太坊节点的连接性和响应性。通过最小化或消除子图中的eth_calls,我们可以显著提高索引速度。

              Eth_call是什么样子的?

              当子图所需的数据无法通过发出的事件获得时,通常需要eth_calls。例如,考虑一个场景,其中子图需要确定ERC20代币是否是特定池的一部分,但合约只发出一个基本的转移事件,而不发出包含我们所需数据的事件:

              1event Transfer(address indexed from, address indexed to, uint256 value);

              假设代币的池成员资格由名为getPoolInfo的状态变量决定。在这种情况下,我们需要使用eth_call来查询这些数据:

              1import { Address } from '@graphprotocol/graph-ts'2import { ERC20, Transfer } from '../generated/ERC20/ERC20'3import { TokenTransaction } from '../generated/schema'45export function handleTransfer(event: Transfer): void {6  let transaction = new TokenTransaction(event.transaction.hash.toHex())78  // Bind the ERC20 contract instance to the given address:9  let instance = ERC20.bind(event.address)1011  // Retrieve pool information via eth_call12  let poolInfo = instance.getPoolInfo(event.params.to)1314  transaction.pool = poolInfo.toHexString()15  transaction.from = event.params.from.toHexString()16  transaction.to = event.params.to.toHexString()17  transaction.value = event.params.value1819  transaction.save()20}

              这是功能性的,但并不理想,因为它减缓了子图的索引速度。

              如何消除eth_calls

              理想情况下,智能合约应该更新已在事件中发出所有必要的数据。例如,修改智能合约以在事件中包含池信息可以消除对eth_calls的需求:

              1event TransferWithPool(address indexed from, address indexed to, uint256 value, bytes32 indexed poolInfo);

              通过此更新,子图可以直接索引所需的数据,而无需外部调用:

              1import { Address } from '@graphprotocol/graph-ts'2import { ERC20, TransferWithPool } from '../generated/ERC20/ERC20'3import { TokenTransaction } from '../generated/schema'45export function handleTransferWithPool(event: TransferWithPool): void {6  let transaction = new TokenTransaction(event.transaction.hash.toHex())78  transaction.pool = event.params.poolInfo.toHexString()9  transaction.from = event.params.from.toHexString()10  transaction.to = event.params.to.toHexString()11  transaction.value = event.params.value1213  transaction.save()14}

              这更具性能,因为它消除了对eth_calls的需求。

              如何优化eth_calls

              如果无法修改智能合约并且需要eth_calls,请阅读“轻松提高子图索引性能:减少eth_calls”由Simon Emanuel Schmid教授所作,学习如何优化eth_calls的各种策略。

              降低eth_calls运行时的开销

              对于无法消除的eth_calls,可以通过在清单中声明来最小化引入的运行开销。当graph-节点处理一个块时,它会在处理程序运行之前并行执行所有声明的eth_calls。未声明的调用在处理程序运行时按顺序执行。运行时的改进来自并行而不是顺序执行调用,这有助于减少调用所花费的总时间,但并不能完全消除它。

              目前,‘eth_calls’只能为事件处理程序声明。在清单中,写

              1event: TransferWithPool(address indexed, address indexed, uint256, bytes32 indexed)2handler: handleTransferWithPool3calls:4  ERC20.poolInfo: ERC20[event.address].getPoolInfo(event.params.to)

              黄色突出显示的部分是调用声明。冒号之前的部分只是一个仅用于错误消息的文本标签。冒号后的部分的格式为Contract[address].function(params)。地址和参数的允许值是event.address和event.params<name>。

              处理程序本身通过绑定到合约并进行调用来访问这个eth_call的结果,与上一节完全相同。graph-节点将声明的eth_calls结果缓存在内存中,处理程序的调用将从内存缓存中检索结果,而不是进行实际的RPC调用。

              注意:声明的eth_calls只能在specVersion>=1.2.0的子图中创建。

              结论

              通过最小化或消除子图中的eth_calls,我们可以显著提高索引性能。

              子图最佳实践1-6

              1. 通过子图修剪提高查询速度

              2. 使用@derivedFrom提高索引和查询响应能力

              3. 通过使用不可变实体和字节作为ID来提高索引和查询性能

              4. 通过避免eth_calls提高索引速度

              5. 通过时间序列和聚合进行简化和优化

              6. 使用嫁接快速部署修补程序

              ⁠在GitHub上编辑⁠

              Immutable Entities和Bytes作为ID时间序列和聚合
              在此页面上
              • TLDR
              • 为什么避免eth_calls是一种最佳实践
              • Eth_call是什么样子的?
              • 如何消除eth_calls
              • 如何优化eth_calls
              • 降低eth_calls运行时的开销
              • 结论
              • 子图最佳实践1-6
              The GraphStatusTestnetBrand AssetsForum安全Privacy PolicyTerms of Service