Pact言語によるセキュアな
スマートコントラクト開発
Hi-Ether Meetup #8 Tokyo
2018.08.29
DMM.com スマートコントラクト事業部 加嵜長門
更新
https://www.amazon.co.jp/dp/4839965137/
加嵜 長門(かさき ながと)
スマートコントラクト事業部エバンジェリスト。
分散処理技術やブロックチェーン技術の研究開発、事
業提案などを担当。
共著に『ブロックチェーンアプリケーション開発の教科
書』(マイナビ出版)、『ビッグデータ分析・活用のための
SQLレシピ』(マイナビ出版)、『詳解 Apache Spark』(技
術評論社)
Twitter: @knagato
2
自己紹介
Pact言語とは
● Kadenaブロックチェーンのコントラクト実装言語
○ https://github.com/kadena-io/pact
3
● セキュアなコントラクト実装に特化
○ 公開鍵ベースのアクセスコントロール
○ 非チューリング完全
○ 形式的検証システム
Kadenaの概要
● ScalableBFTを採用したプライベートチェーン
4https://cyber.stanford.edu/sites/default/files/kadenachainweb-bpase18.pdf
● パブリックチェーンのためのプロトコルを開発中
Pactのサンプルコード
● LISPライクな文法
5
;; Define the module.
(module helloWorld 'admin-keyset
"A smart contract to greet the world."
(defun hello (name)
"Do the hello-world dance"
(format "Hello {}!" [name]))
)
;; and say hello!
(hello "World")
HelloWorld.pact
Pactのサンプルコード
● 組み込みのキーバリューストア
6
;; Set transaction signature KEYS.
(env-keys ["accountadmin" "user123" "user456"])
;; Set transaction JSON data,
;; either as encoded string, or as pact types coerced to JSON.
(env-data { "accounts-admin-keyset": ["accountadmin"] })
(env-data { "123-keyset": { "keys": ["user123"], "pred": "keys-all" },
"456-keyset": { "keys": ["user456"], "pred": "keys-any" } })
KeyValues.pact
実行環境インストール
● Mac OS
7
● Ubuntu
○ バイナリをダウンロード
$ brew install kadena-io/pact/pact
http://kadena.io/pact/downloads.html
実行環境インストール
● Windows
○ Windows Subsystem for Linux が楽(旧 Bash on Ubuntu on Windows)
8
Atom Plugin
9
● AtomのPact言語用プラグインを提供
○ language-pactで検索
動作確認
10
$ pact
pact> (+ 1 2)
3
pact> (+ "hello, " "world")
"hello, world"
pact> (contains 2 [1 2 3])
True
● Pactインタプリタ(Ctrl-Dで終了)
もっと手軽に使ってみる
11
● Try Pact In The Browser
○ http://kadena.io/try-pact/
形式的証明システム
● The pact property checking system
○ https://pact-language.readthedocs.io/en/latest/pact-properties.html
○ https://medium.com/kadena-io/889058bd8c3f
12
● 形式的検証 (Formal Verification)
○ プログラムが正しいことを証明する
○ テストコードは書かない
PactFVの使い方
● Microsoft’s Z3 theorem proverをインストール
○ https://github.com/Z3Prover/z3/wiki
○ apt-get install z3 だとバージョンが古いので、上記から最新版を使う
13
● アノテーションを書く
(defun negate:integer (x:integer)
@doc "negate a number"
@model (properties [(= result (* -1 x))])
(* x -1))
PactFVのデモ
● サンプルコード
14
(defschema account
@doc "user accounts with balances"
@model (invariants [(>= balance 0)])
balance:integer
ks:keyset)
pactFVsample.repl
https://gist.github.com/KasakiNagato/12fbb35341ee49ed2f4f0f74c0f595cd
PactFVのデモ
15
(defun transfer (from:string to:string amount:integer)
@doc "Transfer money between accounts"
@model (properties
[(row-enforced 'accounts 'ks from)
(= 0 (column-delta 'accounts 'balance))])
(with-read accounts from { 'balance := from-bal, 'ks := from-ks }
(with-read accounts to { 'balance := to-bal }
(enforce-keyset from-ks)
(enforce (>= from-bal amount) "Insufficient Funds")
(update accounts from { "balance": (- from-bal amount) })
(update accounts to { "balance": (+ to-bal amount) }))))
pactFVsample.repl
https://gist.github.com/KasakiNagato/12fbb35341ee49ed2f4f0f74c0f595cd
PactFVのデモ
16
$ wget
https://gist.githubusercontent.com/KasakiNagato/12fbb353
41ee49ed2f4f0f74c0f595cd/raw/0bd0fc04f688187c79d89bb3e07
29aba37d204bf/pactFVsample.repl
$ pact
pact> (load "pactFVsample.repl")
pact> (list-modules)
["pactFVsample"]
pact> (verify 'pactFVsample)
PactFVによるプログラムのバグ検出
17
Property proven valid
pactFVsample.repl:21:7:Warning: Invalidating model
found:
Arguments:
from := ""
to := ""
amount := -1
Variables:
from-bal := 1
from-ks := KeySet 3
to-bal := 1
...
発見されたバグと修正案
18
● Amountに負の値を指定された場合
○ 送信者が受信者の残高を奪ってしまうことができる
○ (enforce (> amount 0)) を指定
● FromとToに同じアドレスを指定された場合
○ 不正に自分の残高を増やすことができる
○ (enforce (!= from to)) を指定
より詳しくは
19
● Kadena Whitepapers
○ http://kadena.io/whitepapers.html
● Kadena - Medium
○ https://medium.com/kadena-io
● Kadena - Github
○ https://github.com/kadena-io/pact

Pact言語によるセキュアなスマートコントラクト開発