title | actions | requireLogin | material | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Ownable コントラクト |
|
true |
|
どれ、前のチャプターでセキュリティホールに気がついたか?
setKittyContractAddress
は external
だから、だれでも呼び出すことができるのだ!つまり、この関数を呼び出した奴はクリプトキティーズのコントラクトのアドレスを変更することで、我々のアプリをめちゃくちゃにすることが可能なのだ。
もちろん、アドレスの更新ができるようにするつもりだが、誰でも更新できるようにしたいわけでない。
ではどうすれば良いかというと、よくあるやり方としては、コントラクトをOwnable
(所有可能)とすることだ。これはコントラクトには特別な権限を持つオーナー(所有者)がいることを意味するものだ。
一つ例を見せてやろう。これはSolidityのライブラリにある OpenZeppelin というOwnable
コントラクトだ。OpenZeppelinは安全でしかもコミュニティで検証を経たスマートコントラクトだ。これをDAppで使うことができる。このレッスンの後で、OpenZeppelinのサイトをチェックしておくように。今後非常に役に立つだろう!
下のコントラクトをよく読むように。まだわからないことがいくつもあるが、あとで教えるから今は気にすることはない。
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
function Ownable() public {
owner = msg.sender;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0));
OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
新しいものがいくつかあるから、解説してやるぞ:
- コンストラクタ:
function Ownable()
は**コンストラクタ**だ。これは特別な関数で、コントラクトと同じ名前だ。コントラクトが最初に作成された時に、1度だけ実行されるぞ。 - 関数修飾子:修飾子は半分関数のようなもので、他の関数を編集する際に使うものだ。通常は実行する前に要件をチェックするために使用するぞ。この例で言えば、
onlyOwner
はowner(オーナー)だけが関数を実行できるように、制限をアクセスするために使用されているのだ。関数修飾子については次のチャプターで詳しく説明してやろう。_;
という奇妙なものについてもな。 indexed
キーワード:これは無視して良い。必要ない。
Ownable
コントラクトは基本的には次のようになる。これを覚えておくようにな:
-
コントラクトが作られた時、コンストラクタが
owner
をmsg.sender
(実行した人物だ)に設定する。 -
onlyOwner
修飾子を追加して、owner
だけが特定の関数にアクセスできるように設定する。 -
新しい
owner
にコントラクトを譲渡することも可能だ
onlyOwner
は誰もが皆必要としているものだから非常に一般的になった。だからSolidityのDAppを開発するときには、皆がこのOwnable
コントラクトをコピーペーストしてから、最初のコントラクトの継承を始めているのだ。
我々もsetKittyContractAddress
をonlyOwner
に制限したいから、同じ様にするのだぞ。
新しいファイルの ownable.sol
にすでにOwnable
のコードをコピーしてある。そこでZombieFactory
を継承させることにする。
-
ownable.sol
をimport
するように我々のコードを変更せよ。なに、やり方を忘れてしまっただと?その場合はzombiefeeding.sol
を見て思い出すのだ。 -
ZombieFactory
コントラクトを編集してOwnable
を継承させよ。やり方を忘れていたらzombiefeeding.sol
を見て思い出すように。