---
title: "Solana Program Libraryとは"
description: "Solana Program Libraryを使ってSolana上で分散型アプリケーションを開発する方法"
---

# Solana Program Libraryとは

Solanaは、開発者が分散型アプリケーションを構築・デプロイできる高速なプログラマブルブロックチェーンです。Solanaは、Solana Program Libraryと呼ばれる専用のドキュメントライブラリを維持しています。これは、Solanaブロックチェーン上で使用するために事前にコンパイル・デプロイ・最適化されたプログラム\(すなわちスマートコントラクト\)のコレクションです。

この記事では、Solanaの世界を探り、Solana Program Libraryを使ってどのように素早く開発できるかを理解していきます。Solanaが初めての方でも経験豊富な開発者でも、SPLを使えば独自のカスタムトークンや分散型取引所を簡単に作成・デプロイできます。

## **Solanaにおけるプログラムとは何か**

**Solanaにおけるプログラムは、アカウントと呼ばれるバッファストレージに格納された実行可能コードであり、トランザクションを介して実行できます。これはEthereumや他のプログラマブルブロックチェーンにおけるスマートコントラクトと似ています。** しかし、プログラムと状態がスマートコントラクト内に一緒に格納されるEthereumとは異なり、Solanaは[ステートレスプログラムモデル](https://www.alchemy.com/overviews/solana-account-model)を採用しており、データとプログラムはアカウントに格納されます。

### **Solanaにおけるアカウントとは何か**

Solanaのドキュメントによると、「アカウントとは、データを保持するか実行可能プログラムであるかのいずれかのSolana台帳上のレコードである」とされています。

Solanaをデータベースだと考えてみてください。[アカウント](https://www.alchemy.com/overviews/solana-data-vs-program-accounts)が行であり、公開鍵がIDとして機能し、値がそのアカウントに格納された情報です。この情報は、プログラム\(すなわちスマートコントラクト\)の形か、プログラムのデータ/状態の形のいずれかになります。

アカウントは一意の公開鍵\(256バイト\)によって識別され、通常は「DM6n1qcUCLzJ1RaAuA4gUbBZ9sfHP6KvEwX8oExQqPhk」のようなものになります。

Solanaはコードとそのデータの間に論理的な分離を持っており、そのため実行可能アカウントと非実行可能アカウントという2種類のアカウントが存在します。

#### **1. 実行可能アカウント**‍

不変のプログラムコードのみを格納し、「実行可能」としてマークされているアカウントです。

#### **2. 非実行可能アカウント**‍

これらのアカウントは、変数、アセット、プログラムの状態を含め、そのプログラムが使用しうるすべてのデータを格納します。誰でもこれらのアカウント内のデータを読み取ることはできますが、プログラムの所有者\(デプロイした人\)のみがそれを変更できます。

これらのアカウントは[バリデータノード](https://www.alchemy.com/overviews/what-is-firedancer)によって維持されており、上記の情報を格納するためのメモリ領域と引き換えに「[レント](https://www.alchemy.com/overviews/how-to-calculate-rent-for-solana-programs)」と呼ばれる維持コストを課しています。レントは**lamports**（SolaのネイティブトークンであるSOLの端数単位）で支払われます。

Solanaのコードとプログラムデータが別々に維持されているのは、**Sealevel Parallel Runtime**というシステムによるものです。

### **Sealevel Parallel Runtimeとは何か**

**Sealevel Parallel RuntimeはSolanaによる並列トランザクション処理システムの実装です。** Ethereumのような従来のシングルスレッド型ブロックチェーンは、並行性を回避するために一度に1つのトランザクションしか処理できません。これは、Ethereumのスマートコントラクトが**ステートフル**であること、つまり状態とコードが同じコントラクト内に結合されていることが原因です。

Sealevelの助けにより、Solanaは競合しない数千のトランザクションを並列に処理できます。複数のバリデータコアを利用することで、Solanaはブロック時間400ミリ秒で最大50,000 Tpsを実行できます。これは、トランザクション命令がステートレスであり、事前にどのアカウントのデータを変更するかを決定しているために可能となっています。したがって、同じアカウントデータを共有しないプログラムは同時に実行できます。

## **Solanaにおけるプログラムの種類とは何か**

Solanaのエコシステムは、ネイティブプログラムとオンチェーンプログラムという2つの異なる種類のプログラムで構成されています。両者を見ていきましょう。

### **ネイティブプログラムとは何か**

**ネイティブプログラムは、アカウントストレージの割り当て管理、新規アカウントの作成、トランザクションの処理、Solanaネットワークのルールの強制など、Solanaネットワークの中核機能を実装する役割を担っています。**

ネイティブプログラムはSolanaのコアブロックチェーンモデルの不可欠な一部です。通常、パフォーマンスとセキュリティに最適化された、RustやC/C\+\+のような低レベル言語で書かれています。ネイティブプログラムはどのプログラム/ユーザーからも呼び出すことができますが、これはオペレーティングシステムのカーネルレベルのプログラムがユーザーから直接呼び出しやアクセスができないのとは対照的です。

これらのプログラムの更新は、機能追加、バグ修正、パフォーマンス改善のためのコアブロックチェーンアップグレードやクラスターアップグレードの一環としてのみ行われます。

バリデータの安全性を確保するのに役立つネイティブプログラムは数多くあります。その一部を紹介します。

#### **1. システムプログラム**

システムプログラムは、新規アカウントの作成、2つのアカウント間のSOLの転送、アカウント所有権の割り当てなど、より多くのアカウント管理操作を担っています。

#### 2. Berkeley Packet Filter \(BPF\)：

Berkeley Packet Filterは、オンチェーンでのプログラムのデプロイ、アップグレード、実行を処理します。

#### **3. ステークプログラム**

ステークプログラムは、Solanaブロックチェーン上でのSOLトークンのステーキング管理を担っています。

### **オンチェーンプログラムとは何か**

**オンチェーンプログラムは、ブロックチェーン上に直接デプロイされるユーザー作成のプログラム\(すなわちスマートコントラクト\)です。** これらは、dapp、取引所、練習用コントラクト、マルチシグウォレットの実装、その他の汎用プログラムなど多岐にわたります。

ネイティブプログラムとは異なり、オンチェーンプログラムはSolanaクラスターの中核を成すものではありません。代わりに、開発者がSolanaブロックチェーン上で作成・デプロイするカスタムプログラムです。つまり、オンチェーンプログラムはSolanaブロックチェーンの運用に不可欠なものではありません。

これらはネイティブプログラムが提供するコアインフラの上に構築されており、開発者がSolanaブロックチェーン上で幅広いアプリケーションやサービスを構築できるようにしています。

プログラムがやり取りするデータは別々のデータアカウントに格納され、命令を通じて参照として渡されます。プログラムデータをアップグレードできるのはアカウント所有者のみです。

<ImageBlock
  src="https://media.alchemy.com/1703692327-programs-in-solana.png"
  alt="別々のデータアカウントに状態を格納するSolanaプログラムの図"
  width={557}
  height={385}
  caption="Solanaにおけるプログラム"
/>

## **Solana Program Libraryとは何か**

Solana Program Library \(SPL\)は、Solanaブロックチェーン上で[分散型アプリケーション](https://www.alchemy.com/dapps/top/defi-dapps)を構築するために使用できる、あらかじめ書かれたモジュール式プログラムのコレクションです。SPLは、再利用可能なモジュール式コンポーネントのセットを提供することで、開発者がアプリを作成しやすくすることを目指しており、開発者がゼロから複雑なコードを書く必要性を減らします。

したがって、SPLは開発者が「**ビルディングブロック**」的なアプローチでアプリを構築できるようにしており、各コンポーネントをアプリケーションに簡単に組み込めます。

SPLには複数の汎用オンチェーンプログラムが含まれており、Tokenプログラムとそのバリエーションが最も広く使われています。これらはゼロから実装することなくプロジェクトに組み込むのに役立ちます。

### **SPLの前提条件**

SPLとやり取りするには、CLIによるアプローチか、Solanaブロックチェーンとやり取りするためのJavaScriptコードに[solana/web3.js](https://www.alchemy.com/dapps/web3-js)を組み込む、よく使われるJSアプローチのいずれかを選べます。

どのSolanaクラスターとやり取りする場合でも、[Solana CLI（コマンドラインインターフェース）をセットアップする](https://www.alchemy.com/docs/reference/solana-api-quickstart)必要があります。CLIは初心者の開発者にとって最も扱いやすいものではないかもしれませんが、Solanaアカウントへの最も直接的で安全なアクセスを提供します。さらに、CLIはSolanaのコア開発者が新機能を最初にデプロイする場所でもあります。

## **SPL Tokenプログラムとは何か**

**SPL TokenプログラムはSolanaブロックチェーン上のファンジブルトークンおよびノンファンジブルトークンの汎用実装です。** これは、開発者が独自のトークンを作成できるようにするインターフェースと詳細な実装を提供します。コードはネイティブにRustで書かれており、その自動生成バインディングはCおよびJavaScriptで利用可能です。ソースコードは[SPL GitHubリポジトリ](https://github.com/solana-labs/solana-program-library/tree/master/token/program)で公開されています。

Ethereumでは、[ERC20](https://www.alchemy.com/overviews/erc20-solidity)トークンプログラムはEthereumのERC-20コントラクトとは異なる形で動作します。違いを理解するために例を見てみましょう。

Ethereumブロックチェーン上で3つの異なるトークンを公開したいとします。そのためには、各トークンごとに3つの別々のコントラクトをデプロイする必要があります。そして、各トークンコントラクトはそれぞれの状態（例：残高や転送）を個別に管理します。

一方、Solanaでは、3つの別々のトークンプログラムをデプロイする必要はありません。代わりに、多数のアカウント（例：ミントアカウントと受け取りアカウント）に対して動作できる1つの汎用トークンプログラムをデプロイできます。

ミントアドレスがトークンの種類を一意に識別します。この情報は、Solanaチェーン上に既にデプロイされている単一の静的ERC20プログラムインスタンスに引数として渡すことができます。

## **SPL Tokenプログラムを使ってファンジブルトークンを作成する方法**

SPL Tokenプログラムを使えば、数ステップで自分のファンジブルトークンを作成できます。Tokenプログラムに取り掛かる前に、CLIウォレットのセットアップ、または[PhantomウォレットをSolanaのDevnetに接続](https://www.alchemy.com/docs/add-alchemy-rpc-to-any-project)し、[十分なDevnet SOLをウォレットにエアドロップ](https://www.alchemy.com/overviews/solana-devnet)しておいてください。

### ステップ1：ファンジブルトークンを作成する

create tokenコマンドは、オンチェーンのSPL Tokenプログラムに対して新しいTokenを作成するよう指示するものです。トークンの作成に成功すると、トランザクション署名とともにToken IDを受け取ります。ただし、まだこれらをミントする必要があります。

**これがトークンコマンドです**：`spl-token create-token`

<ImageBlock
  src="https://media.alchemy.com/1703692444-running-spl-token-create-token-command.png"
  alt="spl-token create-tokenコマンドを実行した結果"
  width={1058}
  height={159}
  caption="spl-token create-tokenコマンドを実行した結果"
/>

### **ステップ2：トークンアカウントを作成する**

トークンに関連する情報を別のデータアカウントに格納します。[トークンアカウント](https://www.alchemy.com/overviews/associated-token-account)はSPL-Tokenプログラムによって所有されており、これらのトークンへのアクセスを、トークンを使用/転送できるowner欄（これが私たちのToken-IDです）とともに制御します。

これはデータアカウントであるため、そのデータはTokenプログラムによる追加/ミント、転送、バーンによって変更されます。

**これがトークンアカウント作成コマンドです**：`spl-token create-account`

以下に示すように、トークンとその関連アカウントを作成することで、トランザクション手数料としてわずかなSOLが減っています。また、初期供給量がゼロであることにも注意してください。つまり、トークンをミントすることで望ましい供給量を追加する必要があります。

<ImageBlock
  src="https://media.alchemy.com/1703692522-solana-token-balance.png"
  alt="spl-token create-accountコマンドを実行した後の残高"
  width={892}
  height={225}
  caption="spl-token create-accountコマンドを実行した後の残高"
/>

### **ステップ3：望ましい数量のトークンをミントする**

指定した数のトークンをミントするには、以下のコマンドを実行します。

コマンドが実行されると、指定した数のトークンがファイルシステムウォレットにミントされ、トークン供給量が更新されます。

<ImageBlock
  src="https://media.alchemy.com/1703692591-results-after-minting-tokens.png"
  alt="2,000 SPLトークンをミントした後のターミナル出力。更新された供給量が表示されている"
  width={841}
  height={80}
  caption="2,000トークンをミントした結果"
/>

現在のトークン供給量と、そのトークンに関連するアカウントは、以下のコマンドを実行することで確認できます。

<ImageBlock
  src="https://media.alchemy.com/1703692668-checking-spl-token-supply.png"
  alt="spl-tokenの供給量とアカウント残高を確認した結果"
  width={808}
  height={162}
  caption="spl-tokenの供給量とアカウント残高を確認した結果"
/>

それでは、トークンをSolanaで人気のあるウォレットである[Phantomウォレット](https://www.alchemy.com/dapps/phantom)に転送してみましょう。

### ステップ4：トークンを転送する

計画としては、受取人（私たちのPhantomウォレット）に「x」量のトークンを転送します。「fund recipient」は、受取人のトークンアカウントが存在しない場合にそれを作成する役割を担っています。これは[Associated Token Account](https://www.alchemy.com/overviews/associated-token-account)の作成と呼ばれます。

**トークンを転送するコマンドはこちらです：**

<ImageBlock
  src="https://media.alchemy.com/1703692742-token-transfer-results.png"
  alt="Phantomウォレットへトークンを送信するspl-token transferコマンドのターミナル出力"
  width={1345}
  height={197}
  caption="トークン転送の結果"
/>

転送が成功すると、成功メッセージを受け取ります。

<ImageBlock
  src="https://media.alchemy.com/1703692827-phantom-wallet-transfer-confirmation.png"
  alt="Phantomウォレットの転送成功メッセージ"
  width={358}
  height={533}
  caption="Phantomウォレットの転送成功メッセージ"
/>

転送を確認するには、次のコマンドを実行します：`*spl-token accounts`

注：token supplyコマンドを実行しても、供給量はネットワーク上で流通しているトークンの数を示す一方、残高はトークンアカウントが保有するトークンの数を指すため、依然として2,000トークンと表示されます。

<ImageBlock
  src="https://media.alchemy.com/1703693162-token-balance-vs-token-supply.png"
  alt="SPLトークンアカウントの残高とトークンの総供給量を比較したターミナル出力"
  width={812}
  height={163}
  caption="トークン残高 対 トークン供給量"
/>

### **ステップ5：トークン供給量を制限する**

コントラクトのセキュリティと需要にとって重要な側面の1つは、トークン供給量を制限することです。ミント機能を無効化するには、mint authorityを「None」に設定します。

トークンのmint authorityを無効化するコマンド：`*spl-token authorize mint --disable`

<ImageBlock
  src="https://media.alchemy.com/1703693237-minting-extra-tokens.png"
  alt="ミントを無効化する前に追加で3000トークンをミントする"
  width={899}
  height={201}
  caption="ミントを無効化する前に追加で3000トークンをミントする"
/>

<ImageBlock
  src="https://media.alchemy.com/1703693326-mint-authority-disabled.png"
  alt="SPL Tokenのmint authorityを無効化した後のターミナル出力"
  width={977}
  height={155}
  caption="‍Mint authority無効化の結果"
/>

### **ステップ6：トークンをバーンする**

トークンの供給量を減らしたい場合は、バーンすることを選択できます。

そのためのコマンドはこちらです：`spl-token burn`

<ImageBlock
  src="https://media.alchemy.com/1703693386-burning-spl-tokens.png"
  alt="spl-token burnコマンドを実行したターミナル出力"
  width={904}
  height={122}
  caption="SPLトークンのバーン"
/>

バーンすると、供給量と残高の両方が減少します。この例で見ることができるように、残高は4,978から3,978に減少し、供給量は4,000に減少しました。

<ImageBlock
  src="https://media.alchemy.com/1703693454-spl-token-burn-results.png"
  alt="SPLトークンをバーンした後の残高と供給量の減少を示すターミナル出力"
  width={817}
  height={184}
  caption="SPL Tokenバーンの結果"
/>

SPLは、以下のようなより多くの操作をTokenプログラムを使って実行する方法についての完全なリファレンスガイドを提供しています：

- SOLをトークンでラップする。
- 明示的な受取人トークンアカウントへトークンを転送する。
- ノンファンジブルトークンを作成する。

## **SPLでSolana開発の旅を始めよう**

Solana Program Libraryは、簡単にやり取りできる事前公開済みのオンチェーンプログラムを数多く備えています。SPLを使えば、開発者は基本的な定型トークン作成コードに時間を費やすのではなく、アプリの独自の機能や特徴に集中できます。

初心者で、Solana開発の旅を始めたいなら、最初のステップはSPLと[AlchemyのSolana API](https://www.alchemy.com/docs/reference/solana-api-quickstart)、そして[無料のSolana RPCノードアカウント](https://dashboard.alchemy.com/signup/?a=solana-program-library)を探索することです。これらは、あなたのプログラムをすぐに動かす助けになります。
