Criar um Token Mint

O que é uma Mint Account?

Uma mint account representa exclusivamente um token na Solana e armazena seus metadados globais.

Mint Account Type
/// Mint data.
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Mint {
/// Optional authority used to mint new tokens. The mint authority may only
/// be provided during mint creation. If no mint authority is present
/// then the mint has a fixed supply and no further tokens may be
/// minted.
pub mint_authority: COption<Pubkey>,
/// Total supply of tokens.
pub supply: u64,
/// Number of base 10 digits to the right of the decimal place.
pub decimals: u8,
/// Is `true` if this structure has been initialized
pub is_initialized: bool,
/// Optional authority to freeze token accounts.
pub freeze_authority: COption<Pubkey>,
}

Observe que tanto o Token Program quanto o Token Extension Program compartilham a mesma implementação base para a mint account.

Cada token na Solana possui uma mint account, e o endereço do mint serve como identificador único do token.

Por exemplo, o USD Coin (USDC) tem o endereço de mint EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v. Este endereço identifica exclusivamente o USDC em todo o ecossistema Solana. Você pode visualizar este mint no Solana Explorer.

Como criar uma Mint Account

Criar uma mint account requer a instrução InitializeMint. Veja os detalhes de implementação aqui.

Você precisa invocar duas instruções para criar uma mint account:

  1. System Program: Criar uma conta com espaço alocado para uma mint account e transferir a propriedade para o Token Program.
  2. Token Program: Inicializar os dados da mint account

Typescript

import {
airdropFactory,
appendTransactionMessageInstructions,
createSolanaRpc,
createSolanaRpcSubscriptions,
createTransactionMessage,
generateKeyPairSigner,
getSignatureFromTransaction,
lamports,
pipe,
sendAndConfirmTransactionFactory,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
signTransactionMessageWithSigners
} from "@solana/kit";
import { getCreateAccountInstruction } from "@solana-program/system";
import {
getInitializeMintInstruction,
getMintSize,
TOKEN_PROGRAM_ADDRESS
} from "@solana-program/token";
// Create Connection, local validator in this example
const rpc = createSolanaRpc("http://localhost:8899");
const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");
// Generate keypairs for fee payer
const feePayer = await generateKeyPairSigner();
// Fund fee payer
await airdropFactory({ rpc, rpcSubscriptions })({
recipientAddress: feePayer.address,
lamports: lamports(1_000_000_000n),
commitment: "confirmed"
});
// Generate keypair to use as address of mint
const mint = await generateKeyPairSigner();
// Get default mint account size (in bytes), no extensions enabled
const space = BigInt(getMintSize());
// Get minimum balance for rent exemption
const rent = await rpc.getMinimumBalanceForRentExemption(space).send();
// Instruction to create new account for mint (token program)
// Invokes the system program
const createAccountInstruction = getCreateAccountInstruction({
payer: feePayer,
newAccount: mint,
lamports: rent,
space,
programAddress: TOKEN_PROGRAM_ADDRESS
});
// Instruction to initialize mint account data
// Invokes the token program
const initializeMintInstruction = getInitializeMintInstruction({
mint: mint.address,
decimals: 9,
mintAuthority: feePayer.address
});
const instructions = [createAccountInstruction, initializeMintInstruction];
// Get latest blockhash to include in transaction
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
// Create transaction message
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }), // Create transaction message
(tx) => setTransactionMessageFeePayerSigner(feePayer, tx), // Set fee payer
(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), // Set transaction blockhash
(tx) => appendTransactionMessageInstructions(instructions, tx) // Append instructions
);
// Sign transaction message with required signers (fee payer and mint keypair)
const signedTransaction =
await signTransactionMessageWithSigners(transactionMessage);
// Send and confirm transaction
await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(
signedTransaction,
{ commitment: "confirmed" }
);
// Get transaction signature
const transactionSignature = getSignatureFromTransaction(signedTransaction);
console.log("Mint Address:", mint.address);
console.log("\nTransaction Signature:", transactionSignature);
Console
Click to execute the code.

Rust

use anyhow::Result;
use solana_client::nonblocking::rpc_client::RpcClient;
use solana_sdk::{
commitment_config::CommitmentConfig,
program_pack::Pack,
signature::{Keypair, Signer},
system_instruction::create_account,
transaction::Transaction,
};
use spl_token::{id as token_program_id, instruction::initialize_mint, state::Mint};
#[tokio::main]
async fn main() -> Result<()> {
// Create connection to local validator
let client = RpcClient::new_with_commitment(
String::from("http://localhost:8899"),
CommitmentConfig::confirmed(),
);
let latestBlockhash = client.get_latest_blockhash().await?;
// Generate a new keypair for the fee payer
let fee_payer = Keypair::new();
// Airdrop 1 SOL to fee payer
let airdrop_signature = client
.request_airdrop(&fee_payer.pubkey(), 1_000_000_000)
.await?;
client.confirm_transaction(&airdrop_signature).await?;
loop {
let confirmed = client.confirm_transaction(&airdrop_signature).await?;
if confirmed {
break;
}
}
// Generate keypair to use as address of mint
let mint = Keypair::new();
let space = Mint::LEN;
let rent = client.get_minimum_balance_for_rent_exemption(space).await?;
// Create account instruction
let create_account_instruction = create_account(
&fee_payer.pubkey(),
&mint.pubkey(),
rent,
space as u64,
&token_program_id(),
);
// Initialize mint instruction
let initialize_mint_instruction = initialize_mint(
&token_program_id(),
&mint.pubkey(), // mint address
&fee_payer.pubkey(), // mint authority
Some(&fee_payer.pubkey()), // freeze authority
9, // decimals
)?;
// Create transaction and add instructions
let transaction = Transaction::new_signed_with_payer(
&[create_account_instruction, initialize_mint_instruction],
Some(&fee_payer.pubkey()),
&[&fee_payer, &mint],
latestBlockhash,
);
// Send and confirm transaction
let transaction_signature = client.send_and_confirm_transaction(&transaction).await?;
println!("Mint Address: {}", mint.pubkey());
println!("\nTransaction Signature: {}", transaction_signature);
Ok(())
}
Console
Click to execute the code.

Python

Python
#!/usr/bin/env python3
import asyncio
from solana.rpc.async_api import AsyncClient
from solders.keypair import Keypair
from solders.transaction import VersionedTransaction
from solders.message import MessageV0
from solders.system_program import create_account, CreateAccountParams
from spl.token.instructions import initialize_mint, InitializeMintParams
from spl.token.constants import TOKEN_PROGRAM_ID
# Constants
DECIMALS = 9
async def create_mint(rpc, mint_authority):
"""
Creates and initializes a new mint account
"""
mint = Keypair()
space = 82 # getMintSize() equivalent for SPL Token
# Get minimum balance for rent exemption
rent = await rpc.get_minimum_balance_for_rent_exemption(space)
# Create & initialize mint account
create_account_instruction = create_account(
CreateAccountParams(
from_pubkey=mint_authority.pubkey(),
to_pubkey=mint.pubkey(),
lamports=rent.value,
space=space,
owner=TOKEN_PROGRAM_ID
)
)
initialize_mint_instruction = initialize_mint(
InitializeMintParams(
program_id=TOKEN_PROGRAM_ID,
mint=mint.pubkey(),
decimals=DECIMALS,
mint_authority=mint_authority.pubkey(),
freeze_authority=None
)
)
instructions = [
create_account_instruction,
initialize_mint_instruction
]
# Get latest blockhash
latest_blockhash = await rpc.get_latest_blockhash()
# Create message
transaction_message = MessageV0.try_compile(
payer=mint_authority.pubkey(),
instructions=instructions,
address_lookup_table_accounts=[],
recent_blockhash=latest_blockhash.value.blockhash
)
# Create and sign transaction
signed_transaction = VersionedTransaction(transaction_message, [mint_authority, mint])
print("Mint account created successfully")
print(f"Mint: {mint.pubkey()}")
print(f"Mint Authority: {mint_authority.pubkey()}")
print(f"Decimals: {DECIMALS}")
return mint.pubkey()
async def main():
rpc = AsyncClient("http://localhost:8899")
# Constants
mint_authority = Keypair()
async with rpc:
# Create mint account
await create_mint(rpc, mint_authority)
if __name__ == "__main__":
asyncio.run(main())
Console
Click to execute the code.

Is this page helpful?

Índice

Editar Página