Solanaで支払いフローを構築する前に、5つの基本概念を理解する必要があります。ウォレット、ステーブルコイン、トークンアカウント、手数料、トランザクションです。Solanaの支払いは、複数通貨の決済システムに明確に対応しています。
| 従来の決済モデル | Solana | 説明 |
|---|---|---|
| 顧客ID / 口座番号 | ウォレットアドレス | アカウント保有者の一意の識別子 |
| 通貨(USD、EUR) | トークンミント(USDG、USDC) | 転送される資産の種類 |
| 通貨別残高 | トークンアカウント(ATA) | 特定の通貨/ミントの残高を保持 |
銀行の顧客が単一のIDを持ちながら各通貨の残高を別々に保持するのと同様に、Solanaウォレットは1つのアドレスを持ちますが、保有する各資産ごとに個別のトークンアカウントを持ちます。各コンポーネントを詳しく見ていきましょう。
ウォレット:送信者と受信者
すべての支払いには2つの当事者が関与し、それぞれがウォレットアドレスで識別されます。これは一意の32バイトの公開鍵です(例:7EcDhS...)。
- 送信者:支払いを開始するウォレット。十分なステーブルコインアカウント残高を保持し、トランザクションに署名する必要があります。
- 受信者:送信先のウォレット。署名や既存の残高を保持する必要はありません。
- 手数料支払者:オプションの手数料支払者ウォレット。ユーザー間のステーブルコインのみのトランザクションを補助または有効化するために使用できます。
ウォレットアドレスは銀行口座番号のようなものと考えてください。公開されており、共有しても安全で、資金の送受信に必要です。
ステーブルコイン
ステーブルコインはSolanaでは「トークン」と呼ばれます。トークンはネットワーク上の資産タイプを表します。各トークンには「ミントアドレス」と呼ばれる一意の識別子があります。決済システムを構築する際、やり取りする資産を識別するためにこれらのミントアドレスを参照します。以下は、メインネット上の一般的なステーブルコインミントの例です。
| トークン | 発行者 | ミントアドレス |
|---|---|---|
| USDC | Circle | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v |
| USDT | Tether | Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB |
| PYUSD | PayPal | 2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo |
| USDG | Paxos | 2u1tszSeqZ3qBWF3uNGPFc8TzMk2tdiwknnRMWGWjGWH |
Solanaのステーブルコインに関する詳細については、ステーブルコインソリューションページをご覧ください。
支払いを受け付ける際は、必ずミントアドレスとToken Programを検証してください。トークンは名前を共有できますが、発行者と基礎資産が異なる場合があります。
トークンアカウント
ウォレットはトークンを直接保持しません。代わりに、各ウォレットは保有する各種類のトークンに対してtoken accountの権限を持ちます。支払いは、送信者のtoken accountから同じミントの受信者のtoken accountへトークンを転送することで行われます。
トークンアカウント
Associated Token Accountは、特定のウォレットとミントに紐付けられた決定論的なtoken accountです。ウォレットアドレスとミントが与えられると、ATAアドレスは常に同じになります。
- ミントごとに1つのATA。ウォレットはUSDC用に1つ、USDT用に1つなど、正確に1つのATAを持ちます。
- 受信前に存在する必要がある。存在しないATAにトークンを送信することはできません。
- 通常は送信者が作成。受信者のATAが存在しない場合、送信者は支払いトランザクションの一部としてそれを作成できます。
import { findAssociatedTokenPda } from "@solana-program/token";const [receiverATA] = await findAssociatedTokenPda({mint: USDG_MINT_ADDRESS,owner: receiverWallet.address,tokenProgram: TOKEN_PROGRAM_ADDRESS});
Token Programs
Solanaでは、プログラムはアカウントの状態を管理する実行可能なロジックです。Token accountsはToken Programによって管理されます。これは、転送を検証し、残高をアトミックに更新するオンチェーンコードです。
Solanaには2つのToken Programsがあります。
| プログラム | アドレス | このプログラムを使用する トークンの例 |
|---|---|---|
| Token Program | TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA | USDC、USDT |
| Token-2022 | TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb | PYUSD、USDG |
Token-2022(「Token Extensions」とも呼ばれる)は、転送フック、転送手数料、機密転送などの機能を追加します。両方のプログラムは基本的な転送では同様に動作しますが、ATAを導出する際には正しいプログラムを使用する必要があります。
なぜこれが重要なのか
トークンの作成に使用されるToken Programは、トークンのinstructionsとアカウント状態を管理します。間違ったプログラムを使用すると、トークンを転送できなくなります。
ATAは3つの入力から導出されます:wallet + mint + token_program。間違ったプログラムを使用すると、まったく異なるアドレスが生成されます:
import {findAssociatedTokenPda,TOKEN_PROGRAM_ADDRESS} from "@solana-program/token";import { TOKEN_2022_PROGRAM_ADDRESS } from "@solana-program/token-2022";// USDC uses Token Programconst [usdcAta] = await findAssociatedTokenPda({mint: USDC_MINT,owner: walletAddress,tokenProgram: TOKEN_PROGRAM_ADDRESS // ✓ Correct});// ❌ This will produce a different address because it uses the wrong programconst [wrongUsdcAta] = await findAssociatedTokenPda({mint: USDC_MINT,owner: walletAddress,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS // ❌ Wrong program});// PYUSD uses Token-2022const [pyusdAta] = await findAssociatedTokenPda({mint: PYUSD_MINT,owner: walletAddress,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS // ✓ Correct});
間違ったプログラムでATAを導出すると、無効なアドレスが生成されます。常にプログラムをトークンのmintに一致させてください。
同じ原則が転送instructionsにも適用されます。各トークンプログラムには独自の転送instructionがあり、正しいものを呼び出す必要があります:
import { getTransferInstruction } from "@solana-program/token";import { getTransferInstruction as getTransferInstruction22 } from "@solana-program/token-2022";// For USDC (Token Program)const usdcTransferIx = getTransferInstruction({source: senderUsdcAta,destination: receiverUsdcAta,authority: senderWallet,amount: 1_000_000n // 1 USDC (6 decimals)});// For PYUSD (Token-2022)const pyusdTransferIx = getTransferInstruction22({source: senderPyusdAta,destination: receiverPyusdAta,authority: senderWallet,amount: 1_000_000n // 1 PYUSD (6 decimals)});// *Note*: Most token program JS Client functions include the ability// to specify the token program address. Generally, defining it is a// good practice to ensure you are fully aware of the program you are usingconst usdcTransferIx2 = getTransferInstruction({source: senderUsdcAta,destination: receiverUsdcAta,authority: senderWallet,amount: 1_000_000n // 1 USDC (6 decimals)},{ tokenProgram: TOKEN_PROGRAM_ADDRESS });
間違ったプログラムに転送instructionを送信すると失敗します。プログラムは、関与するtoken accountsを所有していることを検証します。Token Programによって作成されたアカウントはToken-2022経由で転送できず、その逆も同様です。
トークンまたはtoken accountが使用するプログラムを確認するには、mintまたはtoken
accountを取得し、そのownerフィールドを確認します:
import { createSolanaRpc, address } from "@solana/kit";const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");const accountInfo = await rpc.getAccountInfo(address(mintAddress)).send();// The owner field tells you which program manages this tokenconst tokenProgram = accountInfo.value?.owner;// Returns: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA (Token Program)// or: TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb (Token-2022)
決済アプリケーションの場合、サポートされている各トークンと一緒に正しいプログラムアドレスを保存します:
const SUPPORTED_TOKENS = {USDC: {mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",program: TOKEN_PROGRAM_ADDRESS,decimals: 6},PYUSD: {mint: "2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo",program: TOKEN_2022_PROGRAM_ADDRESS,decimals: 6}};
Token Extensions
Token Extensions Program(Token 2022)は、extensionsと呼ばれる追加のinstructionsを通じてより多くの機能を提供します。Extensionsは、トークンミントまたはtoken accountに追加できるオプション機能です。
Token Extensionsの詳細については、Token Extensionsのドキュメントを参照してください。
手数料
Solanaの支払いには、最大3つのコスト要素が含まれます。
| 手数料タイプ | SOL | USD(推定) | 発生タイミング |
|---|---|---|---|
| 基本トランザクション手数料 | 5,000 lamports* | ~$0.0007 | すべてのトランザクション(複数の支払いをバンドルして償却) |
| 優先手数料 | 変動 | 変動 | オプション。混雑時のより高速な処理 |
| アカウント作成(rent) | ~0.0029 SOL | ~$0.40 | 新しいtoken accountを作成する場合のみ |
支払いあたりの総コスト: ほとんどの転送で$0.001未満。新しいtoken accountを作成する場合は、合計で約$0.40が必要です。
Solanaはローカル手数料市場を使用しています。各プログラムのトランザクションは、同じ状態を対象とする他のトランザクションとのみ競合します。つまり、ネットワークの他の場所で高いアクティビティが発生している期間でも、支払い手数料は低く予測可能なままです。rentコストも近い将来50%削減される予定です。
ユーザーがSOLとやり取りする必要がないように、手数料を完全に抽象化できます。実装パターンについては、手数料の抽象化を参照してください。
トランザクションとinstructions
トランザクションは、Solana上の実行のアトミック単位です。すべての操作が成功するか、いずれも成功しないかのどちらかです。各トランザクションには1つ以上のinstructionsが含まれており、これらは個別のコマンド(例:「10 USDCを転送」、「token accountを作成」)です。
典型的な支払いトランザクションには、2つのinstructionsが含まれる場合があります。受信者のtoken accountを作成し(必要な場合)、次にトークンを転送します。両方はアトミックに実行され、部分的な状態は発生しません。支払い処理で説明するように、複数の支払いを1つのトランザクションにバンドルして、コストを削減しスループットを向上させることができます。
まとめ
典型的な支払いフロー:
- 入力の収集。送信者と受信者のウォレットアドレス、および転送されるトークンのミントアドレスを取得します。
- ATAの導出。両者のトークンアカウントを決定します。
- 構築と署名。必要な転送instructionsを含むトランザクションを構築し、送信者の鍵で署名します。
- 送信と確認。トランザクションは1秒以内に完了します。
次のステップ
* lamportはSOLの最小単位で、0.000000001 SOLに相当します
Is this page helpful?