在 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 查看。

相关推荐
guokanglun1 分钟前
Vue.js动态组件使用
前端·javascript·vue.js
-seventy-14 分钟前
Ajax 与 Vue 框架应用点——随笔谈
前端
我认不到你30 分钟前
antd proFromSelect 懒加载+模糊查询
前端·javascript·react.js·typescript
集成显卡33 分钟前
axios平替!用浏览器自带的fetch处理AJAX(兼容表单/JSON/文件上传)
前端·ajax·json
scc214040 分钟前
spark的学习-06
javascript·学习·spark
焚琴煮鹤的熊熊野火41 分钟前
前端垂直居中的多种实现方式及应用分析
前端
我是苏苏1 小时前
C# Main函数中调用异步方法
前端·javascript·c#
转角羊儿1 小时前
uni-app文章列表制作⑧
前端·javascript·uni-app
大G哥1 小时前
python 数据类型----可变数据类型
linux·服务器·开发语言·前端·python
hong_zc2 小时前
初始 html
前端·html