SolanaプログラムとWebアプリケーションを接続しよう!
✅ Devnet でテストを実行する
Anchorの設定がDevnetになっているため、Devnet上で直接テストを実行できます。
実際に、関数がDevnet上で正しく機能していることを確認することもできます。
まずは、以下のコマンドを実行しましょう。
anchor test
問題なく実行されると、以下のように表示されます。
※ 資 金不足のエラーが表示された場合はsolana airdrop 2コマンドを実行してDevnetのSOLを取得します。
Deploy success
🚀 Starting test...
📝 Your transaction signature 5GL5bjhMDbUqmnVeA4pV7CoNfQWKG9FCLcYjeN7wTUu6DHhrERVi1CSMUUu16aGUs8YjCfj1MbP6H9p1EsTvGgRp
👀 GIF Count 0
👀 GIF Count 1
👀 GIF List [
{
gifLink: 'insert_a_gif_link_here',
userAddress: PublicKey {
_bn: <BN: f7b50263adfa281e3460f455e8c5fa3527b84a3b9d2bcc0fedaf69cc7786cbc>
}
}
]
Solana Explorerにアクセスしてトランザクション履歴を確認してみましょう。
上記で実行したテストのトランザクションが確認できるはずです。
ここで、とても大切なことをお伝えします。
anchor testコマンドを実行すると、プログラムが再デプロイされ、スクリプト上の全ての関数が実行されます。
実は、Solanaプログラムはアップグレード可能です。
つまり、再デプロイすると、同じプログラムIDを更新して、デプロイしたプログラムの最新版を指すようになるということです。
また、プログラムがやりとりするアカウントは変わらずに残り、プログラムに関連するデータを保持してくれます。
簡単にまとめると、保存されたデータを分離した状態でプログラムをアップグレードすることができます。
これは、一度デプロイされたスマートコントラクトの変更ができないEthereumとはまったく異なるものです。
🤟 IDL ファイルを Web アプリケーションに接続する
Solana プログラムはDevnetにデプロイされました。
それでは続いて、SolanaプログラムとWebアプリケーションを接続してみましょう。
まず必要なのが、anchor buildコマンドで生成されたidlファイルです。
target/idl/myepicproject.jsonがそのファイルとなっています。
idlファイルは単なるJSONファイルで、関数の名前や受け取るパラメータなど、Solanaプログラムに関する情報を持っています。
このファイルは、デプロイされたプログラムと、Webアプリケーションがやり取りするのに役立ちます。
また、target/idl/myepicproject.jsonを確認すると、一番下にプログラムIDが指定されているのが分かると思います。
これは、Webアプリケーションが接続するプログラムを指定するものです。
target/idl/myepicproject.jsonの中身をすべてコピーし、Webアプリケーションを構築したディレクトリの下にあるsrcの直下にidl.jsonファイルを作成してください( App.jsと同じディレクトリです)。
そこにtarget/idl/myepicproject.jsonの中身をすべて張り付けてください。
そして、App.jsで読み込めるように、以下のとおりimport文を追加してください。
追加する場所はimport './App.css';のすぐ下でOKです。
import idl from "./idl.json";
👻 Phantom Wallet に資金を供給する
Solanaでは、アカウントのデータ読み込みは無料でできますが、アカウントを作成したりデータを追加したりするにはSOLが必要になります。
そのため、今回作成したWebアプリケーションで使用できるDevnet上のSOLをPhantom Walletに供給する必要があります。
このとき、Phantom Walletのアドレスが必要になるので、以下の画像を参考にウォレットアドレスをコピーしましょう。

次に、ターミナルから以下のコマンドを実行します。
※ INSERT_YOUR_PHANTOM_PUBLIC_ADDRESS_HEREに先ほどコピーしたPhantom Walletのアドレスを入れて実行してください。
solana airdrop 2 INSERT_YOUR_PHANTOM_PUBLIC_ADDRESS_HERE --url devnet
Phantom Walletを確認し、Devnetで2 SOLが入っていることを確認できれば完了です。
🍔 Web アプリケーションで Solana プロバイダをセットアップする
Solanaプロバイダーを設定するにあたり、Webアプリケーションに2つのパッケージをインストールする必要があります。
Anchorプロジェクトでもインストールしていますが、同じものをWebアプリケーションにもインストールしましょう。
ルートディレクトリで以下のコマンドを実行します。
npm install @coral-xyz/anchor @solana/web3.js@1
インストールしたパッケージをWebアプリケーションにインポートしましょう。
App.jsのimport idl from './idl.json';のすぐ下に以下のコードを追加します。
import { Connection, PublicKey, clusterApiUrl } from "@solana/web3.js";
import { Program, Provider, web3 } from "@coral-xyz/anchor";
続いて、getProvider関数を作成しましょう。
以下のコードをonInputChange関数のすぐ下に追加します。
const getProvider = () => {
const connection = new Connection(network, opts.preflightCommitment);
const provider = new Provider(
connection,
window.solana,
opts.preflightCommitment
);
return provider;
};
ここでは、Solanaへの認証された接続である「プロバイダ」を作成しています。
プロバイダの作成にはWebアプリケーションに接続されたウォレットが必要です。
ここまでできたら、npm run startコマンドを実行して、ブラウザ上で動作を確認してみてください。
[Connect to Wallet]ボタンをクリックすると、Webアプリケーションに対し、ウォレットへのアクセスを許可することができます。
Phantom WalletはSolana上のプログラムと通信するためのプロバイダを作ることができるのです。
ウォレットが接続されていないと、Solana と通信することができません。
さて、それでは、まだ定義されていない変数を作成しましょう。
App.jsを以下のとおり更新します。
import React, { useEffect, useState } from "react";
import twitterLogo from "./assets/twitter-logo.svg";
import "./App.css";
import { Connection, PublicKey, clusterApiUrl } from "@solana/web3.js";
import { Program, Provider, web3 } from "@coral-xyz/anchor";
import idl from "./idl.json";
// SystemProgramはSolanaランタイムへの参照です。
const { SystemProgram, Keypair } = web3;
// GIFデータを保持するアカウントのキーペアを作成します。
let baseAccount = Keypair.generate();
// IDLファイルからプログラムIDを取得します。
const programID = new PublicKey(idl.metadata.address);
// ネットワークをDevnetに設定します。
const network = clusterApiUrl("devnet");
// トランザクションが完了したときに通知方法を制御します。
const opts = {
preflightCommitment: "processed",
};
// その他の部分は変更しないでください。
SystemProgramは、Solanaを実行するコアプログラムへの参照です。
Keypair.generate()は、プログラムのGIFデータを保持するBaseAccountアカウントを作成するために必要なパラメータを提供します。
idl.metadata.addressでプログラムIDを取得し、clusterApiUrl('Devnet')を実行してDevnetへの接続を確認しています。
preflightCommitment: "processed"では、トランザクションが成功したときの確認を受け取るタイミングを選択しています。
今回は、接続しているノードに寄ってトランザクションが確認されるのを待ちます。
他の方法についてはこちらを参照してみてください。