ブロックチェーンと形式検証
Tezos Japan, DaiLambda, Inc.
Jun FURUSE/古瀬淳, Tokyo, 2019-08-26PPL Summer School ’19
自己紹介: 以前
OCaml の研究とプログラマ
関数型言語の型システムの研究
Haskell も好きです
関数型プログラマin 金融
金融派生商品のモデル化システム(OCaml/Haskell)
HFT(高頻度取引)システム(OCaml)
自己紹介: 現在
日本におけるTezos技術の普及を行う
NPO
Tezosのコア技術開発を行う零細会社
Tezosとは
第三世代仮想通貨
(1st: Bitcoin, 2nd: Ethereum, 3rd: 沢山)
合意アルゴリズム: Proof of Stake
オンチェーン・ガバナンス
通貨記号はꜩ
OCaml で記述されている
形式検証を重視
https://tezos.foundation/
http://tezos.gitlab.io
今日のお話
通貨の歴史
ブロックチェーン概観
ブロックチェーンの技術面
Proof of Stake
Tezos について
ブロックチェーンと形式検証
通貨の歴史
通貨のテーマ
「どうやって円滑に取引を行うか」
物々交換
⇄
複雑は物々交換
←
↘ ↗
通貨の誕生
⇄ ⇄
⇅
貝貨
中国、1100 BC
貝貞負貢財貨貫責貪販
貧貶貽賀貲貳貰貸貯貼
買費貿賈賊賃賂賄賑賓
賜質賞賤賠賣賦賚賢賭
購賽賺賻贄贅贇贊贈贏学名: Monetaria moneta
それ自体に価値(美)がある
通貨の条件
価値の尺度(大小を比較)
交換手段(支払いしやすい)
価値貯蔵手段(蓄える。腐らない)
コイン鋳造
発行可能: 政府がマネーサプライをコントロール可
中国, 800 BC (刀貨, 布貨)
物理媒体に貴金属としての価値がある
通貨発行益→ 通貨発行者vs 偽造者
兌換紙幣の誕生
運びやすい
権力による貴金属(金、銀、銅)への交換保証
サプライは政府の貴金属準備量に限られる
⇄
通貨の物理媒体自体にもはや価値はない
→ より高度な偽造対策が必要
世界初の兌換紙幣
交子, 中国, 1050 AD
鉄銭の手形として民間で誕生
宋政府が銅銭との兌換を保証
クレジット(信用払い)
通貨ではないが、貸し借りを数字で管理することで
通貨による取引回数を減らし、通商を簡便化する
不換紙幣(Fiat Money)
兌換保証がない!「法定通貨」
1971年から、 後の我々の世界
兌換保証が無くなったが、お金はお金として残った
混乱から為替は変動相場制へ
政府が貴金属準備に関係なくマネーサプライをコントロールで
きるようになった
潤沢な資金供給により流通性が高まり経済が発展した
Bretton Woods 体制
世界初の不換紙幣
交子, 中国, 1050 AD
世界初の兌換紙幣であったが…
通貨発行益目当てで大量発行され、
不換紙幣となる
信用を失い徐々に使われなくなった
電子マネー
物理媒体さえない、コンピュータ上のただの数字。
通常、法廷通貨にペッグ
中央管理者、発行体が法廷通貨への兌換を保証
偽造、不正利用対策として暗号技術が使われる
通貨の価値の源泉の根拠
どんどん消えてきている:
物理媒体自体の価値: ない
兌換保証: ない
法廷通貨証書としての物理実体: ない
通貨を通貨たらしめるものは何か?
租税貨幣論(Chartalism)
税金
暴力装置を備え、税金の支払いを強制してくる政府
より過激な理論: 共同幻想
「これは通貨だ」、という共通認識があれば、
中央集権的権威づけさえ必要ないのでは?
Iraqi Swiss dinar (1993-2003)
Somali shillings (1990’s)
Bottle caps (2270’s, Fallout universe )
暗号通貨の勃興
Since 2009-01-03 (Bitcoin)
電子的: 媒体に価値、形がない
非中央集権: 中央管理者がいない
偽造、不正防止のための暗号技術
トラッキングとプライバシー
電子化は追跡を非常に簡単にする。
権力はトラッキングが大好き
民衆はトラッキングされたくない
匿名性も通貨の重要な要件。
https://twitter.com/maryhui/status/1138675837165641733
通貨の歴史
目的: 取引を円滑に: 物々交換、コイン、紙幣、電子マネー
価値の根拠の希薄化
物理媒体の価値
兌換による保証
法による保証
納税の強制
共同幻想
中央管理者のいない分散化された電子マネー、仮想通貨の登場
ブロックチェーン概観
ブロックチェーンとは?
一旦、お金から離れて:
台帳方式DB
分散環境
オープンネットワーク
トークン
スマート・コントラクト
台帳方式
変更履歴集積としてのデータベース
B1 → B2 → B3 → B4 → ..
S0 = ∅
S1 = B1(S0)
Sn = Bn(Sn-1) = Bn(Bn-1(..(B1(S0))))
例:
銀行通帳、大福帳
バージョン管理システム: Git
分散環境
複数のデータベースノードを設け、それぞれが状態
のレプリカを持つ:
耐故障性
負荷分散
分散DB: 衝突
衝突をどう解消するか?
B
→→
A
x = A
x = A
x = A →→x = B
x = B
x = A
x = B
or
?
? ?
合意アルゴリズム
ノード間の衝突を解決するアルゴリズム。
残念なお知らせ: そんなものは存在しない! [FLP85].
一つでもノードが故障しうる環境では、
どんな合意形成アルゴリズムであっても、停止しない
可能性がある。
うれしいお知らせ: Paxos
病的な例では停止しないかもしれないが、
実用上はOK。
衝突はノード間多数決投票で解消
ただし、固定されたノードからな
る閉じたネットワークでしか動作
しない
閉じたネットワーク
…でよいなら「ブロックチェーン」は必要ない。
オープン・ネットワーク
誰もがノードを立てて参加できる
パーミッションレスな公的DBネットワーク:
中央管理者がいない、
中立で改竄が非常に難しい、
低コスト
オープン・ネットワークでの合意問題
なりすましによる票数操作を行う
シビル攻撃により合意形成の操作
と妨害ができてしまう。
サトシ・ナカモトとBitcoin
シビル攻撃(なりすまし)を難しくする:
投票にはDB外の有限のリソースであ
る計算能力を要求
トークン報酬: リソースを提供し正直
に行動することを奨励する
トークンはDB上で管理
換金性のあるトークン→ 暗号通貨の誕生
仮想通貨
オープン・ネットワークDBのシビル攻撃への解
スマート・コントラクト
台帳型DBはアカウント残高にかぎらず、
どんな値、プログラムコードも記録できる。
アカウントへの送金をトリガーに、紐づいたコードを
実行する。
契約の自動執行が可能な、中央管理者のいない分散
アプリケーション(dApps)環境の登場。
ガス代
スマートコントラクトは制限なく実行できない。
DoS攻撃防止のため、コントラクト呼出者は
その実行コストを手数料としてマイナーに支払う。
ガスリミット、ガス欠
呼出者が宣言したり、システムで決まっているガスリミットを
超えたコントラクト呼出は手数料を支払ったうえで失敗する。
VMモデル
ガス代算出のためコントラクト言語はVMとして実装され
opcodeごとにガス使用量が設定されることが多い。
ブロックチェーンとは
台帳方式DB
分散環境
オープンネットワーク
トークン
スマート・コントラクト
ブロックチェーンの技術面
ブロックチェーン・ネットワーク
複数のノードからなるP2Pネットワーク。
各々のノードが台帳DBのレプリカを持っている。
DBへの問い合わせ
近くのノードに台帳の現在の状態を問い合わせると、
ノードが答えをくれる。簡単。
! ?
→
? !
→
DBへの書込: Operationの放流
Operation :
トランザクション(コントラクト呼出を含む)
アカウントの生成など
Operations はP2P ネットワークに伝搬される:
→
→
O1
O1
O1
O1
O1
O1
O2
O2
O2
O2
O2
O2
O2
O2
O
ブロックの生成
ブロック生成者( マイナー)はノードに集まった
からブロック を作り、ネットワークに放流する:
O1
O1
O2
O2
O2
O2
B = [ O1, O2 ]
→
B
O1
⇨ B1 = [ O1, O2 ]
→
B
B
B
B
B
B
B
B
O B
B = [ , . . , ]Ov1
Ovm
台帳の更新
各ノードは自分の持つ最新の台帳状態 に を適用:
    最初期状態(Genesis)
where
ブロックが連なるので“ブロックチェーン”:
S B
= ∅S0
= ( ) = ( (. . ( ( )). . ))Sn Bn Sn−1 Bn Bn−1 B1 S0
B(S) = ( (. . ( (S)). . ))Ovm
Ovm−1
O1
B = [ , . . , ]O1 Ovm
. . . .S0 →
B1
S1 →
B2
→
Bn−1
Sn →
Bn
暗号技術による偽造防止
より正確には
と はデジタル署名されている
where is a raw operation.
はその前のブロック のハッシュ値 を持つ
where
署名関数 とハッシュ関数 は安全だと仮定
O B
O = (o, sig (o))nu o
Bn Bn−1 H( )Bn−1
= (b, sig (b))Bn nv b = ([ , . . , ], H( ))Ov1
Ovm
Bn−1
signx H
衝突
複数のマイナーがブロックを生成提示した場合、
Nakamoto Consensusではチェーンは分岐する:
B = [ O1, O2 ]
→
B
B →
B'
B'
B' = [ O3, O1 ]
B
B'
B B' V'
↗ →
Bn+1
Sn+1 →
Bn+2
Sn+2 →
Bn+3
Sn+3
. . →
Bn−1
Sn−1 →
Bn
Sn
↘ →
B
′
n+1
S
′
n+1
→
B
′
n+2
S
′
n+2
→
B
′
n+3
S
′
n+3
Double Spending 攻撃
両分岐で所持トークンをチェーン外の資産に交換:
↗
↗ →
Bn+1
Sn+1 →
Bn+2
Sn+2 →
Bn+3
Sn+3
. . →
Bn−1
Sn−1 →
Bn
Sn
↘ →
B
′
n+1
S
′
n+1
→
B
′
n+2
S
′
n+2
→
B
′
n+3
S
′
n+3
↘
Proof of Work (PoW)
ブロック提示には計算が必要なパズル の答が必要:
は から生成
は意図的に弱くしたハッシュ関数
長い分岐(より多くの計算量/「票」が集まった案)が
選ばれる:
Q
= (b, sig (b), ) where  ( ) =Bn nv An H
′
An Qn
Qn Sn−1
(⋅)H
′
. . →
Bn
Sn →
Bn+1
Sn+1 →
Bn+2
Sn+2 →
Bn+3
Sn+3 →
Bn+4
Sn+4
↘
B
′
n+1
S
′
n+1
→
B
′
n+2
S
′
n+2
マイナーへの動機付け
計算コストはマイニング報酬でカバーされる:
新しく鋳造されるブロック報酬
各オペレーションに付けられた手数料 :
ブロック を提示することで、マイナーは
の報酬を で得ることができる。
r
f
o = (raw operation,  f )
B
r + Σo∈B fo
B(S)
Nakamoto Consensus
ブロック報酬はそのチェーンでしか有効ではないため、勝ち目
の薄い分岐に賭ける動機は少ない。
より長い分岐によりブロックがダメになる可能性はあるが、ブ
ロックが積み重なるにつれ、確率は指数関数的に減少。
ユーザーがfiatに換金するためトークンを で交換所に送る
の覆る可能性が少なくなった まで待って交換所はfiatを払
い込む
. . → . . →. .Sn−1 →
Bn
Sn →
Bn+1
Sn+1 →
Bn+2
→
Bn+6
Sn+6
Bn
Bn Bn+6
51%攻撃
50%以上の計算資源を占有していれば、長い分岐を作
ってdouble spendingが可能:
⬇
. . → . .Sn−1 →
Bn
Sn →
Bn+1
→
Bn+6
Sn+6
. . → . .Sn−1 →
Bn
Sn →
Bn+1
→
Bn+6
Sn+6
↘ . .S
′
n−1
→
B
′
n
S
′
n →
B
′
n+1
→
B
′
n+6
S
′
n+6
→
B
′
n+7
S
′
n+7
→
B
′
n+8
S
′
n+8
実際にあった51%攻撃
人気のないPoW ブロックチェーンは関わっている計
算力も少ないので、51%攻撃が成功してしまう:
Verge (XVG), 2M USD (2018-04 and 2018-05)
Bitcoin Gold (BTG), 18M USD (2018-05)
Monacoin (MONA), 90K USD (2018-05)
ZenCash (ZEN) 700K USD (2018-06)
ブロックチェーンの技術面
典型的なPoW式ブロックチェーン
Operation の放流
Operation をまとめたブロックの生成、放流
ブロックによる状態更新
衝突による分岐
分岐を抑制、選択するPoW
51%攻撃
Proof of Stake とTezos
PoW は環境に悪い
Bitcoinが一年に使うエネルギー: 73.12TWh
3.6B USD/y.
オーストリア一国の電気使用量に匹敵
670万軒のアメリカの家の電気量
https://digiconomist.net/bitcoin-energy-consumption
集中のリスク
マイナーは集中しやすい:
PoW はコストの安い、電気代の安い国、地域に集中しやすい
PoW 効率を上げるために連合を組む(マイニングプール)ため、
さらに集中する
過集中はネットワークの安全性を損なう
動機付けの不一致
所持者とマイナーの動機が一致しないリスクがある。
仮想通貨を所持者の大部分はマイナーではないし、
PoWではマイナーは仮想通貨の長期保持者である必要はない。
マイナーはマイニング報酬を最大化しようとするが、それは通
貨所持者の利益を損なうかもしれない。
Proof of Stake (PoS)
PoS: シビル攻撃に対する別の投票制限
計算資源ではなくステーク(トークン所持量)に比例した生成権
過去の履歴を変えてブロック生成権を偽造できないので、
シビル攻撃を抑止できる
長期保持しなければ生成権が発生しない
51%攻撃は可能だが、ネットワーク上に流通する過半数のトー
クンを長期間保持する必要がある
Raspberry PI 3, 2watts
for Tezos
PoS: エコクリーン+高分散
パズルを解くためにエネルギーを浪費する必要がない
Mining → Baking
特別なハードウェア(ASIC,GPU)を必要としない
過集中する理由がない
Antminer S9, 1350watts
for Bitcoin
PoS: 動機付けの一致
マイナー⊂ ステークホルダ
合意参加するにはマイナーは長期に渡ってポジション
を持つ必要がある。
生成権は委任可能
マイニング設備を用意できなくても生成権を委任し、
間接的にブロック報酬を得ることができる。
PoSへの攻撃手法
過去のステークを利用したdouble spending 攻撃:
Nothing at stake 攻撃
Long range 攻撃
   ステークを外部資産に交換
⤴ 
→ → → → →
↘ 過去のステークを利用して分岐
→ → → → → こちらを主流にしてしまう
Tezos Consensus
Tezosでのこれらの攻撃に対する対処:
Nothing at stake 攻撃にたいして:
裏書
保証金
Long range 攻撃にたいして
チェックポイント
裏書(endorsement)
Nakamoto Consensus に裏書を導入する。
各ブロックレベル に32人の裏書人を選ぶ:
各裏書人はレベル に提示された の一つに投票する
投票合計の多い枝が勝つ。たった一人でただ伸ばしてもダメ
i
i , . . ,Bi1 Bin
. . → . .Sn−1 →
Bn
Sn →
Bn+1
→
Bn+6
Sn+6
↘ . .S
′
n−1
→
B
′
n
S
′
n →
B
′
n+1
→
B
′
n+6
S
′
n+6
→
B
′
n+7
S
′
n+7
→
B
′
n+8
S
′
n+8
保証金
ブロック生成と裏書には保証金の担保が必要。
分岐を作り出そうとする行為が見つかった場合、保証金は没収
同一レベルでの同じマイナーによるdouble mining
同一レベルでの同じ裏書人によるdouble endorsements
保証金はチェーンの組替が起こりえなくなくなってから返還(15
日後)
  ↕ 同一マイナーによる分岐は罰せられる
  
. . . .→
Bn−1
Sn−1 →
Bn
Sn →
Bn+1
Sn+1 →
Bn+2
. .↘
B
′
n+1
S
′
n+1
→
B
′
n+2
チェックポイント
定期的にチェーン外にブロックのハッシュ を
記録する:
     
H(B)
https://www.news.com
Tezos’s block hash at is , BKveMfA..n H( )Bn
. . → S →. . →. . →. . →. . →. . →. . → S→
Bn
Sn
     . . →. . →. . →. . →. . →. . →↘ →
B
′
n
S
′
n S
″
PoS とTezos
PoW にはエネルギー浪費とインセンティブ不一致の問題が
PoS: ステーク量に応じた投票権を使ったシビル攻撃抑制
エネルギーを食わない
インセンティブの一致
PoSへの攻撃手法: 過去のステークを利用した分岐作成
とTezos での解決方法:
裏書投票
意図的な分岐を罰する保証金
チェックポイント
もうちょっとTezos について
他のTezosの特徴
基本理念
Liquid PoS
オンチェーンガバナンス
形式検証の重視
Tezos基本理念
ブロックチェーンプロトコルはステークホルダのもの
効率より安全性を優先
(仮想的な)純粋PoS
すべてのステークホルダがブロックを提案できる。
直接民主制。
問題: スケールしない:
すべての人が27h/7dマイニング(投票)はできない。
ブロック生成ができなければ次のマイナーに権利が移る。
が、その分チェーンは遅れる
Delegated PoS
ブロック提案できるのは少数のデリゲート。
ステークホルダはデリゲートを選出できる。
間接民主制。
Pros:
少数間の合意形成のため非常に高速 ex. EOS: 21 super nodes.
ステークホルダはデリゲートから報酬の一部を受け取る
Nakamoto Consensus 以外の合意形成を選択しやすい ex. PBFT
Cons
ネットワークが過集中するので安全性を損なう
Liquid PoS (Tezos)
すべてのステークホルダがブロック生成権を持つが、
他のマイナーに生成権を委任することもできる。
「プロトコルは少数の選出議員のものではなく、
ステークホルダ全員のもの」
マイナーの数に上限はない: ex. Tezos: 500
DPoSの速さは望めないが、より分散→より安全
マイニングできないステークホルダも委任によって報酬の一部
を得ることができる
Liquid Democracy (液体民主主義)
https://medium.com/organizer-sandbox/liquid-democracy-true-democracy-for-the-21st-
century-7c66f5e53b6f
Tezos とオンチェーンガバナンス
ブロックチェーンの「ガバナンス」とは
“どうやってプロトコルを改良(フォーク)していくか”
ソフト/ハードフォーク
ソフトフォーク
後方互換
ハードフォーク
後方非互換:
過去の正しいブロックは新プロト
コルでは非互換になる可能性があ
る
ハードフォークのリスク
プロトコルのハードフォークは
コミュニティのハードフォークを引き起こす:
ハッシュパワーやステークが分裂するので安全性が損なわれる
通貨価値に対する共同幻想の劣化
例:
DAO事件後のEthereum とEthereum Classic ハードフォーク
Bitcoin Cash のハードフォークとその後の「ハッシュ戦争」
ガバナンスの目的
コミュニティの分裂を起こさず
スムーズに技術革新を進める
オンチェーンガバナンス
プロトコル更新方法がプロトコル内に規定され、
すべてのプロセスがチェーン上に保存される:
プロトコル更新提案
更新案のテスト
採択投票
各ノードの自動アップグレード
「プロトコルは開発者のものではなく、
ステークホルダのもの」
Tezos: プロトコルの分離
オンチェーンガバナンスの対象を決める:
シェル
ネットワーク層、ストレージ、など。プロトコルには影響しな
いので、対象ではない。
プロトコル
トランザクションの意味や合意形成を定義。
変更はハードフォークとなりうるのでガバナンス対象となる。
Tezosのオンチェーンガバナンス
約90日サイクルのガバナンス:
更新提案コードをアップロード
第一投票: 更新案を一つ選ぶ
第二投票: 選択更新案をテストするか
テスト期間
最終投票: 採択するかを決定
自動更新
Liquid democracy
LPoS と同じように投票権はステークに比例
Tezos: ガバナンス履歴
“Athens”: はじめてのアップグレード
定数の更新など、簡単なもの
2019-05-21: 最終投票通過
2019-05-30: Athensへの以降
“Babylon”: 合意形成アルゴリズムの 他
2019-08-24: 第二投票中
改良
Tezosの特徴
基本理念: 「プロトコルはステークホルダのもの」
Liquid PoS
オンチェーンガバナンス
安全性、形式検証の重視← 後で
Tezosと形式検証
ブロックチェーンとはなんだったか
台帳DB
分散
オープン・ネットワーク
トークンによるインセンティブ
スマートコントラクト
ブロックチェーンの安全性
オープン分散DBの解として
換金性のあるトークン報酬を導入したため:
大量の投機資金が流入
オープンソースとなる宿命
セキュリティホールは即窃盗の対象となる
ブロックチェーンには非常に高い安全性が求められる
スマートコントラクトの安全性
ブロックチェーン上で動くスマートコントラクトにも
高い安全性が求められる。
過去のスマートコントラクト周辺の事件:
The DAO (3.6M ETH, 流通量の15%, 50M USD 盗難)
Parity 脆弱性#1 (150K ETH, 32M USD 盗難)
Parity 脆弱性#2 (513K ETH, 160M USD 凍結)
ここにも高い安全性が求められる。
The DAO
contract user {
do_deposit()
{
bank.deposit(100);
}
do_withdraw()
{
bank.withdraw();
}
}
contract bank {
deposit()
{
map[SENDER] += AMOUNT;
}
withdraw()
{
send(SENDER, map[SENDER]);
map[SENDER] = 0;
}
}
The DAO
contract attack {
do_deposit()
{
bank.deposit(100);
}
do_withdraw()
{
bank.withdraw();
}
default()
{
bank.withdraw();
}
}
contract bank {
deposit()
{
map[SENDER] += AMOUNT;
}
withdraw()
{
send(SENDER, map[SENDER]);
map[SENDER] = 0;
}
}
ブロックチェーンは巨大なソフトウェア
プロトコル: 合意、インセンティブ、トランザクション意味論
スマートコントラクト: 意味論、コンパイラ
暗号アルゴリズム
P2Pネットワーク層
ストレージ層
すべての領域で安全でなければならない。
ブロックチェーンを安全にする
テスト
重要だが十分ではない
形式検証
やっていくべき
ソフトウェアテスト
システムを与えられた条件下で動かして
うまくいくか見る。
動かしてみる。繰り返す。簡単。
有限のコーナーケースしか試せない
テストされていないケースは無保証
形式検証
数理的にプログラムが良い/悪い性質を持つか証明す
る。
もし証明できれば、すべてのケースにつ
いて性質が成り立つ
一般に証明はとても難しい
形式検証手法
静的型付け
モデル検査
定理証明
静的型付け
値や式の持つ性質を型であらわし、
その組み合わせを型が適合するものに制限し、
プログラム全体の性質を保証する。
Pros: 型推論が自動なら比較的容易
Cons: あまり表現力はない
モデル検査
プログラムを有限状態遷移機械に抽象化し、
これが望んでいる性質を満たしているか検査する。
Pros: 自動。失敗した場合、反例を得ることができる。
Cons: 適した抽象化を行うのが難しい。
定理証明
Coq などの定理証明支援系を使って
プログラムの性質を直接証明する。
Pros: 一番強い。
Cons: 証明を書くのは大変…
ブロックチェーンと形式検証
形式検証はクリティカルシステムで使われてきた:
航空宇宙産業
原子力
ブロックチェーンもクリティカルシステム。
形式検証すべき。対象として理想的:
ほぼソフトウェアのみ、オープン
スマートコントラクトは言語の話
逆にブロックチェーンの安全化を材料に、
形式検証技術が発展するべき。
Tezosと形式検証
VMレベルで静的型付けされたスマートコントラクトシステム
スマートコントラクトVMインタプリタをCoqでモデル化、
コントラクトの正しさを検証
暗号プリミティブの正しさを検証
現在進行形
Merkle木を使ったストレージシステムの正しさを検証中
高級言語からVMへのcertifiedコンパイラ、などなど
Michelson: Tezos スマコンVM
スタックVM
完全関数型: 副作用はない
上書き可能な変数がない
トランザクションは関数呼出しでは無い。Reentrancyバグは起こらない
強い静的型付け
実行時型エラーはない: ex "hello" + 10
通貨と数値型の区別: , , ꜩ
任意制度整数: オーバーフローしない
VMレベルでのデータ型: Lists, sets, maps
ℕ ℤ
Michelsonインタプリタ
Michelsonをノード内で実行
純粋関数型: 副作用なし
GADTs による安全化
インタプリタはVMの型システムで型がつくVMの状態(コードと
スタック)しか構成できない
評価(状態遷移)は型付けを保存することを保証
Mi-Cho-Coq: CoqによるVMのモデル化
Coq 証明支援器によるMichelson の再実装
Michelson 周辺の検証フレームワークを提供
再実装により仕様のドキュメントバグを発見
https://gitlab.com/nomadic-labs/mi-cho-coq/
スマートコントラクトの正しさの検証
Mi-Cho-Coqを使ったMichelsonコードの検証
例:
アカウントは複数のユーザで共同管理されており、その操作は
一定数のユーザの電子署名が集まらなければ実行できない。
multi-sig コントラクト
https://gitlab.com/nomadic-labs/mi-cho-coq/blob/master/src/contracts_coq/multisig.v
HACL*: 検証済み暗号ライブラリ
F* で実装、検証された暗号プリミティブ関数群。
Tezos が使用。
ChaCha20, Salsa20, HMAC, SHA-256, SHA-512, Ed25519, etc.
検証したF* コードを高速なC へとコンパイル
検証された性質:
メモリ安全性
アルゴリズムの正しさ
Secret independence: サイドチャネル攻撃耐性
https://github.com/project-everest/hacl-star
F*
Microsoft の開発しているrefinement type 付き
関数型言語。
OCamlとほぼ互換の文法
Z3ソルバを使った検証の一部自動化
OCaml, F#, C, WASM, ASM へのextraction
https://www.fstar-lang.org/
現在進行中のプロジェクト
私が知っている範囲で:
Sparse Merkle木ベースのストレージシステム。
木の操作をはじめとする正しさをF* で証明していく
検証済みコンパイラの開発
高級言語からMichelsonへのコンパイルの正しさを保証
Tezos コントラクトのためのDSL、Why3によるプログラム検証
Plebeia
Archetype
Tezos と形式検証
ブロックチェーンはクリティカルシステム
テストは重要だが、やはり形式検証が重要
ブロックチェーンの全てのコンポネントの検証が望まれる。
Tezosは形式検証を念頭にデザインされており、良いターゲット
Tezos Hands on
カリキュラム
準備
Docker イメージ
Git レポジトリ
基本のアカウント操作
tezos­clientを試す
アカウント作成
トークンのトランザクション
スマートコントラクト入門
Tezosスマートコントラクトの基礎
コンパイラ
コントラクトのコンパイル、デプロイ、呼出
LIGO
準備
準備#1: Dockerとイメージ
をインストール
Linux ユーザはdocker コマンドをsudo なしで起動できるよ
うにした方が便利: ( )
次の二つのイメージをインストール
イメージが動くかチェック
Docker
details
$ docker pull dailambda/tezos­handson:2019­08 ↩  
$ docker pull dailambda/ligo:2019­08 ↩ 
$ docker run dailambda/tezos­handson:2019­08 ↩  
hello tezos 
$ docker run dailambda/ligo:2019­08 ↩  
hello tezos
Prep #2: Git レポのクローン
中身
tezos­handson­node
ハンズオン用のノード起動スクリプト
tezos­client
。これで一通りできます。
ligo
コンパイラ
contracts/
CamLIGOコントラクト例
$ git clone https://gitlab.com/dailambda/docker­tezos­hands­on ­
b tezos­hands­on­2019­08 ↩  
$ cd docker­tezos­hands­on ↩ 
コマンドライン・ウォレット
LIGO
Dockerイメージを自作したい人は…
レポのdocker­node/ とdocker­ligo/ ディレク
トリにあるのでご自由にどうぞ。
準備はできましたか?
通常のTezos開発
通常のTezos開発は、手元にテストネットワークであ
る“Alpha net” のノードを立てて行う:
↪↪
Tezos Network
ただ、ノードがネットワークに同期するには時間が…
今日はサンドボックス環境を使います
↪↪
あなたのコンピュータで閉じている。外部ネットワークを必要
としない。
テスト/メインネットと同期する必要がない。
Tezosの実トークンを買う必要がない。
いつでも環境をリセットできる。
ハンズオン用サンドボックス環境
ノードを立ち上げよう:
注意: ノードはTCP ポート18732 を使う。
何かおかしくなったらリセットできる:
(Linux ではsudo rm ­rf .tezos­handson­node .tezos­handson­client ↩ 
としなければいけないかもしれません。)
$ ./tezos­handson­node ↩ 
# まず tezos­handson­node を止める 
$ rm ­rf .tezos­handson­node .tezos­handson­client ↩  
$ ./tezos­handson­node
起動例
$ ./tezos­handson­node  
Starting /home/tezzy/tezos//tezos­node run ­­data­dir 
/home/tezzy/.tezos­handson­node ­­no­bootstrap­peers ­­private­
mode ­­sandbox /home/tezzy/.tezos­handson­node/sandbox.json ­­
connections=0 
Waiting the node startup... 
Aug 20 05:15:37 ­ node.main: Starting the Tezos node... 
.. 
Aug 20 05:15:38 ­ node.main: The Tezos node is now running! 
Node is up. 
Activating Alpha protocol... 
.. 
Injected BLChsc7x64kH
動いているか確認
新しいターミナルを開いて、
(ノードのプロセスは動かしっぱなしにしてください。)
$ ./tezos­client bootstrapped ↩  
Current head: BLNeoW9n94mD (timestamp: .. 
Bootstrapped.
ICO寄与情報
Tezosの開発資金募集に出資した人たちはメインネッ
トでアカウントを有効にするための寄与情報を持って
いる:
ハンズオンでは2つのダミー寄与情報を用意してある:
$ ls commitments/ 
tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF.json 
tz1X4maqF9tC1Yn4jULjHRAyzjAtc25Z68TX.json
アカウント有効化
打ち間違いに注意!
tz1xx..xxはアカウントの名前(公開鍵ハッシュ)。
aliceはそのエイリアス。どちらでも使える。
最長15秒ほどかかる。
$ ./tezos­client activate account alice with  
     commitments/tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF.json ↩  
.. 
Operation successfully injected in the node. 
.. 
The operation has only been included 0 blocks ago. 
.. 
Account alice (tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF) activated 
with ꜩ20000000.
何が起こった?!
説明します。
$ ./tezos­client activate account alice with 
commitments/tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF.json  
Node is bootstrapped, ready for injecting operations. 
Operation successfully injected in the node. 
Operation hash is 
'oo6rb94mw9Z4rKexQhYDnSZeXXWmcZ65vcz77KTDTcGstYYeeuC' 
Waiting for the operation to be included... 
Operation found in block: 
BKqArov5fNKzptY81CLsacSTTPh7tPmCXoqeQ4pNzKCP6GtGiro (pass: 2, 
offset: 0) 
This sequence of operations was run: 
  Genesis account activation: 
    Account: tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF 
    Balance updates: 
      tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF ... +ꜩ20000000 
1. ノードの状態を確認する
まずノードがネットワークに同期しているか確認:
サンドボックスは常に同期しているので問題ない。
Node is bootstrapped, ready for injecting operations.
→
→
O1
O1
O1
O1
O1
O1
O2
O2
O2
O2
O2
O2
O2
O2
2. Operation をネットワークに注入
アカウントを有効にする
Operation ooyyy..yyy をネッ
トに注入:
Operationがブロックに取込まれるのを待っている。
Operation successfully injected in the node. 
Operation hash is 'ooyyy..yyy' 
Waiting for the operation to be included...
B1 = [ O1, O2 ]
→
B
B
B
B
B
B
B
B
3. Op. が新ブロックに取り込まれる
サンドボックスの中にはマイナーの
プロセスがいる。
Operationが採用され新しいブロック
Bzzz..zzzが作成されたのを検出:
Genesisブロックに書き込まれていたアカウント
tz1Mawer..が有効になった。
Operation found in block: Bzzz..zzz (pass: 2, offset: 0) 
This sequence of operations was run: 
  Genesis account activation: 
    Account: tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF 
    Balance updates: 
      tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF ... +ꜩ20000000
4. 何ブロックか待ってもよい
ブロックはより長い分岐に覆されるかもしれない:
Nakamoto consensus では長く待つほどブロックの確
度は指数関数的に高まる。
このハンズオンでは待つ意味はない。
The operation has only been included 0 blocks ago. 
We recommend to wait more. 
Use command 
  tezos­client wait for 
oo6rb94mw9Z4rKexQhYDnSZeXXWmcZ65vcz77KTDTcGstYYeeuC to be 
included ­­confirmations 30 ­­branch 
BL26XEjqN4uKAnEC52z6ijj3XibpbcM4ysPLUfcJqkMccyHriV3 
and/or an external block explorer. 
Account alice (tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF) activated 
with ꜩ20000000.
Tezos でのoperation の処理
アカウント有効化と同じ:
Operationを作る。
P2Pネットワークに放流する。
マイナーがoperationを使ってブロックを生成する
ブロックがP2Pネットワークに注入される。
Operationの確度はチェーンが長くなるにつれ強くなる。
アカウント状態を調べる
いくら持ってる?
ブロックチェーンが知っている:
alice は
tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF の
エイリアスなので、
$ ./tezos­client get balance for alice ↩  
20000000 ꜩ
$ ./tezos­client get balance for 
tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF ↩  
20000000 ꜩ
他人の口座残高
Tezosアカウントは匿名性ではないので。
他人のアカウント残高も見れてしまう。たとえば、
tz1TGu6TN5GSez2ndXXeDX6LgUDvLzPLqgYV:
打つのが面倒? jun­account.txt というファイルに
入っています:
$ ./tezos­client get balance for  
      tz1TGu6TN5GSez2ndXXeDX6LgUDvLzPLqgYV ↩  
0.000001 ꜩ
$ cat jun­accounts.txt ↩  
tz1TGu6TN5GSez2ndXXeDX6LgUDvLzPLqgYV
アカウントの別名
アカウントには別名をつけられる:
$ ./tezos­client add address jun  
        tz1TGu6TN5GSez2ndXXeDX6LgUDvLzPLqgYV ↩  
 
$ ./tezos­client get balance for jun ↩  
0.000001 ꜩ
tezos­clientが知っているアカウント
aliceの秘密鍵(sk)を知っている。これはあなたのアカウン
ト。
junの秘密鍵は知らない。これはあなたのアカウントではない。
秘密鍵の管理には気をつけて!!
他人に知られたら最後、あなたのアカウントではなく
なる。
$ ./tezos­client list known addresses ↩  
jun: tz1TGu6TN5GSez2ndXXeDX6LgUDvLzPLq.. 
alice: tz1MawerETND6bqJqx8GV3YHUrvMBCD.. (unencrypted sk known)
トークンを送る
junにいくらか送ってみてください
ありがとうございます! なんか沢山出てきた:
説明します。
$ ./tezos­client transfer 100 from alice to jun ↩ 
$ ./tezos­client transfer 100 from alice to jun ↩  
Node is bootstrapped, ready for injecting operations. 
Estimated gas: 10200 units (will add 100 for safety) 
Estimated storage: no bytes added 
Operation successfully injected in the node. 
Operation hash is 'ooJZ1U114ibPfikZNrDSfmqg8Tcs9CzshL4w1vvsDa35DdB72bN' 
Waiting for the operation to be included... 
Operation found in block: BL6H8145DMyPeXBQBc2JPRKpVstJSYkhgyGSFFhEJQGAfYweQ8u (pass: 3, offset: 0) 
This sequence of operations was run: 
  Manager signed operations: 
    From: tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF 
    Fee to the baker: ꜩ0.001258 
    Expected counter: 1 
    Gas limit: 10000 
    Storage limit: 0 bytes 
    Balance updates: 
      tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF ........... ­ꜩ0.001258 
      fees(tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv,6) ... +ꜩ0.001258 
    Revelation of manager public key: 
      Contract: tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF 
      Key: edpkuSR6ywqsk17myFVRcw2eXhVib2MeLc9D1QkEQb98ctWUBwSJpF 
      This revelation was successfully applied 
      Consumed gas: 10000 
  Manager signed operations: 
    From: tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF 
    Fee to the baker: ꜩ0.001186 
    Expected counter: 2 
    Gas limit: 10300 
    Storage limit: 0 bytes 
    Balance updates: 
      tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF ........... ­ꜩ0.001186 
      fees(tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv,6) ... +ꜩ0.001186 
    Transaction: 
      Amount: ꜩ100 
      From: tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF 
      To: tz1TGu6TN5GSez2ndXXeDX6LgUDvLzPLqgYV 
      This transaction was successfully applied 
      Consumed gas: 10200 
      Balance updates: 
        tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF ... ­ꜩ100 
        tz1TGu6TN5GSez2ndXXeDX6LgUDvLzPLqgYV ... +ꜩ100 
 
The operation has only been included 0 blocks ago. 
We recommend to wait more. 
Use command 
  tezos­client wait for ooJZ1U114ibPfikZNrDSfmqg8Tcs9CzshL4w1vvsDa35DdB72bN to be included ­­confirmations 30 ­­branch BLpBxE6wFBQcvNPyUg7sdodpZN3Xra2qGAAJXPG7Z7i9EM94ivj 
and/or an external block explorer.
1. ノードの状態を確認する
Waiting for the node to be bootstrapped before injection... 
Current head: BL.. (timestamp: .., validation: ..) 
Node is bootstrapped, ready for injecting operations.
2. Gas使用量予想とoperationの注入
Estimated gas: 10200 units (will add 100 for safety) 
Estimated storage: no bytes added 
Operation successfully injected in the node. 
Operation hash is 'oOOO..OOO' 
Waiting for the operation to be included...
3. Operation は新しいブロックに
もうちょっと細かく見てみよう
Operation found in block: BL6H8145DMyPeXBQBc2JPRKpVstJSYkhgyGSFFhEJQGAfYweQ8u (pass: 3, offset: 0) 
This sequence of operations was run: 
  Manager signed operations: 
    From: tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF 
    Fee to the baker: ꜩ0.001258 
    Expected counter: 1 
    Gas limit: 10000 
    Storage limit: 0 bytes 
    Balance updates: 
      tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF ........... ­ꜩ0.001258 
      fees(tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv,6) ... +ꜩ0.001258 
    Revelation of manager public key: 
      Contract: tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF 
      Key: edpkuSR6ywqsk17myFVRcw2eXhVib2MeLc9D1QkEQb98ctWUBwSJpF 
      This revelation was successfully applied 
      Consumed gas: 10000 
  Manager signed operations: 
    From: tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF 
    Fee to the baker: ꜩ0.001186 
    Expected counter: 2 
    Gas limit: 10300 
    Storage limit: 0 bytes 
    Balance updates: 
      tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF ........... ­ꜩ0.001186 
      fees(tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv,6) ... +ꜩ0.001186 
    Transaction: 
      Amount: ꜩ100 
      From: tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF 
      To: tz1TGu6TN5GSez2ndXXeDX6LgUDvLzPLqgYV 
      This transaction was successfully applied 
      Consumed gas: 10200 
3.1 公開鍵の開示
aliceのoperationが真正か確かめられるよう、
aliceの公開鍵edpkuSR6ywqsk..をブロックチェ
ーンに開示する必要がある:
  Manager signed operations: 
    From: tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF 
    Fee to the baker: ꜩ0.001258     手数料 
    Expected counter: 1 
    Gas limit: 10000 
    Storage limit: 0 bytes 
    Balance updates:        マイナーへの報酬 
      tz1MawerETND6bqJqx8GV ........... ­ꜩ0.001258   手数料移動 
      fees(tz1ddb9NMYHZi5Uz95zgv,6) ... +ꜩ0.001258   手数料移動 
    Revelation of manager public key: 
      Contract: tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF 
      Key: edpkuSR6ywqsk17myFVRcw2eXhVib2MeLc9D1QkEQb98.. 
      This revelation was successfully applied 
      Consumed gas: 10000
3.2 トランザクション本体
  Manager signed operations: 
    From: tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF 
    Fee to the baker: ꜩ0.001186                      マイナー報酬設定 
    Expected counter: 2 
    Gas limit: 10300 
    Storage limit: 0 bytes 
    Balance updates:                           マイナーへの報酬の支払い 
      tz1MawerETND6bqJqx8GV3YHUrvM ........... ­ꜩ0.001186 
      fees(tz1ddb9NMYHZi5UzPdzTZMY..zgv,6) ... +ꜩ0.001186 
    Transaction: 
      Amount: ꜩ100                                  トランザクション量 
      From: tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF 
      To: tz1TGu6TN5GSez2ndXXeDX6LgUDvLzPLqgYV 
      This transaction was successfully applied 
      Consumed gas: 10200 
      Balance updates: 
        tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF ... ­ꜩ100   aliceが 
        tz1TGu6TN5GSez2ndXXeDX6LgUDvLzPLqgYV ... +ꜩ100   junに
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 B.. 
and/or an external block explorer.
残高照会
本当にトークンが移動したかどうか、確認しよう:
aliceの残高は100ꜩ + マイナーへの手数料分減って
いる。
$ ./tezos­client get balance for alice ↩  
19999899.997556 ꜩ 
$ ./tezos­client get balance for jun ↩  
100.000001 ꜩ
junのトークンは盗めない
秘密鍵を知らないので、盗めない:
aliceの秘密鍵は.tezos­handson­clientディレ
クトリに保存されている:
$ ./tezos­client transfer 100 from jun to alice ↩  
Error: 
  Unknown secret key for tz1TGu6TN5GSez2ndXXeDX6LgUDvLzPLqgYV
$ cat .tezos­handson­client/secret_keys ↩  
[ { "name": "alice", 
    "value": "unencrypted:edsk3NDQq5Cmix9H15GkcoVhWo.." } ]
Tezosのガス、ストレージコストと手数料
Operation注入には次の情報を提示する必要がある:
コスト見積もり
ガスリミット: 計算量上限
ストレージリミット: 追加の記憶容量上限
マイナーインセンティブ
手数料: Operationが新ブロックに採択された場合、発行者から
マイナーに支払う手数料
マイナーは何をするか
コスト見積と手数料を比べる
手数料> コスト見積
Operationをブロックに取り入れ、手数料をもらう
コスト見積> 手数料
Operationは放置される
Operation発行者がすべき事
正しい手数料を提示
低すぎるとブロックチェーンに載せてくれず、タイムアウト。
低すぎるコスト見積を出してもマイナーは騙せない
実際にかかったコストが見積よりも大きくなった場合は、
それをブロックに記載するとマイナーは手数料を貰える。
自分の口座を新しく作る
秘密鍵、公開鍵の組を作る。簡単:
$ ./tezos­client gen keys alice2
$ ./tezos­client list known addresses 
alice2: tz1M9ZZccgEAgtDGMu8R7xniFt.. (unencrypted sk known) 
jun: tz1TGu6TN5GSez2ndXXeDX6LgUDvLzPLqgYV 
alice: tz1MawerETND6bqJqx8GV3YHUrv.. (unencrypted sk known)
Burn: ストレージ手数料
aliceからalice2に10000ꜩ送ってみるが、、、
新しいアカウントのための記録域が必要。そのコスト
として0.257ꜩを要求されている:
$ ./tezos­client transfer 10000 from alice to alice2 
Fatal error: 
  The operation will burn ꜩ0.257 which is higher than the 
configured burn cap (ꜩ0). 
   Use `­­burn­cap 0.257` to emit this operation. 
Exiting
$ ./tezos­client transfer 10000 from alice to alice2  
      ­­burn­cap 0.257 
... 
      Balance updates: 
        tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF ... ­ꜩ10000 
        tz1cMEsG9mvL8zyiGHppcCjcz1Et65zwidfg ... +ꜩ10000 
        tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF ... ­ꜩ0.257   Burn
スマートコントラクト!
Tezos スマートコントラクトのしくみ
スマートコントラクトを持つアカウント名:
KTxxx..xxx
コントラクトの状態
残高
コード
ストレージ
コード呼出
コードはコントラクトに送金することで起動する
Tezosのコントラクトは純粋関数
入力
送金時に与えるパラメータ
ストレージの内容
大域定数
(現在の残高、送金量、送り主、など)
出力
Operationリスト(送金、他コントラクトの呼出など)
新しいストレージの内容
副作用なし
Immutable。純粋関数
Michelson
Tezosスマートコントラクトのための と
その言語。
VMだが高機能:
静的型付け
任意制度 , 。オーバーフローなし。
データ型(options, lists, sets, map)
暗号プリミティブ
読み書きはちょっと 辛い…
スタックVM
 
# 送り元に同額返すMichelsonコード 
 
parameter unit; 
storage unit; 
 
code { 
       CDR ; 
       NIL operation ; 
       AMOUNT; 
       PUSH mutez 0; 
       IFCMPEQ 
         { } 
         { 
           SOURCE ; 
           CONTRACT unit ; 
           ASSERT_SOME ; 
           AMOUNT ; 
           UNIT ; 
           TRANSFER_TOKENS ; 
           CONS ; 
         }; 
       PAIR; 
     } 
 
ℕ ℤ
CameLIGO
今日は、 を使う。
Tezos スマートコントラクトのための高級言語。
コンパイラ
LIGOはMichelsonオプコードにコンパイルされる
文法
PascaLIGO (Pascal風) とCamLIGO (OCaml風)
Cheat sheetやサンプルはここ:
レポの./contractsディレクトリの下
開発中でいろいろ引っかかりはあるが、使えます。
LIGO(http://ligolang.org)
https://gitlab.com/dailambda/mligo_contracts/blob/master/cheat-sheet.md
OCamlプログラマの皆様にお断り
CamLIGO はOCaml ではない。
再帰ありません: let rec
型推論は完全じゃありません: ([] : int list)
パターンマッチのように見えるがパターンマッチではない。
Nested patternはダメ: Some (Some x)
Patternに定数は書けない: 1::[]
match .. with のネストはカッコがいります
はじめてのCamLIGOコントラクト
ストレージの文字列を引数で置き換える:
よくわからない?
説明します。
let main (parameter : string) (storage : string) = 
  ( ([] : operation list),  parameter )
関数定義
関数引数は型を次のように明示する必要がある
(parameter : string)
引数はスペースで区切る:
let f (x : ty1) (y : ty2) = ..
❌let f ( (x : ty1), (y : ty2) ) = ..
let function_name (arg1 : type1) ... (argn : typen) = 
  code
let main (parameter : string) (storage : string) = 
  ( ([] : operation list),  parameter )
コントラクトのEntrypoint
コントラクトの入り口は2引数関数:
起動時に与えられたパラメータ: ここではparameter
ストレージの値: ここではstorage
で、次の組(..., ...) を返す:
Operation のリスト: ここでは空: [] (型の明示が必要)
新しいストレージの値: ここではparameter
let main (parameter : string) (storage : string) = 
  ( ([] : operation list),  parameter )
コンパイルしよう
コントラクトのコードをcontracts/first.mligo に置く
コンパイラにコントラクトのentrypoint名main を渡す
間違いなければ、コードはMichelsonコードにコンパ
イルされ、contracts/first.tzに保存される。
$ ./ligo compile­contract contracts/first.mligo main ↩ 
let main (parameter : string) (storage : string) = 
  ( ([] : operation list),  parameter )
生成されたMichelsonコード
ええっと…?
大丈夫です。説明しません。
{ parameter string ; 
  storage string ; 
  code { {} ; 
         { { { { DUP } ; CAR } ; 
             { { { { DIP { DUP } ; SWAP } } ; CDR } ; 
               { { { DIP { DUP } ; SWAP } ; NIL operation } ; PAIR } ; 
               {} ; 
               DIP { { DIP { DIP { DIP { {} } } } ; DROP } } } ; 
             {} ; 
             DIP { { DIP { DIP { {} } } ; DROP } } } ; 
           DIP { { DIP { {} } ; DROP } } } } }
コントラクトのデプロイ
first: コントラクトのエイリアス名
for alice: コントラクトのマネージャー(持ち主)
transferring 0 from alice: 初期残高は0
running contracts/first.tz: Michelsonコード
­­init '"initial value"': 初期ストレージ値
­­burn­cap 0.506: 記憶域のためのburn
$ ./tezos­client originate contract  
        first for alice  
        transferring 0 from alice  
        running contracts/first.tz  
        ­­init '"initial value"'  
        ­­burn­cap 0.506 ↩ 
うまくいかなかった時は
よくある間違い
打ち間違い
アカウント名はalice?
クォート、ダブルクォートは大事: '"initial value"'
"Error: At line 1 character 0, などなど
Dockerの問題。ファイルfirst.tz はligo スクリプトがある
ディレクトリ下に置く。
Burn cap に関する“Fatal error”
長い初期ストレージ値はより多い記憶域コストがかかる
うまくいきましたか?
説明します。
$ ./tezos­client originate contract first for alice transferring 0 from alice running contracts/first.tz ­­init '"initial value"' ­­burn­cap 0.506 ↩  
Node is bootstrapped, ready for injecting operations. 
Estimated gas: 16275 units (will add 100 for safety) 
Estimated storage: 506 bytes added (will add 20 for safety) 
Operation successfully injected in the node. 
Operation hash is 'ooe54u2xReWTmbV6eWeKZf3SbWNRMGcFdyuVKDU5UpjYtM1EVDU' 
Waiting for the operation to be included... 
Operation found in block: BLCmgqwqMShuD38WYFabrD8o8XRf9Xp7W5ZyUkjQYYiK7ULF8qv (pass: 3, offset: 0) 
This sequence of operations was run: 
  Manager signed operations: 
    From: tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF 
    Fee to the baker: ꜩ0.002139 
    Expected counter: 3 
    Gas limit: 16375 
    Storage limit: 526 bytes 
    Balance updates: 
      tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF ............ ­ꜩ0.002139 
      fees(tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv,10) ... +ꜩ0.002139 
    Origination: 
      From: tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF 
      For: tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF 
      Credit: ꜩ0 
      Script: 
        { parameter string ; 
          storage string ; 
          code { {} ; 
                 { { { DUP ; CAR } ; 
                     { { { DUUP } ; CDR } ; 
                       { { DUUP ; NIL operation } ; PAIR } ; 
                       {} ; 
                       DIP { { DIP { DIP { DIP { {} } } } ; DROP } } } ; 
                     {} ; 
                     DIP { { DIP { DIP { {} } } ; DROP } } } ; 
                   DIP { { DIP { {} } ; DROP } } } } } 
        Initial storage: "initial value" 
        No delegate for this contract 
        This origination was successfully applied 
        Originated contracts: 
          KT1NmLBEGeKrppHESUK9KEkHjj6i4677J3cS 
        Storage size: 249 bytes 
        Paid storage size diff: 249 bytes 
        Consumed gas: 16275 
        Balance updates: 
          tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF ... ­ꜩ0.249 
          tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF ... ­ꜩ0.257 
 
New contract KT1NmLBEGeKrppHESUK9KEkHjj6i4677J3cS originated. 
The operation has only been included 0 blocks ago. 
We recommend to wait more. 
Use command 
  tezos­client wait for ooe54u2xReWTmbV6eWeKZf3SbWNRMGcFdyuVKDU5UpjYtM1EVDU to be included ­­confirmations 30 ­­branch BLTSxQK35VsHuFpvyFJRWkcvxZi2CEmigLvc3FWBarDPXZrFAEP 
and/or an external block explorer. 
Contract memorized as first.
デプロイの結果(要旨)
Gas limit: 16374, Storage limit 526 bytes
マイナー手数料提示: ꜩ0.002139
コントラクトのマネージャーはalice (tz1Mawer..)
初期残高(credit) はꜩ0
Michelsonコードと初期ストレージ値"initial value"
新しく作られたコントラクトのアドレスはKT1NmLBE..
実際のコスト: Gas: 16275, Storage: 249 bytes
新ストレージにかかる記憶域コスト: ꜩ0.249
コントラクトコードなどにかかる記憶域コスト: ꜩ0.257
ウォレットは新しいコントラクトのこと
を知っている
今回はaddresses ではなくcontracts。
$ ./tezos­client list known contracts ↩  
first: KT1NmLBEGeKrppHESUK9KEkHjj6i4677J3cS 
alice2: tz1cMEsG9mvL8zyiGHppcCjcz1Et65zwidfg 
jun: tz1TGu6TN5GSez2ndXXeDX6LgUDvLzPLqgYV 
alice: tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF
コントラクトの状態を調べる
$ ./tezos­client get script code for first ↩  
{ parameter string ; 
  storage string ; 
  code { .. } } 
 
$ ./tezos­client get script storage for first ↩  
"initial value" 
 
$ ./tezos­client get balance for first ↩  
0 ꜩ
スマートコントラクトの呼出
普通の送金と同じだが、
引数を­­arg スイッチで与える:
$ ./tezos­client transfer 0 from alice to first  
     ­­arg '"hello"' ↩  
.. 
    Transaction: 
      Amount: ꜩ0 
      From: tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF 
      To: KT1NmLBEGeKrppHESUK9KEkHjj6i4677J3cS 
      Parameter: "hello" 
      This transaction was successfully applied 
      Updated storage: "hello" 
      Storage size: 241 bytes 
      Consumed gas: 15762 
..
うまくいかなかった時は
打ち間違いをチェック
アカウント名はalice?
コマンドは誤起動を避けるためにわざと長くしてある…
Burn cap に関する“Fatal error”
新たに記憶域を必要とする呼び出しはコストがかかる:
$ ./tezos­client transfer 0 from alice to first  
    ­­arg '"I am creative and give a very long string!"' ↩  
Fatal error: 
  The operation will burn ꜩ0.029 which is higher than the 
configured burn cap (ꜩ0). 
   Use `­­burn­cap 0.029` to emit this operation.
結果を確かめよう
$ ./tezos­client get script storage for first ↩  
"whatever you sent" 
 
$ ./tezos­client get balance for first ↩  
100 ꜩ       Non 0 if you transfer some tokens.
おめでとうございます!!
これであなたもTezos エンジニアです。
Smarter Contracts
Operationリストを返す
非空のoperationリストを返す事で、スマートコント
ラクトからの送金や、他のコントラクトの呼出が可
能。
Smarter Contracts: Boomerang
もし誰かが0でないトークンを送ってきたら、送り元
に返す。
コントラクトの入力
Storage: nothing
Parameter: nothing
ML言語族では特に値を必要としない場合の型として
unit を使う。unit型の値は()
大域定数
使用する大域定数は:
amount: 送金量
source: トランザクションを起動したアカウントのアドレス
Operation関連関数
Operation関連の関数:
Operation.transaction
: 'a ­> tez ­> 'a contract ­> operation
コントラクトに指定した引数とともに送金。
ex. Operation.transaction () 10tz contract
Operation.get_contract
: address ­> _ contract
指定したアドレスを持つコントラクト。
コントラクトの引数の型のため、型情報が必要。
ex. (Operation.get_contract adrs : unit contract)
Boomelang
条件分岐
if e1 then e2 else e3
非空リスト
[ 1 ; 2 ; 3 ]
ローカル変数の定義
let v = e1 in e2    e1 の評価結果を変数v に束縛。
let main (param : unit) (storage: unit) = 
  let ops =  
    if amount = 0tz then  
      ([] : operation list)  
    else  
      [ Operation.transaction () amount  
          (Operation.get_contract source : unit contract) ] 
  in 
  ( ops, () ) 
コンパイルとデプロイ
$ ./ligo compile­contract contracts/boomerang.mligo main 
 
$ ./tezos­client originate contract boomerang for alice  
    transferring 0 from alice running contracts/boomerang.tz  
    ­­burn­cap 0.745
そして呼出!
送ったトークンと同僚がaliceに戻されているのを
確認してください。
$ ./tezos­client transfer 10 from alice to boomerang 
    Balance updates: 
      tz1MawerETND6bqJqx8GV3YHUrvMBCD.. ............ ­ꜩ0.004347 
      fees(tz1ddb9NMYHZi5UzPdzTZMYQQZoM95zgv,15) ... +ꜩ0.004347 
    Transaction: 
      .. 
      Balance updates: 
        tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF ... ­ꜩ10 
        KT1Lw7gDyYr2MFUVJLyA2sQuCSjsc1krcAkb ... +ꜩ10 
    Internal operations: 
      Transaction: 
        .. 
        Balance updates: 
          KT1Lw7gDyYr2MFUVJLyA2sQuCSjsc1krcAkb ... ­ꜩ10 
          tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF ... +ꜩ10 
発展問題
簡単な銀行bank
パラメータ
unit
ストレージ
預金口座テーブル。型は(address, tez) map。アドレスか
ら残高が引ける。
動作
入金が非0ならば、送り主(sender)の残高を更新する。
入金が0ならば、送り主(sender)の残高をすべてsenderに返し、senderの
残高をリセットする。
ヒント
を参考に。
大域変数
amount, sender (送金元)
送金量がゼロか、どうか
amount = 0tz かamount <> 0tz
Map操作
Map.find_opt, Map.update, Map.remove を使う。
Map.find_optの結果による分岐
パターンマッチを使う:
match result with None ­> .. | Some tez ­> ..
./contracts/cheat-sheet.md
ヒント
デプロイ
空のストレージ初期値は­­init '{}' で与える
呼出
map が大きくなる際は新記憶域のための­­burn­cap が必要
超発展問題
attacker: bank にDAO攻撃のようなことをする、
次のようなコントラクト:
初期残高は100tz
自分に0の送金があったらbankのアドレスに10tz送る
自分に非0の送金があったら
残高が200tzを超えていればなにもしない
さもなければ、bankに0tzを送る
bankに十分な残高がある場合、attackerは10tz以
上のトークンをbankから奪えるだろうか。

Blockchain and formal verification (Japanese)