
イーサリアム開発からSolanaへの移行
原題:https://solana.com/ja/news/evm-to-svm
17 April 2024, by Solana Foundation
EVMからSVM(Solana)へ移行するには、仮想マシン間のいくつかの重要な違いを理解する必要がある。本記事では、アカウント、手数料、トランザクション、スマートコントラクト(プログラム)などを含む、これらの違いのいくつかを説明する。また、ツールやSDKを含む開発者のセットアップについても説明する。
終了時には、開発者はSolanaの旅を始めるために必要な知識を得ることができる。
コアの違いを理解する
手始めに、EVMとSVMの最も大きな違いであるアカウントモデルの設計を見てみよう。
アカウントモデル
イーサリアムとは異なり、Solanaはマルチコアを活用し、並列トランザクションをサポートするように設計されている。これを実現するために、Solanaはアカウントモデルを採用している。
Solana上のアカウントとは、データを保持する(データアカウント)か、実行可能なプログラム(Solana上のスマートコントラクトまたはプログラム)であるSolana台帳のレコードである。
イーサリアムと同様に、各アカウントはアドレス識別子を持っている。しかし、各スマートコントラクトが実行ロジックとストレージが結びついたアカウントであるイーサリアムとは異なり、ソラナのスマートコントラクトは完全にステートレスである。実行するためには、ステートをアカウントに渡さなければならない。
コードの例を見てみよう。以下のSolidityのコードでは、int private count = 0という行で状態がスマート・コントラクトに紐付けられている。
contract Counter {
int private count = 0;
function incrementCounter() public
{ count += 1;
}
function getCount() public constant returns (int) {
return count;
}
}
Rust(Solana)では、スマート・コントラクト内にinitialize_counterという構造体がある。この初期カウンターは、カウントが0のアカウントを作成する。カウントをインクリメントするために、アカウントはこのカウンターに渡される。これにより、スマート・コントラクト自体に状態が保持されなくなる。
#[program]
pub mod counter_anchor {
use super::*;
pub fn initialize_counter(_ctx: Context<InitializeCounter>) -> Result<()> {
Ok(())
}
pub fn increment(ctx: Context<Increment>) -> Result<()> {
ctx.accounts.counter.count = ctx.accounts.counter.count.checked_add(1).unwrap();
Ok(())
}
}
#[derive(Accounts)]
pub struct InitializeCounter<'info> {
#[account(mut)]
pub payer: Signer<'info>,
#[account(
init,
space = 8 + Counter::INIT_SPACE,
payer = payer
)]
pub counter: Account<'info, Counter>,
pub system_program: Program<'info, System>,
}
#[derive(Accounts)]
pub struct Increment<'info> {
#[account(mut)]
pub counter: Account<'info, Counter>,
}
#[account]
#[derive(InitSpace)]
pub struct Counter {
count: u64,
}
Solanaでは、データはプログラム外の別アカウントに保存される。プログラム内でロジックを実行するには、実行するアカウントを渡します。
このカウンタ・プログラムの場合、インクリメント関数を呼び出すときにカウンタ・アカウントをプログラムに渡し、プログラムはカウンタ・アカウントの値をインクリメントする。
アカウント・モデル設計の利点
このアカウントモデルの主な利点の一つは、プログラムの再利用性である。
イーサリアム上のERC20インターフェイスでは、開発者が新しいトークンを作成するたびに、ERC20スマートコントラクトを指定された値でイーサリアムに再デプロイしなければなりません。この再デプロイには高いコストがかかります。
しかしSolanaでは、新しいトークンを作るために新しいスマートコントラクトを作成してデプロイする必要はない。その代わりに、Solanaトークン・プログラムを使用して、ミント・アカウントと呼ばれる新しいアカウントを作成し、トークンの数、小数点、誰がミントできるかなどの詳細を渡します。
そしてこれは、トークン・プログラムにトランザクションを送信するだけで実行できる。例えば、Solana Program Library CLIを使えば、コマンド1つで済む:
spl-token create-token
ローカル料金市場
口座モデルのもう一つの利点は、手数料市場が口座ごとにローカルであることだ。
イーサリアムの手数料市場はグローバルだ。NFTコレクションが流行し、誰もがミントを行えば、手数料は誰にとっても上昇する。しかしSolanaでは、手数料市場はアカウントごとのローカルなものであるため、そのNFTコレクションを鋳造している人だけが手数料の上昇分を支払います。参加していないユーザーは影響を受けない。
料金
料金についてさらに掘り下げてみよう。Solanaでは、料金は基本料金、優先料金、家賃の3つに分かれている。それぞれを見てみよう。
基本手数料は取引の署名数に基づいて計算される。各署名には5000ランポート(0.000000001ソル=1ランポート)がかかる。取引に5つの署名がある場合、基本手数料は25000ランポートである。
優先料金は、トランザクションに優先権を与えるために追加できるオプション料金であ る。この手数料はトランザクションで使用されるコンピュートユニットの量に基づいている。イーサリアムガスと同様に、この手数料はトランザクションに必要なコンピューティングリソースの単純な測定値である。
最終的な料金である賃料は、むしろ保証金のようなものだ。開発者がネットワーク上にアカウントを作成したり、スペースを割り当てたりする際には、そのアカウントを維持するためにネットワークにSOLを預けなければならない。賃料は、ネットワーク上に保存されたバイト数に基づいて計算され、スペースを割り当てる際には、さらに基本料金が課金される。
トランザクション
Solanaでは、プログラムの実行はトランザクションがクラスタにサブミットされることから始まる。ソラナ上の各トランザクションは4つの部分で構成される:
1つ以上の命令。命令はSolana上の最小の実行ロジックである。イーサリアムのスマートコントラクトの関数呼び出しのように考えることができる。これらは、状態を更新するためにSolanaランタイムに呼び出しを行うプログラムを呼び出します(例えば、あるアカウントから別のアカウントにトークンを転送するためにトークンプログラムを呼び出します)。
読み書きする口座の配列
1つ以上の署名
最近のブロックハッシュまたはnonce。Ethereumのようにインクリメンタルなnonceを使用する代わりに、Solanaでは最近のブロックハッシュがクラスタから引き出される。このブロックハッシュでは、トランザクションは150ブロックのみ有効であり、長期間のトランザクション署名がかなり後の日付で実行されるのを防ぐ。
EthereumとSolanaのもう一つの大きな違いは、Solanaではトランザクションが複数の命令(Ethereumでは関数呼び出し)を持つことができることだ。これは、1つのトランザクションで機能を連鎖させるためにカスタムスマートコントラクトを作成する必要がないことを意味する。各命令は個別の関数呼び出しとすることができ、トランザクション内で順番に実行される。また、トランザクションはアトミックであり、1つの命令が失敗するとトランザクション全体が失敗する。
トランザクションの制限
イーサリアムのガス制限と同様に、ソラナ・トランザクションにも計算単位の制限がある。

その他の制限は以下の通り:
参照される各アカウントは、1ブロックあたり最大12,000,000個の計算ユニットを使用することができる。
命令は、トランザクションが戻る前に、深さ4でしか呼び出すことができない。
Mempool
イーサリアムとは異なり、Solanaにはmempoolがない。Solanaバリデーターは代わりに、リーダースケジュールで最大4人のリーダーにすべてのトランザクションを転送する。mempoolを持たないことで、トランザクションはブロックハッシュの有効期限が切れるまでリーダーからリーダーへとホップすることになるが、クラスタ全体のゴシップのオーバーヘッドを減らすこともできる。
Solana開発者環境
では、Solanaの開発者ツールをいくつか見てみよう。

プログラミング言語
Ethereumがスマート・コントラクトの記述に主にSolidityを使用しているのに対し、SolanaはRustを使用している。Ethereumから移行する場合は、AnchorフレームワークまたはNeonを検討してください。どちらも、使い慣れたEVMツールを使ってSolanaでビルドできるため、開発者がより早く始めるのに役立ちます。
イーサリアムと同様に、JavaScript、Python、Javaなど、最も一般的なプログラミング言語の多くで利用可能なクライアントサイドSDKがあります。
開発ツール
Solanaには今のところFoundryに相当するものはないが、Solidityで使われているものと同等の幅広いツール群がある。
Tool | Solana Equivalent
Hardhat | Solana Test Validator
Brownie | Program-test,BankRun.js
Ethers, Wagmi | @solana/web.js
Remix | Solana Playground
ABI | Anchor Framework's IDL
Etherscan | SolanaFM,XRay
scaffold-eth | create-solana-dapp
より深く掘り下げるには、開発者向けリソースの広範なリストをご覧ください。
スマートコントラクトの作成
Solana上でプログラムを作成する場合(または既存のEthereumスマートコントラクトを移行する場合)には、いくつかの核となる違いがあります。しかし、最も一般的なものをいくつか見てみよう:
マッピングはSolanaには直接存在しない。代わりに、プログラム由来のアドレスを使用する。マッピングと同様に、プログラム派生アドレスは、キーまたはアカウントからオンチェーンに保存された値へのマップを作成する機能を提供します。
Solanaでは、プログラムはデフォルトでアップグレード可能です。スマートコントラクトは、シンプルなCLIコマンドsolana program deploy <program_filepath>でアップグレードできます。
solidityスマートコントラクトを書く場合、msg.senderか tx.originのどちらかをチェックするのが一般的だ。Solanaにはこれに相当するものがない。各トランザクションは複数の署名者を持つことができ、トランザクションを送信する人が必ずしもそのトランザクションに署名した人とは限らない。
プログラムの詳細と導入方法については、こちらのガイドをご覧ください。
さらに詳しく
以上が、イーサリアムとソラナでの開発における最も重要な違いのいくつかである。もちろん、学ぶべきことは他にもたくさんある。そして、始めるための最善の方法は、すぐに飛び込むことだ!次のステップのためのリソースをいくつか紹介しよう:
開発者がブラウザからSolanaプログラムを書き、ビルドし、デプロイできるSolana Playground
Solana Playgroundを使ったSolana開発入門
イーサリアムとSolanaでの開発の違いをより詳しく見る