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

# Пакетные симуляции

> Узнайте, как симулировать несколько транзакций в одном запросе API или RPC.

Симуляционные пакеты (Simulation Bundles) позволяют вам симулировать несколько транзакций последовательно. Например, чтобы установить определённые
условия перед симуляцией нужной транзакции, вам сначала нужно выполнить несколько других транзакций.

Как [Simulation API](/simulations/bundled-simulations#rpc-bundled-simulations), так и [Simulation RPC](/simulations/bundled-simulations#api-bundled-simulations) поддерживают пакетные симуляции. Эндпоинты получают массив транзакций, которые симулируются одна за другой в пределах одного блока.

## Пакетные симуляции через RPC

[Node RPC](/node-rpc/overview) позволяет читать данные из блокчейна и отправлять транзакции. Но вы также можете симулировать пакетные транзакции в Node через один RPC URL. Симуляции через RPC доступны только в поддерживаемых сетях. Если ваша сеть не поддерживается в Node, вместо этого запускайте пакетные симуляции через [Simulation API](/simulations/bundled-simulations#api-bundled-simulations).

Получите RPC URL из [Dashboard](https://dashboard.tenderly.co/register?redirectTo=gateways).

Перейдите в **Node** > **Copy HTTPS URL** нужной вам сети.

```bash title="example" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
https://mainnet.gateway.tenderly.co/$TENDERLY_NODE_ACCESS_KEY
```

Чтобы симулировать пакетные транзакции через RPC, вызовите метод `tenderly_simulateBundle`. Этот пользовательский метод позволяет симулировать несколько транзакций, передавая их в виде массива. [См. справочник RPC](/node-rpc/rpc-reference?network=ethereum-mainnet\&method=tenderly_simulateBundle).

<Note>
  Транзакции симулируются одна за другой в одном блоке.
</Note>

**Пример**

<Tabs>
  <Tab title="example">
    ```bash title="example" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    curl https://mainnet.gateway.tenderly.co/$TENDERLY_NODE_ACCESS_KEY \
      -X POST \
      -H "Content-Type: application/json" \
      -d \
      '{
        "id": 0,
        "jsonrpc": "2.0",
        "method": "tenderly_simulateBundle",
        "params": [
          [
            {
              "from": "0xe2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2",
              "to": "0x6b175474e89094c44da98b954eedeac495271d0f",
              "data": "0x40c10f19000000000000000000000000e58b9ee93700a616b50509c8292977fa7a0f8ce10000000000000000000000000000000000000000000000001bc16d674ec80000"
            },
            {
              "from": "0xe58b9ee93700a616b50509c8292977fa7a0f8ce1",
              "to": "0x6b175474e89094c44da98b954eedeac495271d0f",
              "gas": "0x7a1200",
              "data": "0x095ea7b3000000000000000000000000f7ddedc66b1d482e5c38e4730b3357d32411e5dd0000000000000000000000000000000000000000000000000de0b6b3a7640000"
            },
            {
              "from": "0xf7ddedc66b1d482e5c38e4730b3357d32411e5dd",
              "to": "0x6b175474e89094c44da98b954eedeac495271d0f",
              "gas": "0x7a1200",
              "data": "0x23b872dd000000000000000000000000e58b9ee93700a616b50509c8292977fa7a0f8ce1000000000000000000000000bd8daa414fda8a8a129f7035e7496759c5af8570000000000000000000000000000000000000000000000000006a94d74f430000"
            }
          ],
          "latest",
          {
            "0x6b175474e89094c44da98b954eedeac495271d0f": {
              "stateDiff": {
                "0xedd7d04419e9c48ceb6055956cbb4e2091ae310313a4d1fa7cbcfe7561616e03": "0x0000000000000000000000000000000000000000000000000000000000000001"
              }
            }
          }
        ]
      }'
    ```
  </Tab>

  <Tab title="response.json">
    ```json title="response.json" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    {
      "id": 0,
      "jsonrpc": "2.0",
      "result": [
        {
          "status": true,
          "gasUsed": "0xd0d9",
          "cumulativeGasUsed": "0x0",
          "blockNumber": "0x121c950",
          "type": "0x0",
          "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000010000000020000000000000000000800000000000000000000000010000000000000000000004000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000020000000002000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000",
          "logs": [
            {
              "name": "Transfer",
              "anonymous": false,
              "inputs": [
                {
                  "value": "0x0000000000000000000000000000000000000000",
                  "type": "address",
                  "name": "src"
                },
                {
                  "value": "0xe58b9ee93700a616b50509c8292977fa7a0f8ce1",
                  "type": "address",
                  "name": "dst"
                },
                {
                  "value": "2000000000000000000",
                  "type": "uint256",
                  "name": "wad"
                }
              ],
              "raw": {
                "address": "0x6b175474e89094c44da98b954eedeac495271d0f",
                "topics": [
                  "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
                  "0x0000000000000000000000000000000000000000000000000000000000000000",
                  "0x000000000000000000000000e58b9ee93700a616b50509c8292977fa7a0f8ce1"
                ],
                "data": "0x0000000000000000000000000000000000000000000000001bc16d674ec80000"
              }
            }
          ],
          "trace": [
            {
              "type": "CALL",
              "from": "0xe2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2",
              "to": "0x6b175474e89094c44da98b954eedeac495271d0f",
              "gas": "0xbeb6d8c",
              "gasUsed": "0x7c65",
              "value": "0x0",
              "input": "0x40c10f19000000000000000000000000e58b9ee93700a616b50509c8292977fa7a0f8ce10000000000000000000000000000000000000000000000001bc16d674ec80000",
              "decodedInput": [
                {
                  "value": "0xe58b9ee93700a616b50509c8292977fa7a0f8ce1",
                  "type": "address",
                  "name": "usr"
                },
                {
                  "value": "2000000000000000000",
                  "type": "uint256",
                  "name": "wad"
                }
              ],
              "method": "mint",
              "output": "0x",
              "subtraces": 0,
              "traceAddress": []
            }
          ],
          "assetChanges": [
            {
              "assetInfo": {
                "standard": "ERC20",
                "type": "Fungible",
                "contractAddress": "0x6b175474e89094c44da98b954eedeac495271d0f",
                "symbol": "dai",
                "name": "Dai",
                "logo": "https://assets.coingecko.com/coins/images/9956/large/Badge_Dai.webp?1696509996",
                "decimals": 18,
                "dollarValue": "0.9996880292892456"
              },
              "type": "Mint",
              "to": "0xe58b9ee93700a616b50509c8292977fa7a0f8ce1",
              "rawAmount": "0x1bc16d674ec80000",
              "amount": "2",
              "dollarValue": "1.9993760585784912109"
            }
          ],
          "balanceChanges": [
            {
              "address": "0xe58b9ee93700a616b50509c8292977fa7a0f8ce1",
              "dollarValue": "1.9993760585784912109",
              "transfers": [
                0
              ]
            }
          ]
        },
        {
          "status": true,
          "gasUsed": "0xb442",
          "cumulativeGasUsed": "0x0",
          "blockNumber": "0x121c950",
          "type": "0x0",
          "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000200000000000000000000000000008000000000000000000000000000000000000000010000000000000000000020000000000000000000000000000000000000000000000000000004000800000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000002000000000000000000000000100010000000000000000000000000000000000000000000000000000000000000",
          "logs": [
            {
              "name": "Approval",
              "anonymous": false,
              "inputs": [
                {
                  "value": "0xe58b9ee93700a616b50509c8292977fa7a0f8ce1",
                  "type": "address",
                  "name": "src"
                },
                {
                  "value": "0xf7ddedc66b1d482e5c38e4730b3357d32411e5dd",
                  "type": "address",
                  "name": "guy"
                },
                {
                  "value": "1000000000000000000",
                  "type": "uint256",
                  "name": "wad"
                }
              ],
              "raw": {
                "address": "0x6b175474e89094c44da98b954eedeac495271d0f",
                "topics": [
                  "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925",
                  "0x000000000000000000000000e58b9ee93700a616b50509c8292977fa7a0f8ce1",
                  "0x000000000000000000000000f7ddedc66b1d482e5c38e4730b3357d32411e5dd"
                ],
                "data": "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000"
              }
            }
          ],
          "trace": [
            {
              "type": "CALL",
              "from": "0xe58b9ee93700a616b50509c8292977fa7a0f8ce1",
              "to": "0x6b175474e89094c44da98b954eedeac495271d0f",
              "gas": "0x79bd80",
              "gasUsed": "0x5fc2",
              "value": "0x0",
              "input": "0x095ea7b3000000000000000000000000f7ddedc66b1d482e5c38e4730b3357d32411e5dd0000000000000000000000000000000000000000000000000de0b6b3a7640000",
              "decodedInput": [
                {
                  "value": "0xf7ddedc66b1d482e5c38e4730b3357d32411e5dd",
                  "type": "address",
                  "name": "usr"
                },
                {
                  "value": "1000000000000000000",
                  "type": "uint256",
                  "name": "wad"
                }
              ],
              "method": "approve",
              "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
              "decodedOutput": [
                {
                  "value": true,
                  "type": "bool",
                  "name": ""
                }
              ],
              "subtraces": 0,
              "traceAddress": []
            }
          ]
        },
        {
          "status": true,
          "gasUsed": "0xe38b",
          "cumulativeGasUsed": "0x0",
          "blockNumber": "0x121c950",
          "type": "0x0",
          "logsBloom": "0x00000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000010000000000000000000004000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000002000000000000000000020000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000",
          "logs": [
            {
              "name": "Transfer",
              "anonymous": false,
              "inputs": [
                {
                  "value": "0xe58b9ee93700a616b50509c8292977fa7a0f8ce1",
                  "type": "address",
                  "name": "src"
                },
                {
                  "value": "0xbd8daa414fda8a8a129f7035e7496759c5af8570",
                  "type": "address",
                  "name": "dst"
                },
                {
                  "value": "30000000000000000",
                  "type": "uint256",
                  "name": "wad"
                }
              ],
              "raw": {
                "address": "0x6b175474e89094c44da98b954eedeac495271d0f",
                "topics": [
                  "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
                  "0x000000000000000000000000e58b9ee93700a616b50509c8292977fa7a0f8ce1",
                  "0x000000000000000000000000bd8daa414fda8a8a129f7035e7496759c5af8570"
                ],
                "data": "0x000000000000000000000000000000000000000000000000006a94d74f430000"
              }
            }
          ],
          "trace": [
            {
              "type": "CALL",
              "from": "0xf7ddedc66b1d482e5c38e4730b3357d32411e5dd",
              "to": "0x6b175474e89094c44da98b954eedeac495271d0f",
              "gas": "0x79bc28",
              "gasUsed": "0x8db3",
              "value": "0x0",
              "input": "0x23b872dd000000000000000000000000e58b9ee93700a616b50509c8292977fa7a0f8ce1000000000000000000000000bd8daa414fda8a8a129f7035e7496759c5af8570000000000000000000000000000000000000000000000000006a94d74f430000",
              "decodedInput": [
                {
                  "value": "0xe58b9ee93700a616b50509c8292977fa7a0f8ce1",
                  "type": "address",
                  "name": "src"
                },
                {
                  "value": "0xbd8daa414fda8a8a129f7035e7496759c5af8570",
                  "type": "address",
                  "name": "dst"
                },
                {
                  "value": "30000000000000000",
                  "type": "uint256",
                  "name": "wad"
                }
              ],
              "method": "transferFrom",
              "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
              "decodedOutput": [
                {
                  "value": true,
                  "type": "bool",
                  "name": ""
                }
              ],
              "subtraces": 0,
              "traceAddress": []
            }
          ],
          "assetChanges": [
            {
              "assetInfo": {
                "standard": "ERC20",
                "type": "Fungible",
                "contractAddress": "0x6b175474e89094c44da98b954eedeac495271d0f",
                "symbol": "dai",
                "name": "Dai",
                "logo": "https://assets.coingecko.com/coins/images/9956/large/Badge_Dai.webp?1696509996",
                "decimals": 18,
                "dollarValue": "0.9996880292892456"
              },
              "type": "Transfer",
              "from": "0xe58b9ee93700a616b50509c8292977fa7a0f8ce1",
              "to": "0xbd8daa414fda8a8a129f7035e7496759c5af8570",
              "rawAmount": "0x6a94d74f430000",
              "amount": "0.03",
              "dollarValue": "0.029990640878677368163"
            }
          ],
          "balanceChanges": [
            {
              "address": "0xbd8daa414fda8a8a129f7035e7496759c5af8570",
              "dollarValue": "0.029990640878677368163",
              "transfers": [
                0
              ]
            },
            {
              "address": "0xe58b9ee93700a616b50509c8292977fa7a0f8ce1",
              "dollarValue": "-0.029990640878677368163",
              "transfers": [
                0
              ]
            }
          ]
        }
      ]
    }
    ```
  </Tab>
</Tabs>

## Пакетные симуляции через API

Используйте эндпоинт API `simulate-bundle`, чтобы симулировать несколько последовательных транзакций одновременно. [См. справочник API](/api-reference).

```bash title="example" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
https://api.tenderly.co/api/v1/account/${TENDERLY_ACCOUNT_SLUG}/project/${TENDERLY_PROJECT_SLUG}/simulate-bundle
```

Результат симуляции показывает генерируемые события и изменения состояния, которые может вызвать транзакция, если вы отправите её в блокчейн.

В случае сбоя транзакции произойдёт ранний возврат со всеми симуляциями до точки сбоя.

**Пример**

<Tabs>
  <Tab title="Shell">
    ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    curl --request POST \
      --url https://api.tenderly.co/api/v1/account/me/project/project/simulate-bundle \
      --header 'Accept: application/json' \
      --header 'Content-Type: application/json' \
      --header "X-Access-Key: $TENDERLY_ACCESS_KEY" \
      --data '{
      "simulations": [
        {
          "network_id": "1",
          "save": true,
          "save_if_fails": true,
          "simulation_type": "full",
          "from": "0xe2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2",
          "to": "0x6b175474e89094c44da98b954eedeac495271d0f",
          "input": "0x40c10f19000000000000000000000000e58b9ee93700a616b50509c8292977fa7a0f8ce10000000000000000000000000000000000000000000000001bc16d674ec80000",
          "state_objects": {
            "0x6b175474e89094c44da98b954eedeac495271d0f": {
              "storage": {
                "0xedd7d04419e9c48ceb6055956cbb4e2091ae310313a4d1fa7cbcfe7561616e03": "0x0000000000000000000000000000000000000000000000000000000000000001"
              }
            }
          }
        },
        {
          "network_id": "1",
          "save": true,
          "save_if_fails": true,
          "simulation_type": "full",
          "from": "0xe58b9ee93700a616b50509c8292977fa7a0f8ce1",
          "to": "0x6b175474e89094c44da98b954eedeac495271d0f",
          "input": "0x095ea7b3000000000000000000000000f7ddedc66b1d482e5c38e4730b3357d32411e5dd0000000000000000000000000000000000000000000000000de0b6b3a7640000"
        },
        {
          "network_id": "1",
          "save": true,
          "save_if_fails": true,
          "simulation_type": "full",
          "from": "0xf7ddedc66b1d482e5c38e4730b3357d32411e5dd",
          "to": "0x6b175474e89094c44da98b954eedeac495271d0f",
          "input": "0x23b872dd000000000000000000000000e58b9ee93700a616b50509c8292977fa7a0f8ce1000000000000000000000000bd8daa414fda8a8a129f7035e7496759c5af8570000000000000000000000000000000000000000000000000006a94d74f430000"
        }
      ]
    }'
    ```
  </Tab>

  <Tab title="request.ts">
    ```ts title="request.ts" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}

    dotenv.config();

    // assuming environment variables TENDERLY_ACCOUNT_SLUG, TENDERLY_PROJECT_SLUG and TENDERLY_ACCESS_KEY are set
    const { TENDERLY_ACCOUNT_SLUG, TENDERLY_PROJECT_SLUG, TENDERLY_ACCESS_KEY } = process.env;

    const batchedSimulations = async () => {
      console.time('Batch Simulation');

      const daiSequence = (
        await axios.post(
          `https://api.tenderly.co/api/v1/account/${TENDERLY_ACCOUNT_SLUG}/project/${TENDERLY_PROJECT_SLUG}/simulate-bundle`,
          // the transaction
          {
            simulations: getTxSequence().map((transaction) => ({
              network_id: '1', // network to simulate on
              save: true,
              save_if_fails: true,
              simulation_type: 'full',
              ...transaction,
            })),
          },
          {
            headers: {
              'X-Access-Key': TENDERLY_ACCESS_KEY as string,
            },
          },
        )
      ).data;
      console.timeEnd('Batch Simulation');
      console.log(JSON.stringify(daiSequence, null, 2));
    };

    function getTxSequence() {
      const fakeWardAddress = '0xe2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2';
      const daiOwner = 'e58b9ee93700a616b50509c8292977fa7a0f8ce1';
      const daiSpend = 'f7ddedc66b1d482e5c38e4730b3357d32411e5dd';
      const daiRecip = 'e58b9ee93700a616b50509c8292977fa7a0f8ce1';
      const daiContract = '0x6b175474e89094c44da98b954eedeac495271d0f';
      return [
        // TX1: Mint 2 DAI for e58b9ee93700a616b50509c8292977fa7a0f8ce1.
        // Must do state override so sender (from) is considered a ward for this simulation
        {
          from: fakeWardAddress,
          to: '0x6b175474e89094c44da98b954eedeac495271d0f',
          input:
            '0x40c10f19000000000000000000000000e58b9ee93700a616b50509c8292977fa7a0f8ce10000000000000000000000000000000000000000000000001bc16d674ec80000',
          // make 0xcace477c66b1f2e151974eeada9ac8b95a31c50593ae1db2f048f0a2b54c1424 a ward
          state_objects: {
            '0x6b175474e89094c44da98b954eedeac495271d0f': {
              storage: {
                '0xedd7d04419e9c48ceb6055956cbb4e2091ae310313a4d1fa7cbcfe7561616e03':
                  '0x0000000000000000000000000000000000000000000000000000000000000001',
              },
            },
          },
        },
        // TX2: e58b9ee93700a616b50509c8292977fa7a0f8ce1 approves 1 DAI to f7ddedc66b1d482e5c38e4730b3357d32411e5dd
        {
          from: '0xe58b9ee93700a616b50509c8292977fa7a0f8ce1',
          to: '0x6b175474e89094c44da98b954eedeac495271d0f',
          input:
            '0x095ea7b3000000000000000000000000f7ddedc66b1d482e5c38e4730b3357d32411e5dd0000000000000000000000000000000000000000000000000de0b6b3a7640000',
        },
        {
          // TX3: 0xf7ddedc66b1d482e5c38e4730b3357d32411e5dd calls transferFrom to transfer 0.5 DAI belonging to e58b9ee93700a616b50509c8292977fa7a0f8ce1, sending them to e58b9ee93700a616b50509c8292977fa7a0f8ce1
          from: '0xf7ddedc66b1d482e5c38e4730b3357d32411e5dd',
          to: '0x6b175474e89094c44da98b954eedeac495271d0f',
          input:
            '0x23b872dd000000000000000000000000e58b9ee93700a616b50509c8292977fa7a0f8ce1000000000000000000000000bd8daa414fda8a8a129f7035e7496759c5af8570000000000000000000000000000000000000000000000000006a94d74f430000',
        },
      ];
    }

    function getWardStorageLocation(wardAddress: string) {
      // calculate the storage location of `wards[wardAddress]`
      // yields 0xedd7d04419e9c48ceb6055956cbb4e2091ae310313a4d1fa7cbcfe7561616e03
      return ethers.utils.keccak256(
        ethers.utils.concat([
          ethers.utils.hexZeroPad(wardAddress, 32), // the ward address (address 0x000..0) - mapping key
          ethers.utils.hexZeroPad('0x0', 32), // the wards slot is 0th in the DAI contract - the mapping variable
        ]),
      );
    }

    batchedSimulations();
    ```
  </Tab>
</Tabs>

## Изучите сценарии использования

* [**Изменения активов и балансов**](/simulations/asset-balance-changes): получайте точные долларовые значения для всех изменений балансов и активов.
* [**Оценка газа**](/simulations/gas-estimation): точно предсказывайте затраты на газ до отправки транзакции.
* [**Переопределения состояния**](/simulations/state-overrides): изменяйте условия блокчейна, такие как временные метки и данные контракта, для тестирования различных сценариев.
* [**Предпросмотр результатов транзакции**](/simulations/transaction-preview): выявляйте и устраняйте проблемы, которые могут привести к сбою транзакций.

## Что дальше

<Card title="Одиночные симуляции" href="" />

<Card title="Симуляция через SDK" href="" />
