10分钟Solana-性能web3-5.3 项目搭建

欢迎订阅专栏10分钟Solana-性能web3

搭建一个 Solana NFT 项目,核心是围绕 Anchor 框架Metaplex Core 标准 展开。下面会带你走过从环境准备到合约部署的完整流程。


🔧 第一步:环境准备

在开始之前,请确保你的开发环境已安装以下工具:

工具 说明 版本要求
Rust Solana 合约的编程语言 latest stable
Solana CLI 与 Solana 网络交互的命令行工具 latest
Anchor CLI 核心开发框架 v0.30.1 或更高
Node.js 运行测试脚本 v16 或更高

安装命令参考

bash 复制代码
# 安装 Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# 安装 Solana CLI
sh -c "$(curl -sSfL https://release.solana.com/stable/install)"

# 安装 Anchor CLI (使用 avm)
cargo install --git https://github.com/solana-foundation/anchor avm --locked
avm install latest
avm use latest

安装完成后,将 Solana CLI 指向开发网(Devnet)并创建测试钱包:

bash 复制代码
solana config set --url https://api.devnet.solana.com
solana-keygen new
solana airdrop 2   # 领取测试 SOL

🚀 第二步:创建 Anchor 项目

使用 anchor init 命令创建一个新项目:

bash 复制代码
anchor init my-nft-project
cd my-nft-project

添加依赖 :在 programs/my-nft-project/Cargo.toml 中添加 mpl-core crate:

toml 复制代码
[dependencies]
anchor-lang = "0.30.1"
mpl-core = { version = "0.8.0", features = ["anchor"] }  # 启用 anchor 功能

📝 第三步:编写 NFT 合约

打开 programs/my-nft-project/src/lib.rs,编写一个创建 NFT Collection 和铸造 NFT 的合约:

rust 复制代码
use anchor_lang::prelude::*;
use mpl_core::{
    ID as MPL_CORE_ID,
    accounts::BaseCollectionV1,
    instructions::CreateV2CpiBuilder,
};

declare_id!("你的程序ID");

#[program]
pub mod my_nft_project {
    use super::*;

    /// 创建 NFT Collection
    pub fn create_collection(
        ctx: Context<CreateCollection>,
        name: String,
        uri: String,
    ) -> Result<()> {
        // 使用 CPI 调用 Metaplex Core 程序创建 Collection
        let cpi_program = ctx.accounts.mpl_core_program.to_account_info();
        
        CreateV2CpiBuilder::new(cpi_program)
            .collection(&ctx.accounts.collection.to_account_info())
            .payer(&ctx.accounts.payer.to_account_info())
            .authority(Some(&ctx.accounts.authority.to_account_info()))
            .system_program(&ctx.accounts.system_program.to_account_info())
            .name(name)
            .uri(uri)
            .invoke()?;
            
        Ok(())
    }

    /// 铸造 NFT 到 Collection
    pub fn mint_nft(
        ctx: Context<MintNft>,
        name: String,
        uri: String,
    ) -> Result<()> {
        let cpi_program = ctx.accounts.mpl_core_program.to_account_info();
        
        CreateV2CpiBuilder::new(cpi_program)
            .asset(&ctx.accounts.asset.to_account_info())
            .collection(Some(&ctx.accounts.collection.to_account_info()))
            .payer(&ctx.accounts.payer.to_account_info())
            .authority(Some(&ctx.accounts.authority.to_account_info()))
            .system_program(&ctx.accounts.system_program.to_account_info())
            .name(name)
            .uri(uri)
            .invoke()?;
            
        Ok(())
    }
}

/// CreateCollection 指令的账户结构
#[derive(Accounts)]
pub struct CreateCollection<'info> {
    /// 新的 Collection 账户 (需是新生成的密钥对)
    #[account(mut)]
    pub collection: Signer<'info>,
    /// 支付交易费用
    #[account(mut)]
    pub payer: Signer<'info>,
    /// 拥有管理权限的账户
    pub authority: Signer<'info>,
    /// 系统程序
    pub system_program: Program<'info, System>,
    /// Metaplex Core 程序
    #[account(address = MPL_CORE_ID)]
    pub mpl_core_program: Program<'info, System>,
}

/// MintNft 指令的账户结构
#[derive(Accounts)]
pub struct MintNft<'info> {
    /// 新的 Asset 账户
    #[account(mut)]
    pub asset: Signer<'info>,
    /// 目标 Collection 账户 (需已存在)
    pub collection: Account<'info, BaseCollectionV1>,
    /// 支付交易费用
    #[account(mut)]
    pub payer: Signer<'info>,
    /// 拥有管理权限的账户
    pub authority: Signer<'info>,
    /// 系统程序
    pub system_program: Program<'info, System>,
    /// Metaplex Core 程序
    #[account(address = MPL_CORE_ID)]
    pub mpl_core_program: Program<'info, System>,
}

代码要点

  • 使用 CPI(跨程序调用) 调用 Metaplex Core 程序来创建 Collection 和 Asset
  • BaseCollectionV1 是 Core 标准中 Collection 的账户类型
  • CreateV2CpiBuilder 是 Core 提供的 CPI 构建器
  • Collection 账户必须是新生成的密钥对,不能重用已有地址

🏗️ 第四步:构建与部署

构建合约

bash 复制代码
anchor build

部署到 Devnet

bash 复制代码
anchor deploy

部署成功后,控制台会打印出程序的 Program ID 。将其更新到 lib.rsdeclare_id! 宏中。


🧪 第五步:编写测试

tests/my-nft-project.ts 中编写测试脚本,使用 TypeScript 与合约交互:

typescript 复制代码
import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import { MyNftProject } from "../target/types/my_nft_project";

describe("my-nft-project", () => {
  const provider = anchor.AnchorProvider.env();
  anchor.setProvider(provider);

  const program = anchor.workspace.MyNftProject as Program<MyNftProject>;

  it("创建 Collection 并铸造 NFT", async () => {
    // 生成 Collection 的密钥对
    const collectionKeypair = anchor.web3.Keypair.generate();
    
    // 调用 createCollection 指令
    await program.methods
      .createCollection("My Collection", "https://example.com/collection.json")
      .accounts({
        collection: collectionKeypair.publicKey,
        payer: provider.wallet.publicKey,
        authority: provider.wallet.publicKey,
        systemProgram: anchor.web3.SystemProgram.programId,
        mplCoreProgram: new anchor.web3.PublicKey("CoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d"),
      })
      .signers([collectionKeypair, provider.wallet.payer])
      .rpc();

    // 生成 Asset 的密钥对
    const assetKeypair = anchor.web3.Keypair.generate();
    
    // 调用 mintNft 指令
    await program.methods
      .mintNft("My NFT", "https://example.com/nft.json")
      .accounts({
        asset: assetKeypair.publicKey,
        collection: collectionKeypair.publicKey,
        payer: provider.wallet.publicKey,
        authority: provider.wallet.publicKey,
        systemProgram: anchor.web3.SystemProgram.programId,
        mplCoreProgram: new anchor.web3.PublicKey("CoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d"),
      })
      .signers([assetKeypair, provider.wallet.payer])
      .rpc();
  });
});

运行测试:

bash 复制代码
anchor test

这会自动启动本地验证器、部署程序并执行测试。


🧠 理解 Metaplex Core 的核心概念

上面的代码中多次提到了几个 Core 的核心概念,理解它们有助于你更好地开发和定制:

概念 说明
Asset Core 标准中的 NFT,采用单账户设计,将所有权和元数据存储在 Asset 自身,而非依赖多个账户
Collection NFT 的集合,用于组织和管理一组 Asset,共享元数据和插件
Plugin(插件) Core 的扩展机制,可以为 Asset 或 Collection 附加版税(Royalties)冻结(Freeze)属性(Attributes) 等功能
CPI(跨程序调用) 从你的程序调用 Metaplex Core 程序的方式来创建和管理 Asset

📚 资源与进阶

资源 说明
Metaplex Core 官方文档 最权威的参考,涵盖所有指南和 API
在 Anchor 中使用 Metaplex Core 官方中文指南,涵盖安装、账户反序列化、CPI 模式
创建 Core Asset 使用 JavaScript SDK 创建 NFT 的指南
创建 Core Collection 创建 Collection 的详细说明

建议阅读顺序

  1. 先通读 在 Anchor 中使用 Metaplex Core 了解基础
  2. 参考示例项目 smart-contract-using-the-latest-Metaplex-mpl-core-Anchor-dependencies
  3. 根据业务需求为 NFT 添加插件(如版税、属性等)

如果需要深入了解某个具体环节(如插件系统、Candy Machine 集成等),可以随时告诉我。

相关推荐
程序员爱钓鱼2 小时前
Rust 项目目录结构详解:从 Hello World 到企业级项目
后端·rust
2601_9615934212 小时前
Rust 开发环境配置繁琐?RustRover 开箱即用搞定编码调试
开发语言·后端·macos·rust
冬奇Lab14 小时前
每日一个开源项目(第154篇):Warp - 从‘好看的终端‘到 Agentic 开发环境
人工智能·rust·llm
想你依然心痛21 小时前
内存安全语言在嵌入式中的对比:Rust vs Ada vs SPARK——形式化验证、运行时
安全·rust·spark
TechubNews1 天前
马云金融公司斥资4400万美元购买以太坊,布局Web3扩展
web3·区块链
喜欢打篮球的普通人1 天前
Trition程序编写:从“Hello CUDA“到“Hello Triton“:向量加法背后的编译黑魔法
开发语言·后端·rust
独孤留白1 天前
从C到Rust:Trait Copy 数据位拷贝属性
rust
咸甜适中1 天前
rust语言学习笔记——Tokio库(异步编程)
笔记·学习·rust·tokio