区块链研究实验室 | 如何使用Flow和IPFS显示NFT收藏品

这是一个由三部分组成的系列文章的第二部分,该系列文章主要介绍Flow区块链、NFT和IPFS。您可以在这里阅读第一部分:

区块链研究实验室 | 如何使用Flow和IPFS创建NFT

在本教程中,我们将构建一个简单的React应用程序,该应用程序与Flow智能合约对接,以进行身份验证并获取用户拥有的NFT。然后,我们将解析NFT的元数据,以获取NFT底层数字资产(在本例中为视频)的IPFS位置。快速提醒我们正在努力的NFT-我们正在构建的NFT。

设置

对于本教程,您需要运行Flow仿真器。如果您不记得如何开始,请查看上一篇文章。一定要注意,Flow仿真器是Flow区块链的内存表示形式。因此,如果在第一篇文章和这篇文章之间,您关闭了模拟器,则需要继续执行以下操作:

启动模拟器

部署项目

铸造您的NFT

在本系列的第1部分中将详细介绍每个步骤。

另外,您将需要在计算机上安装NodeJS。

和往常一样,您将需要一个文本编辑器。

设置反应和依赖

我将pinata-party在这些教程的第一部分中开始的父目录中创建我的React应用程序。但是,如果需要,您可以在一个全新的目录中创建您的React应用程序。

要创建我们的应用程序,请运行:

npx create-react-app pinata-party-frontend

完成所有安装后,您将拥有一个名为的新目录pinata-party-frontend。切换到该目录,我们将需要安装一些依赖项。

首先,根据此处有关Flow的文档,您需要安装Flow JS SDK。实际上,对于前端设置的第一部分,我们将仅遵循Flow文档。

让我们继续运行下方命令:

npm i @onflow/fcl @onflow/types

我们将一些值存储为应用程序的全局变量。我们将利用环境变量。作为回应,这意味着创建.env文件并设置键值对,其中键以前缀REACT_APP。如果您遵循Flow文档,则将其设置为与他们的测试网连接。为了本教程的缘故,我们将连接到Flow仿真器。因此,我们需要进行一些更改。在您的.env文件中添加以下内容:

REACT_APP_ACCESS_NODE=http://localhost:8080REACT_APP_WALLET_DISCOVERY=https://fcl-discovery.onflow.org/testnet/authnREACT_APP_CONTRACT_PROFILE=0xf8d6e0586b0a20c7

REACT_APP_ACCESS_NODE如上所示,将值替换为本地仿真器URL。将REACT_APP_CONTRACT_PROFILE值替换为部署项目时收到的地址。

现在我们已经有了,我们需要创建一个配置文件,该文件将用于与Flow JS SDK进行交互。在src名为的目录中创建一个文件config.js。添加以下内容:

import {config} from "@onflow/fcl"config().put("accessNode.api", process.env.REACT_APP_ACCESS_NODE) .put("challenge.handshake", process.env.REACT_APP_WALLET_DISCOVERY) .put("0xProfile", process.env.REACT_APP_CONTRACT_PROFILE)
该配置文件仅帮助JS SDK与Flow区块链(在这种情况下为仿真器)一起使用。要使该文件在整个应用程序中可用,请打开该index.js文件并添加以下行:
import "./config"

现在,让我们进行一些身份验证。如果您不想的话,不需要强迫人们进行身份验证,但是对本教程的第三部分进行身份验证非常重要,因为它可以实现NFT资产的转移。

我们需要创建一个身份验证组件。在src目录中,创建一个名为的文件AuthCluster.js。在该文件内,添加以下内容:

import React, {useState, useEffect} from 'react'import * as fcl from "@onflow/fcl"
const AuthCluster = () => { const [user, setUser] = useState({loggedIn: null}) useEffect(() => fcl.currentUser().subscribe(setUser), []) if (user.loggedIn) { return ( <div> <span>{user?.addr ?? "No Address"}</span> <button className="btn-primary" onClick={fcl.unauthenticate}>Log Out</button> </div> ) } else { return ( <div> <button className="btn-primary" onClick={fcl.logIn}>Log In</button> <button className="btn-secondary" onClick={fcl.signUp}>Sign Up</button> </div> ) }}
export default AuthCluster

使用登录和注册按钮来利用Flow JS SDK连接到钱包发现提供程序的能力很简单。您可以注册一个帐户或使用现有帐户登录。太好了!

现在,我们需要将此组件添加到我们的应用程序中。现在让我们保持简单。将App.js文件替换为以下内容:

import './App.css';import AuthCluster from './AuthCluster';function App() { return ( <div className="App"> <AuthCluster /> </div> );}export default App;

如果立即启动该应用程序(npm start),您应该会看到一个带有登录名和注册按钮的页面。实际上,这两个按钮都可以使用。试试看。

好的,既然我们的React应用程序已经设置好并且我们的依赖项已经安装,那么让我们开始构建为帐户获取NFT并显示它们的功能。

从FLOW中获取NFT

为了显示第一篇文章中介绍的NFT,我们需要能够与Flow区块链进行通信。在本教程的情况下,我们需要能够与Flow仿真器进行通信。我们已经告诉我们的应用程序,当我们设置.env文件时,仿真器正在端口8080上运行。但是现在,我们如何使用JavaScript与Flow对话?

幸运的是,Flow在其JS SDK中内置了此功能。如果您还记得的话,我们之前编写了一个脚本,用于根据NFT的令牌ID查找NFT,并返回令牌的元数据。它看起来像这样:

import PinataPartyContract from 0xf8d6e0586b0a20c7
pub fun main() : {String : String} { let nftOwner = getAccount(0xf8d6e0586b0a20c7) // log("NFT Owner") let capability = nftOwner.getCapability<&{PinataPartyContract.NFTReceiver}>(/public/NFTReceiver)
let receiverRef = capability.borrow() ?? panic("Could not borrow the receiver reference")
return receiverRef.getMetadata(id: 1)}

现在,我们只需要能够将其转换为JavaScript调用即可。让我们创建一个新组件,该组件将允许我们获取数据并最终显示NFT数据。在src目录中,创建一个名为的文件TokenData.js。在该文件中,添加以下内容:

import React, { useState } from "react";import * as fcl from "@onflow/fcl";
const TokenData = () => { const [nftInfo, setNftInfo] = useState(null) const fetchTokenData = async () => { const encoded = await fcl .send([ fcl.script` import PinataPartyContract from 0xf8d6e0586b0a20c7 pub fun main() : {String : String} { let nftOwner = getAccount(0xf8d6e0586b0a20c7) let capability = nftOwner.getCapability<&{PinataPartyContract.NFTReceiver}>(/public/NFTReceiver) let receiverRef = capability.borrow() ?? panic("Could not borrow the receiver reference") return receiverRef.getMetadata(id: 1) } ` ]) const decoded = await fcl.decode(encoded) setNftInfo(decoded) }; return ( <div className="token-data"> <div className="center"> <button className="btn-primary" onClick={fetchTokenData}>Fetch Token Data</button> </div> { nftInfo && <div> { Object.keys(nftInfo).map(k => { return ( <p>{k}: {nftInfo[k]}</p> ) }) } <button onClick={() => setNftInfo(null)} className="btn-secondary">Clear Token Info</button> </div> } </div> );};
export default TokenData;

在此文件中,我们将创建一个具有用于获取令牌数据的按钮的组件。我们还创建了一个清除令牌数据的按钮。单击提取按钮后,它会调用我们创建的函数fetchTokenData。该函数使用Flow JS SDK来执行与在本教程的第一部分中从命令行执行的完全相同的脚本,但是在React中执行。我们获取执行结果,并将结果设置为状态变量nftInfo。如果存在该变量,我们将从屏幕上的NFT元数据和一个使我们清除数据的按钮中呈现键值对。

我还添加了一些CSS,以使事情看起来不那么简单。如果要添加相同的CSS,就在这里,而您所要做的就是替换App.css为:

.App { display: flex; flex-direction: column; min-height: 500px; justify-content: center; align-items: center;}
button { padding: 10; height: 30px; min-width: 100px; cursor: pointer;}
.btn-primary { border: none; background: rgb(255, 224, 0); color: #282828;}
.btn-secondary { border: none; background: rgb(0, 190, 221); color: #282828;}
.center { text-align: center;}
.token-data { margin-top: 100px;}

现在,只需将新组件添加到组件App.js下方即可,如下所示AuthCluster:

import './App.css';import AuthCluster from './AuthCluster';import TokenData from './TokenData';function App() { return ( <div className="App"> <AuthCluster /> <TokenData /> </div> );}export default App;

立即签出您的应用,然后尝试获取您的令牌数据。它看起来应该像这样:

这太酷了!我们正在查找指定帐户所拥有的NFT,然后从该令牌中获取元数据。我们正在屏幕上显示该元数据,但是我们知道该元数据中的一个值会解析为视频文件。让我们看看是否可以在屏幕上渲染出来?

从IPFS获取媒体

您已经注册了Pinata帐户,并通过Pinata上传界面将视频文件添加到IPFS。这意味着您已经能够从IPFS提取内容。在Pin Explorer中,当您单击哈希时,您将被带到Pinata IPFS网关,在那里您的IPFS内容将被解析并显示给您。为了本教程的缘故,我们将使内容更加通用,同时强调IPFS的优点。

也就是说,您不必从Pinata网关中获取内容。相反,我们将从公共Protocol Labs网关获取它。

让我们潜入。

回到TokenData.js文件中,让我们添加一种显示最终从IPFS检索到的视频文件的方法。更新您的文件,使其看起来像这样:

import React, { useState } from "react";import * as fcl from "@onflow/fcl";
const TokenData = () => { const [nftInfo, setNftInfo] = useState(null) const fetchTokenData = async () => { const encoded = await fcl .send([ fcl.script` import PinataPartyContract from 0xf8d6e0586b0a20c7 pub fun main() : {String : String} { let nftOwner = getAccount(0xf8d6e0586b0a20c7) let capability = nftOwner.getCapability<&{PinataPartyContract.NFTReceiver}>(/public/NFTReceiver) let receiverRef = capability.borrow() ?? panic("Could not borrow the receiver reference") return receiverRef.getMetadata(id: 1) } ` ]) const decoded = await fcl.decode(encoded) setNftInfo(decoded) }; return ( <div className="token-data"> <div className="center"> <button className="btn-primary" onClick={fetchTokenData}>Fetch Token Data</button> </div> { nftInfo && <div> { Object.keys(nftInfo).map(k => { return ( <p>{k}: {nftInfo[k]}</p> ) }) } <div className="center video"> <video id="nft-video" canplaythrough controls width="85%"> <source src={`https://ipfs.io/ipfs/${nftInfo["uri"].split("://")[1]}`} type="video/mp4" /> </video> <div> <button onClick={() => setNftInfo(null)} className="btn-secondary">Clear Token Info</button> </div> </div> </div> } </div> );};
export default TokenData;

我们添加了一个video元素,其源指向IPFS上的文件。您会注意到,我们必须拆分该uri值才能获取IPFS哈希,以便可以从IPFS网关中获取内容。让我们谈论一下这个URI。

我们使用NFT创建的uri看起来像ipfs://Qm…。我们之所以创建它,是因为IPFS桌面客户端将允许您单击并打开默认情况下看起来类似的链接。另外,Brave浏览器支持粘贴看起来像这样的链接。我们认为,随着我们的发展,这种链接格式将得到越来越多的支持。

但是,在这种情况下,我们需要散列,以便可以从IPFS公共网关获取内容。完成后,链接将如下所示:

https://ipfs.io/ipfs/QmRZdc3mAMXpv6Akz9Ekp1y4vDSjazTx2dCQRkxVy1yUj6

现在,如果您尝试在我们的应用程序中获取令牌数据,则应获得以下内容:

我们的NFT不再是区块链上的匿名令牌。这是真正的实时数字资产!您的视频可能会有所不同,但希望您在应用程序中看到的结果基本上是相同的体验。

总结

这是一个非常简单的应用程序,您可以做很多事情来使其更漂亮,更具交互性,甚至向其中添加更多Flow元素。Flow JS SDK功能强大,因此我建议您通读文档。

我们使用Flow成功地向我们的应用程序添加了身份验证,我们创建了一个接口以获取有关NFT的信息,并且我们创建了一种不仅显示原始元数据,而且还显示基础数字资产的方法。所有这一切都由Flow区块链和IPFS来保护。我们知道NFT由说自己拥有它的人拥有,并且我们知道显示的内容是有效的,因为哈希已编码到NFT中。

在本系列的最后一部分中,我们将专注于创建一个迷你市场,使我们能够转让NFT,敬请期待~!

作者:链三丰,来源:区块链研究实验室

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

留言与评论(共有 0 条评论)
   
验证码:
微信号已复制,请打开微信添加咨询详情!