
SolanaのdAppを構築して使ってみよう
こんにちは。SHIFTアプリケーション開発テクノロジーGの上田です。
ブロックチェーン技術を使った分散型アプリケーション(dApp)を実際に使ってみようと思います。
今回は高速かつ手数料が安価なSolana(ソラナ)基盤上で構築します。

分散型アプリケーション(dApp)とは?
1. 中央集権型アプリケーションとの違い
通常のアプリケーション(例えば、FacebookやXなど)は、中央集権型のサーバーに依存しています。これらのサーバーは特定の企業や組織によって管理され、データの保存や処理が行われます。このため、データの改ざんや不正アクセスのリスクが存在します。
2. dAppの特徴
一方、dAppはブロックチェーン技術を利用して動作します。ブロックチェーンは分散型のデータベースであり、複数のノード(コンピュータ)がネットワークに参加してデータを共有・管理します。これにより、以下のような特徴があります:
透明性:すべてのトランザクション(取引や操作)がブロックチェーン上に記録され、誰でも確認できるため、不正が難しくなります。
耐改ざん性:一度記録されたデータは変更が難しいため、データの信頼性が高まります。
分散性:中央の管理者が存在せず、ネットワーク全体でデータを管理するため、システムの耐障害性が向上します。
3. Solanaの利点
Solanaは高速かつ手数料が安価なブロックチェーンプラットフォームです。以下のような利点があります:
高速なトランザクション処理:Solanaは1秒間に約4,000トランザクションを処理できるため、リアルタイム性が求められるアプリケーションに適しています。
低コスト:トランザクション手数料が非常に低く、2025年1月13日時点で平均$0.0025です。これにより、ユーザーにとって経済的な負担が少なくなります。
dAppはブロックチェーン技術を活用することで、透明性、耐改ざん性、分散性を実現したアプリケーションです。特にSolanaを利用することで、高速かつ低コストなシステムを構築することができます。これにより、信頼性の高い、ユーザーに優しいアプリケーションを提供することが可能になります。
dAppの構成要素
スマートコントラクト
dAppのバックエンドロジックを担う部分で、ブロックチェーン上でデータを処理するロジックを提供します。
例:NFTの作成・購入・販売のロジック
SolanaのスマートコントラクトはRustという言語を使って開発され、ブロックチェーン上にデプロイします。
基本的にはAnchorというフレームワークを使います。
フロントエンド
React.jsやNext.jsを利用して構築することが一般的です。
Solanaのブロックチェーンと通信するために@solana/web3.jsライブラリを利用します。
ウォレット接続
ユーザーの認証や資産の管理を行うためにウォレットを利用します。ウォレットにもいくつか種類がありますが、それらとの接続をするライブラリ@solana/wallet-adapter-reactを利用します。
環境構築
次のページを参考に環境構築を行ってください。
https://solana.com/ja/docs/intro/installation
Install Dependenciesの部分のみ対応してください。
インストールされるもの
Rust (1.84.0)
Solanaプログラムを作成するためのプログラミング言語。
Solana CLI (2.0.22)
Solanaプログラムのビルドやデプロイを含むすべてのツールを含む。
Anchor CLI (0.30.1)
Solanaプログラムを開発するためのフレームワーク。Rustが使われています。
Node.js (v23.6.0)
AnchorのテストファイルやSolanaプログラムのフロントエンドの開発に利用。
Solana dAppのテンプレートの作成にも利用されます。
Yarn (1.22.22)
環境構築の確認
以下のコマンドを実行して問題がなければ準備完了です。
Rust
rustc --version
出力結果(2025/01/14時点)
rustc 1.84.0 (9fc6b4312 2025-01-07)
Solana CLI
solana --version
出力結果(2025/01/14時点)
solana-cli 2.0.22 (src:faea52f3; feat:607245837, client:Agave)
Anchor CLI
anchor --version
出力結果(2025/01/14時点)
anchor-cli 0.30.1
Node.js
node --version
出力結果(2025/01/14時点)
v23.6.0
Yarn
yarn --version
出力結果(2025/01/14時点)
1.22.22
ウォレットアプリ(Phantom)のインストール
Phantomは、Solana、Ethereum、Polygonなどの複数のブロックチェーンに対応した暗号通貨ウォレットアプリです。ユーザーはこのアプリを使って、暗号通貨の保管、送受信、交換、ステーキング、NFTの管理などを行うことができます。
dAppでトランザクションへの署名などが必要になりますが、Phantomで署名していくことになります。 Chromeの拡張機能として提供されているので拡張機能を追加してください。
ウォレットアプリにウォレットを登録
Phantomを使ってウォレットを作成することもできますが、せっかくなのでインストールしたSolana CLIで作成したウォレットを登録してみましょう。
Solana CLIでウォレットを作成
solana-keygen new
Generating a new keypair
For added security, enter a BIP39 passphrase
NOTE! This passphrase improves security of the recovery seed phrase NOT the
keypair file itself, which is stored as insecure plain text
BIP39 Passphrase (empty for none):
Enter same passphrase again:
Wrote new keypair to /home/[user]/.config/solana/id.json
================================================================================
pubkey: 33jsb9H4Ter5E1CHJ6ojvZ4qYhsqo5iRLUpZNgUAf4yg
================================================================================
Save this seed phrase and your BIP39 passphrase to recover your new keypair:
awake husband forget begin unit feature involve decline foster layer roof laptop
================================================================================
ここで作成されたpubkeyがウォレットのアドレスになります。
/home/[user]/.config/solana/id.jsonは秘密鍵で非常に重要です。 この内容は誰にも教えないようにしてください。
Phantomに登録
上記で作成したウォレットをPhantomに登録しましょう。
拡張機能のPhantomを起動
左上のアイコンからウォレット追加/接続ボタンを押下
「秘密鍵のインポート」を選択
「秘密鍵」に /home/[user]/.config/solana/id.jsonの内容を貼り付ける

SOLを入金(実際にお金はかかりません)
dAppのトランザクション処理の手数料として少額の手数料が発生します。(0.3 ~ 0.8円)
これらはウォレットに入金されているSOLをもとに支払われます。
今回はdevnetという開発のステージング環境のような場所で利用するのでSOLを無料で手に入れることができます。
エアドロップのリクエスト
エアドロップはdevnetクラスターへの接続の場合のみ可能です。
solana config set --url devnet
solana airdrop 2
出力結果
Requesting airdrop of 2 SOL
Signature: 2uy4vvPe1kWioep1NjuPJvpM9yqYoqyfR82xu3hnGr8JEpQu8hwdPiHDsgmvrZV5SeGcUuBKFiDnjUmCE7ump5XS
2 SOL
残高の確認
ウォレットの残高を確認するために以下のコマンドを利用します。
solana balance
出力結果
2 SOL
Phantomで残高を確認
Phantomでも残高を確認できます。 ただし、デフォルトでmainnet-betaというメインのネットワークに接続されているため反映されていないはずです。
以下の方法でdevnetに接続します。
ウォレットを選択し設定を開く
デベロッパー設定を選択
testnetモードをONにする
Solana Devnetになっていることを確認

これで環境構築は完了です!
dAppを使ってみよう
今回使うのはテンプレートとして作成されている数値の増減可能なカウンターアプリです。
以下の図で言うとdAppの四角の中に相当します。

テンプレート作成
npx create-solana-dapp
実行すると聞かれる情報は以下を入力してください。
┌ create-solana-dapp 4.1.2
│
◇ Enter project name
│ sample
│
◇ Select a framework
│ Next.js
│
◇ Select a template
│ next-tailwind-counter
これでフロントエンドについても作成されたので画面がどうなっているか見てみましょう。
cd sample
npm install
npm run dev

ウォレット接続
dAppはウォレット接続からすべてが始まります。
画面左上のSelect Walletを選択してください。
これによって通常のアプリで言うログインができた状態になります。
この状態でスマートコントラクトに対して接続したウォレットアドレスを使って通信し実行することができます。

スマートコントラクトの実行
見えにくいですが、headerのSample Program(http://localhost:3000/sample )を押下してください。
するといくつかのカウンターが作成されています。

では一つ数字を増やしてみましょう。
カウンターを一つ選んでincrementを押下
Phantomで署名を求められるので確認

どこにデータが保存されている?
これらのカウントのデータはどのように保持されているか見てみましょう。
このデータの内容はSolana CLIで確認することができます。
それぞれのカウンターは以下のようにアカウント(アドレス)があり、データもこれに紐づきます。

Solana CLIで配下のコマンドでアドレスに紐づいたデータを見ることができます。
アカウントに紐づいたデータを取得
solana account [アドレス] --url https://api.devnet.solana.com
この二つのアドレスに紐づくデータを見てみます。
①カウントを1つ増やしたアドレス (BkHkee1Vo2BysZKHW1SLHPovamaBdxHB3Bf9PmcG9ZXU)
Public Key: BkHkee1Vo2BysZKHW1SLHPovamaBdxHB3Bf9PmcG9ZXU
Balance: 0.00095352 SOL
Owner: coUnmi3oBUtwtd9fjeAvSsJssXh5A5xyPbhpewyzRVF
Executable: false
Rent Epoch: 18446744073709551615
Length: 9 (0x9) bytes
0000: ff b0 04 f5 bc fd 7c 19 01 ......|..
0000: ff b0 04 f5 bc fd 7c 19 01がデータの部分になります。
②カウントが0のアドレス (99xzJKJL29QsmRWBGJne98KqJxjxgFAiqneqN38vSNw3)
Public Key: 99xzJKJL29QsmRWBGJne98KqJxjxgFAiqneqN38vSNw3
Balance: 0.00095352 SOL
Owner: coUnmi3oBUtwtd9fjeAvSsJssXh5A5xyPbhpewyzRVF
Executable: false
Rent Epoch: 18446744073709551615
Length: 9 (0x9) bytes
0000: ff b0 04 f5 bc fd 7c 19 00 ......|..
0000: ff b0 04 f5 bc fd 7c 19 00がデータの部分になります。
データ部分の比較

テンプレートのスマートコントラクトの実装を見てみるとSampleという構造体を定義し、その中にcountというフィールドを持たせています。countはu8型(1バイトの符号なし整数)として定義されています。
#[account]
#[derive(InitSpace)]
pub struct Sample {
count: u8,
}
Solanaのアカウントデータの最初の8バイトは識別子として使用されているため、このデータ部分の最後の部分がカウントの数値にあたります。
データの保存先
このアドレスとそのデータはSolanaのバリデーター(1,400台程度のコンピュータ)が保持して管理されています。
それぞれのバリデーターがデータの正しさのコンセンサスととることでデータが正しいものであることを保証します。
まとめ
ここまででテンプレートのdAppを使ってみてSolanaでどのようにデータが扱われているかを見ることができました。 今回はすでにあるものを使っただけですが、次はスマートコントラクトを作成してより複雑なことを試してみたいと思います。
皆さんもこの方法でどのようなサービスが作れるか考えてみてください!
執筆者プロフィール:上田
SHIFT アプリケーション開発テクノロジーグループ所属の開発エンジニアです。
モノづくりが大好きで子供を寝かしつけた後はひたすら何かを作って楽しんでいます。
✅SHIFTへのお問合せはお気軽に
SHIFTについて(コーポレートサイト)
SHIFTのサービスについて(サービスサイト)
SHIFTの導入事例
お役立ち資料はこちら
SHIFTの採用情報はこちら
PHOTO:UnsplashのShubham Dhage