本篇文章介绍了Metaplex Core,这是Solana上一个新轻量级NFT标准,旨在降低铸造成本并提高组合性。通过Umi JavaScript库,读者能够学习如何创建和管理自己的NFT,包括创建集合资产、铸造资产、查询资产以及转移资产的完整步骤,适合希望在Solana上开展NFT项目的开发者。
Metaplex 最近在 Solana 上宣布了一种新的轻量级 NFT 标准,称为 Metaplex Core。本指南将教你关于 Metaplex Core 的知识,以及它的重要性,以及如何使用 Metaplex Core 和 Umi JavaScript 库铸造你的第一个 NFT。
让我们开始吧!
编写一个脚本,以使用 Umi JavaScript 库铸造一个 Metaplex Core NFT。
依赖项 | 版本 |
---|---|
@metaplex-foundation/umi | ^0.9.1 |
@metaplex-foundation/umi-bundle-defaults | ^0.9.1 |
@metaplex-foundation/mpl-core | ^0.2.0 |
@solana/web3.js | ^1.91.1 |
solana cli | 1.18.1 |
让我们开始吧!
Metaplex Core 是一种轻量级的 Solana NFT 标准,它利用单账户设计。该设计允许更高效的执行、更低的铸造成本和更高的可组合性。原始的 Metaplex 标准构建在 Solana 的 SPL 代币标准之上,这需要多个账户才能铸造 NFT(例如,代币账户、元数据账户和主版本账户)。它们的相关程序必须被调用以铸造 NFT。这不仅可能难以管理,而且成本也可能很高(每次铸造超过 0.02
SOL,相比之下,原为 .0037
)并且消耗大量计算资源。更高的计算要求意味着交易失败的可能性可能更大(因为超过计算限制),而且在使用跨程序调用(CPI)与你自己程序中的 NFT 交互时会受到限制。
Core 使用单账户结构和可选附加功能。让我们看一下。Core 账户结构定义如下:
字段 | 大小(字节) | 描述 |
---|---|---|
key | 1 | 账户区分符。 |
owner | 32 | 资产的拥有者。 |
update_authority | 33 | 资产的更新权限。 |
name | 4 + length | 资产的名称。 |
uri | 4 + length | 指向链外数据的资产 URI。 |
seq | 1 + (可选,8) | 用于通过压缩进行索引的序列号。 |
除了 Core 账户结构,Core 还支持可选附加功能。插件可以附加到 Core 资产或集合资产,允许插件修改单个资产或整个集合的行为。插件分为三种类型:
以下是 Core 中可用插件的总结:
插件 | 类型 | 可用对象 | 描述 |
---|---|---|---|
Transfer Delegate | 拥有者管理 | Core Asset | 允许拥有者委托可以转移资产的程序。 |
Freeze Delegate | 拥有者管理 | Core Asset | 允许拥有者委托可以冻结资产的程序。 |
Burn Delegate | 拥有者管理 | Core Asset | 允许拥有者委托可以销毁资产的程序。 |
Royalties | 权限管理 | Core 或 Collection | 为资产设置版税和规则。 |
Update Delegate | 权限管理 | Core 或 Collection | 允许权限委托可以更新资产的程序。 |
Attribute | 权限管理 | Core 或 Collection | 存储键值对数据(例如,特征)。 |
Permanent Transfer Delegate | 永久性 | Core 或 Collection | 允许拥有者委托可以转移资产的程序。 |
Permanent Freeze Delegate | 永久性 | Core 或 Collection | 允许拥有者委托可以冻结资产的程序。 |
Permanent Burn Delegate | 永久性 | Core 或 Collection | 允许拥有者委托可以销毁资产的程序。 |
让我们尝试铸造一个 Core NFT!
mkdir core-demo && cd core-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 @metaplex-foundation/umi @metaplex-foundation/umi-bundle-defaults @metaplex-foundation/mpl-core @solana/web3.js@1
欢迎使用 Solana Devnet,但为了本指南的快速交易时间,我们将使用 Localnet。要在 Localnet 上使用 Core,我们必须首先在本地网络上部署 Core 程序。为此,我们需要使用 solana program dump
命令。这将有效地从 Solana 的 Devnet 获取 Core 程序并将其存储,以便我们可以在本地网络上部署。
在你的终端中运行以下命令:
solana program dump -u d CoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d core.so
这将下载存储在 Devnet 上的 Core 程序可执行文件( 程序 ID:CoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d)并保存在你当前的目录中。请注意该文件保存的位置,因为我们稍后将需要它。
在你的项目目录中,打开 app.ts
并导入必要的依赖项:
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
import {
createV1,
mplCore,
fetchAssetV1,
transferV1,
createCollectionV1,
getAssetV1GpaBuilder,
Key,
updateAuthority,
pluginAuthorityPair,
ruleSet
} from '@metaplex-foundation/mpl-core'
import { TransactionBuilderSendAndConfirmOptions, generateSigner, signerIdentity, sol } from '@metaplex-foundation/umi';
我们正在从 Metaplex 库中导入一些方法。我们将在使用它们的过程中详细介绍。
接下来,我们将初始化 Umi 并设置我们的签名者和付款者。将以下代码添加到你的 app.ts
文件中:
const umi = createUmi('http://127.0.0.1:8899', 'processed').use(mplCore())
const asset = generateSigner(umi);
const payer = generateSigner(umi);
umi.use(signerIdentity(payer));
const txConfig: TransactionBuilderSendAndConfirmOptions = {
send: { skipPreflight: true },
confirm: { commitment: 'processed' },
};
在此代码片段中,我们正在使用本地网络端点初始化 Umi,并设置 processed
触及级别(以允许快速处理时间,作为我们的演示)。我们还为资产和付款者生成了一个签名者。付款者将用于支付交易费用(这是通过使用 umi.use
设置的)。
我们还定义了一个 txConfig
对象,将在我们的交易中传入以设置 skipPreflight
和 commitment
选项。
接下来,我们将创建一个 main
函数,该函数将容纳我们脚本的逻辑。将以下代码添加到 app.ts
文件的 main
函数中:
async function main() {
// 1. 空投给付款者
console.log('1. Airdropping to: ', payer.publicKey.toString());
const airdropAmount = sol(100);
await umi.rpc.airdrop(umi.identity.publicKey, airdropAmount, txConfig.confirm);
// 2. 创建一个集合资产
// 3. 在集合中创建一个资产
// 4. 按所有者获取资产
// 5. 按集合获取资产
// 6. 转移资产
}
main().catch(console.error);
在这里,我们创建了一个包含六个步骤的函数(我们将在下一步中填充这些步骤)。我们预填充的第一步是向付款者账户空投一些 SOL。这是支付交易费用所必需的。
接下来,我们将创建一个集合资产。将以下代码添加到 main
函数的第 2
节中:
// 2. 创建一个集合资产
const collectionAddress = generateSigner(umi);
console.log('2. Creating Collection:', collectionAddress.publicKey.toString());
const collectionUpdateAuthority = generateSigner(umi);
const creator1 = generateSigner(umi);
const creator2 = generateSigner(umi);
await createCollectionV1(umi, {
name: 'Quick Collection', // 👈 替换此项
uri: 'https://your.domain.com/collection.json', // 👈 替换此项
collection: collectionAddress,
updateAuthority: collectionUpdateAuthority.publicKey,
plugins: [\
pluginAuthorityPair({\
type: 'Royalties',\
data: {\
basisPoints: 500,\
creators: [\
{\
address: creator1.publicKey,\
percentage: 20,\
},\
{\
address: creator2.publicKey,\
percentage: 80,\
},\
],\
ruleSet: ruleSet('None'), // 兼容规则集\
},\
}),\
],
}).sendAndConfirm(umi, txConfig);
在这里,我们创建了两个新的签名者( collectionUpdateAuthority
和 collectionAddress
),尽管权限是可选的(默认是付款者)。然后,我们使用来自 mpl-core
库的 createCollectionV1
方法创建一个新的集合资产。我们传入集合的名称、URI、集合地址和更新权限。
确保用你想要的值更新 name
和 uri
。你可以使用 QuickNode 的 IPFS 服务 上传并托管你的 NFT 图像和元数据。
我们使用 Royalties
插件为集合设置版税。在这个例子中,我们使用两个随机创作者,并将基本点数设置为 500
(5%)。Core 资产的一个奇妙特性是,其版税可以在集合级别设置并将适用于集合中的所有资产。这是一种简单管理版税的方式(这意味着我们的 NFT 的冗余更少)。我鼓励你探索 pluginAuthorityPair
方法,以查看可以添加到集合的其他插件/参数对。
然后,我们使用我们的 umi
实例和 txConfig
对象发送并确认交易。
现在我们已经有了一个集合,让我们为其铸造一个资产。
// 3. 在集合中创建一个资产
await createV1(umi, {
name: 'Quick Asset #1', // 👈 替换此项
uri: 'https://your.domain.com/asset-id.json', // 👈 替换此项
asset: asset,
collection: collectionAddress.publicKey,
authority: collectionUpdateAuthority,
}).sendAndConfirm(umi, txConfig);
这一次,我们使用 createV1
方法创建一个新资产。我们传入资产名称、URI(请确保更新为你自己的)、资产地址、集合地址及集合的更新授权。有几件事情需要注意:
当前,Core 并不支持数字资产标准,因此我们需要使用 getProgramAccounts
来获取资产。Metaplex 包含一个用于构建 GPA 查询的辅助函数 getAssetV1GpaBuilder
。将以下代码添加到 main
函数的第 4
和第 5
节中:
// 4. 按所有者获取资产
const assetsByOwner = await getAssetV1GpaBuilder(umi)
.whereField('key', Key.AssetV1)
.whereField('owner', payer.publicKey)
.getDeserialized();
console.log(assetsByOwner);
// 5. 按集合获取资产
const assetsByCollection = await getAssetV1GpaBuilder(umi)
.whereField('key', Key.AssetV1)
.whereField(
'updateAuthority',
updateAuthority('Collection', [collectionAddress.publicKey])
)
.getDeserialized();
console.log(assetsByCollection);
这两个查询非常相似——它们将我们的 umi
实例传递给 getAssetV1GpaBuilder
方法,并将 key
字段设置为 Key.AssetV1
(从 mpl-core
导入)。第一个查询根据所有者获取资产,第二个查询根据集合获取资产。第二个查询还将 updateAuthority
字段设置为 updateAuthority('Collection', [collectionAddress.publicKey])
以通过集合地址进行筛选。
每个查询都应该在控制台上记录一个资产数组。
最后,让我们将资产转移到另一个账户中。将以下代码添加到 main
函数的第 6
节中:
// 6. 转移资产
const recipient = generateSigner(umi);
await transferV1(umi, {
asset: asset.publicKey,
newOwner: recipient.publicKey,
collection: collectionAddress.publicKey,
}).sendAndConfirm(umi, txConfig);
如果你曾经使用过 SPL 代币进行过任何转移,这应该看起来令人兴奋地简单!这是单个账户模型的一个显著优势——无需担心代币账户或代币账户初始化。只需传递新的目的地,并确保你有有效的转移资产的权限 🙌。请注意,对于在集合中的资产,我们需要传递集合地址。
你可以通过添加以下内容验证资产是否已被转移:
const transferredAsset = await fetchAssetV1(umi, asset.publicKey);
if (transferredAsset.owner.toString() !== recipient.publicKey.toString()) {
throw new Error('Transfer failed');
}
干得好!让我们测试我们的脚本。
要在 localnet 上运行我们的代码,我们需要打开两个终端窗口。在第一个终端中,使用你已经部署的 Core 程序启动 localnet。运行:
solana-test-validator -r --bpf-program CoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d core.so
确保用之前使用 solana program dump
下载的文件的正确路径替换 core.so
。
在 localnet 启动后,在第二个终端运行你的脚本:
ts-node app.ts
你应该在终端中看到每一步的输出!干得好!
如果遇到任何错误,请仔细检查你的代码,并确保已安装正确的依赖项。如果你仍然遇到问题,请随时通过 Discord 与我们联系。
想要继续在 Core 上练习吗?以下是一些启发体验的想法:
addPluginV1
和 createPlugin
方法为你的 NFT 添加 FreezeDelegate
,以启用无需托管的质押。revokePluginAuthorityV1
从你的 NFT 中移除 FreezeDelegate
。burnV1
方法销毁 NFT。updateV1
方法更新 NFT,或使用 updateCollectionV1
方法更新集合。如果你准备好脱离本地主机,QuickNode 提供了快速部署项目的工具。今天就 开始 免费开发者计划吧!
Metaplex Core 为构建低成本、更具可组合性的 Solana NFT 项目创造了令人兴奋的新机会。你现在可以使用单个账户铸造、转移和管理 NFT。我们期待看到你正在构建的内容。请在 Discord 上给我们留言,告诉我们你正在进行的工作!
告诉我们 如果你有任何反馈或请求新主题。我们很乐意听取你的意见。
- 原文链接: quicknode.com/guides/sol...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!