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

相关推荐
weixin_3823952310 分钟前
为小工厂量身打造:本地部署的物料管理系统带缺料计算
前端·制造
__zRainy__16 分钟前
解决pnpm v10+不自动构建
前端·pnpm·工程化
猫猫不是喵喵.1 小时前
Vue3 Props 属性
前端·javascript·vue.js
醉城夜风~2 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华3 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子5 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅5 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni5 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学7 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端