本文介绍如何使用 Solana Web3 库和 Metaplex JS SDK 从终端更新 Solana devnet 上 NFT 的元数据,包括获取现有 NFT、上传新元数据和更新 NFT 的步骤。
你是否正在为你的 NFT 收藏更新特征?修改版税/创作者以反映团队的变化?提升你的 PFP 收藏的艺术质量?无论出于何种原因,更新你创建的 NFT 的元数据,是任何 NFT 开发者都应具备的一个实用工具。
在本指南中,你将使用 Solana Web3 库和 Metaplex JS SDK,从终端更新 Solana devnet 上一个 NFT 的元数据。我们将涵盖三个步骤来更新你的 NFT 的元数据:
安装 Nodejs(版本 16.15 或更高)
具备 Typescript 经验,并安装最新版本的 ts-node(你可以通过在终端输入 npm update -g typescript ts-node 来更新到最新版本)
在你开始之前
确保你已在 Solana 的 devnet 上铸造了一个 NFT,并能访问权限钱包。你可以通过跟随这个 指南:如何使用 Typescript 在 Solana 上铸造 NFT 创建一个(源代码)。
🚨 确保在你 NFT 的配置中选择 mutable: true 。只有可变的 NFT 元数据可以被更新。
在终端中创建一个新的项目目录:
mkdir update-metadata
cd update-metadata
为你的应用创建一个文件 app.ts:
echo > app.ts
使用"yes"标志初始化你的项目,以使用新包的默认值:
yarn init --yes
#或者
npm init --yes
创建一个 tsconfig.json,启用 .json 导入:
tsc -init --resolveJsonModule true
我们需要添加 Solana Web3 和 SPL Token 库用于本练习。此外,我们将使用 Metaplex 的 JS SDK。在你的终端中输入:
yarn add @solana/web3.js@1 @metaplex-foundation/js
#或者
npm install @solana/web3.js@1 @metaplex-foundation/js
要跟随本指南,你需要具有相同的 Solana 文件系统钱包(密钥对写入 guideSecret.json 文件),它是你 NFT 的权限方。如果你还没有 NFT 或 NFT 的权限钱包,请按照我们的 指南:如何使用 Typescript 在 Solana 上铸造 NFT 创建一个(源代码)。
确保将你的钱包保存到项目目录中,命名为 guideSecret.json(你可以直接从 mint-nft 项目的目录中复制)。如果你需要 devnet SOL,请通过在下面输入你的钱包地址请求一些:
🪂 请求 Devnet SOL
空投 1 SOL (Devnet)
设置后,你的环境应该看起来像这样:
打开 app.ts,并在 第1行 粘贴以下导入:
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
import { Metaplex, keypairIdentity, bundlrStorage, Nft, Sft } from "@metaplex-foundation/js";
import secret from './guideSecret.json';
简化调试的日志
现在你可以访问 RPC 端点的日志,帮助你更有效地排除问题。如果你遇到 RPC 调用问题,只需查看 QuickNode 仪表板上的日志,即可快速识别并解决问题。了解更多关于日志历史限制的信息请见 我们的定价页面
除了我们在前一步创建的钱包外,我们还导入了一些来自 Solana Web3 和 Metaplex JS 库的必要方法和类。
要在 Solana 上构建,你需要一个 API 端点与网络连接。你可以使用公共节点或部署和管理自己的基础设施;然而,如果你希望获得更快的响应时间,你可以将繁重的工作交给我们。
QuickNode 现在接受 Solana 支付 🚀
你现在可以 用 USDC 在 Solana 上支付 QuickNode计划。作为首个接受 Solana 付款的多链提供商,我们现在为开发者简化了这一过程——无论你是创建新账户还是管理现有账户。 在这里了解更多关于使用 Solana 支付的信息。
看看为什么超过 50% 的 Solana 项目选择 QuickNode,你可以在 这里注册一个免费账户。我们将使用一个 Solana Devnet 节点。
复制 HTTP 提供程序链接:
在 app.ts 中的导入语句下,声明你的 RPC,并建立 Connection 到 Solana:
const QUICKNODE_RPC = 'https://example.solana-devnet.quiknode.pro/0123456/';
const SOLANA_CONNECTION = new Connection(QUICKNODE_RPC);
你需要声明一些变量以运行你的脚本:
在 SOLANA_CONNECTION 下方添加以下声明,以建立我们将使用的钱包和我们将要更新的 NFT:
const WALLET = Keypair.fromSecretKey(new Uint8Array(secret));
const MINT_ADDRESS = '6cuiqk2VubzAgtUvFjBvosjCJUWG81EvW1F28qtX4EDn';
确保你包括的 NFT 的权限设置为你的 WALLET,并且该 NFT 是可变的。
通过在 Metaplex.make() 中调用我们的 SOLANA_CONNECTION 来建立一个新的 Metaplex 实例。我们的实例将使用我们刚创建的 Keypair 和 bundlrStorage(用于使用 Solana 向 Arweave 上传文件的选项):
const METAPLEX = Metaplex.make(SOLANA_CONNECTION)
.use(keypairIdentity(WALLET))
.use(bundlrStorage({
address: 'https://devnet.bundlr.network',
providerUrl: QUICKNODE_RPC,
timeout: 60000,
}));
通过包含我们的网络连接、钱包和存储路由,API 将使我们轻松地向 Solana 网络提交交易。
我们将创建一个包含新元数据的 NEW_METADATA 对象。创建一个新的常量 NEW_METADATA,并包括以下属性:
const NEW_METADATA = {
imgType: 'image/png',
imgName: 'QuickPix New MetaName',
description: 'New description!',
attributes: [\
{trait_type: 'Speed', value: 'Quicker'},\
{trait_type: 'Type', value: 'Pixelated'},\
{trait_type: 'Background', value: 'QuickNode Blue 2'}\
]
};
随意用你自己的值替换名称、描述和属性。
注意:你必须在这里包含所有特征(即使某些未更改),因为这些都将上传以替换现有元数据(例如,注意我们在这里包含了图像类型——即使它不会被改变,我们仍然必须在上传时再次包含它)。
创建一个异步函数 main,用于执行所有步骤,并在下一行调用它:
async function main() {
console.log(`正在更新 NFT 的元数据: ${MINT_ADDRESS}}`);
}
main();
这不会做太多,但你应该能够运行代码以确保此时没有错误:
ts-node app
你应该在控制台中看到一条日志,说明你即将更新我们 NFT 的元数据——那么我们开始吧!如果你遇到错误或有疑问,请在 Discord 上给我们留言,我们将乐意提供帮助。
在我们可以编辑 NFT 之前,我们必须先获取它。Metaplex 的 JS SDK 通过 nfts().findByMint() 使这变得简单。在你的 main() 函数中添加:
//步骤1 - 获取现有 NFT
console.log(`步骤1 - 获取现有 NFT`);
const nft = await METAPLEX.nfts().findByMint({ mintAddress: new PublicKey(MINT_ADDRESS) });
if (!nft || !nft.json?.image) {throw new Error("无法找到现有 NFT 或图像 URI!")}
console.log(` 找到了 NFT!`)
findByMint() 方法应该返回一个 Nft 类型的对象。如果查询没有返回值或关联图像,我们将抛出一个错误并终止脚本。否则,我们将记录 NFT 已找到的信息。
接下来,我们需要将新的元数据上传到 Arweave,以获取可以与 NFT 关联的 URI。我们将使用在我们的 指南:如何使用 Typescript 在 Solana 上铸造 NFT 中创建的相同 uploadMetadata() 函数。创建一个新的函数 uploadMetadata,接受 5 个参数:imgUri,imgType,nftName,description 和 attributes:
async function uploadMetadata(imgUri: string, imgType: string, nftName: string, description: string, attributes: {trait_type: string, value: string}[]) {
console.log(`步骤2 - 上传元数据`);
}
接下来,调用 nfts().uploadMetadata()。我们需要按照以下方式传递我们的参数:
const { uri } = await METAPLEX
.nfts()
.uploadMetadata({
name: nftName,
description: description,
image: imgUri,
attributes: attributes,
properties: {
files: [\
{\
type: imgType,\
uri: imgUri,\
},\
]
}
});
console.log(' 元数据 URI:',uri);
return uri;
现在在 main() 中调用我们的函数。在 uploadImage 之后,使用 NEW_METADATA 填充参数调用 uploadMetadata:
//步骤2 - 上传元数据
const newUri = await uploadMetadata(nft.json.image, NEW_METADATA.imgType, NEW_METADATA.imgName, NEW_METADATA.description, NEW_METADATA.attributes);
如果你想测试你的函数,你可以记录 newUri,然后运行 ts-node app。当你准备好时,让我们更新这个 NFT 的元数据!
与我们之前的函数一样,Metaplex API 简化了这个过程,允许我们通过单个方法 nfts().update() 来更新 NFT。为了运行此方法,我们必须传递在第一步中获取的 nft 对象,以及我们的 newUri。
在 uploadMetadata() 函数之后,在 main() 之前创建一个新的异步函数 updateNft():
async function updateNft(nft:Nft|Sft, metadataUri: string, newName: string) {
console.log(`步骤3 - 更新 NFT`);
}
最后,在我们的函数内部,调用 nfts().update(),传递我们的 metadataUri 和其他函数参数,并记录结果:
await METAPLEX
.nfts()
.update({
name: newName,
nftOrSft: nft,
uri: metadataUri
}, { commitment: 'finalized' });
console.log(` 成功!🎉`);
console.log(` 更新的 NFT: https://explorer.solana.com/address/${nft.address}?cluster=devnet`);
此函数使用 Metaplex Metadata Program 更新代币的链上元数据。请注意,与 create() 方法不同,update() 方法不返回任何值。
如果你需要使用新的 NFT 对象,你需要运行 const updatedNft = await metaplex.nfts().refresh(nft); (为了我们的目的,我们现在不需要这样做,所以不使用它)。
现在你所需要做的就是在 main() 中调用此函数,将 CONFIG 中的参数传递给它:
//步骤3 - 更新 NFT
updateNft(nft, newUri, NEW_METADATA.imgName);
你已经准备好了!如果你想与我们的代码进行对照,整个工作簿可在 GitHub 上找到 这里。
当你准备好时,在终端中输入:
ts-node app
是的!你看到类似这样的内容吗?
续写链接到 Solana Explorer。如果你向下滚动,你应该能够看到链上元数据,以及新的名称和我们上传的元数据的链接:
做得很好。
你现在有一个方便且可重复使用的脚本,可以直接从终端更新 NFT 元数据!我们非常想知道你计划如何使用它以及你正在进行的 NFT 项目。请在 Discord 或 Twitter 上分享你的项目!
如果你对本指南有任何反馈或问题,请 告诉我们。我们很乐意听到你的声音!
- 原文链接: quicknode.com/guides/sol...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!