![見出し画像](https://assets.st-note.com/production/uploads/images/142898905/rectangle_large_type_2_f3899e74be316ff5ded8b6e1541c0f26.png?width=800)
【完全保存版】初めてのTransfer Hook(Solana)
0 はじめに
本日は、SolanaのTransfer Hookを扱っていきます。
トークンの送付時に、別の処理を行うことで、今回は、簡単なメッセージを表示します。
とはいえ、いきなり全てを理解するのは大変なので、この記事ではどのような処理を行っているのかの流れを掴んでいきたいと思います。
1 処理の実行
まずは、こちらのリンクから処理を行ってみましょう。
1 テストトークンの取得
初めて行う場合は、こちらの第2章第1節までを元に、テストトークンを取得してください。
2 デプロイの実行
では、プログラムをデプロイしてみましょう。
「Build」を実行します。
![](https://assets.st-note.com/img/1717451327378-j9ovJz7GPF.png?width=800)
その後、「Deploy」を行います。
![](https://assets.st-note.com/img/1717451355351-7MmddS8FTz.png?width=800)
このようになれば成功です。
![](https://assets.st-note.com/img/1717451372053-Q6gLORZjEq.png?width=800)
3 テストの実行
こちらのボタンを押すと、テストができます。
下のようになれば成功です。
![](https://assets.st-note.com/img/1717451411809-ywfjxd4fRF.png?width=800)
今回は、ここで行ったテストが、何をやっていたのかの概要を、以下で見ていきます。
2 TransferHook付きのミントアカウントの作成
ここでは、TransferHook付きのミントアカウントを作ります。
1 アカウントの作成
まずは、「createAccount」で通常のミントアカウントを作ります。
![](https://assets.st-note.com/img/1717311072180-T5Xhq39sPZ.png?width=800)
2 TransferHookプログラムの結び付け
まず、事前に「TransferHook」プログラムを準備します。
「createInitializeTransferHookInstruction」を使用し、このプログラムをミントに結びつけます。
![](https://assets.st-note.com/img/1717311322195-1Ez8aqLDJl.png?width=800)
3 基礎情報の設定
最後に、「createInitializeMintInstruction」を使い、基本的な情報を設定します。
小数点以下の桁数やミント権限のあるウォレットの指定などを行います。
![](https://assets.st-note.com/img/1717311509027-gcK16ayrMd.png?width=800)
3 送付元・送付先の作成
1 送付元トークンアカウントの作成
ミントアカウントのトークンを取得するには、そのためのトークンアカウントが必要です。
「createAssociatedTokenAccountInstruction」を使い、自身のトークンアカウントを作成します。
![](https://assets.st-note.com/img/1717312027324-ahVzv8uZg5.png?width=800)
2 送付先トークンアカウントの作成
同様にして、送付先のトークンアカウントを作成します。
![](https://assets.st-note.com/img/1717312101416-TiwyeERUhp.png?width=800)
3 送付元トークンアカウントへのミント
最後に、送付元トークンアカウントに「createMintToInstruction」で100トークンをミントします。
これにより、送る準備ができました。
![](https://assets.st-note.com/img/1717361927015-Pdo8flo5Tp.png?width=800)
4 ExtraAcountMetaListの初期化
ここでは、まず、何をやりたいのかを考えましょう。
1 概要
例えば今回、送付時に、その一部を手数料として、別のアカウントに送りたいとします。
そのように、「送付処理」に直接関係がないアカウントが出てくることがあり、そのアカウントを保管する必要があります。
それを保管するために作るのが、「ExtraAccountMetaList」です。
![](https://assets.st-note.com/img/1717448457034-4AroJYNzdZ.png?width=800)
2 PDAの導出
では、作っていきましょう。
まずは、「Mintアカウント」と「extra-account-metas」という文字からPDAを導きます。
![](https://assets.st-note.com/img/1717362323136-AxmO8T1i5c.png?width=800)
今回作成した、「transfer_hook」というプログラムから派生したPDA(プログラム派生アドレス)です。
この時点では、アドレスを見つけただけで、アカウントが作成されていません。
3 アカウントの初期化
今回作成した、「transfer_hook」内の「initializeExtraAccountMetaList」を使って初期化します。
今回は、送付時にメッセージを表示するだけで、別のアカウントは必要ないので、今回はこのリストにアカウントは含まれません。
![](https://assets.st-note.com/img/1717362420236-72WJGj3SvC.png?width=800)
5 Transfer Hook付きの送付
1 送付の実行
では、最後に、「createTransferCheckedWithTransferHookInstruction」を使って、Transfer Hook付きの送付を行います。
![](https://assets.st-note.com/img/1717363282541-gAn7O9qsJX.png?width=800)
2 コードの確認(参考)
この辺りの処理は、コードを見た方が結局わかりやすいと思うので、見ていきたいと思います。
ポイントは、TransferHook用の何かを渡しているわけではなく、通常必要な情報のみを渡しています。
その上で、「createTransferCheckedInstruction」でInstructionを作成しています。
![](https://assets.st-note.com/img/1717449424064-9D8n7ELbEZ.png?width=800)
その上で、ミント情報から、「Transfer Hook」を取り出しています。
「Transfer Hook」が存在すれば、「addExtraAccountMetasForExecute」で追加していることがわかります。
このように、汎用的な仕組みをとっているのはとても良いと思いました。
![](https://assets.st-note.com/img/1717449620870-VvoiOt03qh.png?width=800)
3 fallback関数の実行
そして、この「createTransferCheckedWithTransferHook」が実行されるタイミングで、「fallback」関数が実行されます。
![](https://assets.st-note.com/img/1717363477378-Xua4fhF4le.png?width=800)
今回は中身まで見ないですが、ここで、「transfer_hook」という関数がよばれ、「Hello Transfer Hook!」が実行されることになります。
![](https://assets.st-note.com/img/1717450457921-xmWBOfusdd.png?width=800)
6 トランザクションを確認しよう
では、流れが理解できたので、トランザクションを確認してみましょう。
実際の送付は最後のみで行われていたので、こちらをSolscanで見てみましょう。
![](https://assets.st-note.com/img/1717450697133-5EBgM1T0PN.png?width=800)
まずは、このように送付が行われたことが確認できました。
![](https://assets.st-note.com/img/1717450769346-GWDch6ZmaP.png?width=800)
そして、こちらの「Program Logs」でメッセージが表示されていることが確認できます。
![](https://assets.st-note.com/img/1717450786354-r2lE9s64B5.png?width=800)
今回は以上です。
サポートをしていただけたらすごく嬉しいです😄 いただけたサポートを励みに、これからもコツコツ頑張っていきます😊