当前位置: 首页 > 工具软件 > Solana > 使用案例 >

151-Solana入门(十五)- 创建ata账户

颛孙高义
2023-12-01

创建ata账户

创建Associated Token Account

我们来看一下create_associated_token_account这个指令



/// Create an associated token account for the given wallet address and token mint
///
/// Accounts expected by this instruction:
///
///   0. `[writeable,signer]` Funding account (must be a system account)
///   1. `[writeable]` Associated token account address to be created
///   2. `[]` Wallet address for the new associated token account
///   3. `[]` The token mint for the new associated token account
///   4. `[]` System program
///   5. `[]` SPL Token program
///   6. `[]` Rent sysvar
///
pub fn create_associated_token_account(
    funding_address: &Pubkey,
    wallet_address: &Pubkey,
    spl_token_mint_address: &Pubkey,
) -> Instruction {
    let associated_account_address =
        get_associated_token_address(wallet_address, spl_token_mint_address);

    Instruction {
        program_id: id(),
        accounts: vec![
            AccountMeta::new(*funding_address, true),
            AccountMeta::new(associated_account_address, false),
            AccountMeta::new_readonly(*wallet_address, false),
            AccountMeta::new_readonly(*spl_token_mint_address, false),
            AccountMeta::new_readonly(solana_program::system_program::id(), false),
            AccountMeta::new_readonly(spl_token::id(), false),
            AccountMeta::new_readonly(sysvar::rent::id(), false),
        ],
        data: vec![],
    }
}

那么我们就来invoke一下

    invoke(
        &create_associated_token_account(
            signer_info.key,
            signer_info.key,
            mint_info.key,
        ),
        &[
            signer_info.clone(),
            ata_info.clone(),
            ass_token_program_info.clone(),
            mint_info.clone(),
            token_program_info.clone(),
            system_info.clone()
        ],
    )?;

在此之前

我们还是把创建ata和

create_account还有initialize_mint放在一起

3个指令连起来试一试

use borsh::BorshSerialize;
use solana_program::{
    system_instruction,
    account_info::{next_account_info, AccountInfo},
    sysvar::{clock::Clock,rent::Rent, Sysvar},
    entrypoint::ProgramResult,
    program_error::ProgramError,
    program::{invoke, invoke_signed},
    pubkey::Pubkey,
    msg,
};

use spl_associated_token_account::instruction::create_associated_token_account;
use spl_token::instruction::{initialize_mint};
use crate::{ ferror, state::*, utils::*};

pub fn process_init(
    program_id: &Pubkey,
    accounts: &[AccountInfo],
) -> ProgramResult {
    let account_info_iter = &mut accounts.iter();
    let authority_info = next_account_info(account_info_iter)?;
    let signer_info = next_account_info(account_info_iter)?;
    let mint_info = next_account_info(account_info_iter)?;
    let ata_info = next_account_info(account_info_iter)?;
    let token_program_info = next_account_info(account_info_iter)?;
    let ass_token_program_info = next_account_info(account_info_iter)?;
    let rent_info = next_account_info(account_info_iter)?;
    let system_info = next_account_info(account_info_iter)?;

    assert_signer(&signer_info)?;
    let size = 82;
    let rent = &Rent::from_account_info(&rent_info)?;
    let required_lamports = rent.minimum_balance(size);

    msg!("Create Account");
    invoke(
        &system_instruction::create_account(
            signer_info.key,
            mint_info.key,
            required_lamports,
            size as u64,
            token_program_info.key,
        ),
        &[signer_info.clone(), mint_info.clone()],
    )?;

    msg!("Initialize Mint");
    invoke(
        &initialize_mint(
            token_program_info.key,
            mint_info.key,
            authority_info.key,
            Some(authority_info.key),
            9,
        )?,
        &[authority_info.clone(), mint_info.clone(),rent_info.clone(),token_program_info.clone(),],
    )?;

    msg!("Create Associated Token Account");
    invoke(
        &create_associated_token_account(
            signer_info.key,
            signer_info.key,
            mint_info.key,
        ),
        &[
            signer_info.clone(),
            ata_info.clone(),
            ass_token_program_info.clone(),
            mint_info.clone(),
            token_program_info.clone(),
            system_info.clone()
        ],
    )?;

    Ok(())
}

然后我们来调用一下

import {Button, StyleSheet, View} from 'react-native';
import {
    clusterApiUrl,
    Connection,
    Keypair,
    PublicKey, sendAndConfirmTransaction,
    SystemProgram,
    SYSVAR_RENT_PUBKEY, Transaction,
    TransactionInstruction
} from "@solana/web3.js";
import * as bip39 from "bip39";
import * as ed25519 from "ed25519-hd-key";
import * as web3 from "@solana/web3.js";
import * as spl from "@solana/spl-token";

export default function App() {
    return (
        <View style={styles.container}>
            <Button title="test" onPress={() => test01()}></Button>
        </View>
    );
}

const test01 = async () => {
    // Connect to cluster
    var connection = new Connection(
        clusterApiUrl('devnet'),
        'confirmed',
    );

    const derivePath = `m/44'/501'/1'/0'`;
    const text = 'abc abc abc';
    const seed = bip39.mnemonicToSeedSync(text).toString('hex');
    const derivedSeed = ed25519.derivePath(derivePath, seed).key;
    const wallet = web3.Keypair.fromSeed(derivedSeed);
    console.log(wallet.publicKey.toBase58());

    const programId = new PublicKey('99jnnLfxCAp3QXBmMg31eU5kus8mE79SEKDqEn8VnLHF')
    const mint = Keypair.generate();
    const TOKEN_PROGRAM_ID = new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
    const assTokenProgram = new PublicKey("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL");
    const ASSOCIATED_TOKEN_PROGRAM_ID = new PublicKey("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL");
    const [ata] = await PublicKey.findProgramAddress(
        [
            wallet.publicKey.toBuffer(),
            TOKEN_PROGRAM_ID.toBuffer(),
            mint.publicKey.toBuffer(),
        ],
        ASSOCIATED_TOKEN_PROGRAM_ID
    );
    console.log("ata:::", ata.toBase58());

    const keys = [
        {
            pubkey: wallet.publicKey,
            isSigner: false,
            isWritable: true,
        },
        {
            pubkey: wallet.publicKey,
            isSigner: true,
            isWritable: true,
        },
        {
            pubkey: mint.publicKey,
            isSigner: true,
            isWritable: true,
        },
        {
            pubkey: ata,
            isSigner: false,
            isWritable: true,
        },
        {
            pubkey: TOKEN_PROGRAM_ID,
            isSigner: false,
            isWritable: false,
        },
        {
            pubkey: ASSOCIATED_TOKEN_PROGRAM_ID,
            isSigner: false,
            isWritable: false,
        },
        {
            pubkey: SYSVAR_RENT_PUBKEY,
            isSigner: false,
            isWritable: false,
        },
        {
            pubkey: SystemProgram.programId,
            isSigner: false,
            isWritable: false,
        }

    ];

    const data = Buffer.from([0]);
    const initIX = new TransactionInstruction({
        keys: keys,
        programId: programId,
        data,
    })
    const initTX = new Transaction()
    initTX.add(initIX)
    const signature = await sendAndConfirmTransaction(
        connection,
        initTX,
        [wallet, mint],
    )
    console.log("signature::::", signature)
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
        alignItems: 'center',
        justifyContent: 'center',
    },
});

这是在合约里面去创建ata

其实也可以在前端去创建ata

    const mint_tx = new anchor.web3.Transaction().add(
      anchor.web3.SystemProgram.createAccount({
        fromPubkey: wallet.publicKey,
        newAccountPubkey: mintKey.publicKey,
        space: MINT_SIZE,
        programId: TOKEN_PROGRAM_ID,
        lamports,
      }),
      createInitializeMintInstruction(
        mintKey.publicKey,
        0,
        wallet.publicKey,
        wallet.publicKey
      ),
      createAssociatedTokenAccountInstruction(
        wallet.publicKey,
        NftTokenAccount,
        wallet.publicKey,
        mintKey.publicKey
      )
    );

    const res = await program.provider.sendAndConfirm(mint_tx, [mintKey]);

在合约中和在前端都可以

就看具体的需求了

这一篇有一点奇怪

写得也挺长的,挺具体的

但是官方一直给我一个提示

就是说我的文章质量不行

原文是这样的

此文章质量较低,不会获得较多流量扶持! 可能的原因为:篇幅太短,广告涉嫌违规,外链过多,缺少代码,图片涉嫌违规。

我觉得和平时写的也没有很大的区别

为什么这一篇就不行呢

奇怪

 类似资料: