跳到内容

AA Snap:账户抽象的民主化

ETHIndia 黑客马拉松获奖者

6 分钟阅读
AA Snap:账户抽象的民主化

MetaMask Snaps 是让 MetaMask 成为全球最具扩展性钱包的发展路线图。作为开发者,您可以通过全新的方式将您的功能和 API 带入 MetaMask。Web3 开发者是这一增长的核心,本系列旨在展示当今正在构建的创新 MetaMask Snaps。

AA Snap

Snap 代码库:https://github.com/a42io/AAsnap

您为什么要构建它?

AA Snap 的构建目标是让账户抽象(AA)对所有开发者和用户都触手可及。我们相信 AA 在未来将被广泛使用。然而,目前开发者将其集成到 dapp 中以及用户使用它都需要付出相当的努力。

从开发者的角度来看,除了支持 EOA 之外,还需要编写额外的代码来支持 AA。

从用户的角度来看,他们无法使用 MetaMask 等常用钱包,而需要另外安装支持 AA 的钱包,这带来了糟糕的用户体验。

因此,我们希望通过利用 MetaMask Snaps 使 AA 的集成和使用变得更加简便。

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

AA Snap 由三个组件构成:一个示例前端、MetaMask snap 以及一个临时服务器。该 snap 使开发者和用户能够非常轻松地使用 AA 钱包(支持 EIP-4337 的合约钱包)。完整实现请参阅代码库。

示例前端

示例前端基于 MetaMask 提供的模板构建。它向开发者展示了如何通过 AA Snap 轻松地将 AA 集成到他们的 dapp 中。

例如,可以使用以下简单代码获取 AA 钱包的余额。

const balance = (await window.ethereum.request({
    method: 'wallet_invokeSnap',
    params: [
        defaultSnapOrigin,
        {
            method: 'balance',
        },
    ],
})) as string;
复制

要从 AA 钱包发送交易,只需传入受益人地址和金额,编写以下代码即可。

await window.ethereum.request({
    method: 'wallet_invokeSnap',
    params: [
        defaultSnapOrigin,
        {
            method: 'transfer',
            params: {
                to,        // beneficiary address
                value,     // value in ETH or MATIC
            },
        },
    ],
});
复制

从用户角度来看,使用 AA 钱包有多简便?点击此处体验:https://AAsn.app

Snap

该 snap 通过以下代码获取 AA 实例。为了实现 AA,我们使用了 @account-abstraction/sdk npm 包。

由于 AA 钱包地址可以从用户的 EOA 确定性地推导出来,因此无需用户输入。

export const getAbstractAccount = async (): Promise<SimpleAccountAPI> => {
    const provider = new ethers.providers.Web3Provider(wallet as any);
    await provider.send('eth_requestAccounts', []);
    const owner = provider.getSigner();
    const aa = new SimpleAccountAPI({
        provider,
        entryPointAddress,
        owner,
        factoryAddress,
    });
    return aa;
};
复制

从 AA 钱包发送交易分为三个步骤:

  1. snap 使用 snap 的 snap_confirm 方法在 MetaMask 中显示确认提示。此步骤并非必需,但为了更好的用户体验而有必要保留,因为用户无法得知他们将要签名的内容详情。

  2. 代码创建 AA 钱包的用户操作,并请求对用户操作的哈希值进行签名。此过程与从 EOA 创建交易并签名几乎相同。

  3. 通过我们的服务器将已签名的用户操作发送至 bundler。

export const transfer = async (target: string, ethValue: string) => {
    const value = ethers.utils.parseEther(ethValue);
    const aa = await getAbstractAccount();
    const address = await aa.getAccountAddress();

    // 1. Show confirmation within MetaMask
    const result = await wallet.request({
        method: 'snap_confirm',
        params: [{
            prompt: 'Transfer',
            description: 'Transfer from your Abstraction Account',
            textAreaContent: `from: ${address}\ntarget: ${target}\nvalue: ${ethValue}`,
        }],
    });

    if (!result) {
        return;
    }

    // 2. Create a signed user operation of AA wallet
    const op = await aa.createSignedUserOp({
        target,
        value,
        data: '0x',
        maxFeePerGas,
        maxPriorityFeePerGas,
    });

    const printedOp = await printOp(op);
    const body = JSON.stringify({
        op: printedOp,
    });

    // 3. Send a signed user operation to the bundler
    const response = await fetch(SERVER_END_POINT {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body,
    });
};
复制

临时服务器

在黑客松期间,我们在 snap 内部调用 sendUserOpToBundler 方法时遇到了错误。由于没有时间深入排查问题,我们决定创建一个服务器来临时解决该问题。临时服务器仅接收已签名的用户操作并将其传递给 bundler。

该错误可能来源于依赖项,因为 MetaMask Snaps 执行环境存在一些限制。我们认为可以通过参考以下文档来移除临时服务器:修补依赖项

app.post('/aa', async (req, res) => {
  const provider = new ethers.providers.JsonRpcProvider(
    process.env.RPC_ENDPOINT,
  );
  const client = await getHttpRpcClient(
    provider,
    process.env.BUNDLER_URL as string,
    process.env.ENTRY_POINT_ADDRESS as string,
  );

  try {
    const uoHash = await client.sendUserOpToBundler(JSON.parse(req.body.op));
    return res.json({
      uoHash,
    });
  } catch (e) {
    console.log(e);
    return res.status(400).send();
  }
});
复制

如果您要继续实现这个项目,下一步计划是什么?

我们希望移除不必要的服务器端代码,让 snap 独立运行。此外,目前像我们这样的 MetaMask Snaps 开发者有可能将待签名的交易哈希替换为恶意哈希,因此我们希望引入或提出一种防范机制。

能介绍一下您自己和您的团队吗?

我们的团队在日本和新加坡经营着一家小型初创公司——a42。a42 正在构建一款 Web3 智能锁"wΞlock",支持通过包括 NFT 和 ENS 在内的智能合约进行身份验证:https://a42.io/w3lock。2022 年,我们参加了多场黑客松,学习 MetaMask Snaps 等新技术。

Hideyoshi Moriya(piyo.eth):Hideyoshi 自 2017 年起开始试验和构建基于以太坊的应用程序。他于 2017 年开发了协作 NFT 艺术项目"Pixereum"。他曾在 Google 担任技术产品专家,并于 2019 年创立了自己的公司"a42"。在 a42,他开发能够在现实世界中运行的 dapp。他目前正在基于 2021 年开发的概念验证,开发一款可通过 ENS/NFT 开锁的 Web3 智能锁"wΞlock":https://twitter.com/hm0429/status/1465241679800111107

Hiroyuki Tachibana(tachibana.eth):Hiroyuki 是 a42 的联合创始人兼工程师。他主导了为物联网设备构建区块链身份验证模块"w3a.io"的项目,并获得了以太坊基金会的资助。他在 2022 年的多场 ETHGlobal 黑客松中获得了多个奖项。他目前正在为 Web3 智能锁产品开发 zkp 隐私解决方案。

Yusuke Moriya(yskmyskm.eth):Yusuke 是 a42 的设计师。他曾担任 CG/VFX 艺术家,参与过各类视频制作,涵盖全球品牌到小型音乐视频项目。他在影视行业拥有 12 年经验,擅长使用计算机图形进行抽象表达。他还曾担任摄影师和纪录片导演。

您认为 MetaMask Snaps 为 Web3 领域带来了哪些机遇?

我们相信 MetaMask Snaps 将使复杂的 Web3 技术对开发者和用户都更加易于使用,并将极大地帮助传统 Web 应用程序与 Web3 融合。我们对构建 MetaMask Snaps 的热情,就如同第一家移动应用商店诞生时一样令人振奋。我们鼓励您亲身尝试,将您的想法变为现实!

对于有意尝试 MetaMask Snaps 的开发者,您有什么建议?

我们建议从 MetaMask Snaps 模板 (https://github.com/MetaMask/template-snap-monorepo) 开始,先对其进行修改。

小贴士:您可能想知道如何获取注入的 ethereum 对象。wallet 对象与其等效。

使用 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 不作任何明示或暗示的保证,并对第三方开发的 Snaps 免除一切责任。使用区块链相关软件存在风险,使用 MetaMask Snaps 即表示您完全承担上述风险。

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

评价此翻译

本文作者:

  • MetaMask

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

    阅读所有文章