onlyOwner 修饰符可能是 Solidity 中最常见的模式之一。
在以下示例中,setMessage() 函数只能由被指定为所有者的地址调用。
function setMessage(string calldata _message) external onlyOwner {
message = _message;
}
然而,常用的 OpenZeppelin Ownable 实现存在一个缺点,即它允许所有者将所有权转移到一个不存在或输入错误的地址。
对于智能合约来说,Ownable2Step 比 Ownable 更安全,因为所有者不会意外地将智能合约的所有权转移给输入错误的地址。与直接转移给新所有者不同,只有当新所有者接受所有权时,转移才会最终完成。
Ownable2Step 是在 2023 年 1 月的 OpenZeppelin 4.8 版本更新期间发布的。这里是代码。
以下是一个最小示例:
import "@openzeppelin/contracts/access/Ownable2Step.sol";
contract ExampleOwnable2Step is Ownable2Step {
string public message;
constructor() Ownable(msg.sender) {}
function setMessage(string calldata _message) external onlyOwner {
message = _message;
}
}
Ownable2Step 继承自 Ownable 并重写了 transferOwnership() 以使新所有者处于 “pending”(待定)状态。接收者随后必须调用 acceptOwnership() 以最终完成转移。这确保了只有能够访问其私钥的地址,或者能够控制该智能合约地址的地址,才能控制该智能合约。
目前放弃所有权(即将所有权转移给零地址)仍然没有两步验证机制。如果不需要放弃所有权,那么更安全的做法是重写 "renounceOwnership()",使其在被调用时发生 revert。
了解更多
本教程是我们高级 solidity 训练营 的一部分。
原文首发于 2023 年 4 月 8 日