现在我们有了个基本版的合约 PetIncubator 了,它继承自 Ownable 接口,我们也可以在 PetMating 里面的函数中使用 onlyOwner 函数修饰符。
这就是合约继承的工作原理。记得:
PetMating is PetIncubator PetIncubator is Ownable 复制代码
因此 PetMating 也是个 Ownable, 并可以通过 Ownable 接口访问父类中的函数/事件/修饰符。往后,PetMating 的继承者们同样也可以这么延续下去。
函数修饰符
函数修饰符看起来跟函数没什么不同,不过关键字modifier 告诉编译器,这是个modifier(修饰符),而不是个function(函数)。它不能像函数那样被直接调用,只能被添加到函数定义的末尾,用以改变函数的行为。
咱们仔细读读 onlyOwner:
/**
* @dev 调用者不是‘owner’,就会抛出异常
*/
modifier onlyOwner() {
require(msg.sender == owner);
_;onlyOwner 函数修饰符是这么用的:
contract MyContract is Ownable {
event LaughManiacally(string laughter);
//注意! `onlyOwner`发挥作用了 :
function likeABoss() external onlyOwner {
LaughManiacally("Muahahahaha");
}
}注意 likeABoss 函数上的 onlyOwner 修饰符。 当你调用 likeABoss 时,首先执行 onlyOwner 中的代码, 执行到 onlyOwner 中的 _; 语句时,程序再返回并执行 likeABoss 中的代码。
可见,尽管函数修饰符也可以应用到各种场合,但最常见的还是放在函数执行之前添加快速的 require检查。
因为给函数添加了修饰符 onlyOwner,使得唯有合约的所有者(也往往是部署者)才能调用它。
注意:所有者(owner)对合约享有的特权当然是正当的,不过也可能被恶意使用。比如,万一,所有者添加了个后门,允许他偷走别人的资产呢?
所以应用部署在智能合约平台上并不能保证它真正的安全可靠,你需要阅读并理解它的源代码,才能发现它有没有被部署者恶意植入后门;作为开发人员,你要做到既给自己留下修复 bug 的余地,又尽量地放权给使用者,让他们放心把数据放在你的智能合约应用中。
实战演习
现在我们可以限制第三方对 setKittyContractAddress的访问,除了我们自己,谁都无法去修改它。
将 onlyOwner 函数修饰符添加到 setKittyContractAddress 中。


