前のセクションでは、アカウントをフェッチすることで Solanaネットワークからデータを読み取る 方法を学びました。Solanaネットワークへのデータの書き込みには トランザクションが必要です。トランザクションには1つ以上の instructionsが含まれており、各instructionはプログラムを呼び出します。
プログラムは各instructionのビジネスロジックを定義します。トランザクションを送信すると、SolanaランタイムはトランザクションのinstructionsをCONTENT順に実行します。トランザクションはアトミックです。トランザクション内のすべてのinstructionが成功するか、トランザクション全体が失敗するかのどちらかです。
このセクションの例では、以下の方法を示します:
- アカウント間のSOL転送
- 新しいトークンミントの作成
SOLの転送
以下の例では、あるアカウントから別のアカウントにSOLを転送します。アカウントのオーナーとして指定されたプログラムのみが、アカウントのデータを変更したり、残高からlamportを差し引いたりすることができます。ウォレットアカウントはSystem Programによって所有されているため、ウォレットアカウント間でSOLを転送するには、System Programのtransferinstructionを呼び出すinstructionが必要です。送信元アカウントもトランザクションに署名する必要があります。
import { createClient, generateKeyPairSigner, lamports } from "@solana/kit";import { solanaRpc, rpcAirdrop } from "@solana/kit-plugin-rpc";import { generatedPayer, airdropPayer } from "@solana/kit-plugin-signer";import { getTransferSolInstruction } from "@solana-program/system";const client = await createClient().use(generatedPayer()).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900"})).use(rpcAirdrop()).use(airdropPayer(lamports(1_000_000_000n)));const receiver = await generateKeyPairSigner();const transferInstruction = getTransferSolInstruction({source: client.payer,destination: receiver.address,amount: lamports(10_000_000n)});const result = await client.sendTransaction([transferInstruction]);console.log("Transaction Signature:", result.context.signature);const { value: senderBalance } = await client.rpc.getBalance(client.payer.address).send();const { value: receiverBalance } = await client.rpc.getBalance(receiver.address).send();console.log("Sender Balance:", senderBalance);console.log("Receiver Balance:", receiverBalance);
ローカルテストvalidator用のKitクライアントを作成します。このスニペットはペイヤー署名者を追加し、ローカルRPCエンドポイントに接続し、エアドロップを有効にして、転送用のテストSOLでペイヤーに資金を提供します。
const client = await createClient().use(generatedPayer()).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900"})).use(rpcAirdrop()).use(airdropPayer(lamports(1_000_000_000n)));
レシーバーの署名者を生成します。送信者はclient.payerで、generatedPayer()によって作成され、airdropPayer()によって資金が提供されました。
const receiver = await generateKeyPairSigner();
getTransferSolInstruction()ヘルパーはSystem Program
instructionsを作成します。このinstructionsは、source署名者からdestinationアドレスへ、指定されたamountのlamportsをSOLとして転送します。
const transferInstruction = getTransferSolInstruction({source: client.payer,destination: receiver.address,amount: lamports(10_000_000n)});
instructionsの配列を指定してclient.sendTransaction()を呼び出します。Kitクライアントはinstructionsを1つのトランザクションにまとめ、instructionsに付加された署名者で署名し、トランザクションを送信して確認を待ちます。
const result = await client.sendTransaction([transferInstruction]);console.log("Transaction Signature:", result.context.signature);
トランザクションが確認された後、client.rpc を使用して両方の残高を取得します。
const { value: senderBalance } = await client.rpc.getBalance(client.payer.address).send();const { value: receiverBalance } = await client.rpc.getBalance(receiver.address).send();
トークンを作成する
以下の例では、Token Extensions Program を使用して新しいトークン mint account を作成します。mint account とは、小数点以下の桁数、供給量、mint 権限、凍結権限などのトークンのグローバル設定を定義するアカウントです。
mint account を作成するには、2つのinstructionsが必要です:
- System Program を呼び出して、Token Extensions Program が所有する新しいアカウントを作成します。
- Token Extensions Program を呼び出して、そのアカウントを mint として初期化します。
import { createClient, generateKeyPairSigner, lamports } from "@solana/kit";import { solanaRpc, rpcAirdrop } from "@solana/kit-plugin-rpc";import { generatedPayer, airdropPayer } from "@solana/kit-plugin-signer";import { getCreateAccountInstruction } from "@solana-program/system";import {fetchMint,getInitializeMintInstruction,getMintSize,TOKEN_2022_PROGRAM_ADDRESS} from "@solana-program/token-2022";const client = await createClient().use(generatedPayer()).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900"})).use(rpcAirdrop()).use(airdropPayer(lamports(1_000_000_000n)));const mint = await generateKeyPairSigner();const space = BigInt(getMintSize());const rent = await client.rpc.getMinimumBalanceForRentExemption(space).send();const createAccountInstruction = getCreateAccountInstruction({payer: client.payer,newAccount: mint,space,lamports: rent,programAddress: TOKEN_2022_PROGRAM_ADDRESS});const initializeMintInstruction = getInitializeMintInstruction({mint: mint.address,decimals: 2,mintAuthority: client.payer.address,freezeAuthority: client.payer.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});const result = await client.sendTransaction([createAccountInstruction,initializeMintInstruction]);console.log("Mint Address:", mint.address);console.log("Transaction Signature:", result.context.signature);const mintAccount = await fetchMint(client.rpc, mint.address);console.log("Mint Account:", mintAccount);
Kitクライアントを作成してファンドし、新しいmint accountのアドレスとして使用する署名者を生成します。クライアントのペイヤーがアカウント作成に資金を提供し、トランザクション手数料を支払います。
const client = await createClient().use(generatedPayer()).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900"})).use(rpcAirdrop()).use(airdropPayer(lamports(1_000_000_000n)));const mint = await generateKeyPairSigner();
mint accountのサイズをバイト単位で計算し、そのデータをアカウントに保存するために必要なlamportsを計算するRPCリクエストを行います。この必要な残高はrentと呼ばれます。
const space = BigInt(getMintSize());const rent = await client.rpc.getMinimumBalanceForRentExemption(space).send();
最初のinstructionはSystem
Programを呼び出します。このinstructionはpayerを使用してnewAccountに資金を提供し、mint
accountのspaceを割り当て、rent免除に必要なlamportsを転送し、programAddressに所有権を割り当てます。
const createAccountInstruction = getCreateAccountInstruction({payer: client.payer,newAccount: mint,space,lamports: rent,programAddress: TOKEN_2022_PROGRAM_ADDRESS});
2番目のinstructionはToken Extensions
Programを呼び出します。このinstructionはmintアドレスをdecimalsの値、mintAuthority、freezeAuthorityで初期化し、mint
accountを所有するtokenProgramを指定します。
const initializeMintInstruction = getInitializeMintInstruction({mint: mint.address,decimals: 2,mintAuthority: client.payer.address,freezeAuthority: client.payer.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});
両方のinstructionsを1つのトランザクションで送信します。mint accountが存在しないとToken Extensions Programがミントデータをアカウントに書き込めないため、アカウント作成instructionはミント初期化instructionより前に記述する必要があります。
const result = await client.sendTransaction([createAccountInstruction,initializeMintInstruction]);
トランザクションが確認された後、mint accountを取得します。
const mintAccount = await fetchMint(client.rpc, mint.address);console.log("Mint Account:", mintAccount);
Is this page helpful?