在 Arweave 中轻松管理文件:借助 4EVERLAND 完成 Web3 前端Path Manifests的终极指南

为什么使用Path Manifests?

当在 IPFS 上发布 NFT 时,图片和元数据会被上传到 IPFS 网络以获得一个根 CID,其形式如下:

ipfs://bafybeic36ik6cngu37xbzmpytuvyo7z3lyeen44clkkxq5d263zj4nkzr4

通过使用这个根 CID,每个 NFT 的图片路径可以按照 root cid/'file name的格式来定义。例如,一个 NFT 的元数据中的图片路径可能如下所示:

ipfs://bafybeie7byrnb3vo2lc2lwaqm5lox6jiow5ntzod3aoquki36gtirdhodm/0.png

同样的,如果我们想在Arweave 上发布NFT,可以使用 Path Manifets 来集合NFT,这样也可以通过路径方式来访问NFT.

例如

https://arweave.net/Bgw5-GwpymUoe5VMeb-No9WWXpjWsq_8g4oeiGP5RnA/0.png

而不是通过每一张图片在 arweave 上的 ID 来访问它:

​​​​​​https://arweave.net/ISvPQyG8qWzJ1Pv5em5xK8Ht38HZ3ub1fPHbFEqDPK0

如何创建NFT

下面讲解如何使用 4EVERLAND Bucket + Path Manifests 将NFT文件存储到Arweave网络中。

创建Bucket并上传NFT 文件

首先,需要在4everland dashboard 创建一个bucket 并开启Sync to AR 按钮

然后,在Bucket中将您的nft文件夹上传,获取所有nft的TxID,除了在dashboard中手动操作外,您也可以使用 S3 Compatible API 上传获取。

Init S3 client

复制代码
// initS3Client.js
import { S3 } from '@aws-sdk/client-s3'
export const client = new S3({
    endpoint: 'https://endpoint.4everland.co',
    credentials:{
        accessKeyId: '',
        secretAccessKey: '',
        sessionToken: '',
    },
    forcePathStyle: false,
    region: 'eu-west-2'
})

批量上传NFT:

复制代码
import { Upload } from '@aws-sdk/lib-storage'
import { clinet } from './initS3Client.js'
let files = [] //  File Arrary
let Bucket = 'NFT_Bucket'
files.forEach(aysnc(file) => {
    try{
       const task = new Upload({
            client,
            Bucket,
            Key: 'YOUR_folder' + '/' + file.name,
            Body: file,
            ContentType: file.type
        })
        await task.done()
    }catch(error){
     console.log(error)
    }
})


// 同步到AR需要时间,可以等待几分钟后,获取 AR Hash(Tx ID) list:

let arHashPath = {}
files.forEach(aysnc(file) => {
    try{
       const data = await client.headObject({
           Bucket,
           Key: 'YOUR_folder' + '/' + file.name,
       })
        const meta = data.Metadata;
        arHashPath[file.name] = {id: meta["arweave-hash"] ?? ''}
    }catch(error){
     console.log(error)
    }
})

生成图片的Manifests ID

获取到每张NFT的TxID后,按照Path Manifests 标准集合成如下json文件,标准详情可以参考官方说明

复制代码
//manifest-files.json 
{
  "manifest": "arweave/paths",
  "version": "0.1.0",
  "paths": {
    "01.jpeg": {
      "id": "ItVxP8RILEsBjTObeO_piBUME31mj9fa8XJ00v_A94o"
    },
    "02.jpeg": {
      "id": "eiCwWO60Qd8J6wz1ndB82jNgSDotAC8peN38ZAVonl4"
    },
    "03.jpeg": {
      "id": "YUHwbOdf2sSKdGps03qH9LJHX4caYKM5_BOdBpMXOxc"
    },
    "04.jpeg": {
      "id": "kD8Eft7JP82_u9whX710vzsSntn_WP07TgrSB2bGEso"
    },
    "05.jpeg": {
      "id": "KSeYJwZORk3BzelAazsmd6laGAAugHPMqHoXTZ0V4BE"
    }
  }
}

然后将此manifest-files.json文件也上传到bucket,需要规定 Content-Type tag 为 application/x.arweave-manifest+json,获取此文件的ArHash 作为图片的 Manifest ID

复制代码
let manifestFile = {
  manifest: 'arweave/paths',
  version: '0.1.0',
  paths: arHashPath
}

let blob = new Blob([JSON.stringify(manifestFile)], {
  type: "application/json",
});
async function upload(){
    try{
       const task = new Upload({
            client,
            Bucket,
            Key: 'YOUR_folder' + '/' + 'manifest-files.json',
            Body: blob,
            ContentType: 'application/x.arweave-manifest+json'
        })
        await task.done()
    }catch(error){
     console.log(error)
    }
}
// 上传
await upload()


async function getMainfestArHash(){
    try{
        const data = await client.headObject({
           Bucket,
           Key: 'YOUR_folder' + '/' + 'manifest-files.json',
        })
        const meta = data.Metadata;
        if (meta) {
            return meta["arweave-hash"];
        }
        return "";
    }catch(error){
     console.log(error)
    }
}
// 同步到AR需要时间,可以等待几分钟后执行
const arHash =  await getMainfestArHash()
console.log(arHash)

获取到TxID 为 udKzWCDO2PFvxHjiTRhNXuDslsE4jiKlu9A2gY1b1WE

小窍门:如果你的图片很多,可以巧用4EVERLAND Hosting 模块来生成manifest ID。

  1. 在bucket中选中您的NFT 文件夹,点击'Snapshot'并切换到snapshot列表对文件夹进行publish。

  2. 复制snapshot中的ipfs cid,进入hosting页面,在'IPFS Deploy'中输入CID部署

  3. 部署平台选择'Arweave',部署成功后的AR Hash 便是这些图片的ManifestID

使用Manifests ID 为每张NFT 创建metadata

为每张nft生成metadata.json,以01.jpeg为例,如下

复制代码
//文件名:0
{
    "name": "nft-ocean",
    "attributes": [
        {
            "trait_type": "tokenID",
            "value": "0"
        }
    ],
    "description": "nft-ocean image",
    //填入图片的ManifestID + '/'+文件名 
    "image": "ar://QmZ3Y31SwLU77CDfBoL5MphuSmrv414d2ZyunVcbNAJQRQ/01.jpeg"
}

参考上面上传图片的步骤,将每张nft的metadata.json文件以TokenID 命名后,上传到bucket,并将获取到的TxIDs再次集合生成一个Manifest格式的json 文件。

复制代码
{
    "manifest":"arweave/paths",
    "version":"0.1.0",
    "paths":{
        "0":{
            "id":"JcFZfJEJrDKudQsRfN2JnsBPUQTynk0i5XfUqCBcERw"
        },
        "1":{
            "id":"vEUOeIky5hv2GlD2SP2d9TYAua2pkxYxehOczqTGqfU"
        },
        "2":{
            "id":"hd6bI2-c0gr-9ZZsoO8jn_CTRFqWIRwRj5WckgfbmEY"
        },
        "3":{
            "id":"PVAOd8D2JGCW5oOf4bulbQn2npcaaDAexY8sJKzZiEU"
        },
        "4":{
            "id":"lT4RbJEIGsqwwEZB0gxeT1x0nov40crEtBWDHgKQx80"
        }
    }
}

将此 manifest-metadata.json 文件上传bucket,并注明content type 为application/x.arweave-manifest+json,获取此文件的ArHash (TxID),此 ID 便是最终需要设置在合约里面的BaseURI。

本案例获取到的TxID为:2svkHmAC3So_M-LUtDlcDeqPZEwSZsY64AB9L8cA-Uk

将NFT部署到合约

具体步骤请参考 NFT 合约部署教程 ,前面步骤完全一致,到'准备资源'步骤时跳过,直接到设置BaseURI步骤。

我们需要将上面NFT metadata 生成的Manifest ID 写入到BaseURI 中。

setBaseURI.js

复制代码
require("dotenv").config()
const hre = require("hardhat");
const PRIVATE_KEY = process.env.PRIVATE_KEY
const NETWORK = process.env.NETWORK
const API_KEY = process.env.API_KEY


const provider = new hre.ethers.providers.InfuraProvider(NETWORK, API_KEY);
//编译完成合约会自动生成
const abi = require("../artifacts/contracts/NFT_WEB3_EXPLORER.sol/NFT_WEB3_EXPLORER.json").abi
const contractAddress = "合约地址"
const contract = new hre.ethers.Contract(contractAddress, abi, provider)
const wallet = new hre.ethers.Wallet(PRIVATE_KEY, provider)
const baseURI = "ar://2svkHmAC3So_M-LUtDlcDeqPZEwSZsY64AB9L8cA-Uk/" //metadata 的Manifest ID

async function main() {
  const contractWithSigner = contract.connect(wallet);
  //调用setBaseURI方法
  const tx = await contractWithSigner.setBaseURI(baseURI)
  console.log(tx.hash);
  await tx.wait();
  console.log("setBaseURL success");
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });

后续步骤与教程一致,完成mint后到opensea 查看。

相关推荐
腾讯TNTWeb前端团队2 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰5 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪5 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪5 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy6 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom6 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom7 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom7 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom7 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom7 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试