过去,开发者通过构建自己的中心化式索引服务器从区块链中提取数据,将数据存储在数据库中,并通过API进行公开。这需要大量的工程和硬件资源,并破坏了去中心化所需的重要安全性。
本文将向您展示如何在去中心化的web基础设施区块链数据上轻松部署api。
分布式web基础设施
分布式Internet的概念和发展方向通常称为Web3。Web3通过以下附加功能增强了我们今天所知的互联网:
分权
可验证的
不信任
自我管理
为了实现去中心化,协议定义了提供一系列数字服务的网络,如计算、存储、带宽、身份和其他不需要中介的web基础设施。这些协议通常分布在多个节点(服务器)上,因此大多数希望成为网络并提供服务的人都可以参与。
以图表为基础
在本文中,我们还将研究这样一个协议图,以及如何使用存储在以太坊区块链中的数据来构建和部署我们自己的graphqlapi。
Graph是一种索引协议,用于查询以太坊等区块链和IPFs等网络。任何人都可以构建和发布一个名为subgraph的开放API,这使得数据易于访问。
子图定义要通过graphqlapi提供的数据、数据源和数据访问模式。作为一个开发人员,您可以选择使用另一个已经部署了其子图形的开发人员,或者定义和部署您自己的子图形并使用它。
子图由几个主要部分组成
1Graphql模式
graphql模式定义要保存和查询的数据类/实体。您还可以在体系结构中定义关系和全文搜索功能等配置。
2子图列表(yaml配置)
该列表定义了子图索引的智能契约、它们的abi、这些契约中要注意的事件,以及如何将事件数据映射到在graph节点中存储和允许查询的实体。
3程序集脚本映射
Assembyscript映射使您能够保存要使用架构中定义的实体类编制索引的数据;diagramcli还使用子图模式的组合来生成assembyscript类以及智能合约的ABI。
开始构建
既然我们已经很好地理解了graph及其工作原理,那么让我们开始编写一些代码。
在本教程中,我们将构建一个子图来查询Zora智能合约中的NTF数据,实现查询以获取NFT及其所有者,并在它们之间建立关系。
前提条件:
要在本教程中取得成功,您应该在计算机上安装node.。我建议您使用NVM或FNM来管理node.的版本。
在图形资源管理器中创建图形项目
首先,打开图形资源管理器,然后登录或创建一个新帐户。接下来,转到仪表板并单击添加子图以创建新的子图。
使用以下属性配置子图:
子图名称-zoranft子图
副标题-用于查询NFT子图
可选-填写描述和GitHub URL属性
使用graph cli初始化新子图
接下来,安装graph cli:
美元;npm公司;安装-g@graphprotocol/graph cli#;或美元;纱线;全球;添加@graphprotocol/graph命令行
安装graph cli后,可以使用graph cliinit命令初始化新的子图。
有两种方法
图中的1
美元;图形;初始化--来自示例/[]
2.现有智能合约
如果您已将智能合约部署到以太坊主网络或测试网络之一,则从合约初始化新的子图是启动和运行的简单方法。
美元;图形;初始化--来自合同/[--网络]/[--abi]//[]
在我们的示例中,我们将使用Zora代币契约,因此我们可以通过使用–from contract标志传递契约地址来从契约地址进行初始化:
美元;图形;初始化--来自合同;0xabEFBc9fD2F806065b4f3C237d4b59D9A97Bcac7-网络;主网/--合同名称;代币索引事件;子图;名称›您的用户名/Zoranftsubgraph?目录;至;创建;公司;子图;在›Zoranftsubgraph?以太坊;网络›主网;合同;地址›0xabEFBc9fD2F806065b4f3C237d4b59D9A97Bcac7?合同;姓名·代币
此命令根据作为参数传入的协定地址,从协定生成基本子图。通过使用此约定地址,CLI将初始化项目中的某些内容,以帮助您开始。
子图的主要配置和定义在subgraph.yaml文件中。子图代码库由几个文件组成
Subgraph.yaml:包含子图列表的yaml文件。
架构。Graphql:一种Graphql体系结构,用于定义为子图存储的数据以及如何通过Graphql查询数据。
程序集脚本映射:将事件数据从以太坊转换为架构中定义的实体的程序集脚本代码。
我们将使用subgraph.yaml中的条目:
描述(可选):子图的可读描述。将子图部署到托管服务时,图形资源管理器将显示此描述。
Repository(可选):可以在其中找到子图列表的存储库的URL。
Datasources.source:子图来源的智能合约的地址,以及要使用的智能合约的ABI。
Datasources.source.startblock(可选):数据源从中开始索引的块的编号。
Datasources.mapping.entities:数据源写入存储的实体。每个实体的架构都在schema.grapql文件中定义。
Datasources.mapping.abis:源协定的一个或多个命名ABI文件,以及在映射中与之交互的任何其他智能协定。
Datasources.mapping.eventhandlers:列出子图响应的智能协定事件以及映射中的处理程序(在示例中为./SRC/映射。TS),将这些事件转换为存储中的实体。
定义实体
通过该图,可以在模式中定义实体类。Grapql和graph节点生成**字段,用于查询该实体类的各个实例和集合。每个应该是实体的类都必须用@entity指令进行注释。
我们要索引的实体/数据是token和user。这样,我们可以索引用户和用户创建的代币。
为此,请使用以下代码更新schema.grapql:
类;代币@实体{身份证号码:ID!代币ID:;BigInt!内容URI:;字符串!元数据URI:;字符串!创建者:用户!所有者:用户!}类;用户@实体{身份证号码:ID!代币:[代币!]!@派生自(字段:quot;所有者(quot;);已创建:[代币!]!@派生自(字段:quot;creatorquot;)}
通过@derivedfrom(来自文档)通过“关系”
可以通过@derived from字段在实体上定义反向查找。这将在实体上创建一个虚拟字段,该字段可以查询,但不能通过映射API手动设置。
相反,它派生自另一个实体上定义的关系。对于这种关系,存储关系的两边都没有什么意义,当只存储一方并派生另一方时,索引和查询的性能会更好。
现在我们已经为应用程序创建了graphql模式,我们可以在本地生成实体,开始在mappingscli创建的实体中使用它们
图形;编码基因
为了使工作中的智能合约、事件和实体变得简单和类安全,graph cli通过子图的graph QL模式和数据源中包含的合约ABI的组合生成assembyscript类。
用实体和映射更新子图
现在我们可以配置子图了。Yaml使用我们刚刚创建的实体并配置它们的映射。
为此,首先用datasources.mapping.entities的用户和代币实体更新字段
实体:代币-用户
接下来,更新datasources.mapping.eventhandlers以仅包括以下两个事件处理程序:
事件处理程序:-事件:标记已更新(已索引);uint256,地址,字符串);经办人:手电筒更新-事件:转移(索引);地址,索引;地址,索引;(第256页);经办人:手转移
**,更新配置以添加startblock:
资料来源:地址:quot;0XABEFBC9FD2F8065B4F3C237D4B59D9A97BCAC7quot;;abi:;代币;启动块:一千一百五十六万五千零二十
程序集脚本映射
接下来,打开Src/mappings。Ts来编写我们在子图中定义的映射事件处理程序。
使用以下代码更新文件:
导入{代币更新;作为;代币更新事件;转账;作为;转移事件;代币;作为;代币合约};来自;quot;../generated/Token/tokenquot;导入{代币;用户};从39;../ 生成/模式#39;出口;功能;handleTokenUri更新(事件:TokenUriUpdateEvent):无效{让;代币=Token.load(event.params.tokenId.toString());token.contentURI=event.params.uuri;token.save();}出口;功能;把手转移(事件:转让方):无效{让;代币=Token.load(event.params.tokenId.toString());如果(!代币)代币=新建;代币(event.params.tokenId.toString());token.creator=event.params.to.toHexString();token.tokenID=event.params.tokenId;让;代币合约TokenContract.bind(event.address);token.contentURI=tokenContract.tokenURI(event.params.tokenId);token.metadataURI=tokenContract.tokenMetadataURI(event.params.tokenId);}token.owner=event.params.to.toHexString();token.save();让;用户=User.load(event.params.to.toHexString());如果(!用户){用户=新建;用户(event.params.to.toHexString());user.save();}}
这些映射将处理创建、传输或更新新代币的事件。当触发这些事件时,映射会将数据保存到子图中。
运行生成
接下来,让我们运行一个构建以确保所有配置都正确。为此,请运行以下生成命令:
美元;图形;建造
如果生成成功,您应该在根目录中看到一个新的生成文件夹。
部署子图
要部署,我们可以使用deploy来使用graph cli运行命令。要部署,首先需要**在graph Explorer中创建的子图的访问代币:
接下来,运行以下命令:
美元;图形;授权;https://api.thegraph.com/deploy/ 美元;纱线;部署
部署子图后,您应该会看到它显示在仪表板中:
单击子图时,它应打开图形资源管理器:
查询数据
现在我们在仪表板中,应该可以开始查询数据了。运行以下查询以获取代币及其元数据的列表:
{;代币{身份证;代币ID;内容URI;元数据URI
我们还可以配置订单方向:
{;代币;订购者:id;订单方向:描述){身份证;代币ID;内容URI;元数据URI
或者选择跳过一些结果来实现一些基本的分页:
{;代币;跳过:100个;订购者:id;订单方向:描述){身份证;代币ID;内容URI;元数据URI
或查询用户及相关内容:
{;用户{身份证;代币{身份证;内容URI}}}
更新子图
如果我们想对子图进行一些更改,然后重新部署它,我们应该怎么做?假设我们想给子图添加一个新函数。假设除了现有的查询函数之外,我们还想添加这个函数,以便按照创建NFT的时间戳进行排序。
要做到这一点,我们需要向实体添加一个新的created at timestamp字段标记
类;代币@实体{身份证号码:ID!代币ID:;BigInt!内容URI:;字符串!元数据URI:;字符串!创建者:用户!所有者:用户!quot;添加;新建;创建日期时间amp字段6035;创建日期时间戳:比京特!}
现在我们可以重新运行代码生成:
图形;编码基因
接下来,我们需要更新映射以保存新字段:
//更新;公司;手部转移;功能;至;添加;公司;创建日期时间戳;至;公司;代币;对象导出;功能;把手转移(事件:转让方):无效{让;代币=Token.load(event.params.tokenId.toString());如果(!代币)代币=新建;代币(event.params.tokenId.toString());token.creator=event.params.to.toHexString();token.tokenID=event.params.tokenId;//添加;公司;创建日期时间戳;至;公司;代币;对象;token.createdAtTimestamp=event.block.timestamp;让;代币合约TokenContract.bind(event.address);token.contentURI=tokenContract.tokenURI(event.params.tokenId);token.metadataURI=tokenContract.tokenMetadataURI(event.params.tokenId);}token.owner=event.params.to.toHexString();token.save();让;用户=User.load(event.params.to.toHexString());如果(!用户){用户=新建;用户(event.params.to.toHexString());user.save();}}
现在我们可以重新部署子图:
美元;纱线;部署
重新部署子图后,我们现在可以按时间戳查询最近创建的NFT:
{;代币;orderBy:createdAtTimestamp,订单方向:描述){身份证;代币ID;内容URI;元数据URI
文章标题:如何在以太坊上构建graphqlapi
文章链接:https://www.btchangqing.cn/254369.html
更新时间:2021年05月10日
本站大部分内容均收集于网络,若内容若侵犯到您的权益,请联系我们,我们将第一时间处理。