您当前的位置:首页 > 互联网百科 > 区块链

Solana区块链NFT开发教程

时间:2022-08-03 13:55:56  来源:  作者:新缸中之脑

在这个教程中,我们将学习如何编写 Rust 智能合约并使用 Metaplex 在 Solana 上铸造 NFT

 

用熟悉的语言学习 Web3.0 开发 : JAVA | php | Python/ target=_blank class=infotextkey>Python | .NET / C# | Golang | Node.JS | Flutter / Dart

在 Solana 开发中,我们回面临许多奇怪的自定义错误和错误,并且由于 Solana 开发生态系统没有 Eth 开发生态系统那么大,因此修复它们 可能非常困难和令人沮丧。但不用担心。当遇到困难时,只需在正确的地方寻找解决方案。

在我的开发过程中,我不断地在Anchor discord 服务器、Metaplex和Superteam服务器上提出疑问,并查看 GitHub 上的其他代码仓库和 Metaplex 程序库本身。

1、项目概况

在这个教程中,我们将使用的工具包括:

  • Solana CLI 工具— 官方 Solana CLI 工具集
  • Anchor Framework — 用于开发 Solana 程序的高级框架。这是必须的,除非你是大神级开发人员,不过在这种情况下你应该不会阅读此博客。哈哈。
  • Solana/web3.js — web3.js的 Solana 版本
  • Solana/spl-token — 使用 spl 通证的包
  • Mocha — 一个 JS 测试工具

2、准备工作

在命令行使用以下命令将你的网络设置为 devnet:

1
solana config set --url devnet

要确认它是否有效,请在执行上述命令后检查输出:

12345
Config File: /Users/anoushkkharangate/.config/solana/cli/config.ymlRPC URL: https://api.devnet.solana.comWebSocket URL: wss://api.devnet.solana.com/ (computed)Keypair Path: /Users/anoushkkharangate/.config/solana/id.jsonCommitment: confirmed

接下来,请参考Solana wallet docs设置 文件系统钱包,并使用命令solana airdrop 1添加一些devnet的 sol通证。

最后,使用另一个anchor CLI终端 通过以下命令创建一个anchor项目:

1
anchor init <name-of-your-project>

确保Anchor.toml也设置为 devnet。

1234567891011
[features]seeds = false[programs.devnet]metaplex_anchor_nft = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"[registry]url = "https://anchor.projectserum.com"[provider]cluster = "devnet"wallet = "/Users/<user-name>/.config/solana/id.json"[scripts]test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"

3、导入依赖项

在项目中,必须有一个名为程序的文件夹。转到programs/<your-project-name>/Cargo.toml并添加这些依赖项。确保使用版本0.24.2, 可以使用avm来更改它:

1234
[dependencies]anchor-lang = "0.24.2"anchor-spl = "0.24.2"mpl-token-metadata = {version = "1.2.7", features = ["no-entrypoint"]}

由于安全漏洞,Anchor 已删除 0.24.2 之前的所有版本,因此请确保使用该版本

然后转到src 中的lib.rs文件并导入这些:

12345
use anchor_lang::prelude::*;use anchor_lang::solana_program::program::invoke;use anchor_spl::token;use anchor_spl::token::{MintTo, Token};use mpl_token_metadata::instruction::{create_master_edition_v3, create_metadata_accounts_v2};

现在我们可以编写 mint 函数了!

4、NFT账户结构实现

首先,让我们mint为函数创建账户结构:

123456789101112131415161718192021222324252627
#[derive(Accounts)]pub struct MintNFT<'info> {    #[account(mut)]    pub mint_authority: Signer<'info>,/// CHECK: This is not dangerous because we don't read or write from this account    #[account(mut)]    pub mint: UncheckedAccount<'info>,    // #[account(mut)]    pub token_program: Program<'info, Token>,    /// CHECK: This is not dangerous because we don't read or write from this account    #[account(mut)]    pub metadata: 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    pub token_metadata_program: UncheckedAccount<'info>,    /// CHECK: This is not dangerous because we don't read or write from this account    #[account(mut)]    pub payer: AccountInfo<'info>,    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>,    /// CHECK: This is not dangerous because we don't read or write from this account    #[account(mut)]    pub master_edition: UncheckedAccount<'info>,}

不要担心未检查的帐户,因为我们会将其传递给 Metaplex 程序,它会为我们检查。

为了在 Anchor 中使用 Unchecked 帐户,我们需要在每个帐户上方添加此注释:

1
/// CHECK: This is not dangerous because we don't read or write from this account

5、NFT合约Mint函数实现

让我们创建一个函数,使用刚刚创建的结构来铸造通证:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
pub fn mint_nft(        ctx: Context<MintNFT>,        creator_key: Pubkey,        uri: String,        title: String,    ) -> Result<()> {        msg!("Initializing Mint NFT");        let cpi_accounts = MintTo {            mint: ctx.accounts.mint.to_account_info(),            to: ctx.accounts.token_account.to_account_info(),            authority: ctx.accounts.payer.to_account_info(),        }; msg!("CPI Accounts Assigned");        let cpi_program = ctx.accounts.token_program.to_account_info();        msg!("CPI Program Assigned");        let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);        msg!("CPI Context Assigned");        token::mint_to(cpi_ctx, 1)?;        msg!("Token Minted !!!");        let account_info = vec![Solana NFT            ctx.accounts.metadata.to_account_info(),            ctx.accounts.mint.to_account_info(),            ctx.accounts.mint_authority.to_account_info(),            ctx.accounts.payer.to_account_info(),            ctx.accounts.token_metadata_program.to_account_info(),            ctx.accounts.token_program.to_account_info(),            ctx.accounts.system_program.to_account_info(),            ctx.accounts.rent.to_account_info(),        ];        msg!("Account Info Assigned");        let creator = vec![Solana NFT            mpl_token_metadata::state::Creator {                address: creator_key,                verified: false,                share: 100,            },            mpl_token_metadata::state::Creator {                address: ctx.accounts.mint_authority.key(),                verified: false,                share: 0,            },        ];        msg!("Creator Assigned");        let symbol = std::string::ToString::to_string("symb");        invoke(            &create_metadata_accounts_v2(                ctx.accounts.token_metadata_program.key(),                ctx.accounts.metadata.key(),                ctx.accounts.mint.key(),                ctx.accounts.mint_authority.key(),                ctx.accounts.payer.key(),                ctx.accounts.payer.key(),                title,                symbol,                uri,                Some(creator),                1,                true,                false,                None,                None,            ),            account_info.as_slice(),        )?;        msg!("Metadata Account Created !!!");        let master_edition_infos = vec![Solana NFT            ctx.accounts.master_edition.to_account_info(),            ctx.accounts.mint.to_account_info(),            ctx.accounts.mint_authority.to_account_info(),            ctx.accounts.payer.to_account_info(),            ctx.accounts.metadata.to_account_info(),            ctx.accounts.token_metadata_program.to_account_info(),            ctx.accounts.token_program.to_account_info(),            ctx.accounts.system_program.to_account_info(),            ctx.accounts.rent.to_account_info(),        ];        msg!("Master Edition Account Infos Assigned");        invoke(            &create_master_edition_v3(                ctx.accounts.token_metadata_program.key(),                ctx.accounts.master_edition.key(),                ctx.accounts.mint.key(),                ctx.accounts.payer.key(),                ctx.accounts.mint_authority.key(),                ctx.accounts.metadata.key(),                ctx.accounts.payer.key(),                Some(0),            ),            master_edition_infos.as_slice(),        )?;        msg!("Master Edition Nft Minted !!!");        Ok(())    }

如果想调试你的程序,最好使用msg!()记录想要检查的任何值。它接受字符串,因此必须使用std::string::ToString来转换。 你的日志将出现在终端或.anchor/program-logs/<program-id>

 

有几点需要说明一下。

creator数组需要包含铸造 NFT 的人,但你可以将份额设置为 0,所以这并不重要。这是代码:

123456789101112
let creator = vec![Solana NFT            mpl_token_metadata::state::Creator {                address: creator_key,                verified: false,                share: 100,            },            mpl_token_metadata::state::Creator {                address: ctx.accounts.mint_authority.key(),                verified: false,                share: 0,            },        ];

我还没有实现集合,因为它不在本指南的范围内,但你可以使用以下方法来实现:

1
mpl_token_metadata::instruction::set_and_verify_collection

为什么我在这里将 Max supply 设置为 0?在 Metaplex 中,如果是一种通证,那么你必须将其最大供应量设置为零,因为总供应量 - 声称的供应量 (1-1) 等于 0。

12345678910
&create_master_edition_v3(                ctx.accounts.token_metadata_program.key(),                ctx.accounts.master_edition.key(),                ctx.accounts.mint.key(),                ctx.accounts.payer.key(),                ctx.accounts.mint_authority.key(),                ctx.accounts.metadata.key(),                ctx.accounts.payer.key(),                Some(0), // max supply 0            ),

编写函数后,运行anchor build && anchor deploy,应该会看到已部署的程序 ID

 

将此程序 ID 粘贴到Anchor.toml和lib.rs文件中,替换全部的默认ID即
Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS。

6、调用 Mint 函数

在做任何事情之前,请确保已导入@solana/web3.js和@solana/spl-token。 在tests/<test-file>.ts里面添加这些导入和常量:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
import {  TOKEN_PROGRAM_ID,  createAssociatedTokenAccountInstruction,  getAssociatedTokenAddress,  createInitializeMintInstruction,  MINT_SIZE,} from "@solana/spl-token";import { LAMPORTS_PER_SOL } from "@solana/web3.js";const { PublicKey, SystemProgram } = anchor.web3; qconst TOKEN_METADATA_PROGRAM_ID = new anchor.web3.PublicKey(      "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"    );    const lamports: number =      await program.provider.connection.getMinimumBalanceForRentExemption(        MINT_SIZE      );    const getMetadata = async (      mint: anchor.web3.PublicKey    ): Promise<anchor.web3.PublicKey> => {      return (        await anchor.web3.PublicKey.findProgramAddress(          [            Buffer.from("metadata"),            TOKEN_METADATA_PROGRAM_ID.toBuffer(),            mint.toBuffer(),          ],          TOKEN_METADATA_PROGRAM_ID        )      )[0];    };    const getMasterEdition = async (      mint: anchor.web3.PublicKey    ): Promise<anchor.web3.PublicKey> => {      return (        await anchor.web3.PublicKey.findProgramAddress(          [            Buffer.from("metadata"),            TOKEN_METADATA_PROGRAM_ID.toBuffer(),            mint.toBuffer(),            Buffer.from("edition"),          ],          TOKEN_METADATA_PROGRAM_ID        )      )[0];    };    const mintKey: anchor.web3.Keypair = anchor.web3.Keypair.generate();

现在让我们制作通证和关联的通证账户,如下面代码所示:

12345678910111213141516171819202122232425262728293031323334353637
const NftTokenAccount = await getAssociatedTokenAddress(      mintKey.publicKey,      program.provider.wallet.publicKey    );    console.log("NFT Account: ", NftTokenAccount.toBase58());    const mint_tx = new anchor.web3.Transaction().add(      anchor.web3.SystemProgram.createAccount({        fromPubkey: program.provider.wallet.publicKey,        newAccountPubkey: mintKey.publicKey,        space: MINT_SIZE,        programId: TOKEN_PROGRAM_ID,        lamports,      }),      createInitializeMintInstruction(        mintKey.publicKey,        0,        program.provider.wallet.publicKey,        program.provider.wallet.publicKey      ),      createAssociatedTokenAccountInstruction(        program.provider.wallet.publicKey,        NftTokenAccount,        program.provider.wallet.publicKey,        mintKey.publicKey      )    );    const res = await program.provider.send(mint_tx, [mintKey]);    console.log(      await program.provider.connection.getParsedAccountInfo(mintKey.publicKey)    );    console.log("Account: ", res);    console.log("Mint key: ", mintKey.publicKey.toString());    console.log("User: ", program.provider.wallet.publicKey.toString());    const metadataAddress = await getMetadata(mintKey.publicKey);    const masterEdition = await getMasterEdition(mintKey.publicKey);    console.log("Metadata address: ", metadataAddress.toBase58());    console.log("MasterEdition: ", masterEdition.toBase58());

注意:mint 和 freeze 权限必须相同,否则不起作用。


createInitializeMintInstruction( mintKey.publicKey, 0,
program.provider.wallet.publicKey,// mint auth
program.provider.wallet.publicKey // freeze auth
),

现在,调用 mint 函数并传递数据和帐户:

1234567891011121314151617181920
const tx = await program.rpc.mintNft(      mintKey.publicKey,      "https://arweave.net/y5e5DJsiwH0s_ayfMwYk-SnrZtVZzHLQDSTZ5dNRUHA",      "NFT Title",      {        accounts: {          mintAuthority: program.provider.wallet.publicKey,          mint: mintKey.publicKey,          tokenAccount: NftTokenAccount,          tokenProgram: TOKEN_PROGRAM_ID,          metadata: metadataAddress,          tokenMetadataProgram: TOKEN_METADATA_PROGRAM_ID,          payer: program.provider.wallet.publicKey,          systemProgram: SystemProgram.programId,          rent: anchor.web3.SYSVAR_RENT_PUBKEY,          masterEdition: masterEdition,        },      }    );    console.log("Your transaction signature", tx);

好了!现在只需运行anchor test,就应该能够铸造你的 NFT:

123456789
Account:  4swRFMNovHCkXY3gDgAGBXZwpfFuVyxWpWsgXqbYvoZG1M63nZHxyPRm7KTqAjSdTpHn2ivyPr6jQfxeLsB6a1nXMint key:  DehGx61vZPYNaMWm9KYdP91UYXXLu1XKoc2CCu3NZFNbUser:  7CtWnYdTNBb3P9eViqSZKUekjcKnMcaasSMC7NbTVKuEMetadata address:  7ut8YMzGqZAXvRDro8jLKkPnUccdeQxsfzNv1hjzc3BoMasterEdition:  Au76v2ZDnWSLj23TCu9NRVEYWrbVUq6DAGNnCuALaN6oYour transaction signature KwEst87H3dZ5GwQ5CDL1JtiRKwcXJKNzyvQShaTLiGxz4HQGsDA7EW6rrhqwbJ2TqQFRWzZFvhfBU1CpyYH7WhH    ✔ Is initialized! (6950ms)  1 passing (7s)✨  Done in 9.22s.

如果提示任何带有 0x1 等十六进制值的自定义程序错误,请将十六进制值转换为纯文本,然后前往metaplex github 并使用你的浏览器搜索“error(”

可以在这里查看 NFT:solscan

7、结束语

我希望本指南对所有 Solana 极客有用。当我第一次尝试铸造 NFT 时感到非常困难,希望这篇文章对你有所帮助。 可以从这里下载教程里的代码。


原文链接:
http://blog.hubwiz.com/2022/08/03/mint-nft-on-solana/



Tags:NFT   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
在这个教程中,我们将学习如何编写 Rust 智能合约并使用 Metaplex 在 Solana 上铸造 NFT。 用熟悉的语言学习 Web3.0 开发 : Java | Php | Python | .Net / C# | Golang | Node...【详细内容】
2022-08-03  Tags: NFT  点击:(0)  评论:(0)  加入收藏
你听过Web3(Web3.0)吗?你知道区块链、元宇宙、虚拟货币、NFT都与Web3.0是有关系的吗?今天就让我们用一篇文章来好好了解Web3.0,看看它与过往的Web1.0、Web2.0有什么差异及优势?对...【详细内容】
2022-07-17  Tags: NFT  点击:(32)  评论:(0)  加入收藏
今时今日,我们不可能逃避围绕NFTs、metaverse和Web3所产生的传闻。在过去的几个月里,我们收到了许多来自客户、朋友和合作伙伴的问题,询问我们对上述所有问题的看法,更重要的是,...【详细内容】
2022-07-10  Tags: NFT  点击:(21)  评论:(0)  加入收藏
出品|虎嗅科技组作者|周舟头图|视觉中国扎克伯格,终于对自己最重量级的产品facebook“动手了”,他开始探索起NFT和Web3。2022年6月30日,Meta发言人在推特上表示,已开始在Facebook上...【详细内容】
2022-07-02  Tags: NFT  点击:(37)  评论:(0)  加入收藏
本文为万向区块链双碳项目负责人李群在“商业认知研究院&middot;每周研讨”上分享的内容。“碳中和”是全人类面临的共同议题,世界大部分国家都开始坚定地执行此策略。中国也...【详细内容】
2022-06-15  Tags: NFT  点击:(28)  评论:(0)  加入收藏
合并即将到来,这将是以太坊迄今为止最大的升级。  不过,这种重大的技术转变将如何影响以太坊的 NFT 生态系统呢?  现在还很难得出结论,但有一些重要的观点是需要被关注的。...【详细内容】
2022-06-14  Tags: NFT  点击:(49)  评论:(0)  加入收藏
一转眼又2022年了,将目光再次看向已经过去了的2021年,被文艺界视作“元宇宙年间”,数字藏品市场越来越火爆,以至于更多的企业家和艺术家都想在这个领域分一杯羹,NFT是元宇宙中产...【详细内容】
2022-06-13  Tags: NFT  点击:(29)  评论:(0)  加入收藏
来源:科技日报以加密、确权、独一无二等为标签却屡屡遭遇负面事件大火的NFT,防得住盗版防不住小偷?近日,由一只“猴子”引发的盗窃案迅速成为国内社交网站的霸屏话题。此“猴子...【详细内容】
2022-05-16  Tags: NFT  点击:(47)  评论:(0)  加入收藏
1、中藏数字藏品于11:11发售《中藏徽章&middot;青花蓝》。 2、NFTCN(Bigverse)于5月1日-5月7日免费发布《五一假期滑板NFT》,注册即可领取。 3、新华数藏于10:00发售《中华有...【详细内容】
2022-05-06  Tags: NFT  点击:(337)  评论:(0)  加入收藏
五一5天假,实打实玩了5天的NFT,很明显的意识到自己不合适这个圈子,挣不了这个钱。简要谈几点,警戒自己以后不要入圈。先说战绩, 前后投了小一万。亏了1000左右。浏览器 app玩这个...【详细内容】
2022-05-06  Tags: NFT  点击:(94)  评论:(0)  加入收藏
▌简易百科推荐
在这个教程中,我们将学习如何编写 Rust 智能合约并使用 Metaplex 在 Solana 上铸造 NFT。 用熟悉的语言学习 Web3.0 开发 : Java | Php | Python | .Net / C# | Golang | Node...【详细内容】
2022-08-03  新缸中之脑    Tags:NFT   点击:(0)  评论:(0)  加入收藏
为了理解智能合约以及为什么它对 Web 3.0 很重要,首先必须了解互联网从 Web 1.0 到 Web 3.0 的演变。 自从1980 年代初首次推出以来,由于从 Web 1.0 开始的多次调整和改进,互联...【详细内容】
2022-08-01  听朕有话要讲    Tags:智能合约   点击:(5)  评论:(0)  加入收藏
什么是REITs CHAIN?REITs CHAIN全球资产数字化生态公链,是去中心化、开源的有智能合约的公链。有着丰富的Web3+DeFi+NFTs+DAOs+Metaverse新生态。采用PoW+DPoS混合机制,两个账...【详细内容】
2022-07-26  REITsCHAIN    Tags:区块链   点击:(9)  评论:(0)  加入收藏
在区块链世界中,智能合约是不可缺少的一部分。而作为一种真正意义上运行在去中心化网络上的合约,Solidity在智能合约的编写中占据了非常大的份额,学习solidity属于入门区块链的...【详细内容】
2022-07-14  程序员客栈    Tags:区块链   点击:(10)  评论:(0)  加入收藏
本文为万向区块链双碳项目负责人李群在“商业认知研究院&middot;每周研讨”上分享的内容。“碳中和”是全人类面临的共同议题,世界大部分国家都开始坚定地执行此策略。中国也...【详细内容】
2022-06-15  万向区块链    Tags:区块链   点击:(28)  评论:(0)  加入收藏
合并即将到来,这将是以太坊迄今为止最大的升级。  不过,这种重大的技术转变将如何影响以太坊的 NFT 生态系统呢?  现在还很难得出结论,但有一些重要的观点是需要被关注的。...【详细内容】
2022-06-14  明明不想贪    Tags:NFT   点击:(49)  评论:(0)  加入收藏
上文,我们介绍了区块链的概念,今天就稍微深入一下,尽可能通俗地介绍一下:区块链的运行原理?通过上文的小故事,我们知道了区块链的概念,它的本质就是解决信任问题,降低信任成本的技术...【详细内容】
2022-06-13  算法的秘密    Tags:区块链   点击:(34)  评论:(0)  加入收藏
在最大的NFT市场“OpenSea”上,“ShanghaiQing蔬菜NFT”横空出世!!!元宇宙已经让人费解,NFT浪潮又席卷而至。今天的内容,跟大家一起仔细聊聊,NFT究竟是怎么一回事儿~什么是NFT?NFT,...【详细内容】
2022-04-25  DR科技  搜狐号  Tags:NFT   点击:(95)  评论:(0)  加入收藏
“卧久者 行必远,伏久者 飞必高”。2022年,确实是非常重要的一年。它是下一个时代的开始,更是百年未有之大变局的开始。经济需要重塑,被疫情的出现加速了这个进程。社会产能过...【详细内容】
2022-04-24  静思己过298    Tags:区块链   点击:(50)  评论:(0)  加入收藏
Dep-DAO基于DREP底层公链发起的DAO组织生态,旨在打造一个去中心化组织,实施社区共建生态协同自治,在此基础上DEP应运而生,搭载web3.0技术,集DeFi2.0、swap和DAO于一体的多功能生...【详细内容】
2022-04-18  阿sir看点    Tags:区块链   点击:(54)  评论:(0)  加入收藏
站内最新
站内热门
站内头条