ALISがβ版公開ということで何か書きたいなあと思いネタを探していたのですが、ALISといえば全てのプロジェクト進捗を公開していることが有名ですので、公開されているソースコードのICO用に書かれているスマートコントラクト部分を読んでみることにしました。
github : https://github.com/AlisProject/ico-contracts
まずはトークン実装部分から。
ico-contractsはtruffleを使用しているようなので、contracts以下にsolidityで書かれたスマートコントラクトがあります。
https://github.com/AlisProject/ico-contracts/tree/master/contracts
この中の、AlisToken.solがトークンの本体ですが、実体は16行(2018.5現在)。
https://github.com/AlisProject/ico-contracts/blob/master/contracts/AlisToken.sol
ポイントになるのは、MintableTokenとBurnableTokenを継承しているところでしょうか。
contract AlisToken is MintableToken, BurnableToken {
Mintは造幣局と訳されたりしますが、文字通りトークンを後から増やすことができる仕組みです。
import 'zeppelin/contracts/token/MintableToken.sol';
openzeppelin-solidityに書かれていますのでちょっとのぞいてみます。
StandardTokenを継承していますので、ERC20に準拠したトークンであることがわかります(ERC20の説明は省略)。
実装自体はかなり単純で、mint関数にトークンを追加数アドレスと追加量を渡すと、トータルトークン数(totalSupply)、追加したアドレス(balances[_to])にトークンを追加、イベントの発火(アプリケーション側にmintしたことを伝える)をしているだけです。
function mint(address _to, uint256 _amount) onlyOwner canMint public returns (bool) {
totalSupply_ = totalSupply_.add(_amount);
balances[_to] = balances[_to].add(_amount);
emit Mint(_to, _amount);
emit Transfer(address(0), _to, _amount);
return true;
}
onlyOwnerはトークンの作成者のみがこのトークンを増やせるというためのもので、これがないと誰でもトークンが増やせるのでトークンが無価値になります。
canMintはトークンの作成者がもうトークンは増やさないと決めた時に立てるフラグのようです。finishMinting()を呼び出すことでフラグが立てられます。これも間違えて実行してしまうとトークンが一生増やせないので相当実行前には検証が必要なものになります。
modifier canMint() {
require(!mintingFinished);
_;
}
function finishMinting() onlyOwner canMint public returns (bool) {
mintingFinished = true;
emit MintFinished();
return true;
}
BurnableTokenの方は、独自で実装されているようです。(つまり、openzeppelin-solidityには実装がないということでしょうか?)
https://github.com/AlisProject/ico-contracts/blob/master/contracts/lib/BurnableToken.sol
Burnは文字通り燃やすことですので、トークンを消滅させるということですね。これも当たり前ですが一度燃やすと一生返って来ません。
Burn部分だけ取り出すと、Burnしたい量をインプットにして、インプットが正の数であれば(ここで負の数が通ってしまったら逆にトークンが増えてしまうので)、このコントラクを実行している人のアドレスから指定した量だけトークンを減算しています。ちなみにこれはonlyOwnerになっていませんが、まあ好き好んで自分のトークンをBurnする人もいないから必要ないという判断でしょうか。
function burn(uint _value) public {
require(_value > 0);
address burner = msg.sender;
balances[burner] = balances[burner].sub(_value);
totalSupply = totalSupply.sub(_value);
Burn(burner, _value);
}
ちなみに、イーサリアムのようにアカウントベースで残高を記録している場合には、上記のようにbalancesから値を引くだけで良いですが、ビットコインのようにUTXOベースの場合、Burnしたい UTXOを誰も秘密鍵をもっていないアドレスに送るみたいなことが必要になります。
ということで、AlisTokenはトークン発行者がトークンを増やせる仕様になっていて、かつ、トークンを指定した分だけ消せる仕様になっていることがわかりました。
次回は、クラウドセール部分を読みます。