---
title: "什麼是 User Operations?"
description: "定義、參數與運作方式"
---

# 什麼是 User Operations?

使用者操作（User operations）是包含交易細節的物件，會代表發送者的智能合約帳戶執行。使用者操作是一種偽交易物件，讓 Account Abstraction 得以運作，而不需要對 Ethereum 及支援 [ERC-4337](https://www.alchemy.com/overviews/what-is-account-abstraction) 的第二層區塊鏈進行共識層變更。

無論是要開發智能合約錢包（SCWs），或是要讓去中心化應用程式相容於 SCWs，了解定義使用者操作的參數、使用者操作欄位在建構過程中如何被填入、使用者操作如何被 bundler 打包，以及如何由 paymaster 驗證與執行，都會很有幫助。

<CalloutBlock>
  透過我們的 Embedded Accounts 與帳戶抽象基礎設施，讓新使用者可以[建立內嵌電子郵件與 passkey 錢包](https://www.alchemy.com/smart-wallets)！
</CalloutBlock>

## 觀看：以 Solidity 建構並執行使用者操作

<ExternalVideo
  url="https://youtu.be/NM04uxcCOEw?si=GP-JehvonrZ_6qtJ"
  provider="youtube"
  providerUid="NM04uxcCOEw"
/>

## **使用者操作包含哪些欄位？**

使用者操作（UOs）包含與一般交易相似的欄位（例如 sender、to、calldata、maxFeePerGas、maxPriorityFee、signature 與 nonce），但也有幾個專屬於使用者操作結構的新欄位，包括 callGasLimit、verificationGasLimit、preVerificationGas，以及 paymasterAndData。

UO 欄位的定義可以在[官方 ERC-4337 規格文件](https://eips.ethereum.org/EIPS/eip-4337)中找到。以下是簡要說明：

- **callGasLimit** - 主執行呼叫要使用的 gas
- **verificationGasLimit** - 完成驗證步驟要使用的 gas
- **preVerificationGas** - 支付給 bundler，用以涵蓋預驗證執行與 calldata 成本的 gas
- **paymasterAndData** - 贊助的 paymaster 位址，以及要傳送給 paymaster 的資料

Alchemy AA 基礎設施團隊工程師 **David Philipson** 撰寫的「You Could Invented Account Abstraction」系列文章第一部分，說明了[使用者操作的設計與架構](https://www.alchemy.com/overviews/what-is-account-abstraction)。

接下來，讓我們了解正確填入使用者操作各欄位的標準流程。

## **傳送使用者操作的流程是什麼？**

將使用者操作（user op）傳送給 [bundler](https://www.alchemy.com/overviews/what-is-a-bundler) 的典型流程包含多個步驟：

1. 建構部分填入的使用者操作，填入 sender、nonce、initCode 與 callData
1. 透過 eth_estimateUserOperationGas 向 bundler RPC 估算部分使用者操作的 gas
1. 填入 preVerificationGas、verificationGasLimit、callGasLimit
1. 若使用的 paymaster 不依賴使用者操作的內容（例如 [ERC20](https://www.alchemy.com/overviews/erc20-solidity) paymaster），可以在此步驟填入 paymasterAndData。
1. 估算此操作所需的 gas 費用，並填入 maxFeePerGas 與 maxPriorityFeePerGas
1. （選用）將使用者操作傳送給贊助的 paymaster 進行簽署，並填入 paymasterAndData
1. 這個步驟必須在此時完成，因為 paymaster 的簽章需要上述所有欄位都已填入。
1. 簽署使用者操作，填入 signature，並透過 eth_sendUserOperation 將使用者操作傳送給 bundler

雖然開發者可以使用原生的 [ethers.js](https://www.alchemy.com/dapps/ethers-js) 取得每個使用者操作欄位的值，但也有一些 web3 開發工具可以讓 UO 的建構更容易。

## **開發者可以使用什麼工具來建構使用者操作？**

像是 Alchemy 開源的 AA SDK 這類使用者操作建構工具，比起使用原生 ethers.js 製作使用者操作更加容易。

### **Alchemy 的 AA SDK**

Alchemy 的 AA SDK 是以 viem 建構的，提供開發者輕量化的套件。[GitHub 上的 aa-sdk](https://github.com/alchemyplatform/aa-sdk) 也透過 aa-ethers 函式庫支援 ethers.js 的 signers 與 providers。

使用 aa-sdk 建構使用者操作的主要好處之一，是它提供兩個實用方法：

1. **sendUserOperation** - 處理 gas 估算、請求 paymasterAndData、簽署等等
1. **sendTransaction** - 將交易物件資料（from、to、data 與 value）轉換為使用者操作

建構使用者操作的操作順序相當複雜，而 Alchemy 的 AA-SDK 透過執行一連串的操作來簡化 UO 的建構：先以 **getDummyPaymasterData**，再以 **estimateGas** 估算 gas，接著執行 **getFeeData**，最後執行 **getPaymasterAndData**。

在取得使用者操作各欄位的值之後，它會使用 target、callData 與選用的 value 來建構並簽署使用者操作。接著它會將使用者操作傳送給 bundler，並取得該使用者操作的雜湊值。

如果你想使用 Alchemy 的 paymaster、其他 paymaster，或是打算為自己的 SmartAccounts 加入支援，請閱讀 [Alchemy AA SDK 文件](https://www.alchemy.com/docs/wallets/reference/aa-sdk/core)，其中有完整說明如何輕鬆建立 UOs。

<ExternalVideo
  url="https://youtu.be/7aJ5bonMSyQ?si=P6ZANXn3HQYUssJr"
  provider="youtube"
  providerUid="7aJ5bonMSyQ"
/>

## **使用者操作如何被加入使用者操作記憶體池（mempool）？**

在使用者操作被加入 mempool 之前，必須先通過一系列檢查，以確認它符合 ERC-4337 規格中所定義的預期行為。使用者操作也必須通過驗證模擬檢查，以確認它是有效的，並且能夠支付其 gas 費用（無論是透過發送者的錢包，還是透過 paymaster 的贊助政策）。

### **1. 檢查使用者操作的有效性**

初步的一系列檢查說明於 ERC-4337 規格中的「Client behavior upon receiving a UserOperation」章節，以下為摘要：

- 發送者必須是既有的合約，或是 initCode（用於建立合約）不為空（但兩者不可同時成立）
- 若 **initCode** 不為空（因為此使用者操作會建立帳戶），則需判斷該 factory 是否已質押
- **verificationGasLimit** 必須足夠低（小於或等於 **MAX_VERIFICATION_GAS**）
- **preVerificationGas** 必須足夠高，以支付 calldata gas 及額外的 overhead gas 費用
- **paymasterAndData** 必須為空，或以 paymaster 位址開頭
- 若存在 paymaster，其在鏈上必須有非空的程式碼、有資金可支付此使用者操作，且未被禁止使用
- **callgas** 至少要等於一筆非零數值的 **CALL** 所需的成本
- **maxFeePerGas** 與 **maxPriorityFeePerGas** 必須高於客戶端可接受的最低值
- 發送者在池中沒有其他的使用者操作（或此使用者操作是為了取代既有項目而建構的）

有許多規則會影響這些檢查，詳細內容都在規格文件中有完整說明。

在這篇使用者操作的入門介紹中，我們的目的只是傳達用來判斷使用者操作有效性的高層次檢查。

### **2. 模擬使用者操作**

一旦使用者操作通過這些基本檢查，客戶端就需要模擬該使用者操作，以驗證它是否有能力支付其執行成本，無論是使用自己的資金還是透過 paymaster。

為了模擬使用者操作，bundler 會呼叫 **simulateValidation\(\)** 方法，該方法接著會呼叫發送者帳戶上的 **validateUserOp** 函式；若將由 paymaster 贊助執行此使用者操作所需的 gas 費用，則會呼叫 paymaster 合約帳戶上的 **validatePaymasterUserOp**。

呼叫 **simulateValidation\(\)** 方法之後，它會以 **ValidationResult** 回應進行 revert。此函式被 revert 是預期中的行為，這被視為成功的結果。

如果 **ValidationResult** 以不同的錯誤進行 revert，代表該使用者操作未通過驗證模擬，因此不會被加入 mempool。若使用者操作回傳 **sigFail**，則會被排除於 mempool 之外；此外，若 **validUntil** 回應已過期，UO 也可能會被排除於 mempool 之外。

**注意：** 如果使用者操作中存在 initCode，帳戶工廠（account factory）將會建立一個帳戶，接著模擬程序將會使用這個新建立的帳戶繼續進行。

現在使用者操作已經完成建構、檢查、模擬，並加入 mempool，接下來就可以將它傳送給入口點（entry point）合約進行驗證與執行了！

### **使用者操作如何被驗證與執行？**

為了讓使用者操作中的交易細節能夠發佈到鏈上，入口點合約需要驗證該使用者操作；若該 UO 通過驗證，入口點合約便會執行該交易，並向 bundler 償還其所支付的 gas 費用。

**使用者操作驗證與執行的基本步驟如下：**

1. bundler 透過 handleOps\(\) 方法，將使用者操作傳送給單一的入口點合約
1. 針對每個操作，入口點合約會在該操作發送者的錢包上呼叫 validateOp\*
1. 若有任何操作未通過驗證步驟，該操作會被捨棄
1. 接著，會在每個操作發送者的錢包上呼叫 executeOp，同時追蹤所使用的 gas 數量
1. 從發送者的錢包或 paymaster 將 ETH 轉帳給 bundler，以支付執行每個操作所使用的 gas

\*所有的驗證步驟會先全部執行完畢，之後才會執行所有已通過驗證的使用者操作的執行步驟。

以下這張圖說明了入口點合約如何代表發送者的智能合約錢包，驗證並執行使用者操作：

<ImageBlock
  src="https://media.alchemy.com/1703862507-user-operations-validations-executions.png"
  alt="使用者操作如何被驗證與執行"
  width={960}
  height={540}
/>

使用者操作是一種偽交易物件，讓智能合約錢包得以在 Ethereum 及相對應的 L2 上，作為使用者的主要錢包。智能合約錢包帶來了[web3 使用者體驗上的優勢](https://www.alchemy.com/overviews/smart-contract-wallet-benefits)，讓區塊鏈更容易被使用，而這一切都是透過 [Ethereum 與各 L2 上的 AA 基礎設施提供者](https://www.alchemy.com/account-abstraction) 才得以實現。

如果你的 [web3 產品支援智能合約錢包](https://www.alchemy.com/docs/how-to-make-your-dapp-compatible-with-smart-contract-wallets)，歡迎探索 Alchemy 的 AA 基礎設施，包括我們針對 Ethereum、Polygon、Arbitrum、Optimism 以及常用測試網（如 Sepolia）所提供的 Gas Manager API 與 Bundler API！
