Tezos ハンズオン~ Tezos実習
DaiLambda, Inc. 古瀬淳, Osaka, 2019-05-11Singularity Hive
print
カリキュラムカリキュラム
準備
Dockerイメージのインストール
Gitレポのクローン
アカウントを作る
テストネットの無料アカウントを入手
基本的な送金
tezos-clientを試してみる
Tezosスマートコントラクト入門
スマートコントラクトの概念
コンパイラを使ってみる
コントラクトのデプロイと起動
fi
準備準備
DockerイメージのインストールDockerイメージのインストール
Tezosの概要説明中にやっておいてください:
をインストール
Linuxユーザーはsudoなしで立ち上げられるように( )
演習用イメージをネット/USBからインストール:
動作確認
Docker
参考
$ docker pull furuse/tezos-hands-on-fi ↩ (ネット)
もしくは
$ docker load < tezos-hands-on-fi.tar ↩  (USBメモリ)
$ docker run furuse/tezos-hands-on-fi ↩ 
Hello Tezos!
GitレポのクローンGitレポのクローン
中身中身
tezos-client.sh
Tezos公式の 。これで全部できる。
fi-comp.sh
のコンパイラ。
bash.sh
イメージの中身にアクセスするシェル。最終手段。
fi-sample/
のサンプル
$ git https://gitlab.com/dailambda/docker-tezos-hands-on ↩ 
コマンドラインウォレット
fi
fi
スクリプトがうまく動かない時はスクリプトがうまく動かない時は
イメージ内のシェルに入って実行してください:
Ubuntuなのでsudo apt install emacs-noxとかして。
./tezos-client.sh と./fi-comp.sh があります。
CTRL+D で抜けると全部パァになります。しない。
$ docker run -it furuse/tezos-hands-on-fi bash ↩ 
Dockerイメージを作りたい人Dockerイメージを作りたい人
Gitレポのdocker/にあるから好きにしてください
じゃあ、はじめます!じゃあ、はじめます!
テストネットを使いますテストネットを使います
今日はTezosのテスト用ネットワーク、
Alphanetを使います。
本番のMainnetとほぼ同じですが、
トークンをタダで貰えます。売れませんが。
Block time が30秒(Mainnet は60秒)
半年に一回ぐらいリセットされる
普通はローカルノードを使うが…普通はローカルノードを使うが…
通常の開発ではローカルにTezosノードを建てて、
それをTezosネットへの入り口として使います。
今日は外部ノードを使います今日は外部ノードを使います
ただ、ノードの設定や同期に時間がかかるので、
今日は外部にあるノードを使うことにします:
設定が反映されているか確認してください:
$ ./tezos-client.sh -A ホスト名 -P ポート番号 config update ↩ 
$ cat .tezos-client/config ↩ 
{ .. "node_addr": "ホスト名", "node_port": ポート番号, .. }
アカウントを作ろうアカウントを作ろう
蛇口から飲め蛇口から飲め
から無料アカウントを入手してください
tz1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.json という
ファイルが手に入ります。
Tezos faucet (https://faucet.tzalpha.net/)
アカウントをアクティベートするアカウントをアクティベートする
tz1xxx..xxx.jsonをtezos-client.sh と同じディレクト
リに置いて:
ミスタイプに注意
tz1xx..xxがアカウント名(パブリックキーハッシュ)です。
aliceはその短縮名。(好きなのを選んでよい)
ブロックチェーンに登録するので時間がかかります
$ ./tezos-client.sh activate account alice 
with tz1xxx..xxx.json ↩ 
..
Operation successfully injected in the node.
..
The operation has only been included 0 blocks ago.
..
Account alice (tz1xx..xx) activated with ꜩ23728.975596.
何が起こった?!?!何が起こった?!?!
説明します。
$ ./tezos-client activate account alice with tz1xxx..xxx.json ↩ 
Node is bootstrapped, ready for injecting operations.
Operation successfully injected in the node.
Operation hash is 'ooyyy..yyy'
Waiting for the operation to be included...
Operation found in block: BLzzz..zzz (pass: 2, offset: 0)
This sequence of operations was run:
Genesis account activation:
Account: tz1xxx..xxx
Balance updates:
tz1xxx..xxx ... +ꜩ23728.975596
The operation has only been included 0 blocks ago.
We recommend to wait more.
Use command
tezos-client wait for ooyyy..yyy to be included --confirmations
30 --branch B.. ..
Account alice (tz1xxx..xxx) activated with ꜩ23728.975596.
1. 接続先ノードのチェック1. 接続先ノードのチェック
接続先ノードがネットワークと十分に同期されているかチェッ
ク:
Node is bootstrapped, ready for injecting operations.
2. 操作をP2Pに流す2. 操作をP2Pに流す
アカウント操作(オペレーション、今回はアカウントのアクティ
ベーション) ooyyy.yyy をP2Pネットワークに流し込む:
操作がブロックに取り入れられるのを待っている。
Operation successfully injected in the node.
Operation hash is 'ooyyy..yyy'
Waiting for the operation to be included...
3. 操作が新ブロックに入る3. 操作が新ブロックに入る
ネットワーク上のベイカーが操作をブロックに取り入れ、新
しいブロックBLzzz.zzzを作成した事を検知:
Operation found in block: BLzzz..zzz (pass: 2, offset: 0)
This sequence of operations was run:
Genesis account activation:
Account: tz1xxx..xxx
Balance updates:
tz1xxx..xxx ... +ꜩ23728.975596
Genesisブロックに記載されていたアカウントtz1xxx.xxxが、表
示されたトークン数でアクティベートされた。
4. 分散合意を待ってみてもよい4. 分散合意を待ってみてもよい
分散合意アルゴリズムにより、ブロックが低い確率で他のブ
ロックに取って代わられる可能性がある。
長く待てば待つほど指数関数的に確実になる。
今回は待たずにいきましょう。
The operation has only been included 0 blocks ago.
We recommend to wait more.
Use command
tezos-client wait for ooyyy..yyy to be included --confirmations
30 --branch B..
and/or an external block explorer.
Account alice (tz1xxx..xxx) activated with ꜩ23728.975596.
30ブロック待って本当に合意が取れたか待ってみてはいかが?
Tezosネットでの操作の流れTezosネットでの操作の流れ
アクティベーションに限らず、流れは同じ:
やりたいことをアカウント操作にする
操作をP2Pネットワークに放流する
ベイカーが操作を取り込んでブロックを作る
ブロック作成がP2Pネットワークで伝えられる
分散合意により各程度が高まっていく
アカウントを調べるアカウントを調べる
いくら持っている?いくら持っている?
ブロックチェーンが知っています:
alice はtz1xxx.xxx の別名なので:
でもいいよ
$ ./tezos-client.sh get balance for alice ↩ 
23728.975596 ꜩ
$ ./tezos-client.sh get balance for tz1xxx.xxx ↩ 
他の人の残高もわかります他の人の残高もわかります
ブロックチェーンは匿名ではありません。
私のアカウントは、
tz1ZD7QcE3yWfj6v8pwfbKTgdb3HU1q8EMM4
少ない、、、
$ cat jun-account.txt ↩ 
tz1ZD7QcE3yWfj6v8pwfbKTgdb3HU1q8EMM4
$ ./tezos-client.sh get balance for 
tz1ZD7QcE3yWfj6v8pwfbKTgdb3HU1q8EMM4 ↩ 
484.412385 ꜩ
アカウントの短縮名アカウントの短縮名
いちいち正式なアカウント名書いてられないので:
あいかわらず少ない、、、
$ ./tezos-client.sh add address jun 
tz1ZD7QcE3yWfj6v8pwfbKTgdb3HU1q8EMM4 ↩ 
$ ./tezos-client.sh get balance for jun ↩ 
484.412385 ꜩ
ウォレットが知ってるアカウントウォレットが知ってるアカウント
aliceは秘密鍵(sk)を知っている、あなたのアカウント。
junは秘密鍵がない。つまり、他人のアカウント。
$ ./tezos-client.sh list known addresses ↩ 
alice: tz1xxx..xxx (unencrypted sk known)
jun: tz1ZD7QcE3yWfj6v8pwfbKTgdb3HU1q8EMM4
ブロックエクスプローラでも確認ブロックエクスプローラでも確認
ブラウザから口座情報を調べることができる。例えば、
TzScan OS for Alphanet: http://node1.nyc.tezos.org.sg:8001
トークンを送ってみるトークンを送ってみる
ぜひ私に送ってください!!ぜひ私に送ってください!!
ありがとうございます。また何か出た:
説明します。
$ ./tezos-client.sh transfer 100 from alice to jun ↩ 
$ ./tezos-client.sh transfer 1 from alice to jun ↩  
Node is bootstrapped, ready for injecting operations.
Estimated gas: 10100 units (will add 100 for safety)
Estimated storage: no bytes added
Operation successfully injected in the node.
Operation hash is 'ooZZZ..ZZZ'
Waiting for the operation to be included...
Operation found in block: BLYYY..YYY (pass: 3, offset: 0)
This sequence of operations was run:
Manager signed operations:
From: tz1xxx..xxx
Fee to the baker: ꜩ0.001273
Expected counter: 40305
Gas limit: 10200
Storage limit: 0 bytes
Balance updates:
tz1xxx..xxx ............. -ꜩ0.001273
fees(tz3AAA..AAA,..) .... +ꜩ0.001273
Transaction:
Amount: ꜩ100
From: tz1xxx..xxx
To: tz1ZD7QcE3yWfj6v8pwfbKTgdb3HU1q8EMM4
This transaction was successfully applied
Consumed gas: 10100
Balance updates:
tz1xxx..xxx ... -ꜩ100
tz1ZD7QcE3yWfj6v8pwfbKTgdb3HU1q8EMM4 ... +ꜩ100
The operation has only been included 0 blocks ago.
We recommend to wait more.
Use command
tezos-client wait for ooZZZ..ZZZ to be included --confirmations 30 --branch BLYYY..YYY
and/or an external block explorer.
1. 接続先ノードチェック1. 接続先ノードチェック
Node is bootstrapped, ready for injecting operations.
2. ガス見積もり、操作の放流2. ガス見積もり、操作の放流
Estimated gas: 10100 units (will add 100 for safety)
Estimated storage: no bytes added
Operation successfully injected in the node.
Operation hash is 'ooZZZ..ZZZ'
Waiting for the operation to be included...
3. 操作が新ブロックに入る3. 操作が新ブロックに入る
Operation found in block: BLYYY..YYY (pass: 3, offset: 0)
This sequence of operations was run:
Manager signed operations:
From: tz1xxx..xxx
Fee to the baker: ꜩ0.001273
Expected counter: 40305
Gas limit: 10200
Storage limit: 0 bytes
Balance updates:
tz1xxx..xxx ............. -ꜩ0.001273
fees(tz3AAA..AAA,..) .... +ꜩ0.001273
Transaction:
Amount: ꜩ100
From: tz1xxx..xxx
To: tz1ZD7QcE3yWfj6v8pwfbKTgdb3HU1q8EMM4
This transaction was successfully applied
Consumed gas: 10100
Balance updates:
tz1xxx..xxx ... -ꜩ100
tz1ZD7QcE3yWfj6v8pwfbKTgdb3HU1q8EMM4 ... +ꜩ100
3.5. 操作の内訳3.5. 操作の内訳
ベイカーへのフィー(お駄賃)はꜩ0.001273
カウンタは40305
ガスリミットは10200 (予想される10100 に+100)
ストレージは使わない
alice からベイカーtz3AAA..AAA に手数料ꜩ0.001273
実際のトランザクションの量はꜩ100
tz1xxx..xxx から
tz1ZD7QcE3yWfj6v8pwfbKTgdb3HU1q8EMM4 わたしへ、ありがとう!
実際に使ったガスは予想通り10100
4. 覆されるかもしれない4. 覆されるかもしれない
The operation has only been included 0 blocks ago.
We recommend to wait more.
Use command
tezos-client wait for ooZZZ..ZZZ to be included --
confirmations 30 --branch BLYYY..YYY
and/or an external block explorer.
Tezos の見積もりとフィー(お駄賃)Tezos の見積もりとフィー(お駄賃)
操作をネットワークに投げる人は
操作のコスト見積もり
ガス上限: CPUパワーを消費量
ストレージ上限: 追加記憶容量
フィー(お駄賃)
を提示する
ベーカーがこの操作をブロックにいれてくれたら、これだけあげ
ますよ
ベーカーの行動ベーカーの行動
コスト見積もりとフィーを比べるコスト見積もりとフィーを比べる
フィーがコストを上回りそうなら、自分のブロックに入れて、
フィーをもらう
見合わなければ操作は放置される➡ フィーを上げてみる
コストを低く見積もるのはダメコストを低く見積もるのはダメ
実行中に実コストが見積もりを上回ることが判明した場合、
中断して、その旨ブロックに記載することができる。
➡ フィーだけ取られてしまう。コストをちゃんと見積もる
大抵は見積もりはシミュレーターがちゃんと計算してくれる
スマートコントラクトやるぞスマートコントラクトやるぞ
スマートコントラクト言語fiスマートコントラクト言語fi
の作ったJavaScript っぽい言語を
今日は無謀にも使います。
ドキュメント:
オンラインコンパイラ:
TezosのVM であるMichelson にコンパイルできる
新しすぎるのでクセがあるし、色々足りない 。
ソース:
TezTech
https://learn.fi-code.com/
https://fi-code.com/
https://github.com/TezTech/fi-compiler
Tezos スマートコントラクトのしくみTezos スマートコントラクトのしくみ
コントラクト: KTxxx.xxx アカウント:
残高
コード
ストレージ(記憶領域)
起動: コントラクトに引数を添えて送金するとコードが動く
Tezosのコントラクトは関数Tezosのコントラクトは関数
入力入力
ストレージの内容
起動時に渡された引数
(送金量、現在時間など)
出力出力
新しいストレージの内容
アカウント操作の列(送金、コントラクト呼び出しなど)
Tezosコントラクトに副作用はない。純粋関数型。Tezosコントラクトに副作用はない。純粋関数型。
だからスゴイ。カッコいい。
大域定数
うわっ、Tezosメンドくさ!うわっ、Tezosメンドくさ!
入門したてでこんなん言われたら、うざいやろ?
せやから今日はこういうのなしや
(正味の話、関数型とは~とか説明する時間ないねん
fi はその辺マルッと副作用になっとるfi はその辺マルッと副作用になっとる
関数
関数は何も返さない。以下の副作用を行うだけ。
ストレージ
大域変数の中身を代入で改変していく
アカウント操作の列
アカウント操作関数をコード内で順次実行
はじめてのfi コードはじめてのfi コード
入力された文字列でストレージを上書きする:
なんとなく、わかりますか? よくわからない?
説明します。
storage string s;
entry main(string arg){
storage.s = input.arg;
}
ストレージの宣言ストレージの宣言
このコントラクトは文字列をストレージに持ちます:
Cとかのstatic宣言みたいね。
ストレージの初期値はコントラクトのデプロイ(アップロード)
時に行います。(あとで
storage string s;
関数の定義関数の定義
JavaScript とかC 知っていたら大体同じです:
エントリポイントエントリポイント
コントラクトとして呼び出せる関数、エントリポイントは
entry を前につけます:
関数名 ( 引数, .., 引数) {
コード列 ; .. ; コード列 ;
}
entry main(string arg) {
storage.s = input.arg;
}
名前空間名前空間
変なんだけど、ストレージと引数は名前空間みたいなものを使
わないといかんです。
次のはエラー:
storage.s = input.arg としてください。
storage string s;
entry main(string arg){
s = arg;
}
コンパイルしてみようコンパイルしてみよう
が便利なので使います。https://fi-code.com
fi コンパイラはMichelson コードを吐くfi コンパイラはMichelson コードを吐く
わからない?
説明しません
parameter bytes;storage string;code{DUP;CDR;NIL
operation;PAIR;SWAP;CAR;DUP;PUSH nat 4;PUSH nat
0;SLICE;IF_NONE{PUSH nat 100;FAILWITH}{};DUP;PUSH bytes
0x31a49750;COMPARE;EQ;IF{DROP;DUP;SIZE;PUSH nat
4;SWAP;SUB;DUP;GT;IF{}{PUSH nat 102;FAILWITH};ABS;PUSH nat
4;SLICE;IF_NONE{PUSH nat 101;FAILWITH}{};UNPACK
string;IF_NONE{PUSH nat 103;FAILWITH}
{};PAIR;DUP;CAR;SWAP;SET_CDDR;CDR}{DROP;PUSH nat 400;FAILWITH}}
コントラクトのデプロイコントラクトのデプロイ
のDeploy タブでコマンドを作ります:
Contract Name: simple
Manager: alice
Initial Balance Ꜩ: 0
Storage.S: initial value
https://fi-code.com/
コントラクトのデプロイ#2コントラクトのデプロイ#2
出てきたデプロイコマンドを参考に、
ターミナルでコマンドを実行:
./tezos-client じゃなくて./tezos-client.sh です
初期ストレージ確保のためにネットワーク手数料が必要、この
支払いを--burn-cap で許可する必要があります。
$ ./tezos-client.sh originate contract simple for alice 
transferring 0 from alice 
running 'parameter bytes;storage ...' 
--init '"initial value"' 
--burn-cap 0.57 ↩ 
なんかすごいのでたなんかすごいのでた
説明します
$ ./tezos-client.sh originate contract simple for alice transferring 0 from alice running 'parameter ..' --
init '"init value"' --burn-cap 0.57 ↩ 
..
This sequence of operations was run:
Manager signed operations:
From: tz1xxx..xxx
Fee to the baker: ꜩ0.002398
Expected counter: 40306
Gas limit: 18321
Storage limit: 587 bytes
Balance updates:
tz1xxx..xxx ....... -ꜩ0.002398
fees(baker,176) ... +ꜩ0.002398
Origination:
From: tz1xxx..xxx
For: tz1xxx..xxx
Credit: ꜩ0
Script: { parameter bytes ; code { .. } }
Initial storage: "init value"
No delegate for this contract
This origination was successfully applied
Originated contracts:
KT1BBB..BBB
Storage size: 310 bytes
Paid storage size diff: 310 bytes
Consumed gas: 18221
Balance updates:
tz1xxx..xxx ... -ꜩ0.31
tz1xxx..xxx ... -ꜩ0.257
New contract KT1BBB.BBB originated.
Contract memorized as simple.
デプロイ結果デプロイ結果
落ち着いて読むとわかる(実際の出力はちょっとちがうかも):
ガス上限: 18321, ストレージ上限: 587 bytes に対し、
ベイカーへの手数料としてꜩ0.002398 を提案、支払っている
コントラクトはalice (tz1xxx..xxx) のもの。
初期バランスはꜩ0
デプロイしたコードと、初期ストレージ値は"init value"
作成されたコントラクトのアドレスはKT1BBB..BBB
実際に使ったガスは18221, ストレージは310 bytes
ストレージのためのネット手数料ꜩ0.31
新規アカウント作成ネット手数料ꜩ0.257
知っているコントラクトの表示知っているコントラクトの表示
addresses じゃなくてcontracts:
ブロックエクスプローラーからも確認できます
$ ./tezos-client.sh list known contracts ↩ 
simple: KT1BBB..BB
jun: tz1ZD7QcE3yWfj6v8pwfbKTgdb3HU1q8EMM4
alice: tz1xxx..xx
スマートコントラクトを呼び出す#1スマートコントラクトを呼び出す#1
tz1アカウントにお金を送った時のようにするだけ。ただし、
KT1アカウントへ
パラメータを--arg で指定
fi はちょっと面倒fi はちょっと面倒
エントリポイントを複数持てるよう、引数を独自にエンコード
している。
"hello" を渡すのに、単に--arg '"hello"' ではダメ。
$ ./tezos-client.sh transfer 0 from alice to simple --arg 引数 ↩ 
スマートコントラクトを呼び出す#2スマートコントラクトを呼び出す#2
のCallタブを使います:
Contract Entry: main
Input.Arg: hello
From/Source Address: alice
Smart Contract Address: simple
Amount Ꜩ: 0
なにやらバイナリの引数が出てきます。
https://fi-code.com/
./tezos-client transfer 0 from alice to simple --arg
'0x31a4975005010000000568656c6c6f'
スマートコントラクトを呼び出す#3スマートコントラクトを呼び出す#3
出てきたコマンドを元に./tezos-client.sh を使います:
ストレージが"hello" に変わったのが確認してください。
ブロックエクスプローラでも見てみるといいです。
$ ./tezos-client.sh transfer 0 from alice to simple 
--arg '0x31a4975005010000000568656c6c6f' ↩ 
..
Transaction:
Amount: ꜩ0
From: tz1xxx..xxx
To: KT1BBB..BBB
Parameter: 0x31a4975005010000000568656c6c6f
This transaction was successfully applied
Updated storage: "hello"
Storage size: 305 bytes
Consumed gas: 16997
コマンドラインからコンパイル#1コマンドラインからコンパイル#1
simple.fisimple.fi というファイルを用意:というファイルを用意:
fi-comp.shfi-comp.sh でコンパイルでコンパイル
simple.fi.mlsimple.fi.ml というファイルができますというファイルができます
storage int x;
entry main(int parameter){
storage.x = input.parameter;
}
$ ./fi-comp.sh simple.fi ↩ 
Compilation complete!
$ ls ↩ 
.. simple.fi simple.fi.ml ..
コマンドラインからコンパイル#2コマンドラインからコンパイル#2
デプロイはデプロイはsimple.fi.mlsimple.fi.ml を使う以外は同じを使う以外は同じ
呼び出し引数作成は呼び出し引数作成は
コマンドラインに呼び出しのためのツールがあればよいのです
が、現在はありません
$ ./tezos-client.sh originate contract simple for alice 
transferring 0 from alice 
running simple.fi.ml 
--init '"init value"' 
--burn-cap 0.57 ↩ 
https://fi-code.com/https://fi-code.com/
fiによるスマコン開発の流れ、まとめfiによるスマコン開発の流れ、まとめ
コンパイルコンパイル
か
./fi-comp.sh を使う
デプロイデプロイ
./tezos-client.sh originate contract ... ↩ 
実行実行
で--argを作る
./tezos-client.sh transfer ... --arg ... ↩ 
https://fi-code.com/
https://fi-code.com/
fi足し算fi足し算
引数をストレージに足していく:引数をストレージに足していく:
注意点: 算術二項演算子はうまく動かない注意点: 算術二項演算子はうまく動かない
storage.sum + input.arg はダメ
add( x, y ) を使う
storage int sum;
entry main(int arg){
storage.sum = add( storage.sum, input.arg );
}
fi条件分岐fi条件分岐
if ( 条件式 ) { Then節 } else { Else節 }
fiローカル変数fiローカル変数
let 型 変数名 = 初期値;
Then節やElse節の中では使えません
storage int s;
entry main(int x1){
let int x2 = add ( input.x1, input.x1 );
let int x4 = add ( x2, x2 );
let int x8 = add ( x4, x4 );
storage.s = x8;
}
fi構造体fi構造体
Yes, No の数を記録
注意点: 定数は型を明示注意点: 定数は型を明示
int -196,   nat 4096,   mutez 1000000 (百万マイクロꜩ)
struct Storage(
nat yes,
nat no
);
storage Storage str;
entry main(bool yes){
if ( input.yes ) {
storage.str.yes = add( storage.str.yes, nat 1 );
} else {
storage.str.no = add( storage.str.no, nat 1 );
}
}
fiデータ型fiデータ型
List, Option, Set(集合), Map(キーバリューマップ) が使えます。
を見てね
例Map例Map
型: map[int => string]
メンバシップ検査: in(マップ, キー)
クエリ: get(マップ, キー)
追加/更新: push(マップ, キー, 値)
Map上の繰り返しはできません
https://learn.fi-code.com/overview/maps-and-lists
fiトークン移動fiトークン移動
ありがとうございます:
引数を足して、他のコントラクトを起動することもできます:
が、型がMichelsonレベルで合っていなければいけません
transfer(address "tz1ZD7QcE3yWfj6v8pwfbKTgdb3HU1q8EMM4",
mutez 100000000);
transfer(address "KT1CCC..CCC",
mutez 0,
データ);
fi大域定数fi大域定数
:
AMOUNT : 送ったmutez
BALANCE : 現在アカウントにあるmutez
NOW : 現在のtimestamp
SELF : 自分のコントラクト(再帰呼び出しできる)
SOURCE : 初めにコントラクトを起動したアカウント
SENDER : このコントラクトを呼び出したアカウント/コントラ
クト
OWNER : 実行中のコントラクト
https://learn.fi-code.com/overview/global-constants
fiはいろんなものが足りない!fiはいろんなものが足りない!
コメント書けない
データを文字列にできないint 100 → "100"
再帰関数呼び出しできない
List, Map, Set のiterationができない
…
それでもいろんなスマートコントラクトが書けます。
fiチャレンジfiチャレンジ
投票dApp
NOW がデプロイ時に指定した日付間だけ投票可能
投票候補名と投票数の(Map[string => int])
各アカウントは一回しか投票できない(Set[address])
fi投票dAppソースfi投票dAppソース
struct Storage(
string title,
map[string => int] candidates,
set[address] voters,
timestamp beginning_time,
timestamp finish_time
);
storage Storage str;
entry main(string parameter){
if ( (NOW < storage.str.beginning_time)
|| storage.str.finish_time <= NOW ){
throw (string "voting period is over");
}
if ( in(storage.str.voters, SOURCE) ){
throw (string "you have already voted", SOURCE);
}
let int x;
if ( in(storage.str.candidates, input.parameter) ){
x = get(storage.str.candidates, input.parameter);
push(storage.str.candidates, input.parameter, add(x, int 1));
} else {
throw (string "No such candidate", input.parameter);
}
}
fi投票dAppデプロイfi投票dAppデプロイ
$ ./0tezos-client.sh originate contract vote for alice 
transferring 1 from foobar 
running vote.fi.ml 
--init '(Pair "hello"
(Pair { Elt "No" 1 ; Elt "Yes" 2 }
(Pair {}
(Pair "2019-01-01T00:00:00Z"
"2019-12-31T00:00:00Z"))))' 
--burn-cap 1.788 ↩ 

Tezos hands-on : Tezos exercise