導入
自分のアカウントなのに、自分の意思だけでは中身のデータを直接書き換えられない ―― 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 でないアカウントに対しては、ランタイムのチェックで書き込みが拒否されます。