プログラミングのゴミ箱

日々の学習の中で知らなかったことについて、調べたことを解説します。

Ctypto Zombieで始めるSolidity入門③

この記事は前回の続きです。
前回の記事はこちら↓
chanichiwasshoi.hateblo.jp

このシリーズではCrypto ZombieというSolidityの学習が出来るサイト(しかも無料で)の内容を自分なりにまとめます。
入門編はこれ一つで全部学べるみたいなので、みなさんもぜひやってみてください!
cryptozombies.io

コントラクトの不変性

 Solidityが普通のプログラミング言語と違うのが、コントラクトを一度イーサリアム上にデプロイするとコードは永遠にブロックチェーン上に残り続け、編集も更新もできなくなる。
 これをコントラクトの不変性という。

 しかしこれではあまりに不便なので、大抵は最初にデプロイするプログラムに中身を編集できるようなプログラムを埋め込む。
 例えば、他のコントラクトを実行するようなプログラムを作ったとき、参照するコントラクトのアドレスとABIを変数で持っておく。参照するコントラクトを変更したくなったらその変数を変更できるようにしておけば良い。

fucntion setContract(address _address) external {
    contract = SomeInterface(_address);
}

 このようなプログラムを作っておけばコントラクトを変更できる。

関数修飾子

 先程のプログラムを見るとある欠陥が見つかる。それは、この関数がexternalであるためだれでもコントラクトを変更することが出来ることである。それを解決するための一つの方法に関数修飾子を使う方法がある。
 関数修飾子とは関数実行時に実行される関数のようなものである。modifierを使って定義する。

uint owner = "19fa2891389b...";
modifier myModifier() {
    require(msg.sender == owner);
    _;
}

function hoge() external myModifier {}

 このように書くことでhogeが実行される前にメッセージを送った人のコントラクトが、オーナー変数のコントラクトと等しいかどうか確認することが出来る。オーナー変数に予め自分のコントラクトを入れておけば、自分以外の人にプログラムを攻撃されてしまう心配がない。

引数

 関数拡張子は普通の関数と同じように引数を受け取れる。

modifier olderThan(uint _age, uint _userId) {
  require (age[_userId] >= _age);
  _;
}

function driveCar(uint _userId) public olderThan(16, _userId) {}

時間を使う

 Solidity内で時間を使いたい場合は以下のように出来る。

function updateTimestamp() public {
    lastUpdated = now;
}

function fiveMinutesHavePassed() public view returns (bool) {
  return (now >= (lastUpdated + 5 minutes));
}