跳至內容

撤銷 Snap:撤銷 ERC20 代幣合約上的剩餘授權

一個 ETHWarsaw 黑客松 Snap,讓用戶可以撤銷剩餘的合約授權。

閱讀時間:7 分鐘
撤銷 Snap:撤銷 ERC20 代幣合約上的剩餘授權

MetaMask Snaps 是讓 MetaMask 成為全球最具擴展性錢包的發展藍圖。身為開發者,您可以用全新的方式將您的功能和 API 帶入 MetaMask。Web3 開發者是這項成長的核心,本系列旨在展示當今正在建構的創新 MetaMask Snaps。

Revoke Snap:與 Swix Jedi 和 Adrian 的對談

我們與 Web3 開發者 Swix Jedi 和 Adrian 進行了交流,他們在 ETHWarsaw Hackathon 上共同打造了 Revoke Snap。

Snap 儲存庫: https://github.com/SwixJedi/revokesnap

你們為什麼要建構它?

為了確保外部參與者使用代幣的安全性,ERC20 代幣標準實作了授權額度(allowance)機制,代幣持有者需要批准某個參與者(例如 DEX 智能合約)在選定的限額內使用其代幣。

為了改善 DeFi 使用者體驗中較為繁瑣的部分,許多 DeFi 協議在授權時採用最大值 256 作為批准額度,讓使用者無需每次與合約互動時都重新批准代幣並支付不必要的 gas 費用。

然而,對於活躍的 DeFi 使用者來說,使用上述協議後很容易留下一些剩餘的授權,這是潛在的安全威脅。

雖然目前已有一些解決方案協助使用者處理剩餘授權,但只有部分方案提供直接從使用者介面進行撤銷的功能。這個過程相當耗時,因為每筆授權都需要單獨處理並手動確認。雖然這種方式是安全的,但需要大量持續的手動操作。

這讓我們發現了一個尚未被充分解決的需求,我們可以藉助 MetaMask Snaps 的功能來改善這個問題。

能否帶我們了解技術實作的細節?

我們決定善用 MetaMask Snaps 的以下優勢:

  • 存取 MetaMask 中的所有帳戶

  • 能夠透過使用者的單次批准執行複雜操作

為了提出解決此問題的方案,未來應能實現以下功能:

  • 僅向使用者顯示一次提示,即可存取所有現有及未來的帳戶(硬體錢包除外)

  • 批次撤銷所有現有帳戶的授權,無需個別確認或切換帳戶

  • 主動監控所有使用者帳戶(包括硬體錢包上的帳戶)的新授權,並在偵測到時向使用者顯示通知

透過網頁介面安裝 Revoke Snap 時,MetaMask 將提示所需的權限。

所有權限均在 snap.manifest.json 檔案中指定:

"initialPermissions": {
    "snap_confirm": {},
    "snap_getBip44Entropy_60": {},
    "snap_notify": {},
    "endowment:long-running": {}
  },
複製

這裡有兩項值得特別說明的權限:

1. 控制您的「以太坊」帳戶和資產。 這意味著為了正常運作,我們的 Snap 需要從 MetaMask 取得使用者的父金鑰(私密金鑰),以便代表使用者生成帳戶並簽署交易。

2. 無限期執行。 雖然 Revoke Snap 並非設計為持續在背景執行的實作,但在區塊鏈上完成交易需要時間,而 MetaMask Snaps 內建了 60 秒後的強制終止機制,這可能不足以完成所有交易。此權限允許 RevokeSnap 繞過該安全限制。

取得必要權限後,RevokeSnap 將根據使用者的私密金鑰生成多個帳戶:


// Get chosen amount of wallets (signers) from provider (in this case Metamask)
export async function getSigners(provider: ethers.providers.Provider, amount: number): Promise<Wallet[]> {
    let wallets: Wallet[] = [];

    for (let i=0; i<amount; i++) {
        wallets.push(await getSigner(provider, i));
    }

    return wallets;
}

// Exctract addresses out of wallets
export function getAddresses(wallets: Wallet[]): string[] {
    let addresses: string[] = [];

    for (let i=0; i<wallets.length; i++) {
        addresses.push(wallets[i].address);
    }

    return addresses;
}
複製

// Fetch parent key from Metamask and generate a wallet from it, base on the input index
export async function getSigner(provider: ethers.providers.Provider, index: number): Promise<Wallet> {
    // Metamask uses default HD derivation path
    // https://support.metamask.io/managing-my-wallet/secret-recovery-phrase-and-private-keys/importing-a-seed-phrase-from-another-wallet-software-derivation-path/
    const ethereumNode = (await wallet.request({
      method: 'snap_getBip44Entropy_60',
    })) as unknown as BIP44CoinTypeNode;
    const deriveEthereumAccount = await getBIP44AddressKeyDeriver(ethereumNode);
    // A bug:
    // The current public version of @metamask/key-tree's derive function returns the private key and chain code in a single buffer
    // Ether.js also accepts a 64 byte buffer without errors and returns wrong keys
    // Related issue: https://github.com/ethers-io/ethers.js/issues/2926
    // TODO(ritave): Update to newest key-tree when available and use deriveEthereumAccount(0).privateKey
    const mainAccountKey = (await deriveEthereumAccount(index)).privateKey;
    return new Wallet(mainAccountKey, provider);
  }
複製

接著對剩餘授權進行檢查,搜尋完成後顯示一個按鈕,讓使用者撤銷所有已識別的授權。

點擊「Revoke All」按鈕後,Snap 將針對每筆剩餘授權依序發出一系列交易,逐一將其歸零。由於 Snap 已持有所生成錢包的私密金鑰,除了最初的一次確認外,不需要使用者進行任何額外確認。

如果要繼續實作,下一步是什麼?

由於 Hackathon 期間時間有限,無法打造最優化的解決方案,我們採用了一些仍有改進空間的功能實作。

首先,目前 Snap 中生成的帳戶數量是以函數參數傳入並硬編碼為 3。更好的做法是讓 Snap 使用外部 API(或專用後端)來驗證每個帳戶在指定鏈上的下一筆交易 nonce,並只考慮 nonce 大於 0 的地址。

此外,在授權檢查方面,我們使用了一份已知代幣和參與者地址的簡短清單來展示功能,但理想情況下,授權檢查應更全面。例如,可以使用 RPC 提供者 API(如 Infura)來查找所有授權交易,並解析後顯示在網站上。

能否介紹一下你們自己和團隊?

我是 Jedi,目前在 Swix 擔任首席開發者。我從 2017 年開始接觸加密貨幣,2019 年開始深入鑽研並從事 DeFi 協議的開發工作,主要專注於智能合約方面。在 Swix,我目前致力於將房地產收益上鏈,並將新用戶引入加密貨幣領域。

我是 Adrian,曾在小型新創公司和大型企業擔任軟體開發者和架構師。區塊鏈是我多年來的主要興趣領域,尤其是以太坊生態系統。

在開發 Revoke Snap 的過程中,我們分工合作:Jedi 負責研究 MetaMask Snaps 的運作方式,並為 Snap 內所需的智能合約互動建立必要的基礎架構;Adrian 則負責網頁介面和交易的打包處理。

你們是什麼時候第一次接觸到 MetaMask Snaps 的?體驗如何?

我們是在 ETHWarsaw 的演講中第一次接觸到 MetaMask Snaps,那場演講相當技術性,深入介紹了協議底層的運作機制。這激發了我們進一步研究這個主題的興趣,於是就有了今天的成果。

MetaMask Snaps 與其他錢包有何不同?

我覺得……最關鍵的是這個理念本身。MetaMask Snaps 突破了非託管瀏覽器錢包擴充功能領域中普遍接受的標準——也就是與 Web3 應用程式互動時,每筆交易都需要使用者個別批准。此外,錢包的功能也受限於背後團隊決定實作的功能範疇。

MetaMask Snaps 帶來的是一個平台,能夠由下而上地為任意區塊鏈互動創建原生錢包整合,這與行動應用程式商店的概念非常相似。

您認為 MetaMask Snaps 為 Web3 領域帶來了哪些機會和可能性?MetaMask Snaps 對您意味著什麼?

MetaMask Snaps 為加密貨幣領域帶來的最大價值之一,是改善加密貨幣和 DeFi 協議的使用者體驗。無論是實現交易打包、對同一個 dApp 內所有交易進行一鍵批准、允許在執行信用卡購幣時直接進行合約互動,還是其他更具創意的解決方案,一切都有待時間來揭曉。

我們堅信,尤其對於加密貨幣新用戶而言,將區塊鏈互動的複雜性和繁瑣性抽象化,將會是一個改變遊戲規則的突破。

請告訴我們您和您的團隊使用 MetaMask 建構 MetaMask Snaps 的體驗如何?

建構 Revoke Snap 的一大動力在於,MetaMask Snaps 仍在持續開發中,因此我們現在所做的實驗可以對 MetaMask、MetaMask Snaps 乃至整個加密貨幣領域的未來走向產生實質影響。能夠為 Web3 的未來添磚加瓦,這是一段很棒的體驗。

對於有意嘗試 MetaMask Snaps 的開發者,您有什麼建議?

對於任何想嘗試 MetaMask Snaps 的開發者——放手去做吧。利用 GitHub 上現有的模板儲存庫,MetaMask Snaps 的入門相當直觀,MetaMask 團隊也非常樂於提供協助。這個概念本身潛力巨大,目前已有的實作還不多,因此很容易就能創造出有價值的貢獻。

使用 MetaMask Snaps 進行建構

開始使用 MetaMask Snaps:

  1. 查閱開發者文件

  2. 安裝 MetaMask Flask

  3. 參考 MetaMask Snaps 指南

  4. 透過 Twitter、GitHub discussions 和 Discord 與我們保持聯繫

請留意我們團隊在您附近舉辦的下一場 Hackathon!祝 BUIDLing 愉快 ⚒️

免責聲明:MetaMask Snaps 通常由 Consensys Software 以外的第三方開發。使用第三方開發的 MetaMask Snaps 須由您自行判斷並承擔風險,且您同意對因此類活動所造成的任何損失或損害負完全責任。Consensys 對第三方開發的 MetaMask Snaps 不提供任何明示或暗示的保證,並對第三方開發的 MetaMask Snaps 免除一切責任。使用區塊鏈相關軟體存在風險,使用 MetaMask Snaps 即表示您完全承擔這些風險。

AI 翻譯。可能包含錯誤。請務必核實資訊。

評價此翻譯

本文作者:

  • MetaMask

    MetaMask,前身為 Consensys Software Inc,是全球最大的自託管金融平台,讓用戶能在單一平台上持有、消費、儲蓄並增值其資產,涵蓋加密貨幣與傳統資產。公司正致力於打造實現上述目標的消費者平台,將支付、儲蓄、投資與數位資產整合於一個無縫的使用體驗中。MetaMask 從全球使用最廣泛的自託管錢包發展而來,讓用戶直接掌控自己的資金與資產,服務範圍遍及約 190 個國家。自 2016 年起,MetaMask 在以太坊的發展歷程中扮演了奠基性的角色。時至今日,MetaMask 位居區塊鏈經濟的核心,致力於構建「開放金融」的作業系統,讓每個人都能全面掌握自己的財務生活。

    閱讀所有文章