//tips
//solidity理解
Cryptzombieでsolidityの基礎を理解する。
Events は、ブロックチェーンで何かが生じたときに、コントラクトがアプリのフロントエンドに伝えることができるものでアプリのフロントエンドを接続待ち状態にできる。
pragma solidity ^0.4.19;
contract ZombieFactory {
event NewZombie(uint zombieId, string name, uint dna);
uint dnaDigits = 16;
uint dnaModulus = 10 ** dnaDigits;
struct Zombie {
string name;
uint dna;
}
Zombie[] public zombies;
function _createZombie(string _name, uint _dna) private {
uint id = zombies.push(Zombie(_name, _dna)) - 1;
NewZombie(id, _name, _dna);
}
function _generateRandomDna(string _str) private view returns (uint) {
uint rand = uint(keccak256(_str));
return rand % dnaModulus;
}
function createRandomZombie(string _name) public {
uint randDna = _generateRandomDna(_name);
_createZombie(_name, randDna);
}
}
event NewZombie(uint zombieId, string name, uint dna);でイベントを発行し、eventに渡した値をトランザクション内部に記録できる。solidity0.4.21以降ではeventの前にemit識別子を追加する。
イーサリアムにはWeb3.jsというJavascriptライブラリがあり、先に述べたようにそちらを用いてフロントエンドに反映する。
Ethereumのアドレスは20bytesで、そのアドレスを16進数で表すと40桁の文字列となる。
また、Mappingとはsolidityでデータ保存を行うための方法の一つで、例えばゾンビとアドレスを対応づける際に使用する。
Uint型のkeyをaddress型のvalueにマッピングすると下記のようになる。uintがゾンビのidでaddressが所有者アドレス。
mapping(uint=>address) public zombieToOwner;
これを利用するとゾンビidからzombieToOwnerを通して、ownerAddressを知ることができる。
ZombieToOwner[zombieid]=ownerAddress;
他にも金融系のアプリの場合、ユーザーのアカウントの残高にuintを格納するmapping (address => uint) public accountBalance;、ユーザーIdを基にユーザー名を参照・格納するために使用するmapping (uint => string) userIdToName;などでも用いられる。
マッピングはデータの保管と参照のためのキーバリューストアで、mapping (address => uint) public accountBalance;の例で言えば、キーはaddress で、バリューはuint。
Solidityには全ての関数で利用できるグローバル変数が用意してあり、その一つであるmsg.senderは、関数を呼び出したユーザーの addressを参照できる。
requireというものを使うのだ。requireはある条件を満たさない場合はエラーを投げて実行を止めることができるも
事前にfavoriteNumber[msg.sender] = _myNumber;としてアドレスを入力しているのでセキュリティとして機能する
Solidityには変数を格納できる場所が2つ用意されている。storage とmemoryだ。
Storage はブロックチェーン上に永久に格納される変数。それとは対照的にMemoryは一時的な変数で、外部関数をコントラクトに呼び出す際に消去されるもの。
関数外で宣言された変数の場合はデフォルトで storageとして、ブロックチェーン上に永久に格納される。一方、関数内で宣言された変数はmemoryとして扱われて関数の呼び出しが終われば消えるように設定されている。
コントラクトはブロックチェーン上に書き込まれた段階で誰もが閲覧可能になるため、アドレス制限などによる使用制限を設けることができる。
イーサの受け取りついては、function levelUp() external payable{…}などのpayableを用い、引き出し方法は<address>.transfer(<uint>)を用いてアドレスと引き出し額を指定することで行う。
Web3.jsとはイーサのノードと通信するJsのAPIライブラリでnode package manager(npm)を利用しインストールを行う。
これはターミナルで
$ npm install web3
とすれば良い。
Web3.jsに用意されているコンストラクタ関数web3の引数にwebプロバイダを持たせて初期化することでweb3オブジェクトを生成でき、それを用いてイーサのノードとの通信を実現する。
web3js=new Web3(web3.currentProvider);
さらにスマートコントラクトにアクセスするためにはweb3jsとコントラクトABI(コントラクトにおけるアプリケーションバイナリインターフェース)、コントラクトアドレスを使ってコントラクトオブジェクトを生成する必要がある。
var cryptoZombies;
function startApp(){
var cryptoZombiesAddress=“ADDRESS”
cryptoZombies=new web3js.eth.Contract(cryptoZombiesABI,cryptoZombiesAddress);
}
Webオブジェクトのプロパティethが備えている「contract」コンストラクタ関数web3js.eth.Contractを用いてコントラクトオブジェクトを作成。このオブジェクトに対し、methodsプロパティを使用することでコントラクト関数を呼び出すことができる。
Callで呼び出した関数の戻り値は完了、もしくはpromiseオブジェクトとなり、promiseオブジェクトが完了した際に戻されるのがsolidityで定義された戻り値となる。
実際にコードを書いてみたいので、ここからはオープンソース統合環境のremixを使用してsolidityのサンプルプロジェクトを作成して行く。
https://medium.com/acompany/0%E3%81%8B%E3%82%89%E4%BD%9C%E3%82%8Bdapps%E5%85%A5%E9%96%80-%E3%83%95%E3%83%AD%E3%83%B3%E3%83%88%E3%82%A8%E3%83%B3%E3%83%89%E7%B7%A8-328242b89d05
https://zenn.dev/zzz/articles/5dcaecacefaf1c
https://qiita.com/masahiro-nakamura/items/cb9e09cab301913b8880
まずはremixにてtoken.solファイルを作成。
まずは簡単なhelloworldを表示させてみる。
pragma solidity ^0.4.0;
contract HelloWorld {
string greeting = "HelloWorld";
function sayHelloWorld() public view returns(string) {
return greeting;
}
}
これをremixでデプロイするとdeployed contractsとしてremix上にsayhelloworldボタンが作成されクリックするとhelloworldを返すようになる。
もう少し試した後に、これはブロックチェーンに組み込めているのか、どのような状態かなどについての確認も進めていく。