React Native DApp 开发全栈实战·从 0 到 1 系列(NFT交易-前端部分)

前端

继上一篇《React Native DApp 开发全栈实战·从 0 到 1 系列(NFT交易-合约部分)》,本文进入"前端交互"环节:用 ethers.js 一行行打通 铸造 → 授权 → 挂单 → 购买 的完整闭环。示例拆成三步:

  1. 预览balanceOf 拉取用户 NFT,tokenURI 解析 IPFS 元数据,直接渲染。
  2. 上架
    • create 铸造新 NFT;
    • approve 一键授权给市场合约;
    • list 挂单待售。
  3. 购买 :买家调用 buy,付款即成交,链上所有权瞬间转移。

前置准备

  • hardhat启动网络节点npx hardhat node
  • 合约编译npx hardhat compile 生成对应的xxx.json用获取abi等相关信息
  • 合约部署npx hardhat deploy --tags MyNFT,OZMarketplace 获取合约地址(NFT和交易NFT的合约地址)
  • 节点的私钥导入钱包用来与合约交互时支付对应的gas费

核心代码

代码说明

  • 拿到当前账号的balanceOf
  • 循环tokenid数组拿到ipfs文件
  • 解析ipfs文件
  • 前端展示

1.预览铸造的NFT

javascript 复制代码
import { abi } from "@/abi/SimpleClosedNFT.json";
import * as ethers from "ethers";
const [NFTList,setNFTList]=useState([])
    const nftListFn= async ()=>{
         const provider = new ethers.providers.Web3Provider(window.ethereum);
         await provider.send('eth_requestAccounts', []); // 唤起钱包
        const signer = await provider.getSigner();
        const nft = new ethers.Contract("0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9",abi, signer);//合约地址、abi、
        const userAddress=await signer.getAddress()
        console.log("当前用户",userAddress)
        const nftLength= await nft.balanceOf(userAddress)
        const nftList=[]
        for(let i=0;i<nftLength.toString();i++){
           nftList.push(await nft.tokenURI(i+1))
        }
        let nftArr=[]
        nftList.map((item,index)=>{
            fetch(item).then(r => r.json()).then(data=>{
                nftArr.push({...data,id:index+1})
                setNFTList([...nftArr])
            })//解析ipfs上传的json文件
            
        })  
    }
    useEffect(()=>{
       nftListFn()
    },[])

2.NFT铸造、授权、挂单

代码说明

  • 1.先铸造一个nft
  • 2.在把铸造nft授权给nft交易合约
  • 3.把授权的nft挂单
javascript 复制代码
import { abi as MarketplaceABI } from "@/abi/OZMarketplace.json";
import { abi as NFTABI } from "@/abi/SimpleClosedNFT.json";
import * as ethers from 'ethers';
  const mintNFT=async ()=>{
        const provider = new ethers.providers.Web3Provider(window.ethereum);
        console.log("创建NFT")
        await provider.send('eth_requestAccounts', []); // 唤起钱包
        const signer = await provider.getSigner();
        const nftAddress="0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9"
        const nft = new ethers.Contract("0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9",NFTABI, signer);//nft合约
        const sellContract = new ethers.Contract("0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8", MarketplaceABI, signer);//nft交易合约
        const uri = "https://zygomorphic-magenta-bobolink.myfilebase.com/ipfs/QmQT8VpmWQVhUhoDCEK1mdHXaFaJ3KawkRxHm96GUhrXLB"//ipfs文件
            const price = ethers.utils.parseEther(priceV.toString());//数字价格
            console.log(price)
        try{
          const tx= await nft.create(uri,price,royalty,{value:price})
            const receipt = await tx.wait()
            const tokenId = receipt.logs.map(l => nft.interface.parseLog(l)).find(e => e.name === "Transfer")?.args[2];//铸造成功后获取nft的id
            console.log("tokenId =", tokenId.toString());
           console.log(await nft.tokenURI(tokenId.toString()))//查看ipfs相关信息
           console.log("nft的所有者",await nft.ownerOf(tokenId.toString()))
           const mintPrice=await nft.mintPrice(tokenId.toString())
           console.log("nft的价格",ethers.utils.formatEther(mintPrice)) 
           //授权
const txApprove=await nft.approve("0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8", tokenId.toString());//把铸造的nft授权交易合约
const receiptApprove = await txApprove.wait();
console.log("授权成功","gas消耗:",receiptApprove.gasUsed , "gas价格:",receiptApprove.gasPrice)
console.log("查看授权地址",await nft.getApproved(tokenId.toString()))
//挂单
const listTx=await sellContract.list(tokenId.toString(),ethers.utils.parseEther("1"))
console.log("挂单成功",await listTx.wait())
           router.push({
            pathname:"/home/nftDetails",
            params:{   
                tokenId:tokenId.toString(),
            }
           })

        }catch(err){
            console.log(err)
        }

    }

3.购买NFT

代码说明

  • 1.获取交易tokenid
  • 2.对当前的nft进行售卖
javascript 复制代码
import { abi as MarketplaceABI } from "@/abi/OZMarketplace.json";
import { abi as NFTABI } from "@/abi/SimpleClosedNFT.json";
import { useLocalSearchParams, useRouter } from 'expo-router';
import * as ethers from 'ethers';
const { tokenId } = useLocalSearchParams();//获取交易的tokenid
const sellFn= async ()=>{
const provider = new ethers.providers.Web3Provider(window.ethereum);
await provider.send('eth_requestAccounts', []); // 唤起钱包
const signer = await provider.getSigner();
const user = await signer.getAddress();
console.log("当前账户", user);

const nftContract = new ethers.Contract("0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9", NFTABI, signer);//nft合约
const sellContract = new ethers.Contract("0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8", MarketplaceABI, signer);//nft交易合约
const owner = await nftContract.ownerOf(1);
console.log("所有者",owner)
const price = ethers.utils.parseEther("1");
//售卖
const selltx=await sellContract.buy(tokenId,{value:price})
             const selltxsuccess = await selltx.wait();
             console.log("购买成功","gas消耗:",selltxsuccess.gasUsed , "gas价格:",selltxsuccess.gasPrice)
             console.log("nft的所有者",await nftContract.ownerOf(tokenId))
}

效果图

总结

快速预览表
步骤 核心操作 关键 API
1. 预览 查询用户 NFT 列表 balanceOf + tokenURI
2. 铸造 创建 NFT nft.create(uri, price, royalty, {value})
3. 授权 授权给市场合约 nft.approve(marketplace, tokenId)
4. 挂单 把 NFT 挂到市场 marketplace.list(tokenId, price)
5. 购买 买家支付购买 marketplace.buy(tokenId, {value})

以上就是前端与合约交互的全部过程,整个流程遵循 "铸造 → 授权 → 挂单 → 购买" 的标准 NFT 交易闭环,代码可直接运行于 Hardhat 本地节点,便于本地调试与二次开发。

相关推荐
一 乐8 小时前
婚纱摄影网站|基于ssm + vue婚纱摄影网站系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·spring boot·后端
C_心欲无痕8 小时前
ts - tsconfig.json配置讲解
linux·前端·ubuntu·typescript·json
清沫8 小时前
Claude Skills:Agent 能力扩展的新范式
前端·ai编程
yinuo9 小时前
前端跨页面通信终极指南:方案拆解、对比分析
前端
yinuo9 小时前
前端跨页面通讯终极指南⑨:IndexedDB 用法全解析
前端
xkxnq10 小时前
第二阶段:Vue 组件化开发(第 16天)
前端·javascript·vue.js
wszy180910 小时前
顶部标题栏的设计与实现:让用户知道自己在哪
java·python·react native·harmonyos
烛阴10 小时前
拒绝配置地狱!5 分钟搭建 Three.js + Parcel 完美开发环境
前端·webgl·three.js
xkxnq10 小时前
第一阶段:Vue 基础入门(第 15天)
前端·javascript·vue.js
anyup12 小时前
2026第一站:分享我在高德大赛现场学到的技术、产品与心得
前端·架构·harmonyos