本文へスキップ
BecomeCoder

Solanaコース · 第3章 Solanaのアカウントモデル · レッスン11

所有者(owner) ― 誰がデータを書き換えられるか

ローカル実施

導入

自分のアカウントなのに、自分の意思だけでは中身のデータを直接書き換えられない ―― Solana のアカウントには、そんな一風変わったルールがあります。それを決めているのが owner(所有者) というフィールドです。

説明

すべてのアカウントには、owner という別のアカウント(多くの場合はプログラム)が紐づいています。Solana のルールでは、あるアカウントの data フィールド(中身のデータ)や lamports(残高)を書き換えられるのは、そのアカウントの owner に指定されたプログラムだけ です。

flowchart LR
    U["ユーザーのウォレット"] -->|命令(instruction)を送る| P["owner: CounterProgram"]
    P -->|dataとlamportsを書き換えられる| D["データアカウント<br/>owner = CounterProgram"]
    U -.->|直接は書き換えられない| D

例えば、あなたが自分の SOL 残高を持つ普通のウォレットアカウントを持っているとき、そのアカウントの owner は System Program(Solana があらかじめ組み込んでいる基本プログラムの1つ)になっています。SOL を送金するとき、実際にアカウントの残高(lamports)を書き換えているのは、あなた自身のプログラムではなく System Program です。あなたは「送金してほしい」という命令に署名して依頼するだけです。

自分で作ったカウンタープログラムのデータアカウントであれば、その owner はあなたのカウンタープログラム自身になります。他のどんなプログラムも、そのアカウントの data を勝手に書き換えることはできません。これは非常に強力な安全装置です。あるプログラムのデータアカウントを、無関係な別のプログラムが誤って(あるいは悪意を持って)書き換えてしまう、という事故を、Solana のランタイムがそもそも許さない構造になっています。

// Solanaランタイムが行うチェックのイメージ(擬似コード)
fn write_account_data(account: &Account, calling_program: &Pubkey) -> Result<(), Error> {
    if account.owner != *calling_program {
        return Err(Error::InvalidOwner); // ownerでないプログラムからの書き込みは拒否
    }
    // ここまで来て初めてdataの書き換えが許可される
    Ok(())
}

このため、Solana のプログラムを設計するときは「このデータは誰が owner のアカウントに置くべきか」を最初に考えることになります。多くの場合、自分のプログラムが管理したいデータは、自分のプログラムを owner とするアカウントに置きます。

演習

あなたが管理していないアカウントの data を、あなたのプログラムから直接書き換えることはできるでしょうか。理由も合わせて答えてみましょう。

ヒント1を見る

data を書き換えられるのは、そのアカウントの owner に指定されたプログラムだけです。

ヒント2を見る

あなたのプログラムが owner でないアカウントに対しては、ランタイムのチェックで書き込みが拒否されます。