> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Solanaトランザクションの送信方法

> 本番レベルのSolanaトランザクション送信ワークフローを構築するためのステップバイステップガイド。計算最適化、優先手数料、確認戦略を学びます。

<Tip>
  これは**基本的な**トランザクション送信パスです — 送信ごとに課金され、信頼性が生のスピードよりも重要な場合（支払い、ウォレット、アプリ）に最適です。取引を行い、最小の遅延を求める場合は、代わりに[Helius Sender](/ja/sending-transactions/sender)を使用してください。
</Tip>

独自のトランザクション送信ロジックを構築することは、アプリケーションの最大限のパフォーマンス、コントロール、および信頼性を確保するための最良の方法です。[Helius SDK](/ja/sdks)は、開始するための便利なラッパーを提供しますが、本番システムにはこの手動ワークフローの理解と実装を強くお勧めします。

このガイドでは、独自のソリューションを構築するために必要な手順を説明します。

### 手動ワークフロー

手動でトランザクションを送信するには、次のステップを実行します。

<Steps>
  <Step title="初期トランザクションの構築">
    指示を組み立て、トランザクションに署名してシミュレーションできるようにします。
  </Step>

  <Step title="計算ユニットの最適化">
    トランザクションをシミュレートして、必要な正確なCUを決定し、小さな余裕を追加します。
  </Step>

  <Step title="優先手数料の追加">
    Helius Priority Fee APIから手数料の見積もりを取得し、それをトランザクションに追加します。
  </Step>

  <Step title="送信と再送信">
    最終トランザクションを送信し、確認を処理するための堅牢なポーリング戦略を実装します。
  </Step>
</Steps>

<Info>
  Helius SDKはオープンソースです。`sendSmartTransaction`メソッドの基礎コードを[Node.js SDK](https://github.com/helius-labs/helius-sdk)および[Rust SDK](https://github.com/helius-labs/helius-rust-sdk)で確認して、このワークフローの本番レベルの実装を見てください。
</Info>

### 1. 初期トランザクションの構築

まず、トランザクションに含めるすべての指示を集めます。それから、`Transaction`または`VersionedTransaction`オブジェクトを作成します。また、最近のブロックハッシュを取得する必要があります。

この例では、バージョン付きトランザクションを準備しています。この段階で、次のステップでシミュレーションできるようにするために署名する必要があります。

```typescript theme={"system"}
import {
  Connection,
  Keypair,
  TransactionMessage,
  VersionedTransaction,
  SystemProgram,
  LAMPORTS_PER_SOL,
} from "@solana/web3.js";

const connection = new Connection("YOUR_RPC_URL");
const fromKeypair = Keypair.generate(); // Assume this is funded
const toPubkey = Keypair.generate().publicKey;

// 1. Build your instructions
const instructions = [
  SystemProgram.transfer({
    fromPubkey: fromKeypair.publicKey,
    toPubkey: toPubkey,
    lamports: 0.001 * LAMPORTS_PER_SOL,
  }),
];

// 2. Get a recent blockhash
const { blockhash } = await connection.getLatestBlockhash();

// 3. Compile the transaction message
const messageV0 = new TransactionMessage({
  payerKey: fromKeypair.publicKey,
  recentBlockhash: blockhash,
  instructions,
}).compileToV0Message();

// 4. Create and sign the transaction
const transaction = new VersionedTransaction(messageV0);
transaction.sign([fromKeypair]);
```

### 2. 計算ユニット（CU）の使用を最適化

手数料の無駄を避けたり、トランザクションの失敗を避けるために、計算ユニット（CU）制限を可能な限り正確に設定する必要があります。これを実現するには、[`simulateTransaction`](/ja/api-reference/rpc/http/simulatetransaction) RPCメソッドを使用してトランザクションをシミュレートします。

シミュレーション自体が成功するように最初に高いCU制限でシミュレーションし、その後、応答から得られる`unitsConsumed`を使用して実際の制限を設定するのが最良の方法です。

```typescript theme={"system"}
import { ComputeBudgetProgram } from "@solana/web3.js";

// Create a test transaction with a high compute limit to ensure simulation succeeds
const testInstructions = [
    ComputeBudgetProgram.setComputeUnitLimit({ units: 1_400_000 }),
    ...instructions, // Your original instructions
];
const testMessage = new TransactionMessage({
    payerKey: fromKeypair.publicKey,
    recentBlockhash: blockhash,
    instructions: testInstructions,
}).compileToV0Message();
const testTransaction = new VersionedTransaction(testMessage);
testTransaction.sign([fromKeypair]);

// Simulate the transaction to get the exact CUs consumed
const { value: simulationResult } = await connection.simulateTransaction(testTransaction);

if (!simulationResult.unitsConsumed) {
  throw new Error("Simulation failed to return unitsConsumed");
}

// Add a 10% buffer to the CU estimate
const computeUnitLimit = Math.ceil(simulationResult.unitsConsumed * 1.1);

// Create the instruction to set the CU limit
const setCuLimitInstruction = ComputeBudgetProgram.setComputeUnitLimit({
    units: computeUnitLimit,
});
```

これで、計算制限を正確に設定する命令が得られました。これを最終トランザクションに追加します。

### 3. 適切な優先手数料を設定

次に、トランザクションに追加する最適な優先手数料を決定します。現行のネットワーク状況に基づいたリアルタイムの見積もりを得るために、Heliusの[Priority Fee API](/ja/priority-fee-api)を使用するのが最良です。

`getPriorityFeeEstimate` RPCメソッドを呼び出す必要があります。Heliusのステークされた接続を介しての含まれる確率を高めるために、`recommended: true`オプションを使用してください。

```typescript theme={"system"}
// The transaction needs to be serialized and base58 encoded
const serializedTransaction = bs58.encode(transaction.serialize());

const response = await fetch("YOUR_RPC_URL", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
        jsonrpc: "2.0",
        id: "1",
        method: "getPriorityFeeEstimate",
        params: [
            {
                // Pass the serialized transaction
                transaction: serializedTransaction, 
                // Use 'recommended' for Helius's staked connections
                options: { recommended: true },
            },
        ],   
    }),
});
const data = await response.json();

if (!data.result || !data.result.priorityFeeEstimate) {
    throw new Error("Failed to get priority fee estimate");
}

const priorityFeeEstimate = data.result.priorityFeeEstimate;

// Create the instruction to set the priority fee
const setPriorityFeeInstruction = ComputeBudgetProgram.setComputeUnitPrice({
    microLamports: priorityFeeEstimate,
});
```

### 4. 構築、送信、確認

新しい計算予算命令で最終トランザクションを組み立てて送信し、着地が確認されるまでの堅牢なポーリングメカニズムを実装します。

<Warning>
  RPCプロバイダーのデフォルトの再試行ロジック（[`maxRetries`](/ja/api-reference/rpc/http/sendtransaction)での`sendTransaction`）に依存しないでください。Heliusのステークされた接続があなたのトランザクションをリーダーに直接送信しますが、それでもドロップされる可能性があります。信頼性のある確認のために、独自の再送信ロジックを実装する必要があります。
</Warning>

一般的なパターンは、ブロックハッシュが失効するまで定期的に同じトランザクションを再送信することです。\*\*新しいブロックハッシュを取得する場合にのみトランザクションに再署名してください。\*\*同じブロックハッシュで再署名すると、重複したトランザクションが確認される可能性があります。

```typescript theme={"system"}
// 1. Add the new instructions to your original set
const finalInstructions = [
  setCuLimitInstruction,
  setPriorityFeeInstruction,
  ...instructions,
];

// 2. Re-build and re-sign the transaction with the final instructions
const { blockhash: latestBlockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();

const finalMessage = new TransactionMessage({
  payerKey: fromKeypair.publicKey,
  recentBlockhash: latestBlockhash,
  instructions: finalInstructions,
}).compileToV0Message();

const finalTransaction = new VersionedTransaction(finalMessage);
finalTransaction.sign([fromKeypair]);

// 3. Send the transaction
const signature = await connection.sendTransaction(finalTransaction, {
  skipPreflight: true, // Optional: useful for bypassing client-side checks
});

// 4. Implement a polling loop to confirm the transaction
let confirmed = false;
while (!confirmed) {
    const statuses = await connection.getSignatureStatuses([signature]);
    const status = statuses && statuses.value && statuses.value[0];

    if (status && (status.confirmationStatus === 'confirmed' || status.confirmationStatus === 'finalized')) {
        console.log('Transaction confirmed!');
        confirmed = true;
    }

    // Check if the blockhash has expired
    const currentBlockHeight = await connection.getBlockHeight();
    if (currentBlockHeight > lastValidBlockHeight) {
        console.log('Blockhash expired, transaction failed.');
        break;
    }
    
    // Wait for a short period before polling again
    await new Promise(resolve => setTimeout(resolve, 2000)); 
}
```

この例は基本的なポーリングループを提供します。本番用アプリケーションでは、異なる確認ステータスや潜在的なタイムアウトの処理など、より高度なロジックが必要です。

## サンドイッチ攻撃からの保護

統計的にサンドイッチ攻撃に関連付けられたバリデーターからトランザクションをルーティングするため、RPC URLに`mev-protect=true`クエリパラメータを追加します。トランザクションロジックを変更する必要はありません。

```
https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY&mev-protect=true
```

<Card title="MEV保護" icon="shield-halved" href="/ja/sending-transactions/mev-protect">
  MEV保護がどのように機能するか、どのメソッドをサポートしているか、そのトレードオフを確認してください。
</Card>

## トランザクションでリベートを獲得する

あなたのトランザクションが生み出すMEVの一部をSOLで自動的に支払われる形で獲得することができます。トランザクションロジックを変更する必要はありません。

<Card title="トランザクションリベート" icon="coins" href="/ja/sending-transactions/backrun-rebates">
  `sendTransaction`コールにパラメータを1つ追加するだけで、SOLリベートの獲得を開始できます。
</Card>

## 関連メソッド

<CardGroup cols={2}>
  <Card title="sendTransaction" href="/ja/api-reference/rpc/http/sendtransaction">
    署名済みトランザクションをネットワークに送信
  </Card>

  <Card title="simulateTransaction" href="/ja/api-reference/rpc/http/simulatetransaction">
    トランザクションをシミュレートして計算ユニットを見積もる
  </Card>

  <Card title="getSignatureStatuses" href="/ja/api-reference/rpc/http/getsignaturestatuses">
    トランザクションの確認ステータスを確認
  </Card>

  <Card title="getLatestBlockhash" href="/ja/api-reference/rpc/http/getlatestblockhash">
    トランザクション署名のための最新のブロックハッシュを取得
  </Card>

  <Card title="getBlockHeight" href="/ja/api-reference/rpc/http/getblockheight">
    失効チェックのために現在のブロックの高さを取得
  </Card>
</CardGroup>
