本文介绍了Solana上使用Metaplex刻录数据的过程,包括创建项目、连接到Solana Devnet、生成密钥对,以及使用相关依赖项进行刻录的数据操作。读者可以通过具体步骤,掌握如何在链上创建和获取Inscription,并提供了有关如何关联多个Inscription和修改权限的进一步探索。
如果你仔细观察过你的 NFT 的 metadata,你可能会注意到,metadata URI 和图像并没有实际存储在 Solana 上。相反,它们通常存储在第三方存储服务(例如 Arweave、Shadow 或 IPFS)中,而 URI 存储在 Solana 上。这主要是由于链状态中存储大量数据的存储限制和成本。然而,随着 Bitcoin Ordinals 和 BRC-20 代币的快速增长,一些 Solana 标准开始出现以在链上存储数据。铭文(Inscriptions)是存储图像字节数据(或其他数据)在链上的 Solana 账户。这允许可验证的可变性、程序内交互、动态数据等。
在本指南中,我们将讨论 Metaplex 铭文标准,如何创建它们,以及如何从中获取数据。
编写一个脚本,使用 Metaplex 在链上铭刻数据,并从 Solana 的 devnet 获取数据。
依赖项 | 版本 |
---|---|
@metaplex-foundation/umi | ^0.8.10 |
@metaplex-foundation/umi-bundle-defaults | ^0.8.10 |
@metaplex-foundation/mpl-inscription | ^0.8.0 |
@solana/web3.js | ^1.87.6 |
让我们开始吧!
mkdir inscriptions-demo && cd inscriptions-demo && echo > app.ts
安装 Solana Web3 依赖项:
yarn init -y
yarn add @metaplex-foundation/umi @metaplex-foundation/umi-bundle-defaults @metaplex-foundation/mpl-inscription @solana/web3.js@1
或
npm init -y
npm install --save @metaplex-foundation/umi @metaplex-foundation/umi-bundle-defaults @metaplex-foundation/mpl-inscription @solana/web3.js@1
创建一个 tsconfig.json,启用 .json 导入:
tsc -init --resolveJsonModule true
要在 Solana 上开发,你需要一个 API 终端来与网络连接。你可以使用公共节点或自行部署和管理基础设施;但是,如果你想要 8 倍更快的响应时间,可以将繁重的工作交给我们。
看看为什么超过 50% 的 Solana 项目选择 QuickNode,并在 这里 注册一个免费账户。我们将使用 Solana Devnet 终端。
复制 HTTP 提供者链接:
你将需要一个拥有 Devnet SOL 的纸钱包来铸造铭文。如果没有,你可以使用以下命令创建一个:
🔑 生成一个新的纸钱包与 Devnet SOL
创建新钱包
你可以将生成的 secret
和 AUTHORITY
粘贴到你的 app.ts
文件中。此仅用于测试目的——你永远不应将你的私钥提交到公共代码库。
你可以在 QuickNode Multi-Chain Faucet 中获取 Devnet SOL。
在你选择的代码编辑器中打开 app.ts,并在第 1 行导入以下内容:
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import { Keypair } from "@solana/web3.js";
import { fetchInscriptionMetadata, findInscriptionMetadataPda, findInscriptionShardPda, initialize, mplInscription, writeData, fetchInscription } from '@metaplex-foundation/mpl-inscription';
import { createSignerFromKeypair, generateSigner, signerIdentity } from '@metaplex-foundation/umi';
import { fromWeb3JsKeypair } from "@metaplex-foundation/umi-web3js-adapters";
const secret = [...] // 将此替换为你的私钥;
const AUTHORITY = Keypair.fromSecretKey(new Uint8Array(secret));
这些导入将使我们能够创建一个 Umi 实例,建立与 Solana 的 Devnet 连接,并铸造一个铭文。
添加你的 QuickNode 端点并定义一个 AUTHORITY
密钥对。在你的导入下,添加以下内容:
const ENDPOINT = 'https://example.solana-devnet.quiknode.pro/123465/'; // 👈 将此替换为你的 QuickNode 端点
让我们开始概述将用于创建铭文的函数。在 app.ts 中添加以下内容:
async function inscribe(endpoint: string, authority: Keypair) {
// 1. 创建 UMI 实例
console.log('1. 创建 UMI 实例');
// 2. 获取必要的账户密钥
console.log('2. 正在获取必要的账户密钥');
// 3. 创建铭文
console.log('3. 正在创建铭文');
// 4. 获取铭文元数据
console.log('4. 正在获取铭文元数据');
// 5. 获取铭文
console.log('5. 正在获取铭文');
}
inscribe(ENDPOINT, AUTHORITY);
我们的函数还没有任何功能,但我们将随着进展逐步填充它。你应该能够通过运行以下命令来验证一切正常:
ts-node app.ts
我们的日志应该打印到控制台:
inscription % ts-node guide.ts
1. 创建 UMI 实例
2. 正在获取必要的账户密钥
3. 正在创建铭文
4. 正在获取铭文元数据
5. 正在获取铭文
让我们填充这个函数。
让我们首先创建一个 UMI 实例,这将使我们能够连接到 Solana 的 devnet,并使用 Metaplex 铭文程序。在 app.ts 中添加以下内容:
// 1. 创建 UMI 实例
console.log('1. 创建 UMI 实例');
const umi = createUmi(endpoint).use(mplInscription());
umi.use(signerIdentity(createSignerFromKeypair(umi, fromWeb3JsKeypair(authority))));
我们正在使用我们的 QuickNode 端点创建一个 UMI 实例,并添加 Metaplex 铭文程序。最后,我们将我们的密钥对添加到 UMI 作为我们的签名者。这将使我们能够签署交易并为我们的铭文提供账户租金。
要创建我们的铭文,我们需要传递少数几个账户到 API:
在你的 inscribe
函数中添加以下内容:
// 2. 获取必要的账户密钥
console.log('2. 正在获取必要的账户密钥');
const inscriptionAccount = generateSigner(umi);
const inscriptionShardAccount = findInscriptionShardPda(umi, { shardNumber: Math.floor(Math.random() * 32) });
const inscriptionMetadataAccount = await findInscriptionMetadataPda(umi, {
inscriptionAccount: inscriptionAccount.publicKey,
});
我们正在为我们的铭文账户生成一个随机密钥对,并使用铭文账户来获取铭文元数据 PDA。我们还使用 findInscriptionMetadataPda
来查找由我们的随机分片号播种的铭文分片账户的 PDA。
我们将创建并发送一个交易到网络以创建我们的铭文。该交易将包括两个指令:
在你的 inscribe
函数中添加以下内容:
// 3. 创建铭文
console.log('3. 正在创建铭文');
const tx = await initialize(umi, {
inscriptionAccount,
inscriptionMetadataAccount,
inscriptionShardAccount,
}).add(
writeData(umi, {
inscriptionAccount: inscriptionAccount.publicKey,
inscriptionMetadataAccount,
value: Buffer.from(
'QuickNode Inscriptions Guide' // 👈 将此替换为你的铭文数据
),
associatedTag: null,
offset: 0,
})
).sendAndConfirm(umi, {confirm: {commitment: 'finalized'}});
initialize
指令获取我们的 Umi 实例和我们在步骤 2 中定义的所有三个账户。 writeData
指令不需要分片账户,因为它将在 initialize
步骤中更新(用于跟踪铭文排名)。writeData
指令确实需要 WriteDataInstructionArgs,这包括:
value
:铭文数据(作为 Uint8Array)。在本例中,我们写入字符串 "QuickNode Inscriptions Guide",但它可以是图像、JSON 或任何其他数据。associatedTag
:用于将多个铭文与单一铭文元数据相关联的可选相关标签(例如,图像和 JSON)(请参见关于 initializeAssociatedInscription
指令的下一部分)。offset
:写入数据的偏移量。因为我们一次写入所有数据,所以我们可以将偏移量设置为 0,但如果你希望将数据附加到现有铭文,可以将偏移量设置为现有数据的长度。然后我们发送并确认该交易。我们等待交易被 finalized
,以便立即获取铭文元数据和铭文数据。
现在我们铭刻的消息应该存储在链上,让我们验证一下我们的铭文元数据和数据是否正确。首先,让我们看看元数据。在你的 inscribe
函数中添加以下内容:
// 4. 获取铭文元数据
console.log('4. 正在获取铭文元数据');
const inscriptionMetadata = await fetchInscriptionMetadata(umi, inscriptionMetadataAccount);
console.log(" Inscription", inscriptionAccount.publicKey.toString());
console.log(" Inscription Metadata", inscriptionMetadataAccount[0].toString());
console.log(" Inscription number: ", inscriptionMetadata.inscriptionRank.toString());
我们只需使用 fetchInscriptionMetadata
函数获取并解码我们的铭文元数据。然后,我们解析返回的数据以显示我们的铭文账户地址、铭文元数据账户地址和铭文排名。
现在,令人兴奋的部分。让我们获取我们的铭文数据。在你的 inscribe
函数中添加以下内容:
// 5. 获取铭文
console.log('5. 正在获取铭文');
const inscription = await fetchInscription(umi, inscriptionAccount.publicKey);
const text = Buffer.from(inscription).toString('utf8');
console.log(" Inscription Data:",text);
同样,我们使用来自 Metaplex 铭文 API 的函数 fetchInscription
来获取和解码我们的铭文数据。然后我们将数据转换为字符串,并将其记录到控制台。
仔细检查你的工作,确保在你的代码编辑器中没有错误。纠正任何错误,然后你就可以创建你的第一个铭文!
在你的终端中运行你的脚本:
ts-node app.ts
你应该看到以下输出:
inscription % ts-node guide.ts
1. 正在建立与集群的连接
2. 如果需要,正在向 devnet 进行 SOL 空投
3. 正在获取必要的账户密钥
4. 正在创建铭文
5. 正在获取铭文元数据
Inscription DgHhQJ93pQ6srkY6gB2mnixZFBQ8d5EzQ22yS562kNu9
Inscription Metadata 6nJngcmYNpPxohcgswRcY4xu8XNDWWEcrcr2BmcHGevv,255
Inscription number: 5161
6. 正在获取铭文
Inscription Data: QuickNode Inscriptions Guide
干得不错!你已经使用 Metaplex 铭文标准在 Solana Devnet 上铭刻了一些数据。
铭文程序有几个额外的指令值得探索。
如果你想要用数据铭刻现有的 NFT,可以使用 initializeFromMint
指令。该指令将创建一个铭文账户、创建铭文元数据账户、写入我们的铭文元数据,并更新分片计数器。这只能由 token_metadata.update_authority
执行。与 initialize
指令的几个显著区别:
initialize
不同,initializeFromMint
指令要求 inscriptionAccount
是一个通过铸造账户播种的 PDA 参见。mintAccount
和 tokenMetadataAccount
。 // 3. 创建铭文
console.log('3. 正在创建铭文');
const tx = await initializeFromMint(umi, {
mintInscriptionAccount: inscriptionAccount,
metadataAccount: inscriptionMetadataAccount,
mintAccount: mint.publicKey,
tokenMetadataAccount, // 来自 token metadata 的元数据账户
inscriptionShardAccount, // 用于并发处理
}).add(
writeData(umi, {
inscriptionAccount,
metadataAccount: inscriptionMetadataAccount,
value: Buffer.from(
JSON.stringify(metadata) // 要铭刻的你的 NFT 的元数据
),
associatedTag: null,
offset: 0,
})
).sendAndConfirm(umi, {confirm: {commitment: 'finalized'}});
铭文程序允许你将数据写入多个铭文账户,并将它们与单一的铭文元数据账户相关联。如果你想要为单一 NFT 存储多个数据(例如,图像和 json),这会很有用。
// ...(首先使用 .initialize() 初始化铭文和铭文元数据账户,如我们之前所做的)
const associatedInscriptionAccount = findAssociatedInscriptionPda(umi, {
associated_tag: 'image',
inscriptionMetadataAccount,
});
// 创建一个关联铭文账户。
await initializeAssociatedInscription(umi, {
inscriptionAccount: inscriptionAccount.publicKey,
associationTag: 'image',
}).sendAndConfirm(umi);
// 将图像数据写入关联铭文账户
await writeData(umi, {
inscriptionAccount: associatedInscriptionAccount,
inscriptionMetadataAccount,
value: imageBuffer,
associatedTag: 'image',
offset: i,
}).sendAndConfirm(umi)
如果你希望,可以从铭文账户中移除所有数据。这只能由铭文元数据中定义的某个授权进行。注意:如果铭文已经被雕刻(未来的功能),则无法使用此功能。清除数据将删除所有现有数据并将其大小调整为 0。
await clearData(umi, {
inscriptionAccount: inscriptionAccount.publicKey,
inscriptionMetadataAccount,
associatedTag: null, // 在此使用创建时使用的相同标签
})
API 包括两个函数,用于更新铭文元数据账户的授权:addAuthority
和 removeAuthority
。两者都必须由现有授权签署,并要求 inscriptionMetadataAccount
。addAuthority
函数要求你传递 newAuthority
以添加。removeAuthority
函数允许删除一个可选的 authority
——如果没有传递,则签署授权将从铭文元数据账户中移除。
示例:
await addAuthority(umi, {
inscriptionMetadataAccount,
newAuthority: authority.publicKey,
}).sendAndConfirm(umi)
await removeAuthority(umi, {
inscriptionMetadataAccount,
}).sendAndConfirm(umi)
你可以关闭一个铭文账户(类似于销毁一个代币)。这将关闭账户并将租金返回给授权者。
await close(umi, {
inscriptionAccount: inscriptionAccount.publicKey,
inscriptionMetadataAccount,
})
你现在已准备好开始在 Solana 上铭刻数据!你可以使用 Metaplex 铭文 API 创建铭文、从铭文中获取数据等等。你正在构建什么?加入我们 Discord 并告诉我们!遇到问题?在我们的 Discord 上提问。关注我们的 Twitter 获取新闻和更新。
让我们知道 如果你有任何反馈或新的主题请求。我们很想听到你的声音。
- 原文链接: quicknode.com/guides/sol...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!