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

# 填充订单

> 在 EVM 链、Tron 和 Bitcoin 上交付输出资产以完成 LI.FI 意图。

要完结意图并领取被锁定的输入资金，求解器必须交付订单中描述的所有输出。本页涵盖 EVM、Tron 和 Bitcoin 的填充。

***

## EVM 订单

通过调用 `fillOrderOutputs`，将意图输出提交到 `output.settler` 中指定的输出结算器。

```solidity theme={"system"}
function fillOrderOutputs(
    uint32 fillDeadline,
    bytes32 orderId,
    MandateOutput[] calldata outputs,
    bytes32 proposedSolver
) external;
```

交易在以下情况下会回滚：

1. 未设置授权
2. 调用者余额不足
3. `fillDeadline` 已过期
4. `outputs` 中的第一个输出已被填充
5. `outputs` 中的任何外部调用回滚
6. 无法解码订单 context
7. 目标链错误
8. 输出结算器合约错误

<Note>
  `orderId` 不匹配不会导致回滚。
</Note>

在所有输出都交付之后，继续进行[结算](/lifi-intents/for-solvers/settlement)以完结订单并接收被锁定的输入。

***

## Tron 订单

填充 Tron 输出的方式与 EVM 填充类似：在 Tron `OutputSettler` 上调用 `fillOrderOutputs`。通过 **TronWeb** 提交交易，使用 20 字节规则解码地址（base58check，去掉 `0x41` 版本字节）。

有关地址转换和提交细节，请参阅 [Tron 与 EVM 对比](/lifi-intents/knowledge-database/tron-deltas#for-solvers)。

***

## Bitcoin 订单

<Note>
  LI.FI Intents 上的 BTC 支持目前尚未上线，仍在开发中。如果你有兴趣填充 BTC 订单，请与我们联系，我们将协助你完成接入。
</Note>

要确定某个订单是否涉及 Bitcoin 交易，请检查 `orderDto.order.outputs[].token`。

* 前 30 个字节应为 `0x000000000000000000000000BC0000000000000000000000000000000000`（第 13 个字节为 `0xBC`）
* 第 31 个字节表示链上验证之前所需的确认数（`0x00` 和 `0x01` 都表示 1 次确认，`0x02` 表示 2 次，依此类推）
* 第 32 个字节是一个地址版本标识符，解码为 `uint8`

### 地址版本

| Version | Name    | Encoding            | Prefix | Hash Length |
| ------- | ------- | ------------------- | ------ | ----------- |
| 0       | Unknown | Ignore              |        |             |
| 1       | P2PKH   | Base58Check(00+PKH) | 1      | 20          |
| 2       | P2SH    | Base58Check(05+SH)  | 3      | 20          |
| 3       | P2WPKH  | Bech32              | bc1q   | 20          |
| 4       | P2WSH   | Bech32              | bc1q   | 32          |
| 5       | P2TR    | Bech32m             | bc1p   | 32          |

`outputs[].recipient` 字段包含目标哈希或 witness，而非人类可读的地址。使用版本字节和收款人哈希来重建 Bitcoin 地址。

```typescript theme={"system"}
import bs58check from 'bs58check';
import { bech32, bech32m } from 'bech32';

const hexStringToUint8Array = (hexString: string) =>
  Uint8Array.from(
    hexString.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16))
  );

function decodeBitcoinAddress(
  version: number,
  recipientHash: string,
  testnet = false,
): string {
  if (version === 1) {
    const prefix = !testnet ? '00' : '6F';
    const bytes = hexStringToUint8Array(
      prefix + recipientHash.replace('0x', '').slice(0, 40)
    );
    return bs58check.encode(bytes);
  }
  if (version === 2) {
    const prefix = !testnet ? '05' : 'C4';
    const bytes = hexStringToUint8Array(
      prefix + recipientHash.replace('0x', '').slice(0, 40)
    );
    return bs58check.encode(bytes);
  }
  const prefix = !testnet ? 'bc' : 'tb';
  if (version === 3) {
    const bytes = hexStringToUint8Array(
      recipientHash.replace('0x', '').slice(0, 40)
    );
    const words = bech32.toWords(bytes);
    words.unshift(0x00);
    return bech32.encode(prefix, words);
  }
  const bytes = hexStringToUint8Array(
    recipientHash.replace('0x', '').slice(0, 64)
  );
  if (version === 4) {
    const words = bech32.toWords(bytes);
    words.unshift(0x00);
    return bech32.encode(prefix, words);
  }
  if (version === 5) {
    const words = bech32m.toWords(bytes);
    words.unshift(0x01);
    return bech32m.encode(prefix, words);
  }

  throw Error(`Unsupported Address Type ${version}`);
}
```

### 构造 Bitcoin 交易

创建一笔交易，其中至少包含一个与订单输出描述完全匹配的输出。该交易可以有任意数量的输入和额外输出，从而支持批量填充和归集。

如果输出上设置了 calldata，请在填充输出之后立即添加一个 `OP_RETURN` 输出：

```typescript theme={"system"}
import * as bitcoin from 'bitcoinjs-lib';

bitcoin.initEccLib(ecc);

const psbt = new bitcoin.Psbt({
  network: mainnet ? bitcoin.networks.bitcoin : bitcoin.networks.testnet,
});

// ... add inputs

psbt.addOutput({ address: to, value: outputValue });

const opReturnData = returnData.replace("0x", "");
if (opReturnData.length > 0) {
  const data_embed = bitcoin.payments.embed({
    data: [hexStringToUint8Array(opReturnData)],
  });
  psbt.addOutput({
    script: data_embed.output!,
    value: 0n,
  });
}

// ... complete transaction
```

***

## 后续步骤

<CardGroup cols={2}>
  <Card title="结算订单" icon="check" href="/lifi-intents/for-solvers/settlement">
    完结订单并领取被锁定的输入资金
  </Card>

  <Card title="收集订单" icon="inbox" href="/lifi-intents/for-solvers/orderflow">
    通过 WebSocket 和 REST 收集订单
  </Card>

  <Card title="拍卖" icon="gavel" href="/lifi-intents/for-solvers/auctions">
    限价、荷兰式和独占拍卖类型
  </Card>

  <Card title="信誉" icon="star" href="/lifi-intents/for-solvers/reputation">
    求解器信誉系统与注册
  </Card>
</CardGroup>
