トークンの転送とは何ですか?
トークンの転送は、同じミントの別のtoken accountにtoken accountからトークンを移動します。
転送はミント供給量を変更しません。転送はtoken account間の残高のみを更新します。
トークンを転送する方法
トークンの転送には、Token ProgramのrsTransferまたはrsTransferChecked
instructionを使用します。
以下の例では*rsTransferChecked*を使用します。これは、呼び出し元がミントと小数点以下の桁数を提供する必要があり、instructionがアカウント間でトークンを移動する前に、予想されるミントとトークンの精度を検証できるようにします。
Token Extensions
Programでは、*rsTransfer*は非推奨となり、*rsTransferCheckedまたはrsTransferCheckedWithFee*が推奨されます。
ソースアカウントの所有者または承認された委任者が転送に署名します。Token Extensions Programでは、ミントに永続的な委任者拡張機能が有効になっている場合、ミントの永続的な委任者も転送を承認できます。
ソースリファレンス
| 項目 | 説明 | Token Program | Token Extensions Program |
|---|---|---|---|
Account | token accountの状態は、転送によって更新される残高を保存します。 | ソース | ソース |
Transfer | 呼び出し元がミントまたは小数点以下の桁数を提供することなく、token account間でトークンを移動するtransfer instructionです。Token Extensions Programでは、代わりに*rsTransferChecked*を使用してください。 | ソース | ソース |
TransferChecked | 呼び出し元がミントと小数点以下の桁数を提供する必要があり、同じミントのtoken account間でトークンを移動する前にそれらの値をチェックするtransfer instructionです。 | ソース | ソース |
process_transfer | トークン転送の共有プロセッサロジックです。 | ソース | ソース |
Typescript
以下のKitの例は、@solana/kitを使用した推奨アプローチを示しています。
@solana/web3.jsを使用したレガシーの例も参考用に含まれています。
Kit
import { generateKeyPairSigner } from "@solana/kit";import { createLocalClient } from "@solana/kit-client-rpc";import {findAssociatedTokenPda,tokenProgram,TOKEN_PROGRAM_ADDRESS} from "@solana-program/token";const client = await createLocalClient().use(tokenProgram());const mint = await generateKeyPairSigner();const recipient = await generateKeyPairSigner();const result = await client.token.instructions.transferToATA({mint: mint.address, // Mint for the token being transferred.authority: client.payer, // Owner or delegate approving the transfer.recipient: recipient.address, // Account that owns the destination token account.amount: 25n, // Token amount in base units.decimals: 2 // Decimals defined on the mint account.}).sendTransaction();const [sourceTokenAccount] = await findAssociatedTokenPda({mint: mint.address,owner: client.payer.address,tokenProgram: TOKEN_PROGRAM_ADDRESS});const [destinationTokenAccount] = await findAssociatedTokenPda({mint: mint.address,owner: recipient.address,tokenProgram: TOKEN_PROGRAM_ADDRESS});const [sourceTokenAccountData, destinationTokenAccountData] =await client.token.accounts.token.fetchAll([sourceTokenAccount,destinationTokenAccount]);console.log("Mint Address:", mint.address);console.log("\nSource Token Account Address:", sourceTokenAccount);console.log("Source Token Account:", sourceTokenAccountData.data);console.log("\nDestination Token Account Address:", destinationTokenAccount);console.log("Destination Token Account:", destinationTokenAccountData.data);console.log("\nTransaction Signature:", result.context.signature);
Console
Click to execute the code.
Web3.js
import { Connection, Keypair, LAMPORTS_PER_SOL } from "@solana/web3.js";import {createAssociatedTokenAccount,createMint,getAccount,mintToChecked,TOKEN_PROGRAM_ID,transferChecked} from "@solana/spl-token";const result = await transferChecked(connection, // Connection to the local validator.feePayer, // Account paying transaction fees.feePayerATA, // Token account sending the tokens.mintPubkey, // Mint for the token being transferred.recipientATA, // Token account receiving the tokens.feePayer, // Owner or delegate approving the transfer.25, // Token amount in base units.2, // Decimals defined on the mint account.[], // Additional multisig signers.{commitment: "confirmed" // Confirmation options for the transaction.},TOKEN_PROGRAM_ID // Token program to invoke.);const senderTokenAccount = await getAccount(connection,feePayerATA,"confirmed",TOKEN_PROGRAM_ID);const recipientTokenAccount = await getAccount(connection,recipientATA,"confirmed",TOKEN_PROGRAM_ID);console.log("Mint Address:", mintPubkey.toBase58());console.log("\nSource Token Account Address:", feePayerATA.toBase58());console.log("Source Token Account:", senderTokenAccount);console.log("\nDestination Token Account Address:", recipientATA.toBase58());console.log("Destination Token Account:", recipientTokenAccount);console.log("\nTransaction Signature:", result);
Console
Click to execute the code.
Rust
Rust
use anyhow::Result;use solana_client::nonblocking::rpc_client::RpcClient;use solana_commitment_config::CommitmentConfig;use solana_sdk::{program_pack::Pack,signature::{Keypair, Signer},transaction::Transaction,};use solana_system_interface::instruction::create_account;use spl_associated_token_account_interface::{address::get_associated_token_address, instruction::create_associated_token_account,};use spl_token_interface::{id as token_program_id,instruction::{initialize_mint, mint_to_checked, transfer_checked},state::{Account, Mint},};#[tokio::main]async fn main() -> Result<()> {let client = RpcClient::new_with_commitment(String::from("http://localhost:8899"),CommitmentConfig::confirmed(),);let recipient = Keypair::new();let transfer_amount = 25;let transaction = Transaction::new_signed_with_payer(&[transfer_checked(&token_program_id(), // Token program to invoke.&source_token_address, // Token account sending the tokens.&mint.pubkey(), // Mint for the token being transferred.&destination_token_address, // Token account receiving the tokens.&fee_payer.pubkey(), // Owner or delegate approving the transfer.&[], // Additional multisig signers.transfer_amount, // Token amount in base units.decimals, // Decimals defined on the mint account.)?,],Some(&fee_payer.pubkey()),&[&fee_payer],latest_blockhash,);let transaction_signature = client.send_and_confirm_transaction(&transaction).await?;let source_token_account = client.get_account(&source_token_address).await?;let source_token_data = Account::unpack(&source_token_account.data)?;let destination_token_account = client.get_account(&destination_token_address).await?;let destination_token_data = Account::unpack(&destination_token_account.data)?;println!("Mint Address: {}", mint.pubkey());println!("\nSource Token Account Address: {}", source_token_address);println!("Source Token Account: {:#?}", source_token_data);println!("\nDestination Token Account Address: {}",destination_token_address);println!("Destination Token Account: {:#?}", destination_token_data);println!("\nTransaction Signature: {}", transaction_signature);Ok(())}
Console
Click to execute the code.
Python
Python
#!/usr/bin/env python3import asyncioimport jsonfrom solana.rpc.async_api import AsyncClientfrom solders.keypair import Keypairfrom solders.message import Messagefrom solders.pubkey import Pubkeyfrom solders.system_program import create_account, CreateAccountParamsfrom solders.transaction import Transactionfrom spl.token.async_client import AsyncTokenfrom spl.token.instructions import (create_associated_token_account,get_associated_token_address,initialize_mint,InitializeMintParams,mint_to_checked,MintToCheckedParams,transfer_checked,TransferCheckedParams,)from spl.token.constants import MINT_LEN, TOKEN_PROGRAM_IDDECIMALS = 2AMOUNT_TO_MINT = 100AMOUNT_TO_TRANSFER = 25async def main():rpc = AsyncClient("http://localhost:8899")receiver = Keypair()async with rpc:transfer_tokens_instruction = transfer_checked(TransferCheckedParams(program_id=TOKEN_PROGRAM_ID, # Token program to invoke.source=source_token_account, # Token account sending the tokens.mint=mint.pubkey(), # Mint for the token being transferred.dest=destination_token_account, # Token account receiving the tokens.owner=fee_payer.pubkey(), # Account that owns the source token account.amount=AMOUNT_TO_TRANSFER, # Token amount in base units.decimals=DECIMALS, # Decimals defined on the mint account.))latest_blockhash = await rpc.get_latest_blockhash()transaction = Transaction([fee_payer],Message([transfer_tokens_instruction], fee_payer.pubkey()),latest_blockhash.value.blockhash,)result = await rpc.send_transaction(transaction)source_token_account_info = await token.get_account_info(source_token_account)destination_token_account_info = await token.get_account_info(destination_token_account)source_account = {key: str(value) if isinstance(value, Pubkey) else valuefor key, value in source_token_account_info._asdict().items()}destination_account = {key: str(value) if isinstance(value, Pubkey) else valuefor key, value in destination_token_account_info._asdict().items()}print("Mint Address:", mint.pubkey())print("\nSource Token Account Address:", source_token_account)print("Source Token Account:")print(json.dumps(source_account, indent=2))print("\nDestination Token Account Address:", destination_token_account)print("Destination Token Account:")print(json.dumps(destination_account, indent=2))print("\nTransaction Signature:", result.value)if __name__ == "__main__":asyncio.run(main())
Console
Click to execute the code.
Is this page helpful?