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 本地节点,便于本地调试与二次开发。

相关推荐
Duck不必7 小时前
前端项目安全审计工具
前端·github
旺仔小猪7 小时前
【计算机网络】前端配置接口超时时间的方法
前端
qb7 小时前
vue3.5.18源码:一文搞懂ref、computed、watch和render底层关系网
前端·vue.js·前端框架
Xiecj7 小时前
使用Vue3实现鼠标跟随效果
前端
A洛7 小时前
Claude Code项目流飞升!AI自动化测试迎来新纪元:Playwright MCP复用Chrome登录态
前端·人工智能·chrome
黑狼传说8 小时前
从一行 var a = 1 开始,深入理解 V8 引擎的心脏
前端·javascript·v8
原生高钙8 小时前
var, let 和 const
前端·javascript·面试
huabuyu8 小时前
Taro微信小程序高性能无限下拉列表实现
前端
DevRen8 小时前
实现Google原生PIN码锁屏密码效果
android·前端·kotlin