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

# V3 QuoterV2

> V3 交换的链上报价估算合约

# V3 QuoterV2

**QuoterV2** 合约允许在不执行交换的情况下获取给定 V3 交换的预期输出或输入数量。它在链上模拟交换逻辑以返回准确的报价。

<Warning>
  这些函数**不是 Gas 高效的**，**不应在链上调用**。请通过 `eth_call`（静态调用）从链下代码中使用它们。链上交换执行请使用 [V3 Router](/contracts/v3-router) 或 [Universal Router](/contracts/universal-router)。
</Warning>

## 核心函数

### quoteExactInputSingle

返回单池精确输入交换的预期输出数量。

```solidity theme={null}
function quoteExactInputSingle(
    QuoteExactInputSingleParams memory params
) public override returns (
    uint256 amountOut,
    uint160 sqrtPriceX96After,
    uint32 initializedTicksCrossed,
    uint256 gasEstimate
);
```

**参数**（结构体 `QuoteExactInputSingleParams`）：

| 参数                  | 类型        | 描述                           |
| ------------------- | --------- | ---------------------------- |
| `tokenIn`           | `address` | 输入代币地址                       |
| `tokenOut`          | `address` | 输出代币地址                       |
| `amountIn`          | `uint256` | 期望的输入数量                      |
| `fee`               | `uint24`  | 池子费率等级（100、500、3000 或 10000） |
| `sqrtPriceLimitX96` | `uint160` | 价格限制（0 表示无限制）                |

**返回值：**

| 返回值                       | 类型        | 描述              |
| ------------------------- | --------- | --------------- |
| `amountOut`               | `uint256` | 预期输出数量          |
| `sqrtPriceX96After`       | `uint160` | 交换后的池子价格        |
| `initializedTicksCrossed` | `uint32`  | 穿越的已初始化 tick 数量 |
| `gasEstimate`             | `uint256` | 交换的预估 Gas 费用    |

### quoteExactInput

返回多跳精确输入交换的预期输出数量。

```solidity theme={null}
function quoteExactInput(
    bytes memory path,
    uint256 amountIn
) public override returns (
    uint256 amountOut,
    uint160[] memory sqrtPriceX96AfterList,
    uint32[] memory initializedTicksCrossedList,
    uint256 gasEstimate
);
```

| 参数         | 类型        | 描述               |
| ---------- | --------- | ---------------- |
| `path`     | `bytes`   | 编码的交换路径（代币地址和费率） |
| `amountIn` | `uint256` | 期望的输入数量          |

**返回值：**

| 返回值                           | 类型          | 描述             |
| ----------------------------- | ----------- | -------------- |
| `amountOut`                   | `uint256`   | 预期输出数量         |
| `sqrtPriceX96AfterList`       | `uint160[]` | 每一跳后的池子价格      |
| `initializedTicksCrossedList` | `uint32[]`  | 每一跳穿越的 tick 数量 |
| `gasEstimate`                 | `uint256`   | 总预估 Gas 费用     |

### quoteExactOutputSingle

返回单池精确输出交换所需的输入数量。

```solidity theme={null}
function quoteExactOutputSingle(
    QuoteExactOutputSingleParams memory params
) public override returns (
    uint256 amountIn,
    uint160 sqrtPriceX96After,
    uint32 initializedTicksCrossed,
    uint256 gasEstimate
);
```

**参数**（结构体 `QuoteExactOutputSingleParams`）：

| 参数                  | 类型        | 描述            |
| ------------------- | --------- | ------------- |
| `tokenIn`           | `address` | 输入代币地址        |
| `tokenOut`          | `address` | 输出代币地址        |
| `amount`            | `uint256` | 期望的输出数量       |
| `fee`               | `uint24`  | 池子费率等级        |
| `sqrtPriceLimitX96` | `uint160` | 价格限制（0 表示无限制） |

### quoteExactOutput

返回多跳精确输出交换所需的输入数量。

```solidity theme={null}
function quoteExactOutput(
    bytes memory path,
    uint256 amountOut
) public override returns (
    uint256 amountIn,
    uint160[] memory sqrtPriceX96AfterList,
    uint32[] memory initializedTicksCrossedList,
    uint256 gasEstimate
);
```

| 参数          | 类型        | 描述                |
| ----------- | --------- | ----------------- |
| `path`      | `bytes`   | 编码的交换路径（精确输出时为反序） |
| `amountOut` | `uint256` | 期望的输出数量           |

## 回调

### uniswapV3SwapCallback

```solidity theme={null}
function uniswapV3SwapCallback(
    int256 amount0Delta,
    int256 amount1Delta,
    bytes data
) external view override;
```

在报价模拟期间由池子调用。这是内部机制 — 你不需要直接调用此函数。

| 参数             | 类型       | 描述                         |
| -------------- | -------- | -------------------------- |
| `amount0Delta` | `int256` | 池子发送（负值）或接收（正值）的 token0 数量 |
| `amount1Delta` | `int256` | 池子发送（负值）或接收（正值）的 token1 数量 |
| `data`         | `bytes`  | 从交换调用传递过来的回调数据             |

## ABI

```json theme={null}
[
  "function quoteExactInputSingle((address tokenIn, address tokenOut, uint256 amountIn, uint24 fee, uint160 sqrtPriceLimitX96)) returns (uint256 amountOut, uint160 sqrtPriceX96After, uint32 initializedTicksCrossed, uint256 gasEstimate)",
  "function quoteExactInput(bytes path, uint256 amountIn) returns (uint256 amountOut, uint160[] sqrtPriceX96AfterList, uint32[] initializedTicksCrossedList, uint256 gasEstimate)",
  "function quoteExactOutputSingle((address tokenIn, address tokenOut, uint256 amount, uint24 fee, uint160 sqrtPriceLimitX96)) returns (uint256 amountIn, uint160 sqrtPriceX96After, uint32 initializedTicksCrossed, uint256 gasEstimate)",
  "function quoteExactOutput(bytes path, uint256 amountOut) returns (uint256 amountIn, uint160[] sqrtPriceX96AfterList, uint32[] initializedTicksCrossedList, uint256 gasEstimate)"
]
```

## 示例：获取报价

```typescript theme={null}
const QUOTER_ABI = [
  'function quoteExactInputSingle((address,address,uint256,uint24,uint160)) returns (uint256,uint160,uint32,uint256)',
];

const quoter = new ethers.Contract(QUOTER_V2_ADDRESS, QUOTER_ABI, provider);

// 报价：通过 0.3% 池子，1 个 tokenIn 可以换多少 tokenOut？
const [amountOut, sqrtPriceAfter, ticksCrossed, gasEstimate] =
  await quoter.quoteExactInputSingle.staticCall({
    tokenIn: '0xTokenA',
    tokenOut: '0xTokenB',
    amountIn: ethers.parseEther('1'),
    fee: 3000,
    sqrtPriceLimitX96: 0,
  });

console.log(`预期输出: ${ethers.formatEther(amountOut)}`);
console.log(`Gas 预估: ${gasEstimate}`);
```

<Note>
  务必使用 `staticCall`（ethers v6）或 `callStatic`（ethers v5）— 这些函数如果作为普通交易调用会回滚。
</Note>
