まえがき
solanaの重要な技術要素の一つ、PDAについて腹落ちしていなかったので自身の理解のためも含め解説記事を書いてみた。
情報が少なすぎるせいか聞ける人がいないので、間違いや修正補足についてコメントや編集リクエスト大歓迎です。
読む前の前提知識
solanaのAccount、Program、Instractionをざっくり理解していること
PDA(Programm derived address)とは
直訳するとプログラム派生アドレス、文字通りProgram IDと、任意のseed値を基に生成されるハッシュである。
PDAは一見すると公開鍵のように見えるアドレスであるが、これらは生成段階においてオフカーブ1であることを確認するため、紐づく秘密鍵が存在しない。
なお、ProgramIdとSeedの組み合わせによっては、ed25519楕円曲線上の正しい公開鍵が生成されてしまうため、その際にはseedにbumpと呼ばれる値を追加し生成を行う。オフカーブな値が生成されるまでこれを繰り返す。
PDA自体には「オフカーブである公開鍵っぽい文字列である」これ以上の特徴はない。
PDAが解決すること
PDAがないとどうなるのか?前提として、
・solanaではアカウントはすべてアドレスをもち、これは公開鍵が設定される。
・アカウントの情報は、すべて公開されている。
・アカウントの状態を変更するためには、その公開鍵に対応する秘密鍵をっていることを証明する(署名する)必要がある。
つまり、アカウントの数だけ秘密鍵が必要になってしまう。
当然、すべてのアカウントの情報が公開されている場合において、秘密鍵をオンチェーン上のどこかに保管するなどはご法度である。
これを解決するために、PDAが登場する。
solanaにおけるPDAは下記の二つを可能にする。
- Programが、秘密鍵を必要とせずに特定のアドレスにプログラムで署名できる。(つまり、トークンの送信などの実行が可能)
- CPI(Cross-Program Invocation)において、プログラム同士を相互に呼び出し可能する。
PDAを利用するユースケース
それでは、どういうケースで有用なのか。
トークンをA,B間で交換する場合、各々が自分のアカウントから送金する必要があるが、
相手が送ってこない場合を考えるととりっぱぐれのリスクがある。
たとえば、オークション、別々のものを順番に送りあい交換する、二者間で賭けをし勝者が掛け金を受け取る、のようなケースである。
その際、とりっぱぐれ無いよう下記のような流れで取引を行う必要がある。
- Aは信頼できる第三者(escrow)に資産を預け、Bから期待する額を設定する。
- BはAに送金し、それが正しい額であれば、同時にescrowは1.で預かった資産をBに送金する。
この場合、escrowがトランザクションを実行できる必要があるため、
PDAを生成し、それが所有する一時的なアカウント(escrow)の権限を割り当てる。
AがもつトークンX、Bが持つトークンYをそれぞれ交換するケースでの、PDAの生成と権限の委譲は下記のような形。
プログラムは公開されていて変更できず、solanaのトランザクションは一つ失敗すると全体が失敗する仕組みになっているので、
Aが送金を済ませ、あとはBが送金しさえすれば受け取れる状況を作り出すことができる。
その他知っておくといいかもしれないこと
- PDAは「署名」ができるが、暗号技術的に署名をしているわけではない
- ランタイムが渡されたSeedと実行元のProgramIdを見てPDAが生成できるか試し、一致すれば署名済みとしてマークする
- PDAを探す処理はオフチェーンでも可能。計算能力的にも推奨
参考
-
ed25519楕円曲線上に存在しないハッシュのこと。solanaではed25519を用いたキーペアを利用しており、これはPDAではない通常の公開鍵がed25519楕円曲線上にあるということ(対応する秘密鍵がある)を意味する。 ↩