イスカ@コイナー
Solidityを学ぶゲームとしては世界で一番有名なCryptoZombies。ただ、前提レベルとして既にプログラミングができることが必要となります。そこで、この記事では、プログラミングをしたことないけど、Solidityを学びたいという人に向けて解説しながらCryptoZombiesを攻略していきます。
目次
- 1 CryptoZombiesとは?
- 2 実際にCryptoZombiesをやってみる
- 2.1 CryptoZombies攻略チャプター1:レッスンの概要
- 2.2 CryptoZombies攻略チャプター2:コントラクト
- 2.3 CryptoZombies攻略チャプター3:状態変数と整数
- 2.4 CryptoZombies攻略チャプター4:数式演算
- 2.5 CryptoZombies攻略チャプター5:構造体
- 2.6 CryptoZombies攻略チャプター6:配列
- 2.7 CryptoZombies攻略チャプター7:関数の宣言
- 2.8 CryptoZombies攻略チャプター8:新しい構造体を作る
- 2.9 CryptoZombies攻略チャプター9:Private / Public 関数
- 2.10 CryptoZombies攻略チャプター10:さらに関数を続けるぞ
- 2.11 CryptoZombies攻略チャプター 11: Keccak256と型キャスト
- 2.12 CryptoZombies攻略チャプター 12: 統合
- 2.13 CryptoZombies攻略チャプター 13: イベント
- 2.14 CryptoZombies攻略チャプター 14: Web3.js
- 3 CryptoZombiesで自分だけのゾンビを作ろう
CryptoZombiesとは?
CryptoZombiesとは、イーサリアムのプログラム言語であるSolidityをゲームを作りながら学べるオンラインゲームです。Solidityを学ぶゲームとしては世界で一番有名なものになります。
実際にプログラムを作成することで、ゾンビを作ったり、戦わせたりすることができます。
イスカ@コイナー
内容としては下の画像のように、画面左で学習をして、右上のスペースに実際のコードを書いていくという流れになっています。
より詳しくは下記記事をご参考ください。
ゲームを遊びながらdappsプログラミングの勉強ができる?CryptoZombies~始め方~実際にCryptoZombiesをやってみる
イスカ@コイナー
CryptoZombies攻略チャプター1:レッスンの概要
- ページの右にある色々なスライダーを実際に動かしてみること。数字を変えることでゾンビの外観が変わることがわかるだろう。
よし、準備運動はこれくらいで十分だろう。次に進む準備ができたら「次のチャプター」をクリックすれば、次のチャプターから実際にSolidityを教えていくから、覚悟しておけよ!
チャプター1では全くプログラミング知識はいりません。
というのも、これからプログラムで作ることになる、ゾンビが作成される仕組みを学ぶチャプターだからです。赤枠内の横バーをいじると、ゾンビのDNAが変化します。DNAが変化することでゾンビの外観が変わっていますよね。
レッスン1では自動でランダムなDNAを作成することでゾンビ軍団を生み出すゾンビファクトリーを作成していきます。
CryptoZombies攻略チャプター2:コントラクト
ゾンビ軍団を生み出すための、
ZombieFactory
というコントラクトを作成してみよ。
- 右のボックス内に、solidity
0.4.19
バージョンを指定して、コントラクトを使う準備をせよZombieFactory
という空のコントラクトを作成せよ作成が終わったら、下の”答え合わせ”をクリックせよ。もし迷うことがあれば、”ヒント”を押せばヒントをやろう。
チャプター2からプログラムの作成が始まります。
プログラムを使ったことがない人向けに分かりやすく説明していきますね。
イスカ@コイナー
まず、最初に下記のコードが書いていきます。
pragma solidity ^0.4.19;
どのバージョンに基づいてプログラミングしているかを記載しています。
イーサリアムはSolidityという言語を使っているのですが、バージョンによってルールが変わったりするのでどのバージョンを使うかを記載するわけです。
ワタル編集長
イスカ@コイナー
続いて、下記のようなコントラクトを作成していきます。。
contract HelloWorld {
}
コントラクトというのは簡単に言うと操作の塊のことです。
例えば、ペンを持つというのは一言で簡単に表わせますが、実際には複数の動作が必要ですよね。
簡単に分解しただけでも以下のような動作に分けられます。
②ペンに向かって手をのばす。
③手がペンに近づいたら、手を開く。
④手を閉じてペンに触れる。
⑤ペンを握って手を挙げる。
5つの動作のまとまりをペンを持つと私達は言うわけです。
コントラクトというのはこのような動作の集まりを指します。
ですので、上記の例ではHelloWorldという動作はこれらだよということを定義しているのです。
というわけでcryptoZombieとはをコントラクトを使って書いていきましょう。
CryptoZombies攻略チャプター3:状態変数と整数
我々ゾンビのDNAは16桁の数字で決まる。
dnaDigits
というuint
を宣言し、それを16
に設定せよ。
チャプター3も初心者つまずきポイント満載です。
チャプター3からチャプター2で書いたのコントラクトの中身を記載していきます。
さて先ほどのペンを持つという例は非常に簡単に分解しましたが、実際のプログラムでは、そもそもペンとは何なのか、手とは何なのかまでも記載しなければいけません。
プログラミングで初心者がとっつきにくく感じるのがこの定義です。
プログラミングでは1が文字(一)なのか、整数(1)なのか、小数(1.0)なのかを決めておかないといけません。
スペルミスを除く、初心者の多くがつまずくほとんどの要因が整数と少数、整数と文字を計算しようとしたためエラーが起こっていることにあります。
チャプター3では、dnaDigits
をマイナスでない整数と定義します。
マイナス符号のない(unsigned)整数(integer)を略してuint
と記載します。
uint myUnsignedInteger = 100;
定義の仕方は非常に簡単。
まず、数字なのか、文字なのかを決めます。その後に半角スペースを開けて定義したい名前(上記の場合であればmyUnsignedInteger
)を続ければ定義されます。
CryptoZombies攻略チャプター4:数式演算
ゾンビのDNAが16桁の数字だと確認するために、別の
uint
を作成して10^16と設定せよ。後のレクチャーでは剰余演算子である%
を使用して整数を16桁に縮小できる。
dnaModulus
という名前のuint
を作成し、10のdnaDigits
乗に設定せよ。
チャプター4では計算を行っていきます。solidityでは以下の表にある計算を行うことができます。
操作 | プログラムの記号 | 例 |
足し算 | + | 5+2 = 7 |
引き算 | ー | 5-2 = 3 |
掛け算 | * | 5 * 2 = 10 |
割り算 | / | 5 / 2 = 2.5 |
あまりを出す | % | 5 % 2 =1 |
乗算 | ** | 5 ** 2 = 25 |
チャプター3で書いたdnaDigits
を早速利用していきます。
dnaModulus
という名前のuint
を定義し、10のdnaDigits
乗に設定をしていくわけですが、まず忘れずにuint
で新しい定義を忘れずにしていきましょう。
dnaDigits
は数字だと思ってそのまま記載してください。
チャプター3でしっかりとマイナスでない整数として定義したので、機械では数字となっています。
どうして16乗と直接書かずにチャプター3でdnaDigits
をわざわざ定義してからdnaDigits
乗と手間なことをするのかと思ったそこのあなたは鋭いですね。
dnaDigits
乗とわざわざ定義した理由は、今後いろんな計算をして行く中で、パラメーターを変更したいと思った時にわざわざ全て変更していくのは手間ですよね。
そこで予めチャプター3のように定義をしておくことで、今後変更をする時には5行目の数字だけを変更するだけで済むようにするのです。
CryptoZombies攻略チャプター5:構造体
私のアプリでいくつかのゾンビを作りたい!ゾンビは複数のプロパティを持せたいので、構造体を使用するちょうど良いテストだ。
Zombie
という名前のstruct
を作成せよ。Zombie
構造体にプロパティを2種類設定せよ:name
(string
)、と、dna
(uint
)だ。
チャプター5は、構造体の定義していきます。
構造体とは、平たく言うと複数の定義の固まりをさします。
例えば、ペンを定義するときに「15cmの(長さ) 紫色の(色) ボールペン(種類)」と定義したいとき、チャプター3のやり方では、長さか色か種類しか定めることができないですよね。
そこで今回は、structを使うことで複数の定義をまとめていきます。{}の中に決めたい要素、今回はゾンビの名前とDNAを記載していきます。
要素を書き終えたら忘れずに{}を閉じましょう。
CryptoZombies攻略チャプター6:配列
私は自分のアプリにゾンビの軍隊を格納したいのだ。そして格納したゾンビを他のアプリに見せてやるために、公開したい。
- パブリックな
Zombie
構造体の配列を作り、名前をzombies
とせよ。
チャプター6は配列についてです。
配列なんて難しい言葉がでてきましたが、簡単にいえばグループのことです。
指<=親指、人差し指、中指、薬指、小指
つまり、定義したものをまとめてグループにしたものが配列です。
イスカ@コイナー
ゾンビ0、1、2とできた順に点呼していくようなものです。
配列を作るときは[]の中に何も書かない場合、出来上がったゾンビ全てを指すことになります。
さて、配列を作成したらその配列を名付けていきます。
方法は今までと異なり、ゾンビ配列 ゾンビ軍団
のように、配列の後に名付けたい名前を記載すれば完成です。
グループ名の前にpublic
を入れることで、公開することになります。
CryptoZombies攻略チャプター7:関数の宣言
アプリでゾンビを何体も作る必要がある。関数を使ってこれを実現したい。
createZombie
という名前の関数を作成せよ。関数には、__name_ (string
)と、__dna_ (uint
)の、2つのパラメーターを設定せよ。関数の中身は空で構わない – 後で中身を書いていくからな。
チャプター7は関数についてです。
関数ときくと、xとかyとか中学の数学で聞いた可能性がかすかにあるという人が多いのはないでしょうか。もう名前からして、拒絶反応を起こしてギブアップしたいという人もいるかもしれませんが、数学とは一切無縁ですので安心してください。
プログラミングにおける関数というのは、一つ一つの動作のことです。英語でファンクションといい、機能という方が適切でしょう。
チャプター1でコントラクトは動作の集まりといいましたよね。チャプター7では、動作の名前を決めつつ、その動作で必要となる構造体を指定します。
例えば、ペンに向かって手をのばすという動作では、ペンと手が必要ですよね。それと同じように必要となるものを全て指定していきます。
今回では、下記のようにfunctionと最初に関数であることを宣言します。半角スペースを開けて、動作をcreateZombie
と名付けましょう。
function eatHamburgers(string _name, uint _amount) {
}
()内に_name
と、_dna
と使われる構造体をカンマで区切って書いていきます。ここが、チャプター7でのつまづきポイントです。
今回の_name
や_dna
いう構造体はチャプター5で定義した構造体とは別になります。それぞれアンダーバーがついているのが分かりますよね。
通例アンダーバーをつけることで、createZombie
における構造体はcreateZombie
関数内でしか使わないということを表しています。
そのため、チャプター7では構造体を書いていくときには、チャプター5のようにもう一度構造体の種類を宣言した後に名付けていきます。
さて、{}の中身が動作の中身なのですが、具体的には次のチャプターで書いていきます。
ただ、閉じ忘れにご注意ください。
CryptoZombies攻略チャプター8:新しい構造体を作る
createZombie関数を実際に動かすぞ!
- 新しい
Zombie
を作れるように関数の中身を埋めて、それをzombies
配列に格納せよ。但し、新しいZombieのname
とdna
は関数の引数を使用せよ。- 書いたコードを1行で書き直してスッキリさせよ。
チャプター8ではチャプター7で、作成した関数の中に具体的な内容を書いていきます。具体的な内容とは、ゾンビ集団にゾンビを追加していく、まさにクリエイトゾンビの機能になります。
zombies
配列の中に、ゾンビを一体ずつ入れていきましょう。配列.(ドット)push(入れたい構造体);
と書くことで構造体を配列に追加していくことができます。people.push(satoshi);
チャプター8でのつまずきやすいポイントは入れたい構造体の書き方でしょう。
まずチャプター5で記載した構造体の名前を宣言したのちに、チャプター7で宣言した_nameと_dnaをカンマで区切って入れれば、バッチリです。
CryptoZombies攻略チャプター9:Private / Public 関数
我々の
createZombie
関数はデフォルトでpublicになっている。つまりだれでもコントラクトから関数を呼び出してゾンビを作れるということだ!これはあってはならないことだから、privateに変えなければならない。
- private関数になるように、
createZombie
を編集せよ。名付けの通例を忘れるなよ!
チャプター9ではチャプター7とチャプター8で作った関数をプライベートにしていきます。
何のためにやっているのかというとハッキング対策です。
Solidityで作った関数は、基本的に誰でもアクセスできるパブリックの状態です。例えるならば、ロックがかかっていないスマートフォンのような状態になります。
関数をプライベートにして勝手に使えないようにしましょうというのが今回の趣旨です。
function _addToArray(uint _number) private {
numbers.push(_number);
}
プライベートにする方法自体は非常に簡単。
上記のように関数の後にprivate
とつけるだけで関数はプライベートになります。
あと通例で、関数名(上記例だとaddToArray
)の前に_(アンダーバー)をつけ忘れないようにしましょう。
CryptoZombies攻略チャプター10:さらに関数を続けるぞ
文字列からランダムなDNA番号を生成するヘルパー関数を作りたい。
_generateRandomDna
という名前のprivate
関数を作成せよ。パラメーターは_str
(string
)という名前で、戻り値をuint
に設定せよ。- この関数はコントラクトの変数を読み込むことはあるが、編集することはない。そこで修飾子を
view
と設定せよ。- 関数の中身は空にせよ。中身は後で書き込むぞ。
チャプター10については修飾子と戻り値について学びます。
修飾子は修飾語のようなものです。「赤い」リンゴのような形容詞のような情報を追加していく働きをします。チャプター9で関数をプライベートにしたと思いますが、同様に関数の設定を追加します。
イスカ@コイナー
作った関数の中身を他で編集することがないという時にはview
をつけることでセキュリティがアップします。
なお、今回は使いませんがpure
とつけると読み取ることも編集することもできなくなります。
続いて戻り値を記載します。
戻り値なんて大層な名前がついていますが、関数を行った結果のことです
例えば、入れた数字の掛け算を行ってくれるカケザンという関数を作ったとします。この時2と3を入れたら6になるのは分かりますよね。ただ、カケザンという関数に戻り値がない場合、2×3の結果が行われただけで、何も出力されません。
戻り値を設定することで初めて関数を実行した結果となる6が出力されるのです。そのため、関数では戻り値を最後に設定するほことがほとんどです。
さて、では今回の問題ですが、チャプター7とチャプター9の内容も踏まえて回答していく必要があります。
まず最初に関数を作成します。
function sayHello() public view returns (string) {
その後、上記のように private/publicの後に修飾子、戻り値の順番で記述していきます。
CryptoZombies攻略チャプター 11: Keccak256と型キャスト
_generateRandomDna
関数の中身を書いてみよ!以下の点に従って書くように:
- コードの最初の行は
_str
のkeccak256
ハッシュを取得し、擬似乱数の16進数を生成し、それをuint
に型キャストして、rand
というuint
に格納せよ。- DNAは16桁になるようにしたい(
dnaModulus
を覚えているか?)。そこで次の行では上で求めた値のdnaModulus
による剰余(%
)をreturn
するようにせよ。
チャプター11は乱数生成について学びます。今回では、入力した文字によってゾンビのDNAが決まる機能を実装していきます。
乱数乱数とは簡単にいうとランダムな値のこと。サイコロをなげて出た値のように予想できない数字のことを指す。
ワタル編集長
チャプター11は、段階が2つあり2行に渡って記載していく必要があります。
問題② 作成したDNAを16桁にして、
_generateRandomDna
関数の結果とする。問題①では、keccak256
という関数を利用して文字を16進数に変換していきます。
keccak256("aaaac");
→b1f078126895a1424524de5321b339ab00408010b7cf0e6ed451514981e58aa9
上記のように、関数後の()内に文字列を入れると、ランダムな16進数に変換されます。
今回は()にチャプター10で定義した_str
を入れます。
ただ、他の数字と計算ができないので、チャプター3で学んだように状態をマイナスのつかない整数に定義し直します。
方法は同様にuint
を前につけるだけですが、関数を変換する場合は定義する関数を()でくくりましょう。
後は定義した関数をrand
に=で入れれば問題①は完了です。
問題②では、return
を作成した関数を16桁の結果とします。
今回はチャプター5で定義した要素dnaModulus
で定義した要素で割った余りを求めることで、下16桁以外を削除します。
方法としてはチャプター4で学んだ余りを出す計算式の%を使い、 rand
をdnaModulus
で割ります。
そして、計算式の前にreturn
をつけることで今回の問題は完了です。
CryptoZombies攻略チャプター 12: 統合
createRandomZombie
という名前のpublic
関数を作成せよ。そこに_name
(string
)というパラメーターを設定せよ。 (注:public
関数を宣言する方法は、private
関数を宣言したのと同じです)- 関数の最初の行で
_name
で_generateRandomDna
を実行させ、それをrandDna
という名前でuint
に格納せよ。- 次の行で、
_createZombie
関数を実行し、_name
とrandDna
を引数として渡せ。- ソリューションは4行以内とする(関数を閉じる
}
を含む)。
チャプター12ではチャプター7からチャプター11にかけて作った関数を一つの関数にまとめていきます。名前を元にDNAを作って、そのDNAからゾンビをつくる機能ができあがります。
チャプター12の問題は大きく分けて3つ。少し多いように感じられますが、新しいことは特になく今まで学んだことの復習編です。
問題②
_generateRandomDna
関数を利用する。問題③ 関数で作ったDNAを元にゾンビを作り、それを結果として出力していきます。
さて、問題①ですが、これはチャプター7で学んだことを活用してcreateRandomZombie
関数を作成していくだけです。チャプター8で学んだpublic関数にすることも忘れずに追加しましょう。
問題②は_generateRandomDna
関数をチャプター11の問題①と同様に、問題③に関しても_createZombie
関数をチャプター11の問題②と同様に活用していけば答えになります。
CryptoZombies攻略チャプター 13: イベント
新しいゾンビを作る毎にそれをフロントエンドに伝えて、アプリ上に表示させたい。
NewZombie
という名前のevent
を宣言せよ。zombieId
(uint
)、name
(string
)、dna
(uint
)の値を渡すのだ。_createZombie
関数を編集し、zombies
配列に新しいゾンビを追加したらNewZombie
イベントが発生させよ。- ゾンビの
id
が必要だ。array.push()
は新しい長さのuint
配列を返し、配列の最初のインデックスは0であるから、array.push() - 1
が追加したゾンビのインデックスだ。そこで、zombies.push() - 1
結果をid
という名前のuint
に格納し、次の行で作成するNewZombie
イベントで使用できるようにせよ。
さて、今回のチャプターがレッスン1での最後のプログラム作成になります。
チャプター13ではイベントについて学んでいきます。イベントは簡単に言うとユーザーにも見えるようにする機能です。
今までのチャプターでゾンビファクトリーの機能を作成してきましたが、実際にどう動いているのか分かりませんよね。
イベントを活用することで、実際に動いているのがユーザーにもわかるようになります。
問題② 定義したイベントを使う
問題③ イベントを使うのに足りないパラメーターを作る
問題①ではイベントを定義していきましょう。宣言という言葉がつかわれていますが、チャプター1で学んだように、イベントであることを定義するだけです。
event IntegersAdded(uint x, uint y, uint result);
上記のように、event
とまずなんであるのかを書いた後に、NewZombie
とイベントの名前を記載します。
その後、()に利用するパラメータを記載します。
今回はzombieId
、name
、dna
を利用します。パラメーターを記載する際には状態を忘れずにつけておきましょう。
問題②では、問題①で作成したイベントを実際に機能させます。
19行目にイベントの名前(つまりNewZombie
)を記載しましょう。
その後、実際に利用するパラメーターを()内に記載していきます。_createZombie
関数の中にあるので、使える関数は関数を作る際に指定していたパラメーターだけです。
つまり、_name
と_dna
です。それぞれ、問題①で指定した2番目と3番目に記載していきます。
ワタル編集長
zombieId
は?イスカ@コイナー
ということで、問題③ではチャプター8で作成したゾンビ軍団の配列を編集してidを作成します。
編集は簡単で、 zombies.push
をid
に入れるだけ。
ただ、注意していただきたいのは、 - 1
をつけることです。
どのプログラミングでもそうなのですが、配列は0番から始まります。ゾンビ軍団は1人目でなく0人目から数えていくので - 1
をつける必要があるのです。
これで、パラメーターが揃いイベントが完成です。
CryptoZombies攻略チャプター 14: Web3.js
右のボックスに自分の名前を入力し、どんなゾンビになるのかその目で確かめるのだ!
自分の名前のゾンビで楽しんだら、”次のチャプター”をクリックしてゾンビを保存せよ。これでレッスン1は終了だ!
というわけで、ついにチャプター14で名前を入力したら、ゾンビがつくれます。今までのチャプターで作っていた機能が使われていますね。
自分の名前をいれてもよし、憎い相手をゾンビとしていれてもよし。オリジナルのゾンビが出来上がりです。
イラストとかUIの部分はつくっていませんが、既存のプログラムを利用しています。
左にあるWeb3.jsのコードがそうなのですが、現時点ではなんと書いてあるのか分からない人がほとんどだと思います。ただ、気にしなくても大丈夫です。後々のレッスンで学ぶことになります。
CryptoZombiesで自分だけのゾンビを作ろう
レッスン1を終えるとランダムゾンビ生成装置ができあがります。プログラミングしていて完成したものが動いているのをみると感動しますよね。
しかも、オリジナルのゾンビをもらえます。
イスカ@コイナー
ちなみにですが、Crycptゾンビでプログラムをしなくても上記のURLから名前を入れることで、ランダムゾンビ生成装置を試すことができます。
皆さんもこの記事を参考にプログラミングの世界に一歩足を踏み入れてみてはどうでしょうか?
コメントを残す