Solanaでスマートコントラクトを書いてみた

はじめに

こんにちは,morimolymolyです. 今回はSolanaという暗号資産のチェーン上で動くプログラム,スマートコントラクトを書いてみましたのでその感想を記します.

Solanaってなに?

Solanaとは第三世代ブロックチェーンの代表格とも呼ばれているらしい*1,新興チェーンではあるものの勢いがありかつ,実用性があるチェーンだそうです.(これ全部人づてなので諸説あるらしい)

Proof of Historyと呼ばれる新規性のある高速なコンセンサスアルゴリズムを提案,実装しています. ホワイトペーパーによると,

On a 1gbps network connection the maximum number of transactions 29 possible is 1 gigabit per second / 176 bytes = 710k tps max

とのことで,めちゃくちゃすごいTPSがでていることがわかります. しかしバリデータ要件がめちゃくちゃ高いらしいので気をつけて.

docs.solana.com

オタク的嬉しいポイントとして,すべてがRustでかかれている事が挙げられます. 以下のレポジトリはSolanaのコアになっています.

github.com

また,オタク的嬉しいポイント2としてeBPF形式でコントラクトが動くというところがあります. 以下がeBPF VMの実装です. eBPFなバイナリが出力できる言語であればいいので,C/C++はもちろん,Rustもいけますね!!!(LLVMはeBPFのバックエンドをもつので)

github.com

つまりすべてがRustに収束するのです.いやーめでたい.

スマートコントラクトとは

スマートコントラクトはブロックチェーンの上で動くプログラムのことです. 一体何ができるのか?僕にもまだ詳しくはわかりませんが,DeFiなどの非中央集権的経済取引のアプリケーションを書くことができます. いままで証券会社や銀行が中央にいた経済に比べ,手数料が安く取引などが可能に,しかも信頼性のある形でできるようです. 今回は詳しく説明しませんが,日銀が注目するほどなので何やらすごいのでしょう.

coinpost.jp

ともかく,僕はネットワークの上で動く謎のコンピュータをいじってみたい!と言う動機でやってみました.

Rustでスマートコントラクトを書く

スマートコントラクトをRustで書くときにはsolana_sdkかAnchorを使う必要がありますが,テストコードがかんたんにかける,色々ラップしてくれて嬉しいということでAnchorを使いました.入門は以下の記事を読めばいいと思います.

project-serum.github.io

以下にハマリポイントを書いていきます

ハマリポイント: M1 Macでうまく動かない問題

M1 Macだとsolana-test-validatorと呼ばれる必ず一度は呼ばないといけないコマンドが現在叩けません. 以下の記事でがんばってくれ!

dev.to

全然Anchorの情報がない

これがマジできつかった.チュートリアル以上のことをやろうとするとすぐ詰まる. さらに破壊的変更がすぐ入って,数ヶ月前の記事が使えないことが起きる.

ここでひとつ,コホン.

テストコードがドキュメントです.

以下の場所からそれっぽいコードをみて理解しろ!

github.com

何を作ったの?

Anchorのチュートリアル的な記事として,このようなものがありました.

dev.to

この記事はかんたんなカウンターを作って,スマートコントラクトで回すアプリを作っています. しかし,フロント側で毎回カウンター用のアカウント(ややこしいのですが,Solanaでいうストレージのようなものです)を使い捨てるため,カウンターが毎回初期化される問題と言うか仕様がありました.それを解決するために,PDA(Program Derived Address)を用いて問題を解決してみました.(これが正しいかはわからんしらん存ぜぬ)

docs.solana.com

PDAを使うとプログラムにアカウントを紐付けることができるので,プログラム側でアカウントの管理ができます.基本コントラクトはステートレスなのでややこしいですね. このようにして,ウォレットに紐付いたカウンターが生成されました.

www.youtube.com

github.com

脆弱性

GeT_Pwn3d!でセキュリティ絡まないのも変なので,脆弱性を埋め込んでおきました!!!(というのは嘘であきて実装を放り投げたのです)

脆弱性1: 弱い認証

PDAのseedとして,ウォレットの公開鍵の10文字のみを使用している.hashがうまいこと衝突すると問題になる.guessもかんたんだ.

脆弱性2: 認証がない

認証がないのでスマートコントラクトを呼び出す際の引数にウォレットのアドレスを入れてしまえば勝手にカウンターを操作できます.

おわりに

初心者がわけわからん散文かいてすみませんの気持ちしかありませんが,これいけてないよーとかこれこうしたほうがいいよーとかあったらコメントください!

*1:第1世代はBitcoin,第二世代はEthereum