概述
在深入解析Safe多签钱包智能合约:模块中分析FallbackManager
模块时,限于篇幅限制且fallback
合约自成一体,所以我们没有介绍具体的fallback
模块。此篇文章的主要目的是完成这一缺陷,全面介绍fallback
合约。
本文涉及的代码主要位于src/handler
内,读者可自行查阅此仓库。
合理性分析
此节主要关注于我们为什么需要Fallback
合约这一主题,希望可以为读者在后文阅读源代码时起到提纲挈领的作用。
Fallback
在上文中,我们可以知道fallback
函数的主体逻辑是进行了代理合约式的处理将逻辑代码交给此处的fallback
合约执行。我们首先应当知道fallback
函数的作用,此函数用于接受一切无法与其他函数名匹配到的调用都会被发送到fallback
函数中,进一步这些调用被转发到fallback
合约内。
我们可以认为fallback
合约提供了对于GnosisSafe
主合约的强大补充,避免了GnosisSafe
因不具有某些函数而导致无法进行关键功能。在目前,fallback
合约提供了以下功能:
- 向前兼容
1.3.0
之前的safe
合约的功能 - 接受
ERC1155
代币的功能 - 接受
ERC721
NFT 的功能 - 基于
ERC165
实现的向外界暴露接口实现的功能
这些功能体现了Safe
合约开发团队的一个基本目标,即尽可能保持GnosisSafe
主合约的稳定性,将部分新的必要的功能放在可以通过简单的代理方式升级的fallback
合约中。当然,也将部分兼容性功能放在了fallback
合约内。
当然,这不意味着我们可以大肆修改
fallback
合约以增加功能。在代码设计上,复杂而非必要的功能应该以modules
的形式开发。
在最后,我们希望可以获得任一Safe
合约的fallback
合约地址。为达成这一目的,我们需要查询fallback
合约地址存储的变量。在src/base/FallbackManager.sol
中,我们可以看到如下定义:
bytes32 internal constant FALLBACK_HANDLER_STORAGE_SLOT = 0x6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5;
此变量属于internal
,这意味着似乎无法从外界进行读取。实际上,所有的solidity
变量均可以被读取,但前提是需要知道变量的具体位置。而上述FALLBACK_HANDLER_STORAGE_SLOT
正好告诉了我们变量的存储位置,我们可以通过以下命令读取:
cast storage 0xDE06d17Db9295Fa8c4082D4f73Ff81592A3aC437 0x6c9a6c4a39284e37
ed1cf53d337577d14212a4870fb976a4366c693b939918d5 --rpc-url https://rpc.ankr.com/eth
其中,0xDE06d17Db9295Fa8c4082D4f73Ff81592A3aC437
为我选择的Lido
名下的一个safe
多签钱包地址,读者可以自行替换为其他多签钱包地址。
代码运行结果如下:
0x000000000000000000000000f48f2b2d2a534e402487b3ee7c18c33aec0fe5e4
这正是在存储中的“裸”地址(没有被编码),其代表的真实地址为f48f2b2d2a534e402487b3ee7c18c33aec0fe5e4
,其etherscan
地址在这。
Receiver
我们在上文提到fallback
合约提供了这两个功能:
- 接受
ERC1155
代币的功能 - 接受
ERC721
NFT 的功能
可能有读者比较困