Skip to main content
Solana でトランザクションを送信する主な方法は 2 つあります。
  1. ステーク接続を使用する(デフォルト)
  2. Sender などの専用ランディングサービスを使用する(推奨)
この記事では、すべての Helius 有料プランでデフォルトとなっているステーク接続を使用する場合の、トランザクション最適化のベストプラクティスについて説明します。 ステーク接続は、レイテンシがビジネスにとって重要ではないユースケース(決済、ウォレット、ソーシャルアプリなど)に最適です。 専用の超低レイテンシ・トランザクションランディングサービスを求めている上級トレーダー(propAMM、スナイパー、コピートレーダー、清算ボット、アービトラージなど)は、Sender チュートリアルをご覧ください。

概要

Helius のステーク接続は、最小限の確認時間で 100% のトランザクション配信を保証します。ステーク接続でトランザクションのランディング率を最適化するため、次のベストプラクティスを推奨します。
  • 最新のブロックハッシュを取得する際は、コミットメント「confirmed」を使用する
  • 優先手数料を追加し、動的に計算する
  • コンピュートユニット(CU)の使用量を最適化する
  • maxRetries を 0 に設定し、堅牢な再試行ロジックを実装する
  • skipPreflight を true に設定して送信する(任意)
さらに詳しく知りたい場合は、このブログ記事で基本事項をすべて説明しています。

トレーダー向けの推奨最適化

レイテンシに敏感な取引ユースケースには、Sender の使用を推奨します。 ただし、ステーク接続を使用しており、可能な限り低いレイテンシを実現するように構成を最適化したい場合は、前述のベストプラクティスに加えて、次の最適化を推奨します。
  • クライアントサーバー(トランザクションの送信元として使用するマシン)は、米国東部または西ヨーロッパに配置してください。
  • Helius のトランザクション送信サーバーとコロケーションする場合は、FRA または PIT を選択してください。
  • バリデーターネットワークから遠いリージョン(中南米、南アフリカなど)からの送信は避けてください。
  • テールレイテンシを最小限に抑えるため、Helius のリージョンキャッシュをウォームアップしてください。
  • 必要なウォームアップスレッドはリージョンごとに 1 つだけです。それ以上増やしても効果はありません。
  • トランザクション送信時と同じエンドポイントおよび API キーを使用し、getHealth RPC 呼び出しを毎秒送信してください。
これらの効果を実感できるのは、経験豊富なトレーダーに限られます。一般的なアプリ開発者には、以下の「スマートトランザクションの送信」セクションに記載されたガイドラインに従うことを推奨します。
Raw Shreds (UDP) を使用すると、オンチェーンのトランザクションデータを可能な限り高速に取得できます。Helius Dashboard でサブスクライブしてください。

スマートトランザクションの送信

Helius の TypeScript SDK と Rust SDK は、どちらもスマートトランザクションを送信できます。この新しいメソッドは、確認ステータスを処理しながら、最適化されたトランザクションを構築して送信します。 トランザクションでプリフライトチェックをスキップするかどうかなど、トランザクションの送信オプションを設定できます。 最も基本的な使い方では、ユーザーはキーペアと実行したい命令を指定するだけで、残りは Helius が処理します。 Helius は次の処理を行います。
  • 最新のブロックハッシュを取得する
  • 初期トランザクションを構築する
  • 初期トランザクションをシミュレーションし、消費されたコンピュートユニット(CU)を取得する
  • 前のステップで消費された CU に一定の余裕を加えた値を CU 上限に設定する
  • Priority Fee API を介して Helius の推奨優先手数料を取得する
  • 優先手数料(CU あたりのマイクロランポート)を Helius の推奨手数料に設定する
  • 推奨手数料が数秒以内に変動する場合に備え、少額のバッファ手数料を追加する
  • 最適化されたトランザクションを構築して送信する
  • 成功した場合はトランザクション署名を返す
ステーク接続で推奨値以上を必須とすることで、Helius は高品質なトランザクションを送信でき、バリデーターによるレート制限を回避できます。
このメソッドは、Solana でトランザクションを構築、送信、ランディングする最も簡単な方法です。 Helius の推奨手数料を使用すると、いずれかの標準有料プランを利用する Helius ユーザーが送信したトランザクションはステーク接続経由でルーティングされ、ほぼ 100% のトランザクション配信と最小限のレイテンシが保証されます。

TypeScript SDK

sendSmartTransaction メソッドは、バージョン >= 1.3.2 の Helius TypeScript SDK で利用できます。SDK をより新しいバージョンに更新するには、npm update helius-sdk を実行してください。 この例では、任意のアカウントに SOL を送金します。sendSmartTransaction を使用し、プリフライトチェックをスキップせずに最適化されたトランザクションを送信します。

Rust SDK

send_smart_transaction メソッドは、バージョン >= 0.1.5 の Rust SDK で利用できます。SDK をより新しいバージョンに更新するには、cargo update helius を実行してください。 次の例では、任意のアカウントに 0.01 SOL を送金します。 send_smart_transaction を利用し、プリフライトチェックをスキップして、必要に応じて 2 回再試行する最適化済みトランザクションを送信します。

SDK を使用せずにトランザクションを送信する

いずれかの SDK を使用してスマートトランザクションを送信することを推奨しますが、SDK を使用せずに同じ機能を実現することもできます。 TypeScript SDK と Rust SDK はどちらもオープンソースであるため、スマートトランザクション送信機能の基盤となるコードをいつでも確認できます。

初期トランザクションを準備して構築する

まず、初期トランザクションを準備して構築します。これには、一連の命令を含む新しいトランザクションの作成、直近のブロックハッシュの追加、手数料支払者の割り当てが含まれます。 バージョン付きトランザクションでは、TransactionMessage を作成し、ルックアップテーブルがある場合はそれを使用してコンパイルします。 次に、新しいバージョン付きトランザクションを作成して署名します。次のステップでトランザクションをシミュレーションする際、トランザクションが署名済みである必要があるためです。 たとえば、バージョン付きトランザクションを準備する場合は、次のようにします。

トランザクションのコンピュートユニット(CU)使用量を最適化する

トランザクションのコンピュートユニット(CU)使用量を最適化するには、simulateTransaction RPC メソッドを使用してトランザクションをシミュレーションできます。 トランザクションをシミュレーションすると、使用された CU の量が返されるため、この値に応じてコンピュート上限を設定できます。 まず、目的の命令に加えてコンピュート上限を 140 万 CU に設定する命令を含むテストトランザクションを使用することを推奨します。 これは、トランザクションのシミュレーションを確実に成功させるためです。 例:
トランザクションが問題なく実行されるように、ある程度の余裕を追加することも推奨します。次のように設定できます。
次に、コンピュートユニット上限をこの値に設定する命令を作成し、命令の配列に追加します。

トランザクションをシリアライズしてエンコードする

これは比較的簡単です。 まず、トランザクションをシリアライズするために、Transaction 型と VersionedTransaction 型の両方に用意されている .serialize() メソッドを使用します。次に、bs58 パッケージを使用してトランザクションをエンコードします。 コードは bs58.encode(txt.serialize()); のようになります。

適切な優先手数料を設定する

まず、Priority Fee API を使用して優先手数料の見積もりを取得します。トランザクションを渡し、recommended パラメーターを介して Helius の推奨手数料を取得します。
次に、コンピュートユニット価格をこの値に設定する命令を作成し、既存の命令に追加します。

最適化されたトランザクションを構築して送信する

このステップは、最初のステップとほぼ同じです。ただし、コンピュートユニットの上限と価格を最適に設定する 2 つの命令を追加するため、初期命令の配列が変更されています。 次に、トランザクションを送信します。 プリフライトチェックを有効または無効にして送信したり、その他の送信オプションを変更したりしても問題ありません。すべての有料プランで、トランザクションはステーク接続経由でルーティングされます。

トランザクションステータスのポーリングと再ブロードキャスト

ステーク接続はトランザクションをリーダーに直接転送しますが、Banking Stage でトランザクションがドロップされる可能性は残ります。RPC による再試行に依存せず、独自の再ブロードキャストロジックを使用することを推奨します。
sendTransaction RPC メソッドには、RPC のデフォルトの再試行ロジックを上書きできる maxRetries パラメーターがあり、開発者は再試行プロセスをより細かく制御できます。 一般的なパターンは、getLatestBlockhash を介して現在のブロックハッシュを取得し、lastValidBlockHeight を保存して、ブロックハッシュが期限切れになるまでトランザクションを再試行することです。 ブロックハッシュが無効になった場合にのみトランザクションへ再署名することが重要です。そうしないと、両方のトランザクションがネットワークに受け入れられる可能性があります。 トランザクションを送信した後は、再試行する前に確認ステータスをポーリングし、ネットワークがトランザクションを処理および確認したかどうかを確認することが重要です。getSignatureStatuses RPC メソッドを使用して、トランザクションのリストの確認ステータスを調べます。 @solana/web3.js SDK の Connection クラスにも、複数の署名の現在のステータスを取得する getSignatureStatuses メソッドがあります。

sendSmartTransaction によるポーリングと再ブロードキャストの処理方法

sendSmartTransaction メソッドのタイムアウト時間は 60 秒です。ブロックハッシュは 150 スロットにわたって有効であり、各スロットが正確に 400ms であると仮定すると、トランザクションのブロックハッシュは 1 分後に無効になると合理的に想定できます。 このメソッドは、トランザクションを送信し、このタイムアウト時間を使用して署名をポーリングします。
txtSig には、直前に送信したトランザクションの署名が設定されます。 次に、このメソッドは pollTransactionConfirmation() メソッドを使用して、トランザクションの確認ステータスをポーリングします。このメソッドは、5 秒ごとに最大 3 回、トランザクションのステータスを確認します。 この時間内にトランザクションが確認されなかった場合は、エラーが返されます。