今日からレッスン3に入ります。
これまでより一気にレベルアップして、本格的なプログラミングになってきた感じがします。ドラクエ4でいうところのキングレオ戦で一気にボスのレベルが上がる感じに近いです。(多分違う)
今、CryptoKittiesのコントラクトアドレスは直接打ち込まれていますね。
大体プログラマーがこういうコードを見ると、「このクソコードは何ですか?」と突っ込まれること間違いないです。
なので、kittyContractっていう名前のInterfaceを作った上で、_addressを引数とするsetKittyContractAddress関数を作ります。
KittyInterface kittyContract;
function setKittyContractAddress(address _address) external {
kittyContract = KittyInterface(_address);
}
これでアドレスのベタ打ちではなくなりました。
ここでは新しい用語や概念がたくさん出てきます。
まずは「コンストラクタ」。
これは特別な関数で、コントラクトが最初に作成された時に、1度だけ実行されるみたいです。これにより、コントラクトが作られた時、コンストラクタがowner を msg.senderに設定します。
function Ownable() public {
owner = msg.sender;
}
次に、「Ownableコントラクト」の中身。
onlyOwner修飾子を追加して、ownerだけが特定の関数にアクセスできるように設定し、新しいownerにコントラクトを譲渡することも可能にしています。
開発者たちは、コミュニティの手により作成/検証されたため、安全性が既に確かめられているスマートコントラクトであるOpenzeppelinのOwnable.solのコードをコピペしたりインポートし、継承して使っているとのことです。以下の感じですね。
import "./ownable.sol";
contract ZombieFactory is Ownable {
// コントラクトの中身
}
ちなみにOpenZeppelinについてはvoicyでも配信したのでよかったらどうぞ。(こんなところで宣伝w)
これで継承の関係は、Ownable ⇒ ZombieFactory ⇒ZombieFeedingという順番になりました。
また新しい用語が出てきました。
「関数修飾詞」というやつです。
関数っぽいのですが、関数と違うのは以下の点。
1. 最初の宣言が"function"ではなく"modifier"
2. 最後に"_;"で終わらせる必要がある
3. 関数のように直接呼び出すことはできず、代わりに関数定義の最後にこの修飾子をつけることで、関数の動きを変更します(読んだだけだとわかにくいですが、後に出てくるコード見ればあぁここで使ってるのね。ってなります。)
この関数修飾詞の代表的なものがonlyOwner修飾子です。
例を挙げましょう。
まずは以下のようにonlyOwner修飾子を定義します。これで「この関数を呼び出した人がownerである場合」という意味になります。
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
次に、transferOwnsership関数の中で最初に呼び出すことで、イーサリアム側で、そもそもこの関数を使えるのはownerのアドレスだけなんだなと判断しているわけです。
その上で、owner変数に新しいアドレスを代入しています。
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0));
OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
このonlyOwner修飾子が書かれた関数では、msg.senderがownerのものと一致しない限りこの関数を呼び出せないようにしているわけですね。
ちなみに上記2つのコードもOpenzeppelinのOwnable.solの中に書かれており、実際に開発者にも使用されているものです。CryptoZombiesではこのOwnable.solのコードについて全ては説明してはいないため、この後自分でも学んでみようと思います。
CryptoZombiesでも同様にonlyOwnerを使っていますね。
function setKittyContractAddress(address _address) external onlyOwner {
kittyContract = KittyInterface(_address);
}
今日はこのへんで。
それでは良いゾンビーライフを!
【twitter】https://twitter.com/nogacrypto?lang=ja
【voicy】https://voicy.jp/channel/545
【note】https://note.mu/nogacchi