Solanaのメモプログラムを使用すると、請求書番号、注文ID、またはカスタム参照を任意の支払いに添付できます。これらのメモはオンチェーンに永続的に記録され、トランザクションログに表示されるため、支払いを内部システムと簡単に照合できます。
仕組み
メモプログラムは、トランザクションのログにテキストを書き込みます。これらのログはエクスプローラーやRPCプロバイダーによってインデックス化されるため、支払いの照合のためにメモを検索できます。
コア支払いの概念については、Solanaでの支払いの仕組みを参照してください。
メモを追加するには、instructionsを直接構築する必要があり、これによりトランザクションに含まれる内容を制御できます。
以下の手順では、コアフローを示します。完全な実行可能なコードについては、デモを参照してください。
メモプログラムのインポート
@solana-program/memoからgetAddMemoInstructionをインポートして、メモinstructionsを作成します。
転送instructionの作成
ソースATA、宛先ATA、権限(署名者)、および基本単位での金額を指定して、トークン転送instructionを作成します。
メモinstructionの作成
メッセージを含むメモinstructionを作成します。このメッセージは、トランザクションのプログラムログに表示されます。
メモ付きトランザクションの送信
転送instructionとメモinstructionを1つのトランザクションにまとめます。
トランザクションログでメモを確認する
トランザクションが確認されたら、それを取得してログ内のメモを確認します。メモはMemoプログラムからのログメッセージとして表示されます。
Payment with Memo
import { getAddMemoInstruction } from "@solana-program/memo";const transferInstruction = getTransferInstruction({source: senderAta,destination: recipientAta,authority: sender.address,amount: 250_000n});const memoInstruction = getAddMemoInstruction({memo: "Payment for services rendered - Invoice #12345"});const signature = await client.transaction.prepareAndSend({authority: sender,instructions: [transferInstruction, memoInstruction],version: 0});const transaction = await client.runtime.rpc.getTransaction(signature, {encoding: "jsonParsed",maxSupportedTransactionVersion: 0}).send();console.log("Transaction logs with Memo:");console.log(transaction?.meta?.logMessages);
Example Transaction Logs
"Program TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb invoke [1]","Program log: Instruction: Transfer","Program TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb consumed 1682 of 200000 compute units","Program TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb success","Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr invoke [1]",'Program log: Memo (len 46): "Payment for services rendered - Invoice #12345"',"Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr consumed 18097 of 198318 compute units","Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr success","Program ComputeBudget111111111111111111111111111111 invoke [1]","Program ComputeBudget111111111111111111111111111111 success"
デモ
Demo
// Generate keypairs for sender and recipientconst sender = (await generateKeypair()).signer;const recipient = (await generateKeypair()).signer;console.log("Sender Address:", sender.address);console.log("Recipient Address:", recipient.address);// Demo Setup: Create client, mint account, token accounts, and fund with initial tokensconst { client, mint } = await demoSetup(sender, recipient);console.log("\nMint Address:", mint.address);// Derive the Associated Token Accounts addresses (ATAs) for sender and recipientconst [senderAta] = await findAssociatedTokenPda({mint: mint.address,owner: sender.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});const [recipientAta] = await findAssociatedTokenPda({mint: mint.address,owner: recipient.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});console.log("Sender Token Account:", senderAta.toString());console.log("Recipient Token Account:", recipientAta.toString());// =============================================================================// Token Payment with Memo Demo// =============================================================================// Create instruction to transfer tokens from sender to recipient// Transferring 250,000 base units = 0.25 tokens (with 6 decimals)const transferInstruction = getTransferInstruction({source: senderAta,destination: recipientAta,authority: sender.address,amount: 250_000n // 0.25 tokens});// Create instruction to add a memo to the transactionconst memoInstruction = getAddMemoInstruction({memo: "Payment for services rendered - Invoice #12345"});// Prepare and send transaction with both transfer and memo using @solana/clientconst signature = await client.transaction.prepareAndSend({authority: sender,instructions: [transferInstruction, memoInstruction],version: 0});console.log("\n=== Token Payment with Memo Complete ===");console.log("Transaction Signature:", signature.toString());// Fetch final token account balances using @solana/client SPL token helperconst splToken = client.splToken({mint: mint.address,tokenProgram: "auto"});const senderBalance = await splToken.fetchBalance(sender.address);const recipientBalance = await splToken.fetchBalance(recipient.address);console.log("\nSender Token Account Balance:", senderBalance);console.log("Recipient Token Account Balance:", recipientBalance);// Fetch transaction details to view the memo in the logsconst transaction = await client.runtime.rpc.getTransaction(signature, {encoding: "jsonParsed",maxSupportedTransactionVersion: 0}).send();console.log("\nTransaction logs with Memo:");console.log(transaction?.meta?.logMessages);// =============================================================================// Demo Setup Helper Function// =============================================================================
Console
Click to execute the code.
Is this page helpful?