Safe 智能合约账户的基础知识 - 第 1 部分

  • Bazzani
  • 发布于 1天前
  • 阅读 147

这篇文章深入探讨了以太坊的Safe智能账户(Safe Smart Accounts)的基础知识,涵盖了定义、架构、关键功能及其与多重签名和元交易等概念的关系。文章提供了详细的术语说明,并分层次地展示如何安全地操作和管理高价值的安全智能账户,同时为后续的安全最佳实践奠定了基础。

引言

Safe合约账户 是以太坊账户抽象生态系统的关键构建块,提供Safe和模块化的链上资产管理。然而,对于其内部运作有深刻理解是避免关键错误的关键。

本文档定义了必须理解的关键术语和架构组件,以Safe地操作Safe合约账户。作为两部分系列的第一部分,它为第二篇文章打下基础,专注于管理高价值Safe合约账户的Safe最佳实践。

如果你已经熟悉基本知识,可以跳过到第二部分获取有关保护Safe合约账户的实用策略。

定义

外部拥有账户 (EOA)

外部拥有账户 (EOA) 是以太坊上的两种账户类型之一。EOA由私钥控制,没有关联代码,并依赖于非对称加密密钥对。换句话说,它由一个可以用来发起以太坊交易和签署消息的私钥组成。如果有人获得此私钥的访问权,他们将完全控制该账户。这使得私钥成为一个关键的单点故障,如果被泄露,可能导致未授权控制EOA。

智能合约账户

智能合约账户 利用智能合约的可编程性,以扩展与EOA相比的功能。智能合约账户通常由一个或多个EOA,或其他智能合约账户控制。每个智能合约账户都有一个唯一的以太坊地址,仅通过检查地址本身与EOA区分。关键的不同在于智能合约账户不依赖于私钥进行交易验证。相反,智能合约的代码定义了交易认证和授权的逻辑。

元交易

由于智能合约账户无法直接发起以太坊交易,因此它们执行的交易被称为元交易。元交易是一种编码消息,其中包含智能合约账户将要执行的操作的信息。要执行元交易,必须首先将其嵌入在常规以太坊交易中,然后提交到智能合约账户进行验证和执行。元交易不遵循标准的以太坊交易结构,并且根据智能合约账户的实现,可能使用不同的编码和验证机制。

以太坊上的元交易生命周期。

多重签名

多重签名账户是一个智能合约账户,允许你定义定制的所有权和控制结构。多个以太坊账户可以被指定为所有者,你可以指定多少个所有者必须批准交易才能执行。这个配置通常表示为“n-of-m”,其中m代表指定所有者的总数,n是执行交易所需的最低所有者批准数量(法定人数)。

钱包

钱包是一个界面,允许用户管理和与他们的以太坊账户互动。钱包存储EOA的私钥,并使用户能够签署和执行以太坊交易。为了方便起见,在本指南中,我们将钱包分为两类:

  • 硬件钱包: Safe地离线存储私钥的物理设备,提供与互联网断开的隔离签名界面。
  • 软件钱包: 在通常连接到互联网的设备上存储私钥的应用程序,并作为签名的接口。

EIP-712

EIP-712 ² 是一种标准,定义了一种在以太坊中签署和验证结构化数据的方法。它允许用户对链外消息进行签名,然后以标准化的方式在链上进行验证。通过这种标准化的方法,钱包供应商可以轻松实现功能,以清晰地解释EOA所签署的内容,从而防止对任意字节数组进行盲签名。在智能合约账户的背景下,EIP-712通常用于编码和签署元交易。

委托调用

delegatecall 是一种低级以太坊指令,允许智能合约在其自身上下文中执行来自另一合约的代码。这意味着外部代码在调用合约的执行上下文和存储中运行,能够代表其执行。

在某些情况下,使用delegatecall可能存在重大风险。由于delegatecall在调用合约的上下文中执行外部代码,不当处理这些可能导致严重的漏洞。具体而言,如果未受信任的代码被执行,可能完全控制调用合约的存储和功能,可能导致所有资金和智能合约账户的权力受到危害。

Safe 合约账户

概述

Safe合约账户 是一个用Solidity编写的多重签名智能合约账户的实现,由Safe开发。其核心逻辑高度灵活,旨在支持广泛的应用场景。主要特点包括:

  • 支持多种阈值配置,包括“0-of-0”、“1-of-1”和其他“n-of-m”组合 ²
  • 支持通过替代访问方法执行交易的模块(而不是仅依赖于多重签名)。
  • 支持在“n-of-m”方案上增加限制的保护
  • 通过delegatecall指令支持复杂的执行逻辑,使Safe合约账户能够执行来自外部合约的代码。一个明确的例子是Safe库合约,它处理复杂的交易场景。具体来说,批量交易库允许将多个简单的以太坊交易组合并同时执行。

值得强调的是,Safe合约账户的高度灵活性源于其能够适应不同的用例。然而,较简单的系统通常更易于Safe。

系统实体

Safe合约账户智能合约Safe合约账户智能合约是一系列由Safe维护的开源Solidity智能合约。这些合约实现了Safe合约账户以及其他附属系统。safe-smart-account代码库包含核心智能合约。在这些合约中,特别重要的是理解以下内容:

  • Safe: 此单实例合约仅部署一次,供SafeProxy合约通过delegatecall使用。它提供了签名验证、交易执行、所有者管理、模块交互和处理回退函数的核心逻辑。由于它是单实例合约,因此无法直接用作Safe账户,必须通过SafeProxy实例进行访问。
  • Safe代理: 一个将所有调用委托给Safe单例合约的合约。部署代理显著降低了创建Safe账户的成本,因为代理的字节码大小小于完整Safe合约的代码。代理合约本身持有与Safe合约账户相关的所有资产和权限。
  • Safe代理工厂: 提供了一种简单的方法来部署指向单例合约的新代理合约。该合约的唯一目的是创建新的Safe合约账户。

尽管代理/实现方法提高了Gas效率并提供了更大的灵活性,但如果处理不当,也会引入重大风险。例如,攻击者可能会欺骗所有者授权一个交易,将Safe代理中的委托逻辑地址替换为恶意地址,从而获得对Safe智能合约账户的完全控制。

Safe合约账户部署流程。

所有者 一个Safe所有者是对特定Safe账户有控制的账户。只有所有者可以管理Safe的配置和批准交易。所有者可以是EOA或智能合约(通过EIP-1271 ³)。Safe的阈值定义了批准交易之前所需的最低所有者数量。

每个Safe账户维护其自己的所有者列表,作为存储在链上的以太坊地址。所有者可以添加或移除其他所有者,还可以调整阈值,阈值也存储在Safe合约账户的存储中。Safe账户可以拥有任何数量的所有者,阈值可以设置为从一个到总所有者数量的任意值。

Safe{Wallet}

Safe{Wallet} 是一个由Safe主办的全栈应用程序,旨在方便与Safe合约账户的交互。它提供了一个现成的接口,用于操作Safe合约账户,存储签名,并在交易在链上提交和执行之前执行验证检查。这确保在提交到区块链之前,所有必需的批准都已满足,从而促进协调,并改善管理元交易时的用户体验。

除了Safe{Wallet},还存在多个其他界面和工具用于与Safe合约账户交互。其中,以下工具被Safe 推荐作为替代:

  • Palmeradao.xyz: 一个社区开发的替代方案,提供类似于Safe{Wallet}的功能,使用户能够通过用户友好的界面管理多重签名账户。
  • SafeCLI: 设计供强大用户和开发者使用的命令行接口,他们喜欢通过脚本或自动化工作流程与Safe合约账户互动。

Safe元交易

Safe合约账户元交易是专用于Safe合约账户的特定元交易格式。

SafeTx 结构 Safe元交易根据Solidity结构SafeTx进行编码,在Safe智能合约中定义

struct SafeTx {
        address to;
        uint256 value;
        bytes data;
        int8 operation;
        uint256 safeTxGas;
        uint256 baseGas;
        uint256 gasPrice;
        address gasToken;
        address refundReceiver;
        uint256 nonce;
    }

SafeTx结构中的每个字段描述如下:

  • to: 交易的接收地址。
  • value: 交易中要发送的以太币额度(以wei为单位)。
  • data: 交易的数据负载,通常用于调用接收合约上的一个函数。
  • operation: Safe合约账户支持0(CALL)和1(DELEGATECALL)。
  • safeTxGas: Safe交易应使用的Gas。
  • baseGas: 这是与特定Safe交易无关的Gas量,但用于一般事务如签名检查和基础交易费用。safeTxGasbaseGas的总和相当于常规交易的Gas限制。
  • gasPrice: 与常规以太坊交易相同。将Gas价格设置为0意味着不会支付任何退款。
  • refundReceiver: 退款不一定要返回到提交交易的账户,而可以支付给此处指定的任何账户。如果设置为0,将使用tx.origin
  • nonce: 用于防止重放攻击并确保交易按预定顺序执行的序列号。Safe合约账户合约通过要求Safe元交易使用连续、递增的nonce值来强制执行这一点。

对于大多数常见用例,理解tovaluedataoperation字段至关重要。任何在特定Safe元交易中由这些字段描述的操作,一旦经过所需数量的所有者签名,并提交到合约账户,将代表Safe智能合约账户执行。

元交易生命周期 元交易的执行过程概述如下:

1. 元交易创建。 当Safe合约账户需要执行交易时,账户的某个所有者应通过Safe{Wallet} UI交易构建器构建它。重要的是要理解,在此阶段,元交易数据仅存在于Safe{Wallet}后端,并且没有对交易的链上承诺。

显示在Safe{Wallet} UI中的待处理Safe元交易示例。

2. 元交易签名。 至少“n”阈值所有者的Safe合约账户必须验证并签署Safe元交易。签署过程包括使用所有者的EOA账户对EIP-712 SafeTx 类型数据摘要进行签名。每个所有者必须将其签名提交给Safe后端。签名过程包括计算EIP-712** SafeTxHash,这是一个哈希树的根哈希,将SafeTx的每个字段提交给特定的执行域(Safe合约账户和链ID)。这意味着特定的SafeTx将仅被特定的Safe合约账户在特定网络上正确验证,从而保护免受重放攻击。

SafeTxHash哈希树结构的可视化表示。

这是每个签名者都应仔细验证所签署的Safe元交易的关键步骤。 交易数据尚未在链上确定。

3. 元交易提交执行。 任何任意的EOA都可以调用Safe合约账户中的execTransaction函数,提交并执行由“n”法定人数所有者签署的Safe交易。在最后一步中,该交易在链上有效发布。正如你所见,execTransaction函数的参数几乎与SafeTx字段完全相同。然而,由于nonce由Safe合约账户强制执行,因此不需要提供。唯一额外的参数是一个字节数组,包含所有者的签名。

function execTransaction(
        address to,
        uint256 value,
        bytes calldata data,
        Enum.Operation operation,
        uint256 safeTxGas,
        uint256 baseGas,
        uint256 gasPrice,
        address gasToken,
        address payable refundReceiver,
        bytes memory signatures
    ) public payable virtual returns (bool success);

当交易被提交到Safe账户时,账户逻辑首先验证其有效性。如果所需数量的所有者已签署交易,则批准执行。否则,在签名验证步骤中将退回。Safe合约账户确保每个签名者都是授权的所有者,并且其签名与被验证的特定元交易匹配。

在这一阶段,交易在链上被发布并执行,使之不可逆转。

参考文献

[1]: 以太坊改进提案。EIP-712: 类型结构化数据哈希和签名 https://eips.ethereum.org/EIPS/eip-712

[2]: Safe。多重签名 https://docs.safe.global/home/glossary#multi-signature

[3]: 以太坊改进提案。ERC-1271: 合约的标准签名验证方法 https://eips.ethereum.org/EIPS/eip-1271

[4]: X @safe。Safe{Wallet}替代品 https://x.com/safe/status/1893012725602885911

  • 原文链接: medium.com/@bazzanigianf...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Bazzani
Bazzani
Blockchain Security Researcher @ OpenZeppelin