DApp設計與開發 課程筆記(六):NFT交易市場後端開發

孤飞發表於2024-07-02

筆記對應課程內容為成都資訊工程大學區塊鏈產業學院老師梁培利DApp 設計與開發 17-18 課

筆記中提到的名詞不做過多解釋 不懂就搜!

tokenuri 對應一個metadata的 json 資料

上傳一個圖片,將圖片上傳到IPFS,獲得一個cid,然後將json格式的metadata上傳到IPFS,然後給使用者傳送一個NFT

程式碼:https://github.com/liangpeili/nft-market-backend

app.js

import express from 'express';
import cors from 'cors';
import bodyParser from 'body-parser';
import fileUpload from 'express-fileupload';
import { addFileToIPFS, addJSONToIPFS } from './ipfs-uploader.js';
import { mint } from './nft-minter.js';
import dotenv from 'dotenv';
dotenv.config("./.env");

const app = express()

app.set('view engine','ejs')
app.use(bodyParser.urlencoded({extended:true}))
app.use(fileUpload())
app.use(cors())

app.get('/', (req,res) => {
    res.render('home')
})

app.post('/upload', (req, res) => {
    if (!req.files || Object.keys(req.files).length === 0) {
        return res.status(400).json({ message: 'No files were uploaded.' });
    }

    const file = req.files.file;
    const fileName = file.name
    const filePath = 'files/' + fileName

    const title = req.body.title
    const description = req.body.description
    const address = req.body.address

    console.log(title, description, address)

    file.mv(filePath, async (err) => {
        if (err) {
            console.log('error: failed to download the file.')
            return res.status(500).send(err)
        }

        const fileResult = await addFileToIPFS(filePath)
        console.log('File added to IPFS:', fileResult.cid.toString());

        const metadata = {
            title,
            description,
            image: 'http://127.0.0.1:8080/ipfs/' + fileResult.cid.toString() + '/' + fileName
        }
        const jsonResult = await addJSONToIPFS(metadata)
        console.log('Metadata added to IPFS:', jsonResult.cid.toString());

        const userAddress = address || process.env.ADDRESS;
        await mint(userAddress, 'http://127.0.0.1:8080/ipfs/' + jsonResult.cid.toString())

        res.json({ 
            message: 'File uploaded successfully.', 
            metadata
        });
    });
});

const HOST = process.env.HOST 
const PORT = process.env.PORT

app.listen(PORT, HOST, () => {
    console.log(`Server is running on port ${PORT}`)
})

ipfs-uploader.js

import { create } from 'kubo-rpc-client';
import fs from 'fs';
import dotenv from 'dotenv';
dotenv.config("./.env");

const ipfs = create(new URL(process.env.IPFS_URL))

export async function addJSONToIPFS(json) {
  try {
      const result = await ipfs.add(JSON.stringify(json));
      return result;
  } catch (error) {
      console.error('Failed to add JSON to IPFS:', error);
  }
}

export async function addFileToIPFS(filePath) {
  try {
      const file = fs.readFileSync(filePath);
      const result = await ipfs.add({ path: filePath, content: file });
      return result;
  } catch (error) {
      console.error('Failed to add file to IPFS:', error);
  }
}

nft-minter.js

import { ethers, JsonRpcProvider } from "ethers";
import fs from 'fs';
import dotenv from 'dotenv';
dotenv.config("./.env");

export async function mint(address, uri) {
    const provider = new JsonRpcProvider(process.env.RPC);
    const signer = await provider.getSigner()

    const MyNFTAbi = JSON.parse(fs.readFileSync('./abis/MyNFT.json'));
    const MyNFTContract = new ethers.Contract(process.env.NFT, MyNFTAbi, signer);

    const result = await MyNFTContract.safeMint(address, uri);
    console.log(result.hash);
}

// mint('0x70997970C51812dc3A010C7d01b50e0d17dc79C8', 'https://ipfs.io/ipfs/QmZ4tj')

相關文章