メインコンテンツへスキップ

クイックアクセス

他の実装における基本的なカウンター例はこちらです。

GitHub

Native Rust 実装

GitHub

Pinocchio 実装

Guide

ローカル開発


ステップバイステップガイド

プログラムを構築し、MagicBlock の Delegation Program DELeGGvXpWV2fqJUhqcF5ZSYMS4JTLjteaAMARRSaeSh を使って delegation hooks を追加しアップグレードします。
1

プログラムを書き、delegation instructions を追加する

いつも通りに Solana プログラムを書きます。
2

Base Layer で PDA を Delegate する

CPI hooks を追加し、状態アカウントを Ephemeral Rollup セッション経由で delegate、commit、undelegate できるようにします。

これらの公開バリデータは開発用として利用できます。委任命令には、 対象となる ER バリデータを必ず追加してください。

メインネット
  • アジア (as.magicblock.app): MAS1Dt9qreoRMQ14YQuhg8UTZMMzDdKhmkZMECCzk57
  • EU (eu.magicblock.app): MEUGGrYPxKk17hCr7wpT6s8dtNokZj5U2L57vjYMS8e
  • 米国 (us.magicblock.app): MUS3hc9TCw4cGC12vHNoYcCGzJG1txjgQLZWVoeNHNd
  • TEE (mainnet-tee.magicblock.app): MTEWGuqxUpYZGFJQcp8tLN7x5v9BSeoFHYWQQ3n3xzo
Devnet
  • アジア (devnet-as.magicblock.app): MAS1Dt9qreoRMQ14YQuhg8UTZMMzDdKhmkZMECCzk57
  • EU (devnet-eu.magicblock.app): MEUGGrYPxKk17hCr7wpT6s8dtNokZj5U2L57vjYMS8e
  • 米国 (devnet-us.magicblock.app): MUS3hc9TCw4cGC12vHNoYcCGzJG1txjgQLZWVoeNHNd
  • TEE (devnet-tee.magicblock.app): FnE6VJT5QNZdedZPnCoLsARgBwoE6DeJNjBs2H1gySXA
ローカルネット
  • ローカル ER (localhost:7799): mAGicPQYBMvcYveUZA5F5UNNwyHvfYh5xkLS2Fr1mev
3

ER で PDA を Commit する

Solana CLI を使ってプログラムを Solana に直接デプロイします。
4

ER で PDA を Undelegate する

SVM RPC 仕様に準拠したトランザクションを、変更なしでオンチェーン・オフチェーンの両方から送信します。

Counter 例

以下のソフトウェアパッケージが必要になる場合があります。ほかのバージョンでも互換性がある可能性があります。
ソフトウェアバージョンインストールガイド
Solana2.3.13Solana をインストール
Rust1.85.0Rust をインストール
Node24.10.0Node をインストール

コードスニペット

このプログラムは 2 つの主要 instruction を実装しています。
  1. InitializeCounter: カウンターを初期化し 0 に設定(Base Layer で呼ばれる)
  2. IncreaseCounter: 初期化済みカウンターを X 増やす(Base Layer または ER で呼ばれる)
このプログラムは、カウンターの delegation と undelegation 用の専用 instruction も実装しています。
  1. Delegate: カウンターを Base Layer から ER に委任する(Base Layer で呼ばれる)
  2. CommitAndUndelegate: カウンターを ER から Base Layer に同期するようスケジュールし、ER 上で undelegate する(ER で呼ばれる)
  3. Commit: カウンターを ER から Base Layer に同期するようスケジュールする(ER で呼ばれる)
  4. Undelegate: Base Layer 上でカウンターを undelegate する(validator CPI を通じて Base Layer で呼ばれる)
The undelegation callback discriminator [196, 28, 41, 206, 48, 37, 51, 167] and its instruction processor must be specified in your program. This instruction triggered by Delegation Program reverts account ownership on the Base Layer after calling undelegation on ER.With [#ephemeral] Anchor macro from MagicBlock’s Ephemeral Rollup SDK, the undelegation callback discriminator and processor are injected into your program.
以下がプログラムの基本構造です。
pub enum ProgramInstruction {
    InitializeCounter,
    IncreaseCounter {
        increase_by: u64
    },
    Delegate,
    CommitAndUndelegate,
    Commit,
    Undelegate {
        pda_seeds: Vec<Vec<u8>>
    }
}

#[derive(BorshDeserialize)]
struct IncreaseCounterPayload {
    increase_by: u64,
}

impl ProgramInstruction {
    pub fn unpack(input: &[u8]) -> Result<Self, ProgramError> {
        // Ensure the input has at least 8 bytes for the variant
        if input.len() < 8 {
            return Err(ProgramError::InvalidInstructionData);
        }

        // Extract the first 8 bytes as variant
        let (variant_bytes, rest) = input.split_at(8);
        let mut variant = [0u8; 8];
        variant.copy_from_slice(variant_bytes);

        Ok(match variant {
            [0, 0, 0, 0, 0, 0, 0, 0] => Self::InitializeCounter,
            [1, 0, 0, 0, 0, 0, 0, 0] => {
                let payload = IncreaseCounterPayload::try_from_slice(rest)?;
                Self::IncreaseCounter {
                    increase_by: payload.increase_by,
                }
            },
            [2, 0, 0, 0, 0, 0, 0, 0] => Self::Delegate,
            [3, 0, 0, 0, 0, 0, 0, 0] => Self::CommitAndUndelegate,
            [4, 0, 0, 0, 0, 0, 0, 0] => Self::Commit,
            [196, 28, 41, 206, 48, 37, 51, 167] => {
                let pda_seeds: Vec<Vec<u8>> = Vec::<Vec<u8>>::try_from_slice(rest)?;
                Self::Undelegate {
                    pda_seeds
                }
            }
            _ => return Err(ProgramError::InvalidInstructionData),
        })
    }
}
“Undelegate” instruction には正確な discriminator が必要です。これは あなた自身が呼ぶものではなく、ER 上でアカウントが undelegate された後に、 Base Layer 上の validator が CPI コールバックとしてあなたのプログラムへ入ります。
⬆️ Back to Top

高度なコードスニペット

委任済み PDA をリサイズする際には:
  • 新しいアカウントサイズでも rent-exempt を保てるだけの lamports が PDA に必要です。
  • 追加 lamports が必要な場合、差額を提供するために payer account も委任済みである必要があります
  • PDA はプログラム所有である必要があり、lamports 転送に必要な signer をトランザクションに含める必要があります。
  • system_instruction::allocate を使用します。
#[derive(BorshSerialize, BorshDeserialize, Debug)]
pub struct Counter {
    pub count: u64,
}

// Resize counter account
pub fn resize_counter_account(
    counter_acc: &AccountInfo,
    payer: &AccountInfo,
    program_id: &Pubkey,
    new_size: usize,
    bump: u8,
) -> ProgramResult {
    let rent = Rent::get()?;
    let lamports_required = rent.minimum_balance(new_size);

    let current_lamports = counter_acc.lamports();
    if lamports_required > current_lamports {
        let lamports_to_add = lamports_required - current_lamports;
        invoke_signed(
            &system_instruction::transfer(
                &payer.key,
                &counter_acc.key,
                lamports_to_add,
            ),
            &[payer.clone(), counter_acc.clone()],
            &[&[COUNTER_SEED, &[bump]]],
        )?;
    }

    // Allocate new size
    invoke_signed(
        &system_instruction::allocate(&counter_acc.key, new_size as u64),
        &[counter_acc.clone()],
        &[&[COUNTER_SEED, &[bump]]],
    )?;

    // Assign back to program
    invoke_signed(
        &system_instruction::assign(&counter_acc.key, program_id),
        &[counter_acc.clone()],
        &[&[COUNTER_SEED, &[bump]]],
    )?;

    msg!("Counter account resized to {} bytes", new_size);
    Ok(())
}
⬆️ Back to Top

Solana エクスプローラー

Solana 上のトランザクションとアカウントの情報を確認できます。

Solana エクスプローラー

公式 Solana エクスプローラー

Solscan

Solana ブロックチェーンを探索する

Solana RPC プロバイダー

既存の RPC プロバイダーを通じてトランザクションやリクエストを送信します。

Solana

Free Public Nodes

Helius

Free Shared Nodes

Triton

Dedicated High-Performance Nodes

Solana バリデータダッシュボード

Solana バリデータインフラのリアルタイム更新を確認できます。

Solana Beach

Get Validator Insights

Validators App

Discover Validator Metrics

サーバーステータス

Solana と MagicBlock のサーバーステータスを確認しましょう。

Solana Status

Subscribe to Solana Server Updates

MagicBlock Status

Subscribe to MagicBlock Server Status