Web3.0中的索引是什么? 终极指南 (不需要事先了解)

很难说数据工程文化在Web3.0开发人员社区中已经根深蒂固。并不是每个开发人员都能很容易地确定索引在Web3.0上下文中意味着什么。我想定义一些关于这个话题的细节,并谈谈The Graph,它已经成为DApp开发者在区块链上访问数据的事实上的行业标准。

让我们从索引开始。

数据库中的索引是创建一个数据结构的过程,该数据结构对数据库中的数据进行排序和组织,以便能够有效地执行搜索查询。通过在数据库表上创建索引,数据库服务器可以更快地搜索和检索与查询中指定的条件匹配的数据。这有助于提高数据库的性能,并减少检索信息所需的时间。

但是区块链中的索引呢?最流行的区块链架构是EVM(以太坊虚拟机)。

以太坊虚拟机(EVM)是在以太坊区块链上执行智能合约的运行时环境。它是一个在以太坊网络上的每个节点上运行的计算机程序。它负责执行智能合约的代码,还提供sandbox和gas使用控制等安全功能。EVM确保以太坊网络上的所有参与者都能以一致和安全的方式执行智能合约。

你可能知道,区块链上的数据以区块的形式存储,其中包含交易。另外,你可能知道有两种类型的账户:

  1. 外部拥有的账户-由任何普通钱包地址描述
  2. 合约账户——由任何部署的智能合约地址描述

如果您从您的帐户发送一些以太币到任何其他外部所有者的帐户-没有任何中间件环节。但是,如果您将一些以太币发送到具有任何有效载荷的智能合约地址,您实际上会在智能合约上运行一些方法,这些方法实际上会创建一些“内部”交易。

好吧,如果在区块链上可以找到任何交易,为什么不把所有数据转换成一个不断更新的大数据库,可以用类似sql的格式查询呢?

问题是,只有当你有“钥匙”来破译它时,你才能访问智能合约的数据。没有这个“密钥”,区块链上的智能合约数据实际上是一团糟。这个密钥被称为ABI(应用程序二进制接口)。

ABI(应用程序二进制接口)是一个标准,它定义了智能合约与外部世界的通信方式,包括其他智能合约和用户界面。它定义了智能合约的数据结构、函数签名和参数类型,以实现合约与用户之间正确有效的通信。

任何链上智能合约都有ABI。问题是,您可能没有您感兴趣的智能合约的ABI。有时,您可以找到一个ABI文件(它实际上是一个JSON文件,其中包含智能合约的函数和变量的名称-就像一个用于通信的接口)。

  1. Etherscan上(如果智能合约已经被验证)
  2. 在GitHub上(如果开发者开源了项目)
  3. 或者智能合约是否涉及任何标准类型,如ERC-20, ERC-721等。

当然,如果您是智能合约的开发人员,您就拥有ABI,因为它是在编译时生成的。

从开发者的角度看是什么

但是我们不要停留在ABI的概念上。如果我们从智能合约开发者的角度来看待这个话题呢?什么是智能合约?答案比你想象的要简单得多。对于熟悉面向对象编程的人,这里有一个简单的解释:

开发人员代码中的智能合约是一个带有字段和方法的类(对于evm兼容的链,智能合约通常用Solidity编写)。而部署在链上的智能合约则成为该类的对象。因此,它允许用户调用它的方法并更改它的内部字段。

值得强调的是,智能合约状态发生变化的任何方法调用都意味着一个事务,通常紧随其后的是开发人员从代码中发出的事件。让我们举例说明ERC-721(不可替代的令牌集合的通常标准,如BoredApeYachtClub)智能合约的函数调用,该合约在转移NFT的所有权时发出事件。

/**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(address from, address to, uint256 tokenId) internal virtual {
        address owner = ownerOf(tokenId);
        if (owner != from) {
            revert ERC721IncorrectOwner(from, tokenId, owner);
        }
        if (to == address(0)) {
            revert ERC721InvalidReceiver(address(0));
        }

        _beforeTokenTransfer(from, to, tokenId, 1);

        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook
        owner = ownerOf(tokenId);
        if (owner != from) {
            revert ERC721IncorrectOwner(from, tokenId, owner);
        }

        // Clear approvals from the previous owner
        delete _tokenApprovals[tokenId];

        // Decrease balance with checked arithmetic, because an `ownerOf` override may
        // invalidate the assumption that `_balances[from] >= 1`.
        _balances[from] -= 1;

        unchecked {
            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require
            // all 2**256 token ids to be minted, which in practice is impossible.
            _balances[to] += 1;
        }

        _owners[tokenId] = to;
      	
      	emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId, 1);
    }

我们在这里可以看到。要将NFT从你的地址转移到任何其他地址,你需要调用_transfer函数,传递这两个地址的值和这个NFT的ID。在代码中,您可以看到将执行一些检查,然后用户的余额将被更改。但重要的是,在函数代码的末尾,有一行

emit Transfer(from, to, tokenId);

这意味着这三个值将被“发出”到外部,并且可以在区块链的日志中找到。以这种方式保存所需的历史数据效率要高得多,因为将数据直接存储在区块链上太昂贵了。

现在我们已经定义了所有需要的概念来展示索引是什么。

考虑到任何智能合约(作为某个类的对象)在其生命周期中不断被用户(和其他智能合约)调用并改变状态(同时发出事件),我们可以将索引定义为在智能合约的生命周期内收集智能合约数据(其中的任何内部变量,而不仅仅是那些显式发出的变量)的过程,将这些数据与交易id(哈希)和区块号保存在一起,以便能够在将来找到有关它的任何细节。

值得注意的是,如果智能合约没有明确存储这些数据(我们知道它非常昂贵),那么就不可能访问钱包“A”的第一笔交易,代币“B”,或者智能合约“C”(或任何其他东西)中最大的交易。

这就是我们需要索引的原因。我们可以在SQL数据库中做的简单事情在区块链中变得不可能。因为没有索引。

换句话说,这里的“索引”是智能合约数据收集的同义词,因为在Web3.0中没有索引意味着没有数据访问。

过去开发人员是如何编制索引的。他们白手起家:

  1. 他们用Go、Rust等快速编程语言编写高性能代码。
  2. 他们建立了一个数据库来存储数据。
  3. 他们设置了一个API,使数据可以从应用程序访问。
  4. 他们启动了一个存档区块链节点。
  5. 在第一阶段,他们遍历整个区块链,找到与特定智能合约相关的所有交易。
  6. 它们通过存储新实体和刷新数据库中的现有实体来处理这些事务。
  7. 当他们到达链头时,他们需要切换到更复杂的模式来处理新交易,因为由于链重组,每个新区块(甚至是区块链)都可能被拒绝。
  8. 如果链已经重组,他们需要回到分叉块并重新计算所有内容到新的链头。

正如您所注意到的,它不仅不容易开发,而且不容易实时维护,因为每个节点故障都可能需要一些步骤才能再次实现数据一致性。这就是《the Graph》出现的原因。这是一个简单的想法,开发人员和最终用户需要轻松访问智能合约数据,而不需要所有这些麻烦。

Graph项目定义了一个称为“子图”的范式,为了从区块链中提取智能合约数据,您需要描述3件事:

  1. 一般的参数,比如使用什么区块链,索引什么智能合约地址,处理什么事件,从哪个区块开始。这些变量在所谓的“manifest”文件中定义。
  2. 如何存储数据。应该在数据库中创建哪些表来保存智能合约中的数据?答案可以在“schema”文件中找到。
  3. 如何收集数据。应该从事件中保存哪些变量,还应该收集哪些伴随数据(如事务散列、块号、其他方法调用的结果等),以及如何将它们放入我们定义的模式中?

这三件事可以在以下三个文件中优雅地定义:

  1. 子图。清单文件
  2. 模式。图形-模式描述
  3. 映射。ts - AssemblyScript文件

多亏了这个标准,按照这些教程中的任何一个描述整个索引都非常容易:

  1. 如何使用图的子图轻松访问Tornado Cash数据(https://medium.com/@balakhonoff_47314/how-to-access-the-tornado-cash-data-easily-using-the-graphs-subgraphs-a70a7e21449d)
  2. 如何使用图子图和ChatGPT提示访问PEPE币的交易(https://medium.com/@balakhonoff_47314/tutorial-how-to-access-transactions-of-pepe-pepe-coin-using-the-graph-subgraphs-and-chatgpt-5cb4349fbf9e)
  3. 一个初学者的指南,开始使用The Graph(https://docs.chainstack.com/docs/subgraphs-tutorial-a-beginners-guide-to-getting-started-with-the-graph)
  4. 解释子图模式(https://docs.chainstack.com/docs/subgraphs-tutorial-working-with-schemas)
  5. 如何使Python访问实时智能合约数据(https://medium.com/@balakhonoff_47314/how-to-access-real-time-smart-contract-data-from-python-code-using-lido-as-an-example-38738ff077c5)

在这里可以找到更多的教程(https://docs.chainstack.com/docs/chainstack-subgraphs-tutorials)。

它是什么样子的?

正如你在这里看到的,Graph负责索引工作。但是你仍然需要运行一个图节点(它是The Graph的开源软件)。这是另一个范式转变。

由于过去的开发人员一直在运行自己的区块链节点,并且不再这样做,将这个麻烦交给了区块链节点提供商。该图显示了另一种架构简化。Graph托管服务以这种方式寻找开发人员(这里的“用户”):

在这种情况下,用户(或开发人员)不需要运行自己的索引器或图形节点,但仍然可以控制所有算法,甚至不会进入供应商锁定,因为不同的提供商使用相同的the graph描述格式(Chainstack与the graph完全兼容,但值得与您的web3.0基础设施提供商检查此声明)。这是一件大事,因为它可以帮助开发人员加快开发过程并降低操作维护成本。

但在这种范式中,很酷的一点是,任何时候开发人员想让他们的应用程序真正去中心化,他们都可以使用相同的子图无缝地迁移到The Graph去中心化网络。

我在之前的叙述中漏掉了什么。

  1. 正如您可能注意到的,The Graph使用GraphQL而不是REST API。它允许用户对他们创建的任何表进行灵活的查询,并轻松地将它们组合起来并进行过滤。这里有一个很好的视频教你如何掌握它。此外,ChatGPT还可以帮助编写GraphQL查询,正如我在本教程中所展示的那样。
  2. Graph有自己的托管服务,其中包含许多现成的子图。它是免费的,但不幸的是不符合任何生产需求(可靠性、SLA、支持),同步速度比付费解决方案慢得多,但仍然可以用于开发。关于如何在Python中使用这些现成的子图的教程可以在这里(https://medium.com/@balakhonoff_47314/how-to-access-real-time-smart-contract-data-from-python-code-using-lido-as-an-example-38738ff077c5)找到。
  3. 如果你打算在生产中使用子图,我强烈建议使用一些成熟的Web3.0基础设施提供商,如Chainstack,以实现成本效率以及可靠性和速度。
  4. 如果您对子图开发感到不舒服,请不要犹豫,在电报聊天“子图经验分享”(https://t.me/+HHP9q2gWFGNlNGYy)中提出任何问题。
  5. 此外,如果您对智能合约开发有任何疑问,请加入“Solidity development”(https://t.me/dev_solidity)聊天区。
  6. 支持作者,并通过订阅Medium(https://medium.com/@balakhonoff_47314)或Twitter(https://twitter.com/balakhonoff)找到更多关于Web3开发的教程。
展开阅读全文

页面更新:2024-05-09

标签:以太   索引   区块   节点   合约   定义   地址   智能   文件   指南   数据

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top