需要帮助建立一个从Master Edition NFT创建新版本NFT的函数

发布于 2025-02-09 10:16:02 字数 4508 浏览 2 评论 0原文

[映像链接到我的代码]

https://i.sstatic.net/uwtpj.png

我目前正在Rust/Anchor-Solana中编写一个Solana Metaplex NFT程序,专门致力于编写逻辑,以从Master Edition NFT创建NFT。

调用MPL_TOKEN_METADATA :: MINT_NEW_EDITION_FOM_MASTER_EDITION_EDITION_VIA_TOKEN指令时,我发现它同时需要Metadatacode> metadata_mint字段 field as a in as gruments。鉴于,在Metaplex文档上,似乎只需要主记录元数据帐户。

问题:

我应该将哪个帐户密钥或值放入这些字段(metadatametadata_mint),为什么?

代码:

pub fn create_new_edition_nft(
        ctx: Context<CreateNewEdition>,
        edition: u64,
    ) -> Result<()> {
        let edition_infos = vec![
            ctx.accounts.token_program.to_account_info(),
            ctx.accounts.new_metadata.to_account_info(),
            ctx.accounts.new_edition.to_account_info(),
            ctx.accounts.master_edition.to_account_info(),
            ctx.accounts.new_mint.to_account_info(),
            ctx.accounts.new_mint_authority.to_account_info(),
            ctx.accounts.payer.to_account_info(),
            ctx.accounts.token_account_owner.to_account_info(),
            ctx.accounts.token_account.to_account_info(),
            ctx.accounts.new_metadata_update_authority.to_account_info(),
            ctx.accounts.metadata.to_account_info(),
            ctx.accounts.system_program.to_account_info(),
            ctx.accounts.rent.to_account_info(),
        ];
        msg!("Edition Account Infos Assigned");
        invoke(&mint_new_edition_from_master_edition_via_token(
            ctx.accounts.token_program.key(),ctx.accounts.new_metadata.key(),ctx.accounts.new_edition.key(), ctx.accounts.master_edition.key(), ctx.accounts.new_mint.key(),ctx.accounts.new_mint_authority.key(), ctx.accounts.payer.key(), ctx.accounts.token_account_owner.key(), ctx.accounts.token_account.key(), ctx.accounts.new_metadata_update_authority.key(), ctx.accounts.metadata.key(), ctx.accounts.metadata.key(), edition
        ), edition_infos.as_slice())?;

        msg!("A New Edition Nft Minted !!!");
        Ok(())
    }

#[derive(Accounts)]
pub struct CreateNewEdition<'info> {
    /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub new_metadata: UncheckedAccount<'info>,
    /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub new_edition: UncheckedAccount<'info>,
    /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub master_edition: UncheckedAccount<'info>,
    /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub new_mint: UncheckedAccount<'info>,    
    /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub edition_mark_pda: UncheckedAccount<'info>,    
    #[account(mut)]
    pub new_mint_authority: Signer<'info>,
    #[account(mut)]
    pub payer: AccountInfo<'info>,
    // /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub token_account_owner: UncheckedAccount<'info>,
    // /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub token_account: UncheckedAccount<'info>,
    /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub new_metadata_update_authority: UncheckedAccount<'info>,
    /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub metadata: UncheckedAccount<'info>,    
    // #[account(mut)]
    pub token_program: Program<'info, Token>,
    pub system_program: Program<'info, System>,
    /// CHECK: This is not dangerous because we don't read or write from this account
    pub rent: AccountInfo<'info>,
}

文档参考:

在主版本中打印新版本的文档:

https://docs.metaplex.com/programs/token-metadata/token-metadata/instructions#print-a-a-new--new---new--new--版本的版本版本

[image link to my code]

https://i.sstatic.net/UWtpj.png

I am currently writing a Solana Metaplex NFT program in Rust/Anchor-Solana, specifically working on writing a logic to create a edition NFT from a master edition NFT.

While invoking mpl_token_metadata::instruction::mint_new_edition_from_master_edition_via_token instruction, I found out that it requires both metadata and metadata_mint field as arguments. Whereas, on the metaplex documentation, it seems the instruction only requires the Master record metadata account.

Question:

Which account key, or value, should I put in to each of those fields(metadata and metadata_mint) and why?

Code:

pub fn create_new_edition_nft(
        ctx: Context<CreateNewEdition>,
        edition: u64,
    ) -> Result<()> {
        let edition_infos = vec![
            ctx.accounts.token_program.to_account_info(),
            ctx.accounts.new_metadata.to_account_info(),
            ctx.accounts.new_edition.to_account_info(),
            ctx.accounts.master_edition.to_account_info(),
            ctx.accounts.new_mint.to_account_info(),
            ctx.accounts.new_mint_authority.to_account_info(),
            ctx.accounts.payer.to_account_info(),
            ctx.accounts.token_account_owner.to_account_info(),
            ctx.accounts.token_account.to_account_info(),
            ctx.accounts.new_metadata_update_authority.to_account_info(),
            ctx.accounts.metadata.to_account_info(),
            ctx.accounts.system_program.to_account_info(),
            ctx.accounts.rent.to_account_info(),
        ];
        msg!("Edition Account Infos Assigned");
        invoke(&mint_new_edition_from_master_edition_via_token(
            ctx.accounts.token_program.key(),ctx.accounts.new_metadata.key(),ctx.accounts.new_edition.key(), ctx.accounts.master_edition.key(), ctx.accounts.new_mint.key(),ctx.accounts.new_mint_authority.key(), ctx.accounts.payer.key(), ctx.accounts.token_account_owner.key(), ctx.accounts.token_account.key(), ctx.accounts.new_metadata_update_authority.key(), ctx.accounts.metadata.key(), ctx.accounts.metadata.key(), edition
        ), edition_infos.as_slice())?;

        msg!("A New Edition Nft Minted !!!");
        Ok(())
    }

#[derive(Accounts)]
pub struct CreateNewEdition<'info> {
    /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub new_metadata: UncheckedAccount<'info>,
    /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub new_edition: UncheckedAccount<'info>,
    /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub master_edition: UncheckedAccount<'info>,
    /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub new_mint: UncheckedAccount<'info>,    
    /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub edition_mark_pda: UncheckedAccount<'info>,    
    #[account(mut)]
    pub new_mint_authority: Signer<'info>,
    #[account(mut)]
    pub payer: AccountInfo<'info>,
    // /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub token_account_owner: UncheckedAccount<'info>,
    // /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub token_account: UncheckedAccount<'info>,
    /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub new_metadata_update_authority: UncheckedAccount<'info>,
    /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub metadata: UncheckedAccount<'info>,    
    // #[account(mut)]
    pub token_program: Program<'info, Token>,
    pub system_program: Program<'info, System>,
    /// CHECK: This is not dangerous because we don't read or write from this account
    pub rent: AccountInfo<'info>,
}

Documentation Reference:

Documentation for printing a new edition from a master edition:

https://docs.metaplex.com/programs/token-metadata/instructions#print-a-new-edition-from-a-master-edition

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

木落 2025-02-16 10:16:02

您正在谈论的Metaplex上的文档是Solana说明的文档,而不是Rust API。他们不同。如果您查看锈蚀代码,您将看到差异。

文档中描述的帐户与代码提供的帐户匹配:

let accounts = vec![
   AccountMeta::new(new_metadata, false),
   AccountMeta::new(new_edition, false),
   AccountMeta::new(master_edition, false),
   AccountMeta::new(new_mint, false),
   AccountMeta::new(edition_mark_pda, false),
   AccountMeta::new_readonly(new_mint_authority, true),
   AccountMeta::new(payer, true),
   AccountMeta::new_readonly(token_account_owner, true),
   AccountMeta::new_readonly(token_account, false),
   AccountMeta::new_readonly(new_metadata_update_authority, false),
   AccountMeta::new_readonly(metadata, false),
   AccountMeta::new_readonly(spl_token::id(), false),
   AccountMeta::new_readonly(solana_program::system_program::id(), false),
   AccountMeta::new_readonly(sysvar::rent::id(), false),
];

上的地址:

    let (edition_mark_pda, _) = Pubkey::find_program_address(
        &[
            PREFIX.as_bytes(),
            program_id.as_ref(),
            metadata_mint.as_ref(),
            EDITION.as_bytes(),
            as_string.as_bytes(),
        ],
        &program_id,
    );

您正在谈论的变量metadata_mint用于计算链条上的dection> dection_mark_pda链条 将此与文档进行比较,您将看到应提供的内容:

pda tor标记创建 - 将检查是否存在预先存在。 (PDA
['metadata',程序ID,大师元数据薄荷ID,'Edition',
distion_number])其中distion_number不是您的版本号码
传递Args,但实际上Edition_number =
地板(EDITAR/EDITAR_MARKER_BIT_SIZE)。

元数据:=主记录元数据帐户

metadata_mint:= =主元数据Mint ID

The documentation on metaplex you are talking about is the documentation of the solana instructions but not the rust api. They are different. If you take a look at the rust code, you will see the differences.

The accounts described in the documentation match the accounts provided by the code:

let accounts = vec![
   AccountMeta::new(new_metadata, false),
   AccountMeta::new(new_edition, false),
   AccountMeta::new(master_edition, false),
   AccountMeta::new(new_mint, false),
   AccountMeta::new(edition_mark_pda, false),
   AccountMeta::new_readonly(new_mint_authority, true),
   AccountMeta::new(payer, true),
   AccountMeta::new_readonly(token_account_owner, true),
   AccountMeta::new_readonly(token_account, false),
   AccountMeta::new_readonly(new_metadata_update_authority, false),
   AccountMeta::new_readonly(metadata, false),
   AccountMeta::new_readonly(spl_token::id(), false),
   AccountMeta::new_readonly(solana_program::system_program::id(), false),
   AccountMeta::new_readonly(sysvar::rent::id(), false),
];

The variable metadata_mint you are talking about is used to calculate the address of the edition_mark_pda address on chain:

    let (edition_mark_pda, _) = Pubkey::find_program_address(
        &[
            PREFIX.as_bytes(),
            program_id.as_ref(),
            metadata_mint.as_ref(),
            EDITION.as_bytes(),
            as_string.as_bytes(),
        ],
        &program_id,
    );

When you compare this with the documentation, you will see what should be provided:

Edition pda to mark creation - will be checked for pre-existence. (pda
of ['metadata', program id, master metadata mint id, 'edition',
edition_number]) where edition_number is NOT the edition number you
pass in args but actually edition_number =
floor(edition/EDITION_MARKER_BIT_SIZE).

metadata := Master record metadata account

metadata_mint := master metadata mint id

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文