---
title: "プログラム派生アドレス(PDA)とは?"
description: "プログラム派生アドレスとは何か、PDAが通常のアドレスとどう異なるか、PDAのユースケースについて解説"
---

# プログラム派生アドレス(PDA)とは?

Program Derived Addresses（PDA）は、Solanaブロックチェーン上の特殊な属性を持つアカウントです。PDAを正しく使用することで、プログラム間通信を助けるため、[Solana dApp developmentを高速](https://www.alchemy.com/overviews/learn-solana-development)かつ効率的にすることができます。

この記事では、PDAとは何か、どのような問題を解決するのか、どのように機能するのか、そして[Solanaのアカウントモデル](https://www.alchemy.com/overviews/solana-account-model)における他のアカウントとの違いについて説明します。

## **プログラムデリバードアドレス（PDA）とは？**

**Program Derived Addressとは、秘密鍵を持たないSolanaブロックチェーン上のアカウントです**。PDAは公開鍵ではないため、アカウントのアドレスはプログラムID、SHA-512ハッシュ関数、シード配列、そして特殊なbump seedを用いて算出されます。

### **Solanaにおける標準アカウントとは？**

**標準的なSolanaアカウントは秘密鍵と公開鍵（それぞれ32バイト）の両方を持ち、これらが合わさって64バイトのキーペアを構成し、楕円曲線（ED25519）上に存在します**。キーペアが有効であるためには、この曲線上に存在している必要があります。

以下はED25519楕円曲線の表現です：

<ImageBlock
  src="https://media.alchemy.com/1703701173-elliptic-curve-on-solana.png"
  alt="Solanaのアカウントキーペアに使用されるED25519楕円曲線のグラフ"
  width={1600}
  height={900}
  caption="Solanaにおける ED25519 楕円曲線"
/>

## **プログラムアドレスはどのように導出されるのか？**

PDAには主に3つの構成要素が必要です：

1. **Parent Program ID** - PDAを作成する親プログラムのID
1. **Seeds** - 文字列の配列
1. **Bump Seed** - PDAが秘密鍵を持たないことを保証する

**有効なProgram Derived Addressを作成するには、親プログラムのID、シード配列を取得し、それらをSHA-512ハッシュ関数に通す必要があります**。

しかし、約50%のケースでは、このハッシュの結果が_ED25519楕円曲線_上に存在するキーペアになってしまいます。PDAは秘密鍵を持たないため、Program Derived Addressesは**楕円曲線上に存在してはなりません**。PDAが秘密鍵を持つことを防ぐため、特殊な_bump_ seedを使用してハッシュ結果を曲線から「bump」させます。

bump seedは単なる数値で、255から始まります。bump seedを使用してもハッシュ結果が依然として曲線上に存在する場合、ハッシュ関数はbumpを254、253、と減らしながら、生成された結果が曲線上になくなるまで再実行されます。

注：シードには任意の文字列を使用できますが、開発者は親プログラムの状態変数に特化した文脈でシードを使用し、ハッシュマップのような構造を作成します。

## **PDAはどのような問題を解決するのか？**

**Program Derived Addressesはトランザクション署名をプログラム的に生成することでトランザクション確認を効率化し、DeFiアカウントのようなトラストレスなサービスがシームレスに機能することを助けます。**

以下はPDAの仮想的な使用例です。

ユーザーがNFTをデフォルトのプロフィール画像（PFP）として設定できるSolanaプログラムを考えます。このプログラムは2つのプログラムで構成されます：

1. **PFP program** - ユーザーが選択したプロフィール画像を保存するアカウントを作成する
1. **Core program** - ユーザーの入力とPFP programの間のプロキシとして機能する

PFP programがユーザーの選択したプロフィール画像を更新するには、ユーザーのプロフィール画像を変更するトランザクションに署名するために自身の秘密鍵を使用する必要があります。しかし、これはプログラムが秘密鍵をオンチェーンに保存する必要があることも意味します。

Solanaプログラムは自身を代表してトランザクションに署名するために秘密鍵を使用することはできません。なぜなら、その鍵自体がオンチェーンに保存され、誰からも見える状態になってしまうからです。もしこれが起きれば、その秘密鍵はプログラムを代表してトランザクションに署名するために使われ、任意のユーザーのプロフィール画像を変更できてしまいます。

PFP programが数百万のSOLトークンを扱っていたと想像してください。このような悪用は大規模なハッキングとなってしまいます。Program Derived Addressesはこれを解決します。

## **なぜPDAは重要なのか？**

Program Derived Addressesは、異なるプログラム間の通信（Cross Program Invocations）を助け、また親プログラムが簡単に更新・変更できる特定のデータを保存するためのハッシュマップとして機能できるため、Solanaプログラミングにおいて重要な役割を果たします。

### **1. プログラムの状態変数を保存する**

PDAを使うことで、Solana開発者は特定のユーザーに関連する変数または変数の集合を保存・追跡できます。PDAの最適な使用例はその親プログラムの状態変数やデータを保存することです。なぜなら、デフォルトで親プログラムがPDAに代わって変更を行うことを認可されているからです。

### **2. PDAをハッシュマップとして使用する**

マッピングとはキーと値のペアの集合を表し、あるキーに関連付けられた情報を簡単に見つけるために使用されます。Solana開発では、PDAのシードと正しい文字列を使用することで同様の結果を達成できます。

**先ほどのウォレットプロフィール画像の例に戻りましょう。**

ユーザーがウォレットのPFPを選択すると、PFP programは選択された画像とユーザーのアドレスを取り、それらを「シード」として使用し、ユーザーの選択を保存するPDAを作成します。

ハッシュアルゴリズムによってProgram Derived Addressが正常に見つかると、その公開鍵はユーザーのアドレスと選択されたNFTアバターに「マッピング」されます。

このハッシュマップ機能は、別のPDAを第3のシードとして提供することで、さらに活用できます。利用可能なすべてのプロフィール画像を取り、それらを別のPDAに保存し、各プロフィール画像をそのシードとして渡すことで、すべてのプロフィール画像を保存するPDAが得られます。

そして、ユーザーがプロフィール画像を選ぶ際、PDAはハッシュマップのように見えます。なぜならシードが渡されているため、それを見れば、プロフィール画像の選択肢（PFPグループPDA）の中から、第1シードとして渡したユーザーのアドレスが、第2シードとして渡したプロフィール画像を選択したことが分かるからです。

この例は、さらに深いハッシュマップ構造を作るために発展させることができます。

<ImageBlock
  src="https://media.alchemy.com/1703701259-pda-as-hashmap-program-flow.jpeg"
  alt="ハッシュマップとしてのPDAのプログラムフロー - NFTの例"
  width={1024}
  height={768}
  caption="ハッシュマップとしてのPDAのプログラムフロー - NFTの例"
/>

### **3. Cross Program Invocations**

[Cross Program Invocations（CPI）](https://www.alchemy.com/overviews/cross-program-invocation)は、あるプログラムが別のプログラムの関数を呼び出すプロセスです。CPIはコードのコンポーザビリティを向上させるため有用です。

先ほどの例に戻り、ユーザーがプロフィール画像をDegen ApeからSolana Monkey Businessアバターに変更したいとします。

**内部では次のようなことが起きます：**

ユーザーがウォレットにログインすると、core contractはユーザーのアドレス（公開鍵）を取得し、そのユーザーの公開鍵をシードに含む、既に作成済みのPDAを探します。

それを見つけると、core programはPFP programにある'changePFP()'という関数を呼び出します（これがCross-Program Invocationです）。この関数はCore programによって既に「選択」されたPDAを引数として受け取ります。

この関数が呼び出されると、選択されたPDAは、変更を「要求」しているアカウントが自身の親であるかを確認します。PDAが一致しない場合、トランザクションは拒否されます。なぜなら、親プログラムのみがPDAのデータを変更できるからです。

PFP programは選択されたPDAの親であるため、ユーザーのプロフィール画像をDegen ApeからSMBアバターに変更することが許可されます。

<ImageBlock
  src="https://media.alchemy.com/1703701345-cross-program-invocation-with-pda.jpeg"
  alt="PDAを用いたクロスプログラム呼び出し - NFT画像の変更"
  width={1600}
  height={901}
  caption="PDAを用いたクロスプログラム呼び出し - NFT画像の変更"
/>

Program Derived Addressesは、親プログラムが自身を代表して署名することを可能にし、プログラムの状態、ハッシュマップの保存、そしてcross-program invocationsに使用できます。PDAはSolanaプログラミングの領域における基礎的なトピックであり、高速で効率的なdApp developmentを可能にします。

## **Program Derived Address FAQ**

Program Derived Addressesを扱う際には、SolanaがどのようにトランザクションとデータをHandleするかを理解しておくと役立ちます。アカウントの主な2種類はexecutableとnon-executableです。

### **executableアカウントとは？**

executableアカウントは**_programs_**とも呼ばれ、Ethereumのスマートコントラクトに似ています——アカウントがそれと相互作用することで状態を変化させる一片のコードです。

### **non-executableアカウントとは？**

non-executableなデータアカウントは、単にデータ（アカウントが所有するSOLの量、NFT、トークン残高など）を保存するために使用され、本質的にはプログラムの状態変数です。

### **Solanaのプログラムデータストレージは、Ethereumのスマートコントラクトとどう違うのか？**

EthereumとSolanaの間の基礎的な違いの1つは、executableコードのストレージがどのように構成されているかです。Ethereum上のスマートコントラクトは、[スマートコントラクトがすべての状態変数を保存する](https://www.alchemy.com/docs/smart-contract-storage-layout)**storage**を「プリビルド」の状態で備えています。それに対して、Solana上のプログラムはプリビルドされたストレージを持たず、代わりに保存・参照したい様々な状態変数を保持する独立したデータアカウントを持ちます。
