# 交易生命週期

凡是會修改區塊鏈狀態的每個操作，例如轉移代幣或創建資產，都是透過交易來執行的。了解交易的生命週期是使用 OCAP 用戶端建構應用程式的基礎。此過程涉及四個主要階段：準備、編碼、簽署和發送。

OCAP 用戶端提供了一套彈性的方法，讓您可以為了最大程度的控制而單獨執行這些步驟，或者為了方便而使用將它們結合在一起的高階輔助函式。

本指南將分解每個階段，並闡述單一簽章和多重簽章的工作流程。


## 生命週期總覽

下圖說明了一筆交易從準備到最終提交至區塊鏈的完整過程。

<!-- DIAGRAM_IMAGE_START:flowchart:4:3 -->

![Transaction Lifecycle](assets/diagram/core-concepts-transaction-lifecycle-01.jpg)

<!-- DIAGRAM_IMAGE_END -->


## 階段 1：準備 (創建 `itx`)

每筆交易都始於一個 `itx`（內部交易）。這是一個純 JavaScript 物件，其中包含您想執行操作的特定資料。例如，一個轉帳 `itx` 會包含收款人地址和金額。

```javascript 準備 itx icon=logos:javascript
// 我們轉帳交易的核心資料
const itx = {
  to: 'z2C8j81aL2oXpA5t42s2h4g9o8p1k6m3n7b', // 收款人地址
  value: await client.fromTokenToUnit(10),   // 要發送的金額，已轉換為鏈上的基本單位
};
```


## 階段 2：編碼

編碼是將 `itx` 和其他元資料轉換為可進行密碼學簽署的標準化二進位格式。用戶端為每種交易類型提供了一個 `encode{TxType}Tx` 方法（例如 `encodeTransferV2Tx`）。

在此階段，用戶端會自動添加必要的元資料：

* **`from`**：發送方地址，從提供的錢包中衍生而來。
* **`chainId`**：目標區塊鏈的識別碼，會自動獲取。
* **`nonce`**：一個用來防止重放攻擊的唯一數字，預設為當前時間戳 (`Date.now()`)。
* **`pk`**：發送方錢包的公鑰。

編碼函式會返回完整的交易物件和序列化資料的 `Buffer`，後者用於簽署。

```javascript 編碼交易 icon=logos:javascript
const { object: encodedTx, buffer: txBuffer } = await client.encodeTransferV2Tx({
  tx: { itx },
  wallet: senderWallet,
});

console.log('Encoded TX Object:', encodedTx);
console.log('Buffer to be signed:', txBuffer);
```


## 階段 3：簽署

簽署證明了帳戶的所有權並授權該筆交易。單一簽章和多重簽章工作流程的過程有所不同。

### 單一簽章工作流程

這是最常見的情境，即由單一使用者簽署一筆交易。`sign{TxType}Tx` 方法會接收編碼後的交易，使用者的私鑰簽署二進位緩衝區，並填入 `signature` 欄位。

```javascript 使用單一簽章進行簽署 icon=logos:javascript
const signedTx = await client.signTransferV2Tx({
  tx: encodedTx, // 來自編碼步驟的物件
  wallet: senderWallet,
});

console.log('Signature:', signedTx.signature);
```

### 多重簽章工作流程

多重簽章（multisig）交易需要多方批准。這通常用於原子交換或共享帳戶。這個過程是循序的：

1. **準備**：創建初始交易時，會帶有一個 `signaturesList`，其中定義了所有必要的簽署人。
2. **循序簽署**：交易從一個簽署人傳遞給下一個。每個簽署人都會使用對應的 `multiSign{TxType}Tx` 方法來添加自己的簽章。

在內部，`multiSign` 方法會透過在編碼交易以進行簽署前，暫時移除所有現有簽章，來確保每一方都簽署完全相同的交易摘要。

以下是一個 `ExchangeTx` 的範例，其中兩方交換資產。

```javascript 多重簽章範例 icon=logos:javascript
// 步驟 1：Alice（要約人）準備並簽署交換交易。
const txFromAlice = await client.prepareExchange({
  offerToken: 10,
  demandToken: 20,
  receiver: bobWallet.address,
  wallet: aliceWallet,
});

// 步驟 2：將交易發送給 Bob。
// Bob（要求人）添加他的簽章以完成交易。
const txFromBob = await client.finalizeExchange({
  tx: txFromAlice, // 由 Alice 簽署的交易
  wallet: bobWallet,
});

console.log('Alice\'s Signature:', txFromBob.signaturesList[0].signature);
console.log('Bob\'s Signature:', txFromBob.signaturesList[1].signature);
```


## 階段 4：發送

一旦交易被完整簽署，就可以將其發送到區塊鏈節點進行處理。`send{TxType}Tx` 方法處理這最後一步。

為求方便，如果您提供一個錢包和一筆未簽署的交易，這些方法也可以隱式地執行簽署步驟。該方法會返回一個 promise，在成功提交後，該 promise 會解析並回傳交易雜湊值。

```javascript 發送已簽署的交易 icon=logos:javascript
// 使用預先簽署的交易
const hash = await client.sendTransferV2Tx({ tx: signedTx, wallet: senderWallet });

// 或者，讓發送方法自動處理簽署
const hash2 = await client.sendTransferV2Tx({
  tx: { itx }, // 只需內部交易
  wallet: senderWallet,
});

console.log('Transaction sent! Hash:', hash);
```

您也可以加入 `commit: true` 選項，讓用戶端等到交易完全確認並被納入一個區塊後，才解析該 promise。


## 總結

交易生命週期為與區塊鏈互動提供了一個穩健而彈性的框架。透過將過程分解為不同的階段——準備、編碼、簽署和發送——OCAP 用戶端為開發者提供了對交易創建的精細控制，同時也為常見用例提供了簡單的高階輔助函式。

有關交易費用如何處理的更多詳情，請參閱 [Gas 支付](./core-concepts-gas-payment.md) 指南。要了解可用的不同用戶端類型，請參閱 [用戶端架構](./core-concepts-client-architecture.md) 文件。
