跳到内容

撤销 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 黑客马拉松上共同构建了 Revoke Snap。

Snap 代码库: https://github.com/SwixJedi/revokesnap

你们为什么要构建它?

为了确保外部参与者使用代币的安全性,ERC20 代币标准实现了一种授权机制——代币所有者需要批准某个参与者(例如 DEX 智能合约)在选定的限额内使用其代币。

为了改善 DeFi 用户体验中较为繁琐的环节,许多 DeFi 协议在授权时使用最大值 256,这样用户每次与合约交互时就无需重复批准代币,也无需在不必要的 gas 费上花费资金。

然而,对于活跃的 DeFi 用户而言,在使用上述协议后很容易出现遗留授权的情况,这是一个潜在的安全隐患。

虽然目前已有一些解决方案帮助用户处理遗留授权,但只有部分方案支持直接通过用户界面进行操作。这一过程耗时较长,因为每项授权都需要单独处理并手动确认。尽管这种方式较为安全,但需要用户持续进行大量手动操作。

正是这一痛点让我们发现了一个尚未被充分解决的细分需求,我们可以借助 MetaMask Snaps 的能力来改善这一体验。

能带我们了解一下技术实现方案吗?

我们决定充分利用 MetaMask Snaps 的以下优势:

  • 访问 MetaMask 中的所有账户

  • 通过用户的单次批准执行复杂操作

为此问题提出解决方案,未来应能实现:

  • 仅向用户呈现一次提示,即可获得对所有当前及未来账户的访问权限(硬件钱包除外)

  • 批量撤销所有当前账户的全部授权,无需单独确认或切换账户

  • 主动监控所有用户账户(包括硬件钱包上的账户)的新授权,并在检测到时向用户发送通知

通过 Web UI 安装 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 已持有所生成钱包的私钥,除最初的一次确认外,无需用户进行任何额外确认。

如果继续推进,下一步计划是什么?

由于黑客马拉松期间时间有限,无法打造最优方案,我们采用了一些仍有改进空间的功能性实现。

首先,目前 Snap 中生成的账户数量作为函数参数传入,硬编码为 3。更好的方案是让 Snap 使用外部 API(或专用后端)来验证每个账户在指定链上的下一个交易 nonce,并仅考虑 nonce 大于 0 的地址。

此外,在授权检查方面,我们使用了一份已知代币和参与者地址的简短列表来展示功能,但理想情况下,授权检查应在更广泛的范围内进行。例如,可以使用 RPC 提供商 API(如 Infura)查找所有授权交易,并对其进行解析后展示在网站上。

能介绍一下你们自己和团队吗?

我是 Jedi,目前在 Swix 担任首席开发者。我从 2017 年开始接触加密货币,2019 年深入其中,开始专注于 DeFi 协议,主要从事智能合约方向的工作。在 Swix,我目前致力于将房地产收益上链,并将新用户引入加密领域。

我是 Adrian,曾在小型初创公司和大型企业担任软件开发者和架构师。多年来,区块链一直是我最感兴趣的领域,尤其是以太坊生态系统。

在开发 Revoke Snap 的过程中,我们进行了分工:Jedi 负责研究 MetaMask Snaps 的工作原理,并为 Snap 内所需的智能合约交互搭建必要的基础;Adrian 则负责 Web UI 和交易的打包处理。

你们是什么时候第一次接触 MetaMask Snaps 的?体验如何?

我们在 ETHWarsaw 的演讲中第一次接触到 MetaMask Snaps,那次演讲相当技术性,深入介绍了协议底层的运作机制。这激发了我们进一步研究这一课题的兴趣,于是便有了今天的成果。

MetaMask Snaps 与其他钱包有何不同?

说到底……是理念本身。MetaMask Snaps 突破了非托管浏览器钱包扩展领域的既有标准——即在与 Web3 应用交互时,每笔交易都需要用户单独批准,且钱包功能仅限于其背后团队决定实现的内容。

MetaMask Snaps 带来的是一个平台,支持自下而上地为任意区块链交互创建原生钱包集成,这与移动应用商店的模式颇为相似。

你们认为 MetaMask Snaps 为 Web3 领域带来了哪些机遇?它对你们意味着什么?

MetaMask Snaps 为加密领域带来的最大价值之一,是优化加密和 DeFi 协议的用户体验。无论是支持交易打包、在同一 dApp 内对所有交易进行一键授权、在执行信用卡购币时直接与合约交互,还是其他更具创意的解决方案,一切都有待时间来揭晓。

我们坚信,尤其对于加密新用户而言,将区块链交互的复杂性和繁琐性抽象化,将是一个改变游戏规则的突破。

构建 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 讨论区和 Discord 与我们保持联系

请关注我们团队在您附近举办的下一场黑客马拉松!祝 BUIDL 愉快 ⚒️

免责声明:MetaMask Snaps 通常由 Consensys Software 以外的第三方开发。使用第三方开发的 MetaMask Snaps 完全由您自行决定并承担风险,且您同意对因此类活动造成的任何损失或损害承担全部责任。Consensys 对第三方开发的 MetaMask Snaps 不作任何明示或暗示的保证,并对第三方开发的 MetaMask Snaps 免除一切责任。使用区块链相关软件存在风险,使用 MetaMask Snaps 即表示您完全接受并承担上述风险。

AI 翻译。可能包含错误。请务必核实信息。

评价此翻译

本文作者:

  • MetaMask

    MetaMask(前身为 Consensys Software Inc)是全球最大的自托管金融平台,为用户提供一站式服务,涵盖加密资产与传统资产的持有、消费、储蓄与增值。公司正在打造实现上述功能的消费级平台,将支付、储蓄、投资与数字资产整合于一体,带来无缝一体化的使用体验。MetaMask 脱胎于全球使用最广泛的自托管钱包,让用户直接掌控自己的资金与资产,覆盖约 190 个国家和地区。自 2016 年起,MetaMask 在以太坊的发展历程中扮演了举足轻重的奠基角色。如今,MetaMask 处于区块链经济的核心位置,致力于构建「开放货币」的操作系统,让每个人都能全面掌控自己的财务生活。

    阅读所有文章