![見出し画像](https://assets.st-note.com/production/uploads/images/132729324/rectangle_large_type_2_bf450721fec85c7a380347797b087cc3.png?width=800)
【完全保存版】Solanaの「Counter PDA チュートリアル」をやってみよう!
1 PDAチュートリアルの実行
今回は、Solana playgroundの「Counter PDA Tutorial」を進めてみます。
Solana playgroundはこちらです。
こちらから、「Counter PDA Tutorial」を選択します。
![](https://assets.st-note.com/img/1709360646371-ZCdDL8Exex.png?width=800)
「START」から進んでいきます。
![](https://assets.st-note.com/img/1709360686838-EQI6On3T7C.png?width=800)
2 大まかな構成について
今回は、こちらにあるように、PDA(プログラム派生アドレス)を使用して、データを保存します。
0から始まり、呼び出しごとに1増えるデータを格納します。
![](https://assets.st-note.com/img/1709360726024-wXJIWHdRsw.png?width=800)
まずは構成として、次の3つのセクションに分かれます。
①スマートコントラクトの関数
②データバリデータ
③データ構造
![](https://assets.st-note.com/img/1709360818068-zN7or3usTH.png?width=800)
3 データ構造について
まずは、Data Structures(データ構造)を見てみましょう。
![](https://assets.st-note.com/img/1709360943627-m5kXQvox6D.png?width=800)
1 #[account]属性について
まずは、account属性をつけることにより、アカウントシステムと統合されています。
![](https://assets.st-note.com/img/1709367699536-X2RLCqi87r.png?width=800)
これにより、特定のアカウントに紐づけられたデータとなります。
![](https://assets.st-note.com/img/1709368435803-Qrw6rx6rMo.png?width=800)
2 データについて
データとしては、下のように、所有権を持つ公開鍵である、「authority」とカウントを行う「counter」で構成されています。
![](https://assets.st-note.com/img/1709368491262-99YCfjjePl.png?width=800)
4 データの検証について
まず、データ検証はこちらで定義されています。
今回は2つありますね。
ここで、アカウントが特定の条件を満たしているかを検証しています。
![](https://assets.st-note.com/img/1709371789170-Inaq7IYr6w.png?width=800)
例えば、create_counterという関数を実行するアカウントは下の条件を満たしているかをチェックします。
![](https://assets.st-note.com/img/1709371945604-tpC0XiURar.png?width=800)
2 #[derive(Accounts)]マクロについて
#[derive(Accounts)]マクロの下でアカウントのセットを定義しています。
![](https://assets.st-note.com/img/1709372226156-b75zFw32eJ.png?width=800)
3 #[account(mut)]アトリビュートについて
#[account()]アトリビュートを使って、アカウントの条件を指定しています。
下のように、mutの場合は、変更可能であることを示します。
今回の場合は、その直下の、「authority」が変更可能であることを示しています。
![](https://assets.st-note.com/img/1709372341521-7hiJIKz1j6.png?width=800)
4 #[account(init)]について
アカウントを初期化するのを示すため、「init」を指定しています。
![](https://assets.st-note.com/img/1709374463172-ucrSmuME67.png?width=800)
また、アカウントの作成は「システムプログラム」によって行われます。
それを明示的に示すために、「system_program」を設定しています。
![](https://assets.st-note.com/img/1709374726726-pPKnbKzeeR.png?width=800)
5 シードとbumpについて
PDA(プログラム派生アドレス)を作成することを、「seeds」と「bump」を設定することで示しています。
シードには、authorityの公開鍵を使用しているようです。
![](https://assets.st-note.com/img/1709374788694-QvtkhyP6DA.png?width=800)
この「シード」や「bump」、PDAについては別の記事で扱いたいと思います。
概要としては、「プログラムID」「シード」「bump(必要なら)」を使って、PDAを抽出します。
PDAには、秘密鍵がないことが特徴です。
6 #[account(payer)]について
payerでは、ガス代の支払い者を指定しています。
authorityが支払うように設定しています。
![](https://assets.st-note.com/img/1709375075274-FDkof4MSlI.png?width=800)
7 #[account(space)]について
#[account(space)]では、アカウントに割り当てるデータのサイズを指定しています。
![](https://assets.st-note.com/img/1709375284715-0r7tx93lWn.png?width=800)
8 #[account(has_one)]について
has_oneでは「counter」が「authority」によって所有されていることを示しています。
![](https://assets.st-note.com/img/1709375418399-vc3Uf5y1FH.png?width=800)
5 関数の設定について
1 コピペしましょう
まずは、下の右の部分をコピペしましょう。
![](https://assets.st-note.com/img/1709376535404-fg8c5Uh4U9.png?width=800)
2 可変参照について
下の部分で、アカウントへの参照を行っています。
そして、「&mut」をつけることで可変参照(変更できる)にしています。
![](https://assets.st-note.com/img/1709376766785-rW0Vf6DUsh.png?width=800)
3 値の代入
下の部分で、値を入れています。
「authority」には公開鍵、「counter」には0を入れています。
![](https://assets.st-note.com/img/1709376901688-ulVVseOeXS.png?width=800)
4 update_counter関数の設定について
update_counter関数内でも、下のようにコピペしましょう。
もちろん、チュートリアルにあるようにご自身で考えて入れてもいいと思います。
![](https://assets.st-note.com/img/1709377150649-5qBZdcHNF1.png?width=800)
下の部分で、counterに1をプラスするようにしています。
![](https://assets.st-note.com/img/1709377233722-W9mSwl8kj7.png?width=800)
6 ビルドとデプロイについて
1 ビルドについて
準備ができましたので、「build」コマンドでビルドをしましょう。
もちろん、「Build」ボタンを押してでも大丈夫です。
![](https://assets.st-note.com/img/1709361759277-X9Y9rjiaJK.png?width=800)
2 テストトークンを取得する
テストトークンが不足している場合は、下のようにして取得しましょう。
![](https://assets.st-note.com/img/1709361776912-jpdDikqW7w.png?width=800)
3 デプロイについて
最後に、「Deploy」ボタンか「deploy」コマンドで、デプロイを行いましょう。
![](https://assets.st-note.com/img/1709361805896-BPaOF1JMLI.png?width=800)
7 テストコードを見てみよう
テストに移る前に、テストコードを簡単に見てみましょう。
1 システムプログラムの取得
「anchor.web3.SystemProgram」でシステムプログラムを取得しています。
これは、アカウントの作成時に使用されます。
![](https://assets.st-note.com/img/1709412123792-Bo2U2cdNVa.png?width=800)
2 itについて
これは、JestやMochaで使用される関数です。
テストケースを書く際に使用されます。
「async」が使われているので、非同期の処理を含んでいます。
![](https://assets.st-note.com/img/1709412149222-9iyVyv6mry.png?width=800)
3 PDA(プログラム派生アドレス)の抽出
今回のメインである、PDA(プログラム派生アドレス)の抽出を「findProgramAddress」で行っています。
![](https://assets.st-note.com/img/1709412688200-ZlaNAcQa5K.png?width=800)
こちらにあるように、「シード」と「プログラムID」を渡して作っています。
また、現在、非推奨のようで、「findProgramAddressSync」を使うように書かれています。
![](https://assets.st-note.com/img/1709416145960-lTf2ynob93.png?width=800)
そのため、下のように、「findProgramAddressSync」に変更するのが良いと思います。
![](https://assets.st-note.com/img/1709416324120-JrJCD17T6K.png?width=800)
4 カウンター生成関数の実行
「createCounter」関数を実行して、Counterアカウントを生成しています。
counterの値には、PDAのアカウントを入れています。
![](https://assets.st-note.com/img/1709416690344-1jGuiycsBX.png?width=800)
5 アカウントのデータの取得
こちらでも、上と同様、「findProgramAddressSync」を使って、公開鍵を取得しています。
その上で、「fetch」メソッドを使って、アカウントのデータを取得しています。
![](https://assets.st-note.com/img/1709417474696-aI6qEACH1n.png?width=800)
6 カウンター更新関数の実行
では、次に「updateCounter」関数でカウンターを更新しています。
最初と異なる関数を使っているだけで、流れは同じです。
![](https://assets.st-note.com/img/1709417737525-BryTNvjipL.png?width=800)
8 テストの実行
では、テストコマンドでテストを実施してみましょう。
下のように、PDAができたことが確認できました。
![](https://assets.st-note.com/img/1709417970198-tBnTIOtUmN.png?width=800)
counterは、初期値である「0」から、「updateCounter」関数が実行され、「1」になっています。
そして、3つともパスしていることが確認できました。
![](https://assets.st-note.com/img/1709418012094-BCfmcruLUg.png?width=800)
もう一度実行してみると、次は1つ失敗しました。
これは、既にPDAが作られているのに、同じPDAを作ろうとしたためです。(想定通りの失敗です。)
また、「updateCounter」関数は実行され、「counter」の値は「2」になっていることも確認ができました。
![](https://assets.st-note.com/img/1709418150520-OnltY2WZwG.png?width=800)
今回は以上です。
サポートをしていただけたらすごく嬉しいです😄 いただけたサポートを励みに、これからもコツコツ頑張っていきます😊