---
title: "ERC-4337 dummy signature 與 gas token 轉帳"
description: "了解如何在 user operation gas 估算過程中，透過 dummy signature 與 dummy paymasterAndData 值取得 preVerificationGas 與 verificationGasLimit 欄位。"
---

# ERC-4337 dummy signature 與 gas token 轉帳

在[ERC-4337 Gas Estimation](https://www.alchemy.com/blog/erc-4337-gas-estimation)中，我們討論了 ERC-4337 中 gas 的運作方式，以及我們進行 gas 估算的方法。透過這個方法，我們應該能夠為使用者提供提交 user operation 所需的準確數值。可惜事情並沒有那麼簡單。

讓我們深入探討幾個讓 ERC-4337 gas 估算變得更複雜的問題。

## 什麼是虛擬（dummy）`signature` 值？

在大多數智慧合約帳戶的實作中，signature 欄位是在鏈下計算的，方式是對 user operation 進行 hash，再用某種簽章機制（最常見的是 ECDSA）對該 hash 進行簽署。這個 signature 會在驗證階段由帳戶合約在鏈上驗證。

舉例來說，`SimpleAccount` [使用](https://github.com/eth-infinitism/account-abstraction/blob/d1333cf58c17d5cc84e830f3fc3a69081c777979/contracts/samples/SimpleAccount.sol#L93)[EIP-191](https://eips.ethereum.org/EIPS/eip-191)簽章機制對 hash 進行處理，並在其 `validateUserOp` 函式中透過 [OpenZeppelin](https://www.alchemy.com/dapps/openzeppelin) 的 [ECDSA library](https://docs.openzeppelin.com/contracts/2.x/api/cryptography#ECDSA-toEthSignedMessageHash-bytes32-) 在鏈上驗證。

這個 signature 必須在 gas 估算完成之後才能計算，因為那些欄位會被包含在 hash 之中。

然而，gas 估算步驟中有部分需要 signature 欄位已經被填入：`preVerificationGas` 和 `verificationGasLimit `。

### preVerificationGas

在本系列第一篇文章討論 `preVerificationGas` 估算的段落中，我們提到 bundler 用來計算未被計量的 gas 的三種運算方式。

請注意，第 2 步和第 3 步（計算 user op 在 calldata gas 成本中所佔的份額，以及在任何執行 gas overhead 中所佔的份額）都直接取決於 user operation 的長度與內容，包括 `signature` 欄位。

### verificationGasLimit

幾乎所有有實際用途的智慧合約帳戶實作都需要某種形式的 signature 驗證。這個 gas 需要被估算！這個估算過程不能發生 revert，否則就無法計算出 verification gas。

那我們該如何選擇要使用哪個 signature 呢？

## 如何計算虛擬 signature 值

為了解決這些問題，許多 [ERC-4337 bundler](https://www.alchemy.com/overviews/what-is-a-bundler) 會使用「Dummy Signature」，這個值必須由呼叫 `eth\_estimateUserOperationGas` 的一方根據特定的帳戶類型提供。

### 限制條件

這個 dummy signature 有幾項限制：

1. dummy 值的長度應等於該帳戶合約中最大的 signature 長度，並且必須包含該帳戶有效的最大數量非零位元組。
   a. 這樣可以確保 `preVerificationGas` 的計算能夠涵蓋最差情況下 signature 對 calldata 和 entry point overhead 成本的影響。
1. 這個 dummy 值在提供給帳戶的驗證函式時，必須導致最差情況下的 gas 使用量，且不能造成 revert。
1. 這個 dummy 值不應該是任何有效 user operation 的合法 signature。

`SimpleAccount` 的 dummy `signature` 值範例，可在我們針對 [eth_estimateUserOperationGas](https://www.alchemy.com/docs/wallets/api-reference/bundler-api/bundler-api-endpoints/eth-estimate-user-operation-gas) 方法的文件中找到。

**這個 dummy signature 具有以下特性：**

1. 長度與 ECDSA signature 完全相同
1. 包含 ECDSA signature 中允許的最大數量非零位元組
1. 它是一個有效的 ECDSA signature（讓 `.recover\(\)` 呼叫不會 revert）
1. 它不是任何已知 user operation 的 signature，因此 `SimpleAccount` 永遠會回傳 `SIG\_VALIDATION\_FAILED`

帳戶實作者需要確保他們撰寫的驗證函式，能夠接受 dummy signature 作為輸入。

**這代表：**

1. 只對不可能是 dummy signature 的 signature 使用 `REVERT`。當提供的是 dummy signature 時，回傳 `SIG\_VALIDATION\_FAILED`。
1. 注意不要讓 dummy signature 的失敗判斷「提早結束」。也就是說，dummy 值應該完整跑完整個驗證函式，並使用最大量的 gas。
1. 實務上，這表示要移除任何提早 return 的邏輯。帳戶驗證函式可能會很早就判斷出 signature 無效，但仍應繼續執行函式邏輯，直到最後才回傳失敗結果。

## 如何計算虛擬 `paymasterAndData` 值

上述相同的要求也適用於 gas 估算期間的 `paymasterAndData` 欄位：對於任何依賴 gas 欄位數值（例如用於計算 signature）的 paymaster 實作，我們都必須解決提供 dummy 值的同樣問題。

### 限制條件

這個 dummy `paymasterAndData` 有幾項限制：

1. dummy 值的長度應等於最大的 `paymasterAndData` 長度，並且必須包含該帳戶有效的最大數量非零位元組。
   a. 這樣可以確保 `preVerificationGas` 的計算能夠涵蓋最差情況下 `paymasterAndData` 對 calldata 和 entry point overhead 成本的影響。
1. 這個 dummy 值在提供給 paymaster 的驗證函式時，必須導致最差情況下的 gas 使用量，且不能造成 revert。
1. 這個 dummy 值不應該是任何有效 user operation 的合法 `paymasterAndData`。

舉例來說，一個依賴於對 user operation hash 進行贊助簽章驗證的 [sponsoring paymaster](https://www.alchemy.com/overviews/what-is-a-paymaster)，在估算期間需要提供一個具有上述類似特性的 dummy `paymasterAndData` 值：

1. 這個 dummy 值必須包含一個有效的 paymaster 合約地址
1. 針對 `preVerificationGas` 計算所需的最大長度與位元組值
1. 當提供給 paymaster 的驗證函式時，必須消耗最大量的 gas，並回傳 `SIG\_VALIDATION\_FAILED`

Paymaster 實作者需要確保他們撰寫的驗證函式，能夠接受 dummy `paymasterAndData` 作為輸入。

**這代表：**

1. 只對不可能是 dummy 一部分的資料使用 `revert`。改為回傳 ` SIG\_VALIDATION\_FAILED`。
1. 注意不要讓 dummy 的失敗判斷「提早結束」。也就是說，dummy 應該完整跑完整個驗證函式，並使用最大量的 gas。
   a. 實務上，這表示要移除任何提早 return 的邏輯。paymaster 驗證函式可能會很早就判斷出 signature 無效，但仍應繼續執行函式邏輯，直到最後才回傳失敗結果。

## Gas token 轉帳

`verificationGasLimit` 的估算必須將驗證階段中任何 token 轉帳的 gas 成本納入考量。許多 [user op](https://www.alchemy.com/overviews/user-operations) 在驗證期間會進行 token 轉帳，用來預付 gas 費用，並在操作結束時針對未消耗的 gas 進行退款。

這裡有兩種情況：

1. 沒有 Paymaster——這是從 sender 轉帳 ETH 到 entry point 合約。
1. 有 Paymaster——這可以是任何形式（在規範允許的規則範圍內），但通常會是從 sender 轉帳 ERC-20 token 到 paymaster。

#### 如果帳戶資金不足會發生什麼事？

如果 `maxFeePerGas` 被設為非零值，當帳戶沒有足夠的 token 支付費用時，驗證期間的轉帳就會發生 revert。這代表使用者必須先為帳戶注入資金，才能嘗試估算 gas。

**一個目前無法實現的理想流程：**

1. 估算 gas
1. 為帳戶注入 gas 所需資金
1. 送出 operation

一個可能的解決方式，是告訴使用者在呼叫 `eth\_estimateUserOperationGas` 時，讓 `maxFeePerGas` 保持未設定，或設為零。然而，這會導致 gas 成本被設為零，進而讓任何需要進行的 token 轉帳金額也變成零。在[許多帳戶／paymaster 類型](https://github.com/eth-infinitism/account-abstraction/blob/d1333cf58c17d5cc84e830f3fc3a69081c777979/contracts/core/BaseAccount.sol#L101)中，gas 成本為零時會跳過對 `transfer` 的呼叫。這會導致當使用零值 `maxFeePerGas` 時，出現 gas 低估的情況。

另一個問題與使用非零 `maxFeePerGas`，並嘗試採用本系列第一篇文章中「[Attempt 3: Binary Search](https://www.alchemy.com/blog/erc-4337-gas-estimation)」所定義的二分搜尋估算方法有關。

該方法的第一步，是使用一個最大 gas 值來確認該 operation 是可行的。但 sender 可能沒有足夠的資產能在該最大值下支付 gas，而 bundler 也不一定有足夠的資訊能確定費用 token 的餘額（例如在 ERC-20 paymaster 的情況下），以決定正確的上限值。

### Alchemy 的 bundler 如何解決涉及 token 轉帳的 gas 估算問題？

Rundler 針對 `eth\_estimateUserOperationGas` 所採取的方法如下：

#### 沒有 paymaster 的情況

- Rundler 永遠會忽略 `maxFeePerGas` 和 `maxPriorityFeePerGas`，並將其設為 0。
- Rundler 永遠會在 `verificationGasLimit` 上加上固定的 10K gas，用來涵蓋從 sender 轉帳 ETH 存款給 entry point 的成本。
- 客戶端不需要做任何變更。

<CalloutBlock>

💡 第一點與 ERC-4337 規範有所出入，該規範表示「gas limit（與價格）參數是選填的，但若有指定則會被使用」

</CalloutBlock>

#### 有 paymaster 的情況

- Rundler 永遠會忽略 `maxFeePerGas` 和 `maxPriorityFeePerGas`，並將其設為 0。
- 如果任何 paymaster 邏輯是根據費用數值來決定是否執行（例如 ERC-20 轉帳的情況），Rundler 的 `verificationGasLimit` 就一定會被低估。
- 使用這類 paymaster 的使用者，必須自行在客戶端考量因非零費用所產生的額外 gas。

舉例來說，如果使用的是一個會在驗證階段執行轉帳的 ERC-20 paymaster，就應該在 `eth\_estimateUserOperationGas` 回傳的 `verificationGasLimit` 上，永遠加上固定的 75K gas。這需要客戶端了解自己所呼叫的 paymaster 合約，並事先知道因轉帳而導致的 gas 成本低估情況。

<CalloutBlock>

💡 Alchemy 的 [aa-sdk](https://github.com/alchemyplatform/aa-sdk) 讓 paymaster middleware 能夠[相應地調整這個 gas limit](https://github.com/alchemyplatform/aa-sdk/blob/56bc34be3a50a2709ca546ed90a980f3c489cbbe/packages/core/src/provider/types.ts#L43)。

</CalloutBlock>

## 這對開發者來說代表什麼？

Dummy 值與 token 轉帳的問題，會影響到建構智慧合約帳戶、paymaster 以及帳戶客戶端的開發者。

### 智慧合約帳戶開發者

智慧合約帳戶開發者需要確保，能夠根據帳戶驗證函式的執行方式，在客戶端始終決定出一個 dummy signature 值。這個 signature 不能造成 revert，並且必須產生最大的 gas 估算值。

### Paymaster 開發者

Paymaster 開發者必須確保，能夠根據 paymaster 驗證函式的執行方式，始終決定出一個 dummy `paymasterAndData` 值。這個值不能造成 revert，並且必須產生最大的 gas 估算值。

<CalloutBlock>

💡 Alchemy 在其 sponsoring paymaster 中，透過 [alchemy_requestGasAndPaymasterAndData](https://www.alchemy.com/docs/wallets/api-reference/gas-manager-admin-api/gas-abstraction-api-endpoints/alchemy-request-gas-and-paymaster-and-data) 將 gas 估算流程與模擬流程結合，為使用者簡化了這個問題。

</CalloutBlock>

### 帳戶客戶端開發者

如果帳戶客戶端開發者整合的 paymaster 會在驗證階段執行轉帳（或任何其他依據費用數值而定的邏輯），並且使用 Alchemy 的端點來進行估算，就需要將與該轉帳相關的潛在 gas，加到估算所回傳的 `verificationGasLimit` 中。

敬請期待後續文章，我們將介紹更多 ERC-4337 gas 估算的複雜之處！

🦀

## 延伸閱讀

本系列共四篇文章，接下來的文章將探討在 Optimism 與 Arbitrum 等 layer 2 區塊鏈上估算 gas 的挑戰，以及 signature aggregator 的相關議題。

本系列將以 user operation 費用估算流程的完整說明作結。如果你錯過了第一篇文章，可以先了解 ERC-4337 gas 估算的運作方式！

- [How ERC-4337 Gas Estimation Works](https://www.alchemy.com/blog/erc-4337-gas-estimation)
- [L2 Gas and Signature Aggregators](https://www.alchemy.com/blog/l2-gas-and-signature-aggregators)
- [User Operation Fee Estimation](https://www.alchemy.com/blog/user-operation-fee-estimation)
