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

# simulateTransaction

> 模拟发送交易

## 参数

<ResponseField name="transaction" type="string" required>
  要模拟的交易，以 base-64 编码的字符串表示
</ResponseField>

<ResponseField name="config" type="object" optional>
  包含以下内容的配置对象：

  <ResponseField name="sigVerify" type="boolean" optional>
    如果为 true，验证交易签名
  </ResponseField>

  <ResponseField name="commitment" type="string" optional>
    Commitment 级别（processed、confirmed、finalized）
  </ResponseField>

  <ResponseField name="encoding" type="string" optional>
    交易的编码格式（base58、base64、json）
  </ResponseField>

  <ResponseField name="replaceRecentBlockhash" type="boolean" optional>
    如果为 true，将交易的近期 blockhash 替换为最新的 blockhash
  </ResponseField>

  <ResponseField name="accounts" type="object" optional>
    账户配置对象，包含：

    <ResponseField name="encoding" type="string" optional>
      账户数据的编码格式（base58、base64、json）
    </ResponseField>

    <ResponseField name="addresses" type="array" optional>
      要返回数据的账户地址数组
    </ResponseField>
  </ResponseField>

  <ResponseField name="minContextSlot" type="number" optional>
    请求可被评估的最小 slot
  </ResponseField>
</ResponseField>

## 响应

<ResponseField name="result" type="object">
  包含以下内容的对象：

  <ResponseField name="err" type="string | null">
    如果交易模拟失败则为错误信息，成功则为 null
  </ResponseField>

  <ResponseField name="logs" type="array">
    交易指令在执行期间输出的日志消息数组
  </ResponseField>

  <ResponseField name="accounts" type="array" optional>
    带有数据的账户数组（如果已请求）
  </ResponseField>

  <ResponseField name="unitsConsumed" type="number" optional>
    交易消耗的计算单元数量
  </ResponseField>

  <ResponseField name="returnData" type="object" optional>
    模拟的程序返回数据
  </ResponseField>
</ResponseField>

## 代码示例

### 基本请求

```bash theme={null}
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "simulateTransaction",
  "params": [
    "4hXTCkRzt9WyecNzV1XPgCDfGAZzQKNxLXgynz5QDuWWPSAZBZSHptvWRL3BjCvzUXRdKvHL2b7yGrRQcWyaqsaBCncVG7BFggS8w9snUts67BSh3EqKpXLUm5UMHfD7ZBe9GhARjbNQMLJ1QD3Spr6oMTFNhyKNMr3WNFCrXgDS7uV7u",
    {
      "sigVerify": false,
      "commitment": "confirmed",
      "encoding": "base64"
    }
  ]
}'
```

### 使用 web3.js

```typescript theme={null}
import { Connection, Transaction, PublicKey, SystemProgram } from '@solana/web3.js';

const connection = new Connection('https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY');

// Create and simulate transaction
const transaction = new Transaction().add(
  SystemProgram.transfer({
    fromPubkey: new PublicKey('83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri'),
    toPubkey: new PublicKey('J7rBdM6AecPDEZp8aPq5tPmsPzPhQG4HD6YtAcQBDfJj'),
    lamports: 1000000000
  })
);

const simulation = await connection.simulateTransaction(transaction);
console.log('Simulation result:', simulation);

// Simulate transaction with analysis
async function simulateTransactionWithAnalysis(
  transaction: Transaction,
  config: { 
    sigVerify?: boolean;
    commitment?: string;
    replaceRecentBlockhash?: boolean;
  }
) {
  const simulation = await connection.simulateTransaction(transaction, config);
  
  return {
    simulation: {
      success: !simulation.value.err,
      error: simulation.value.err,
      logs: simulation.value.logs,
      unitsConsumed: simulation.value.unitsConsumed
    },
    transaction: {
      recentBlockhash: transaction.recentBlockhash,
      feePayer: transaction.feePayer?.toBase58(),
      instructions: transaction.instructions.length
    },
    metadata: {
      timestamp: Date.now(),
      commitment: config.commitment
    }
  };
}
```

## 注意事项

1. 模拟发送交易但不实际发送
2. 响应包含执行日志和错误信息
3. 模拟在当前状态上执行
4. 不会持久化任何状态变化
5. 对于测试和调试交易非常有用

## 最佳实践

1. 在发送真实交易之前使用模拟
2. 检查计算单元消耗
3. 分析程序日志中的错误
4. 模拟后验证账户状态
5. 适当处理模拟错误

## 常见错误

| 错误码    | 消息                            | 解决方案                  |
| ------ | ----------------------------- | --------------------- |
| -32601 | Method not found              | 验证是否连接到 Solana RPC 节点 |
| -32602 | Invalid params                | 检查交易格式和编码             |
| -32003 | Transaction simulation failed | 验证交易有效性和账户余额          |
| -32004 | Blockhash not found           | 使用更近期的 blockhash      |
| -32005 | Node is behind                | 尝试其他 RPC 节点           |

## 用例

1. **交易分析**
   ```typescript theme={null}
   interface TransactionAnalysis {
     transaction: {
       instructions: number;
       signers: number;
       estimatedUnits: number;
     };
     simulation: {
       success: boolean;
       error: string | null;
       logs: string[];
       unitsConsumed: number;
     };
     analysis: {
       programInvocations: number;
       accountAccesses: number;
       errorAnalysis?: string;
     };
     metadata: {
       timestamp: number;
       commitment?: string;
     };
   }

   class TransactionAnalyzer {
     async analyzeTransaction(
       transaction: Transaction,
       config: { 
         sigVerify?: boolean;
         commitment?: string;
       }
     ): Promise<TransactionAnalysis> {
       const simulation = await connection.simulateTransaction(transaction, config);
       
       const logs = simulation.value.logs || [];
       const programInvocations = logs.filter(log => 
         log.includes('Program') && log.includes('invoke')
       ).length;
       
       const accountAccesses = logs.filter(log =>
         log.includes('Account') || log.includes('Token')
       ).length;
       
       let errorAnalysis;
       if (simulation.value.err) {
         errorAnalysis = this.analyzeError(simulation.value.err);
       }
       
       return {
         transaction: {
           instructions: transaction.instructions.length,
           signers: transaction.signatures.length,
           estimatedUnits: simulation.value.unitsConsumed || 0
         },
         simulation: {
           success: !simulation.value.err,
           error: simulation.value.err,
           logs,
           unitsConsumed: simulation.value.unitsConsumed || 0
         },
         analysis: {
           programInvocations,
           accountAccesses,
           errorAnalysis
         },
         metadata: {
           timestamp: Date.now(),
           commitment: config.commitment
         }
       };
     }
     
     private analyzeError(error: any): string {
       if (typeof error === 'string') {
         if (error.includes('insufficient funds')) {
           return 'Transaction failed due to insufficient funds';
         }
         if (error.includes('invalid account owner')) {
           return 'Transaction failed due to invalid account ownership';
         }
         if (error.includes('account not found')) {
           return 'Transaction failed due to missing account';
         }
       }
       return 'Unknown error occurred during simulation';
     }
   }
   ```

2. **交易验证**
   ```typescript theme={null}
   interface TransactionValidation {
     transaction: {
       signature: string;
       blockhash: string;
       feePayer: string;
     };
     checks: Array<{
       name: string;
       passed: boolean;
       details?: string;
     }>;
     recommendations: Array<{
       type: 'fix' | 'warning' | 'info';
       message: string;
     }>;
     metadata: {
       timestamp: number;
     };
   }

   class TransactionValidator {
     private readonly maxUnits = 200000;
     private readonly minAccountRent = 890880;
     
     async validateTransaction(
       transaction: Transaction,
       config: { 
         sigVerify?: boolean;
         commitment?: string;
       }
     ): Promise<TransactionValidation> {
       const simulation = await connection.simulateTransaction(transaction, config);
       
       const checks: Array<{
         name: string;
         passed: boolean;
         details?: string;
       }> = [];
       
       const recommendations: Array<{
         type: 'fix' | 'warning' | 'info';
         message: string;
       }> = [];
       
       const unitsConsumed = simulation.value.unitsConsumed || 0;
       checks.push({
         name: 'Compute Units',
         passed: unitsConsumed <= this.maxUnits,
         details: `${unitsConsumed} units consumed`
       });
       
       if (unitsConsumed > this.maxUnits) {
         recommendations.push({
           type: 'fix',
           message: 'Transaction exceeds compute unit limit'
         });
       }
       
       checks.push({
         name: 'Simulation',
         passed: !simulation.value.err,
         details: simulation.value.err?.toString()
       });
       
       if (simulation.value.err) {
         recommendations.push({
           type: 'fix',
           message: `Fix simulation error: ${simulation.value.err}`
         });
       }
       
       const logs = simulation.value.logs || [];
       checks.push({
         name: 'Program Execution',
         passed: logs.some(log => log.includes('Program log:')),
         details: 'Program execution logs present'
       });
       
       const rentWarnings = logs.filter(log => 
         log.includes('insufficient lamports for rent')
       );
       
       if (rentWarnings.length > 0) {
         checks.push({
           name: 'Account Rent',
           passed: false,
           details: 'Insufficient lamports for rent'
         });
         
         recommendations.push({
           type: 'fix',
           message: `Ensure accounts have minimum rent: ${this.minAccountRent} lamports`
         });
       }
       
       return {
         transaction: {
           signature: transaction.signatures[0]?.signature?.toString() || '',
           blockhash: transaction.recentBlockhash || '',
           feePayer: transaction.feePayer?.toBase58() || ''
         },
         checks,
         recommendations,
         metadata: {
           timestamp: Date.now()
         }
       };
     }
   }
   ```

3. **交易优化**
   ```typescript theme={null}
   interface TransactionOptimization {
     original: {
       instructions: number;
       unitsConsumed: number;
     };
     optimized: {
       instructions: number;
       unitsConsumed: number;
       savings: number;
     };
     changes: Array<{
       type: 'merge' | 'remove' | 'reorder';
       description: string;
       impact: number;
     }>;
     metadata: {
       timestamp: number;
     };
   }

   class TransactionOptimizer {
     async optimizeTransaction(
       transaction: Transaction
     ): Promise<TransactionOptimization> {
       const originalSimulation = await connection.simulateTransaction(transaction);
       const originalUnits = originalSimulation.value.unitsConsumed || 0;
       
       const changes: Array<{
         type: 'merge' | 'remove' | 'reorder';
         description: string;
         impact: number;
       }> = [];
       
       const optimizedTransaction = new Transaction();
       const instructions = [...transaction.instructions];
       
       const mergedInstructions = this.mergeInstructions(instructions);
       if (mergedInstructions.length < instructions.length) {
         changes.push({
           type: 'merge',
           description: `Merged ${instructions.length - mergedInstructions.length} similar instructions`,
           impact: 0
         });
       }
       
       const cleanedInstructions = this.removeRedundantInstructions(mergedInstructions);
       if (cleanedInstructions.length < mergedInstructions.length) {
         changes.push({
           type: 'remove',
           description: `Removed ${mergedInstructions.length - cleanedInstructions.length} redundant instructions`,
           impact: 0
         });
       }
       
       const orderedInstructions = this.reorderInstructions(cleanedInstructions);
       changes.push({
         type: 'reorder',
         description: 'Reordered instructions for optimal execution',
         impact: 0
       });
       
       orderedInstructions.forEach(instruction => {
         optimizedTransaction.add(instruction);
       });
       
       const optimizedSimulation = await connection.simulateTransaction(optimizedTransaction);
       const optimizedUnits = optimizedSimulation.value.unitsConsumed || 0;
       
       const totalSavings = originalUnits - optimizedUnits;
       changes.forEach(change => {
         change.impact = Math.floor(totalSavings / changes.length);
       });
       
       return {
         original: {
           instructions: instructions.length,
           unitsConsumed: originalUnits
         },
         optimized: {
           instructions: orderedInstructions.length,
           unitsConsumed: optimizedUnits,
           savings: totalSavings
         },
         changes,
         metadata: {
           timestamp: Date.now()
         }
       };
     }
     
     private mergeInstructions(instructions: Array<any>): Array<any> {
       return instructions;
     }
     
     private removeRedundantInstructions(instructions: Array<any>): Array<any> {
       return instructions;
     }
     
     private reorderInstructions(instructions: Array<any>): Array<any> {
       return instructions;
     }
   }
   ```
