在 Foundry 使用 OpenZeppelin 插件进行智能合约升级
从foundry工程化的角度详细解读Openzeppelin中的Arrays库及对应测试。
Create2库本质就是对EVM opcode CREATE2进行的一个封装,可以让开发者在非内联汇编环境下直接使用该opcode。 CREATE2是一种可提前计算合约部署地址的合约部署opcode。而传统的合约部署是通过opcode CREATE完成的。
MerkleProof库提供了用于验证merkle树proof的工具函数。在生成merkle树和对应proof时应当避免使用64字节长度的leaf(进行hash之前)或避免使用非keccak256的哈希函数(进行leaf的hash计算)。这是因为树中经排序的内部节点的拼接可以被重新解释为leaf值。
ERC20FlashMint库是ERC20的拓展。本库在ERC20的基础上实现了IERC3156FlashLender接口,在token层面上支持了闪电贷功能。但是该库默认没有闪电贷手续费,开发者可以通过重写flashFee()方法来自定义手续费计算逻辑。
flashFee()
Context库是合约开发中最常见的库,同时也是最让人迷惑的库。合约代码里面只将msg.sender和msg.data封装成了函数,感觉多此一举。实际上,本库不提供任何context环境切换的细节功能,而是需要目标合约中重写这两个函数起到了可编辑msg.sender和msg.data的目的。
Multicall库提供了一个multicall(bytes[] calldata data)方法,通过该方法可以由调用者在一笔交易中自由组合调用本合约的各个可外部调用的方法。
multicall(bytes[] calldata data)
Math库为合约开发提供了solidity内置的uint256运算以外的其他整形运算方法。solidity内置的整形运算,每一步都会做overflow revert(除非unchecked{}),而Math库会在不影响结果准确性的前提下利用位溢出进行更加tricky的操作。
EIP-712是一个专门用于对结构化数据求hash值以及签名的标准,大大解决了数据“链下签名+链上验证”的问题并提高了链上消息签名的可用性。EIP712合约提供了EIP 712 domain separator的定义与获取——是结构化数据完整编码的一部分。
DoubleEndedQueue库提供了双向队列的数据结构及对应操作库函数,提供了队头或队尾插入及弹出元素值等逻辑功能。本库采用优化过的storage存储且所有操作的时间复杂度都是O(1)。特别要注意的是库中的clear操作仅仅将队头和队尾指针清零,而之前队列中的元素值依然留存在storage中
说在前面的话:Dao治理是个常见的需求,openzeppelin帮我们实现了这个功能。功能一点都不复杂,就是第一次接触会感觉涉及的文件有点多。没关系,多看这篇文章两次就记住了。参考第三部分的代码,就可以实现功能,为了流畅度,一些需要深究的地方,我放在了《补充》这个环节一测试环境fo
在一般语境下,OpenZepplin 指代的其实是:OpenZepplin Contract,一组合约开发的可重用包。同时,由于合约升级相对特殊,它还专门提供了用于编写可升级合约的包。
ECDSA(Elliptic Curve Digital Signature Algorithm)是椭圆曲线数字签名算法的简称。ECDSA库十分重要且使用广泛,其作用是在链上验证某message是否由给定的地址的私钥持有者进行签名的。简而言之,ECDSA库是一个验证地址真实身份的工具库。
IERC1271是合约地址作为signer的签名验证标准。EOA地址可以通过其私钥对msg进行签名,而合约地址理论上是没有私钥的。当合约地址作为msg.sender时,可以通过IERC1271标准进行相关的签名验证工作。
SafeCast库提供了solidity的基础整数类型uintX和intX之间的类型安全转换的库方法。在不同的类型转换之间都加入溢出检查,如果一旦在转换过程中出现类型的溢出会立刻revert。