波多野结衣 蜜桃视频,国产在线精品露脸ponn,a v麻豆成人,AV在线免费小电影

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

在這個(gè)教程中,我們將學(xué)習(xí)如何編寫 Rust 智能合約并使用 Metaplex 在 Solana 上鑄造 NFT。

 

用熟悉的語(yǔ)言學(xué)習(xí) Web3.0 開發(fā) : JAVA | php | Python/ target=_blank class=infotextkey>Python | .NET / C# | Golang | Node.JS | Flutter / Dart

在 Solana 開發(fā)中,我們回面臨許多奇怪的自定義錯(cuò)誤和錯(cuò)誤,并且由于 Solana 開發(fā)生態(tài)系統(tǒng)沒有 Eth 開發(fā)生態(tài)系統(tǒng)那么大,因此修復(fù)它們 可能非常困難和令人沮喪。但不用擔(dān)心。當(dāng)遇到困難時(shí),只需在正確的地方尋找解決方案。

在我的開發(fā)過程中,我不斷地在Anchor discord 服務(wù)器、Metaplex和Superteam服務(wù)器上提出疑問,并查看 GitHub 上的其他代碼倉(cāng)庫(kù)和 Metaplex 程序庫(kù)本身。

1、項(xiàng)目概況

在這個(gè)教程中,我們將使用的工具包括:

  • Solana CLI 工具— 官方 Solana CLI 工具集
  • Anchor Framework — 用于開發(fā) Solana 程序的高級(jí)框架。這是必須的,除非你是大神級(jí)開發(fā)人員,不過在這種情況下你應(yīng)該不會(huì)閱讀此博客。哈哈。
  • Solana/web3.js — web3.js的 Solana 版本
  • Solana/spl-token — 使用 spl 通證的包
  • Mocha — 一個(gè) JS 測(cè)試工具

2、準(zhǔn)備工作

在命令行使用以下命令將你的網(wǎng)絡(luò)設(shè)置為 devnet:

1
solana config set --url devnet

要確認(rèn)它是否有效,請(qǐng)?jiān)趫?zhí)行上述命令后檢查輸出:

1
2
3
4
5
Config File: /Users/anoushkkharangate/.config/solana/cli/config.yml
RPC URL: https://api.devnet.solana.com
WebSocket URL: wss://api.devnet.solana.com/ (computed)
Keypair Path: /Users/anoushkkharangate/.config/solana/id.json
Commitment: confirmed

接下來,請(qǐng)參考Solana wallet docs設(shè)置 文件系統(tǒng)錢包,并使用命令solana airdrop 1添加一些devnet的 sol通證。

最后,使用另一個(gè)anchor CLI終端 通過以下命令創(chuàng)建一個(gè)anchor項(xiàng)目:

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

確保Anchor.toml也設(shè)置為 devnet。

1
2
3
4
5
6
7
8
9
10
11
[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、導(dǎo)入依賴項(xiàng)

在項(xiàng)目中,必須有一個(gè)名為程序的文件夾。轉(zhuǎn)到programs/<your-project-name>/Cargo.toml并添加這些依賴項(xiàng)。確保使用版本0.24.2, 可以使用avm來更改它:

1
2
3
4
[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 之前的所有版本,因此請(qǐng)確保使用該版本

然后轉(zhuǎn)到src 中的lib.rs文件并導(dǎo)入這些:

1
2
3
4
5
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};

現(xiàn)在我們可以編寫 mint 函數(shù)了!

4、NFT賬戶結(jié)構(gòu)實(shí)現(xiàn)

首先,讓我們mint為函數(shù)創(chuàng)建賬戶結(jié)構(gòu):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#[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>,
}

不要擔(dān)心未檢查的帳戶,因?yàn)槲覀儠?huì)將其傳遞給 Metaplex 程序,它會(huì)為我們檢查。

為了在 Anchor 中使用 Unchecked 帳戶,我們需要在每個(gè)帳戶上方添加此注釋:

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

5、NFT合約Mint函數(shù)實(shí)現(xiàn)

讓我們創(chuàng)建一個(gè)函數(shù),使用剛剛創(chuàng)建的結(jié)構(gòu)來鑄造通證:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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(())
    }

如果想調(diào)試你的程序,最好使用msg!()記錄想要檢查的任何值。它接受字符串,因此必須使用std::string::ToString來轉(zhuǎn)換。 你的日志將出現(xiàn)在終端或.anchor/program-logs/<program-id>

 

有幾點(diǎn)需要說明一下。

creator數(shù)組需要包含鑄造 NFT 的人,但你可以將份額設(shè)置為 0,所以這并不重要。這是代碼:

1
2
3
4
5
6
7
8
9
10
11
12
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,
            },
        ];

我還沒有實(shí)現(xiàn)集合,因?yàn)樗辉诒局改系姆秶鷥?nèi),但你可以使用以下方法來實(shí)現(xiàn):

1
mpl_token_metadata::instruction::set_and_verify_collection

為什么我在這里將 Max supply 設(shè)置為 0?在 Metaplex 中,如果是一種通證,那么你必須將其最大供應(yīng)量設(shè)置為零,因?yàn)榭偣?yīng)量 - 聲稱的供應(yīng)量 (1-1) 等于 0。

1
2
3
4
5
6
7
8
9
10
&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
            ),

編寫函數(shù)后,運(yùn)行anchor build && anchor deploy,應(yīng)該會(huì)看到已部署的程序 ID

 

將此程序 ID 粘貼到Anchor.toml和lib.rs文件中,替換全部的默認(rèn)ID即
Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS。

6、調(diào)用 Mint 函數(shù)

在做任何事情之前,請(qǐng)確保已導(dǎo)入@solana/web3.js和@solana/spl-token。 在tests/<test-file>.ts里面添加這些導(dǎo)入和常量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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; q
const 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();

現(xiàn)在讓我們制作通證和關(guān)聯(lián)的通證賬戶,如下面代碼所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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 權(quán)限必須相同,否則不起作用。


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

現(xiàn)在,調(diào)用 mint 函數(shù)并傳遞數(shù)據(jù)和帳戶:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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);

好了!現(xiàn)在只需運(yùn)行anchor test,就應(yīng)該能夠鑄造你的 NFT:

1
2
3
4
5
6
7
8
9
Account:  4swRFMNovHCkXY3gDgAGBXZwpfFuVyxWpWsgXqbYvoZG1M63nZHxyPRm7KTqAjSdTpHn2ivyPr6jQfxeLsB6a1nX
Mint key:  DehGx61vZPYNaMWm9KYdP91UYXXLu1XKoc2CCu3NZFNb
User:  7CtWnYdTNBb3P9eViqSZKUekjcKnMcaasSMC7NbTVKuE
Metadata address:  7ut8YMzGqZAXvRDro8jLKkPnUccdeQxsfzNv1hjzc3Bo
MasterEdition:  Au76v2ZDnWSLj23TCu9NRVEYWrbVUq6DAGNnCuALaN6o
Your transaction signature KwEst87H3dZ5GwQ5CDL1JtiRKwcXJKNzyvQShaTLiGxz4HQGsDA7EW6rrhqwbJ2TqQFRWzZFvhfBU1CpyYH7WhH
    ? Is initialized! (6950ms)
  1 passing (7s)
?  Done in 9.22s.

如果提示任何帶有 0x1 等十六進(jìn)制值的自定義程序錯(cuò)誤,請(qǐng)將十六進(jìn)制值轉(zhuǎn)換為純文本,然后前往metaplex github 并使用你的瀏覽器搜索“error(”

可以在這里查看 NFT:solscan

7、結(jié)束語(yǔ)

我希望本指南對(duì)所有 Solana 極客有用。當(dāng)我第一次嘗試鑄造 NFT 時(shí)感到非常困難,希望這篇文章對(duì)你有所幫助。 可以從這里下載教程里的代碼。


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

分享到:
標(biāo)簽:NFT
用戶無頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定