新着:HeliusがLight Protocolを買収
EthereumからSolanaへ移行する方法:開発者向けガイド
ブログ/リサーチ

EthereumからSolanaへ移行する方法:開発者向けガイド

Developer Experience EngineerXの0xIchigoLinkedInの0xIchigoGitHubの0xIchigo
読了時間:41分

この記事の内容

Ethereumは、近年における最も重要なイノベーションの1つです。史上初めて、多くの業界に革命をもたらす可能性を秘めた、社会的協調のための分散型グローバルプラットフォームが誕生しました。しかし、その重要性にもかかわらず、Ethereumのランタイム環境であるEthereum Virtual Machine(EVM)は、現状では一般消費者向けアプリケーションに適した設計ではありません。EVMはシングルスレッドで動作するガスベースのネットワークであり、手数料が大きく変動します。一方、Solanaは高スループットかつ低レイテンシのネットワークです。低額で予測可能な手数料を備えた並列化インフラストラクチャを提供します。EVMの制約を直接解消し、その基本設計を改善しているため、スケーラブルで効率的なアプリケーションを構築したい開発者にとって魅力的な選択肢です。

この記事は、Solanaでの開発に関心を持つEVM開発者向けの包括的な移行ガイドです。EthereumとSolanaのコンセンサスメカニズム、トランザクションの処理方法、スマートコントラクト開発に使われる言語を取り上げ、両者の根本的な違いを解説します。さらに、アカウントに対してより統一的かつ多面的なアプローチを採用するSolanaのアカウントモデルについて説明します。また、Solanaでの開発体験を向上させるSolidity対応ツール、SolangとNeon EVMについても紹介します。

根本的な違い

このセクションでは、グローバルな協調のための分散型ステートマシンを目指す2つのブロックチェーン、EthereumとSolanaの重要な違いを解説します。両者は、コンセンサスメカニズム、トランザクション処理方式、スマートコントラクト開発に使われる言語において大きく異なります。こうした根本的な違いを深く理解することで、高性能なグローバルステートマシンとしてSolanaがEthereumに対して持つ明確な優位性が見えてきます。

コンセンサスメカニズム

コンセンサスメカニズムは、あらゆるブロックチェーンネットワークの基盤です。トランザクションを検証する方法と、ブロックを安全かつ効率的に、そして分散化された形でブロックチェーンに追加する方法を決定します。EthereumとSolanaはいずれもProof of Stake(PoS)ネットワークです。PoSという共通の基盤を持つ一方で、確認ルールが異なるため、コンセンサスを形成するアプローチも異なります。

Ethereumは、Casper the Friendly Finality Gadget(Casper-FFG)とLMD-GHOSTフォーク選択アルゴリズムを組み合わせたGasperを使用します。この組み合わせが、Ethereumを保護するコンセンサスメカニズムを形成しています。

CasperはPoSベースのファイナリティシステムで、ブロックの確認状態を「ファイナライズ済み」へと引き上げます。Ethereumでは、総ステークの3分の2がそのブロックの採用に賛成票を投じ、さらにその上に別のブロックが構築されると、そのブロックはファイナライズ済みと見なされます。ブロックが正規であるという合意に総ステークの3分の2が必要なため、攻撃者は総ステークの3分の2を所有または操作し、さらにスラッシングによって少なくとも3分の1を失わない限り、別のファイナライズ済みチェーンを作成できません。Casperにより、新規参加者は正規チェーンと確実に同期できます。 

LMD-GHOSTは「Latest Message-Driven Greedy Heaviest Observed Sub-Tree」の頭字語です。Ethereumでどのフォークに従うかを決めるアルゴリズムです。ネットワークのバリデータから最も多くの支持、つまり「重み」を得たフォークを選択します。そのため「greedy heaviest sub-tree」と呼ばれます。そのうえで、各バリデータからの最新メッセージだけが考慮されるようにします。Ethereumに新しいブロックが提案されるたびに、バリデータはこのルールを使って、そのブロックを正規チェーンに含めるべきか判断します。

これに対して、SolanaはProof of History(PoH)のハッシュを使ってコンセンサスを形成します。名称が紛らわしいものの、PoHはコンセンサスアルゴリズムではありません。敵対的なネットワークで時間を証明する方法です。より具体的には、ノード同士が通信せずにイベントの順序について合意できるようにする、暗号学的なタイムスタンプ関数です。リーダー、つまり台帳にエントリを追加するバリデータがブロックにタイムスタンプを付け、前のブロックから一定の時間が経過したことを証明します。 

タイムスタンプを追加すると、データが特定の時点に存在していたことを証明できるため、履歴記録が確立されます。履歴記録は逐次的な原像計算困難性を持つハッシュ関数で作成され、各ハッシュは直前のハッシュに依存します。Verifiable Delay Functions(VDF)は、これらのハッシュを生成するうえで重要な役割を果たします。各ハッシュが前のハッシュを基に構築され、そこから経過した時間を組み込むことを保証します。VDFを統合することでハッシュ処理に時間の次元が加わり、Solana上でタイムスタンプ付きイベントの検証可能なシーケンスを作成できます。

SolanaのProof of Historyメカニズムが暗号学的タイムスタンプによって信頼性の高いイベントシーケンスを作成する仕組みを確認したところで、これがSolanaのコンセンサスメカニズムであるTower BFTとどう統合されるかを理解することが重要です。Tower Byzantine Fault Tolerance(BFT)は、従来のByzantine Fault ToleranceコンセンサスモデルをPoH向けに最適化したSolana独自の方式です。Tower BFTは、PoHが作成した履歴記録を参照フレームワークとして使用します。このフレームワークにより、バリデータは台帳の状態に対して効率的かつ正確に投票できます。Tower BFTでは、バリデータの投票が長時間ロックされ、投票が追加されるほどコミットメントが強くなります。PoHにより、バリデータは互いに通信することなく、台帳の状態についてより迅速かつ十分な情報に基づく判断を下せます。PoHとTower BFTを組み合わせることで、コンセンサスが高速化され、ネットワークのセキュリティと信頼性が向上します。その結果、トランザクションを迅速に確認できる、高スループットでスケーラブルなブロックチェーン環境が実現します。

トランザクション処理と実行環境

ブロックチェーンの効率性とスケーラビリティは、主にトランザクション処理能力と実行環境によって決まります。これらの要素が、トランザクションの実行速度とネットワーク運用のコスト効率を左右します。トランザクション処理へのアプローチと実行環境の特性は、開発者体験に大きな影響を与えます。

Ethereumのランタイム環境は、Ethereum Virtual Machine(EVM)と呼ばれる決定論的なシングルスレッドのスタックマシンとして動作します。数学的な関数のように振る舞い、入力が与えられると決定論的な出力を生成します。Ethereumには状態遷移関数があると定義すると分かりやすいでしょう:f(S, T) = S’。古い状態(S)と新しい有効なトランザクションの集合(T)が与えられると、EVMは新しい有効な出力状態(S’)を生成します。同じトランザクション集合が与えられれば、EVMは必ず同じ最終状態に到達します。これは、ネットワーク内のノード間で一貫性を維持するために不可欠です。

EVMはトランザクションを順番に処理します。逐次処理により、各トランザクションは、その時点までのネットワーク状態を正確に反映した環境で実行されます。逐次実行では、状態変化とガスコストを正確に計算できます。この予測可能性により、開発者とユーザーはトランザクションの結果とコストを明確に把握できます。

Ethereumはシングルスレッド実行モデルを採用し、スマートコントラクトの実行環境を簡素化しています。各トランザクションが順番に処理されるため、開発者は状態変化を予測しやすいという利点があります。状態変化を予測できることで、新しい開発者は実行の複雑さよりもスマートコントラクトのロジックに集中できるため、Ethereumの開発環境は比較的取り組みやすいと言えます。しかし、この単純さはスケーラビリティの課題につながります。逐次処理はネットワークのスループットを制限します。その結果、需要が高まると混雑が発生し、トランザクションの待ち時間が延び、ガス代が上昇する可能性があります。すべてのトランザクションがガスを消費するため、開発者はガス効率を最適化せざるを得ません。これはユーザー体験全体を改善し、非効率なコードによって一般ユーザーがアプリを利用できなくなるような混雑時の問題に対処するためです。

Solanaの開発者は、Ethereumの開発者のようにガス使用量の最適化を心配する必要がありません。Solanaは、Solana Virtual Machine(SVM)と呼ばれる高スループットかつ低レイテンシのステートマシンとして設計されています。SVMの重要な構成要素がSealevelです。これはトランザクションを並列処理するランタイムエンジンです。Solanaでは、各トランザクションが実行時に状態のどの部分を読み書きするかをランタイムに伝えます。ランタイムは、競合しないトランザクションと同じ状態を読み取るトランザクションを並列処理します。Sealevelは、トランザクションのワークロードをバリデータのハードウェアにある複数のスレッドへ分散し、スマートコントラクトの実行を最適化します。そのため、バリデータが1つのコアでトランザクションを処理している間に、別のコアで別のトランザクションを同時に処理できます。

Solana本来の並列性により、トランザクションコストは大幅に削減されます。Solanaのトランザクション手数料には、基本手数料と優先手数料の2種類があります。基本手数料は署名ごとに5000 lamportsで固定されており、ほとんどのトランザクションには署名が1つしかありません。優先手数料は任意で、他のトランザクションよりも自身のトランザクションを優先させるために使用できます。優先手数料が高いトランザクションは、スケジューラによって非決定論的に優先されます。トランザクション手数料は多くの場合、$0.001 USD未満です。投票以外の平均手数料は0.000005~0.00007 SOLの範囲で、最近の優先手数料の利用増加により、上限は通常より高くなっています。現在のSOL価格である~$98.96では、この手数料は約$0.000494~$0.006968 USDに相当します。 

これらの手数料は予測可能でもあります。Solanaは需要を管理するためにローカライズされた手数料市場を使用します。ブロックスペースは、特定のアクティビティのホットスポット、たとえば話題のNFTミントがブロックスペースを独占し、ネットワーク全体の手数料を引き上げないように構成されています。手数料が上昇するのは、需要の高い特定のホットスポットへアクセスしようとするトランザクションだけです。ローカライズされた手数料市場では、本格的なガス戦争を引き起こすことなく優先手数料を利用できます。このローカライズ方式は、トランザクションを順番に処理し、ネットワーク全体の混雑によって手数料が変動するEthereumのようなガスベースのネットワークとは異なります。

Ethereumは、一度に1つのコントラクトしか処理できないシングルスレッドのランタイム環境です。現在のところ、最新のマルチコアハードウェアを活用しておらず、バリデータのハードウェアが十分に利用されていません。ノードのハードウェア要件を低く保とうとする方針も、Ethereumのトランザクション処理を制約しています。一方、Solanaは並列処理機能によってバリデータで利用可能なすべてのコアを活用し、より多くのトランザクションを処理できます。ローカライズされた手数料市場と組み合わせることで、Solanaははるかに高性能なグローバルステートマシンとなります。 

スマートコントラクト言語

Ethereumでスマートコントラクトを開発する際の主要言語はSolidityです。EVM上で動作するスマートコントラクトを作成するために設計された、静的型付けの波括弧構文を持つ言語です。JavaScript、C++、Pythonの影響を強く受けているため、これらの言語に詳しい開発者は簡単に習得できます。

Yulは、EVM互換ブロックチェーン向けに最適化された中間低水準言語です。Yulを使うと、開発者はバイトコードの実行をより細かく制御でき、ガス消費の微調整やその他の低水準操作の管理を非常に効率よく行えます。Yulで直接コーディングするか、コンパイルターゲットとして使用することで、より効率的なコントラクトを作成できます。

Vyperは、シンプルさとセキュリティを重視する人気のPython風言語です。複雑さと潜在的なセキュリティ脆弱性を減らすため、意図的にSolidityより機能が少なく設計されています。Vyperの設計思想では、何よりも可読性と監査可能性を重視します。このアプローチは、Feのような類似言語や、DasyのようなVyperにコンパイルされる言語の開発に影響を与えています。

Rustは、Solanaにおけるスマートコントラクト(一般にプログラムと呼ばれます)開発の共通言語です。高速かつメモリ効率に優れ、C++に匹敵する性能を持ちます。こうした特性により、高スループットかつ低レイテンシのネットワーク向けアプリケーションの開発に適しています。Rustの豊富な型システムと所有権モデルはメモリとスレッドの安全性を確保し、開発者が信頼性と安全性に優れたアプリケーションを構築できるようにします。 

システムプログラミングの経験がない人にとってRustの学習曲線は急ですが、その代わりに堅牢で効率的なコードを作成できます。Rust開発の大半ではAnchorが使われます。Anchorは、定型コードの削減、各種の標準的なセキュリティチェック、シリアライズとデシリアライズ処理の効率化によってプログラム開発を簡素化する、規約を重視したフレームワークです。そのため、開発を始める段階では高度なRustの知識がそれほど重要ではなくなります。参考までに、Anchorのドキュメントでは、ユーザーがRust Bookの最初の9章、つまりRustの基礎を理解していることを推奨しています。Solana Playgroundには、開発を始めるための複数のAnchorチュートリアルがあります。

Rustが推奨されますが、開発者がRustだけに制限されるわけではありません。C、C++、およびLLVMのBPFバックエンドをターゲットにできる任意の言語、つまりBPFバイトコードにコンパイルできる言語を使用できます。VyperなどのPython風言語に詳しい開発者は、Seahorse Langを使ってPythonでプログラムを記述できます。これにより、Rustでコーディングした場合と同じ安全性を維持しながら、Pythonの使いやすさを活用できます。Seahorse UniversityやSeahorse Cookbookなど、Solanaで今すぐプログラミングを始めるのに役立つSeahorseチュートリアルも複数用意されています。

Ethereumから移行する開発者は、Rustだけに縛られるわけではありません。人気とセキュリティ保証の面からAnchorやSeahorseなどのフレームワークを学んで使うことが推奨されますが、常に実現可能とは限りません。SolangとNeon Labsが最近開発したコンパイラとEVM互換の開発環境により、開発者はプログラム開発でSolidityを使用できます。SolidityはSolanaでも活用できます。Solidityによるプログラム開発を始めるには、Solanaのプログラミングモデルの詳細を理解する必要があります。この移行を行う開発者にとって、Solanaのアカウントモデルを理解することは不可欠です。アカウントモデルは、ネットワーク上でのプログラム開発とインタラクションの基盤となるためです。

アカウントモデルを理解する

Ethereumでは、アカウントを外部所有アカウント(EOA)とコントラクトアカウントという2つの主要カテゴリに分類します。EOAはユーザーが使用する標準的なアカウントです。秘密鍵で管理され、Ether残高の保有、トランザクションの送信、コントラクトアカウントとのやり取りが可能です。一方、コントラクトアカウントは、内部に組み込まれたスマートコントラクトコードによって動作が制御される点で異なります。コントラクトアカウントは自律的にトランザクションを開始できず、EOAまたは別のコントラクトアカウントから受信したトランザクションに応答してのみ動作できます。

Solanaはより統一的なアカウントモデルを採用し、アカウントをデータを永続的に保存する多面的なコンテナとして扱います。このモデルでは、どのアカウントもプログラムになり得るため、アカウントとスマートコントラクトの従来の境界が曖昧になります。コードと状態を1つのアカウントにまとめるEthereumとは異なり、Solanaのプログラムはステートレスです。つまり、内部に状態を保存しません。代わりに、処理に必要なすべてのデータは別のアカウントに保存され、トランザクションで参照として渡されます。アカウントを参照として渡すことで、1つの汎用プログラムをデプロイし、異なるアカウントとやり取りできます。Solanaのアカウントモデルはコードとデータを分離し、より効率的でモジュール化された開発環境を実現します。これは、異なるプログラム間で資産を移動せずに複数のプロトコルとやり取りしたいユーザーにとって有利です。Solana上のすべてはアカウントです。 

Solanaのアカウントは、実行可能アカウントと実行不可能アカウントに大別できます。簡単に言えば、実行可能アカウントはコードを実行できるアカウントです。実行不可能アカウントはコードを実行できず、データ保存に使用されます。これは、コードを一切保存していないためです。

実行可能アカウントは、プログラムを保持するアカウントです。プログラムは追加のアカウントを所有し、他のアカウントからの読み取りや入金、データの変更、所有するアカウントからの引き落としを行えます。実行可能アカウントは、オンチェーンプログラムとネイティブプログラムにさらに分類できます。オンチェーンプログラムは、ユーザーが記述してネットワークにデプロイするコードです。通常はデプロイしたアカウントであるアップグレード権限者によってアップグレードできます。ネイティブプログラムは実行可能アカウントの特殊なサブセットで、Ethereumのプリコンパイル済みコントラクトに似ていますが、より幅広い機能を備えています。これらのプログラムはSolanaのコアに統合され、バリデータの運用に必要な機能を提供します。ネイティブプログラムの一例がSystem Programです。このプログラムは、新しいアカウントの作成、アカウントデータの割り当て、プログラムへのアカウントの割り当て、自身が所有するアカウントからのlamportsの送金、トランザクション手数料の支払いを担います。ネイティブプログラムの完全な一覧はこちらで確認できます。

実行可能か実行不可能かにかかわらず、すべてのアカウントには同じフィールドがあります。 

  • アカウントのSOL建てネイティブ残高を追跡するlamportsフィールド
  • アカウントが保存する生のデータバイト配列を表すdataフィールド
  • このアカウントを変更できるプログラムを示すownerフィールド
  • アカウントがトランザクションを承認できるかどうかをトランザクション内で示すsignerフィールド
  • アカウントのデータを変更できるかどうかを指定するwritableフィールド。トランザクションに含まれるアカウントを読み取り専用または書き込み可能としてマークし、並列処理を可能にします
  • アカウントがプログラムを保存しているかどうかを示すexecutableフィールド
  • アカウントで次にレントが発生するエポックを示すrent epochフィールド

レントは、Solana上でアカウントを存続させ、バリデータのメモリ内に保持するためのストレージコストです。アカウントを有効な状態に保つには、最低残高を維持する必要があります。レントによって、未使用または残高不足のアカウントをネットワークが最終的に回収できるため、状態の肥大化を抑えられます。最近の更新により、メインネットではレントを支払うアカウントがなくなりました。代わりに、すべてのアカウントは作成時にレント免除でなければなりません。2年分のレント支払いに相当する最低残高を維持していれば、そのアカウントはレント免除となります。Test DriveやSolana CLIのrentサブコマンドなどのツールを使って、アカウントをレント免除にするために必要なSOLの量を見積もれます。これは、明示的に消去しない限りストレージが維持されるEthereumのリソース割り当てシステムとは異なります。Solanaのアプローチは、状態の肥大化を抑えながら、状態ストレージに対してより予測可能なコスト構造を提供します。

アドレスとProgram Derived Addresses(PDA)

すべてのアカウントは、一意の32バイト公開鍵であるアドレスによって識別されます。アドレスが20バイトであるEthereumのデータモデルとは異なります。Solanaでは、ed25519、つまりSHA-512とCurve22519楕円曲線を使用するEdDSA署名方式を使ってアドレスを生成します。有効なキーペアを持つには、アカウントがed25519曲線上の点でなければなりません。 

Program Derived Addresses(PDA)は、bump、つまり出力を曲線外へずらす値を使って曲線外に生成されるアカウントです。PDAには、親プログラムのアドレス、seedの集合、bumpという3つの主要要素が必要です。seedは任意の値を持つ文字列の配列です。ただし、多くの開発者は親プログラム内の状態変数に関連する特定のseedを作成し、ハッシュマップのようなデータ構造を構築します。したがって、PDAはプログラムID、seed、bumpをSHA-512ハッシュ関数でハッシュして作成されます。

PDAを曲線外にする目的は、PDAの派生元プログラムだけがPDAに代わって署名できるようにすることです。トランザクション署名をプログラムで生成できるため、トランザクションフローが効率化され、トラストレスなdAppsが介入なしで円滑に動作できます。

アカウントとのやり取り

Ethereumのトランザクションは、EOAによって開始される状態変更操作です。スマートコントラクトは独自にトランザクションを開始できず、トランザクションに反応することしかできません。こうした反応はコントラクトのコードによって決まり、トランザクションの実行コストはガスで測定されます。ユーザーは、このガス代を支払うのに十分なEtherを用意する必要があります。

Ethereumのトランザクションは通常、特定のスマートコントラクト関数の呼び出しなど、1つの操作を実行します。1つのトランザクションによってコントラクト内で複数の状態変化が発生する場合でも、すべての変更はその単一のコントラクト呼び出しの範囲内に限定されます。

Solanaでは、トランザクションは、読み取りまたは書き込み対象となるアカウントの配列、1つ以上の署名、1つ以上の命令で構成されます。命令は、単一のプログラム呼び出しに対する指示です。命令は実行ロジックの最小単位であり、最も基本的な操作単位です。命令では、実行するプログラム、関係するすべてのアカウント、操作データを指定します。プログラムは命令内のデータを解釈し、指定されたアカウントを操作します。この構造により、1つのトランザクションで複数のプログラムにまたがる一連の操作をアトミックに実行できます。つまり、すべての命令がまとめて成功するか、まとめて失敗します。Solanaのトランザクションフローは、通常1つのスマートコントラクトまたはEOAの操作に関連付けられるEthereumのモデルとは異なります。

Cross-Program Invocations(CPI)を使うと、同じトランザクション内でプログラムから別のプログラムを呼び出せます。CPI中にコンピュートユニットごとに課金されるアカウントデータのバイト数は250です。200,000ユニットでは約50MBに相当します。CPIでは、プログラム間の呼び出し時に、プログラムで生成した署名を使用できます。これは、Ethereumのスマートコントラクトから別のコントラクトを効率的かつアトミックに呼び出す仕組みに似ています。ただし、呼び出し元プログラムは、呼び出されたプログラムが命令の処理を完了するまで停止します。リエントランシーは、深さが4に固定された直接的な自己再帰に制限されます。これにより、プログラムが中間状態から別のプログラムを呼び出し、その後自身が再び呼び出される可能性を認識できない状況を防ぎます。

Solanaのトランザクションには、Ethereumのガス上限と同様に、効率性を保つためのサイズ制限があります。ただし、Solanaではデータサイズが重視されます。Solanaのトランザクションは、信頼性の高いデータ転送を保証するためにIPv6 Maximum Transmission Unit(MTU)規格に従います。必要なヘッダー領域を確保すると、パケットデータには1232バイトを使用できます。Solanaはサイズ制約を克服するため、複数のトランザクション形式をサポートするバージョン付きトランザクションを導入しました。レガシー形式、つまり元のトランザクション形式に加えて、Address Lookup Tables(ALT)をサポートするVersion 0がリリースされました。ALTは、各アドレスを1バイトのu8インデックスで索引付けし、テーブル形式のデータ構造でオンチェーンに保存します。各アカウントに必要なデータが32バイトではなく1バイトになるため、トランザクションサイズを大幅に削減できます。

Solang

Solang は、Solana および Polkadot 向けの Solidity コンパイラです。Solana と Polkadot のアーキテクチャに合わせた若干の違いはありますが、EVM の Solidity コンパイラのバージョン 0.8 とのソースファイル互換性を目指しています。Solang の重要な特徴の一つは、強力なコンパイラインフラストラクチャである LLVM を使用していることです。LLVM の柔軟性により、Solang は将来的にほかのプログラミング言語もサポートでき、実装とコンパイルが容易になります。この特性は、開発者の Solana または Polkadot への移行を容易にし、Solidity 開発の可能性を広げるという Solang の目標に合致しています。Solang は継続的に開発されており、互換性、効率性、使いやすさの向上に重点を置いています。スキルをクロスチェーンに展開したい Ethereum 開発者にとって、Solang とその注意点を理解することは不可欠です。

インストール

Solang のインストール方法はいくつかあります。Mac では、プライベート tap を使用して Brew から Solang をダウンロードできます。

コード
brew install hyperledger/solang/solang

Solang をインストールする別の方法は、Solang コンテナを使用することです。新しいイメージがこれらのコンテナで自動的に利用可能になるため、Docker を使いたい場合に最適です。v.0.3.3 タグと latest タグがあります。

コード
docker pull ghcr.io/hyperledger/solang:latest

Solang を簡単にインストールして使用する方法の一つが Ancor です。まず、Rust と Node.js がシステムにインストールされていることを確認します。Windows ユーザーは、Windows Subsystem for Linux のセットアップも必要です。次に、Solana のツールスイートをインストールします。Mac と Linux では、次のコマンドで実行できます。

コード
 sh -c "$(curl -sSfL https://release.solana.com/v1.17.13/install)"

別のソフトウェアバージョンを使用する場合は、「v1.17.13」を適切なリリースタグに置き換えてください。または、stable、beta、edge のいずれかのシンボリックチャンネル名を使用できます。システムによっては、PATH 環境変数の更新が必要です。このメッセージが表示された場合は、下にある推奨コマンドをコピーして貼り付け、PATH を更新してください。solana --version を実行すると、目的の solana バージョンを確認できます。

Windows では、管理者としてコマンドプロンプトを開きます。次のコマンドをコピーして貼り付け、Solana インストーラーを一時ディレクトリにダウンロードします。

コード
cmd /c "curl https://release.solana.com/v1.17.13/solana-install-init-x86_64-pc-windows-msvc.exe --output C:\solana-install-tmp\solana-install-init.exe --create-dirs"

次に、以下のコマンドをコピーして貼り付け、Solana の最新バージョンをインストールします。C:\solana-install-tmp\solana-install-init.exe v1.17.13. インストールが完了したら、Enter キーを押します。

コマンドプロンプトのウィンドウを閉じ、一般ユーザーとして新しいウィンドウを開き直します。solana –-version を実行し、目的のバージョンの solana がインストールされていることを確認します。

次に、Anchor をインストールします。

Anchor version manager(avm)を使用して Anchor をインストールすることを推奨します。次のコマンドを使い、cargo 経由で実行できます。

コード
cargo install -git https://github.com/coral-xyz/anchor avm --locked --force.

次に、最新バージョンをインストールして使用します。

コード
avm install latest
avm use latest

# Verify the installation
avm –version

Anchor バージョン 0.28 では、開発者が Solang で直接ビルドできます。anchor init project_name —solidity コマンドで新しい Solang プロジェクトを作成できます。これにより、新しい Solang プログラムと、クライアント経由でプログラムを操作する方法を示すテストファイルが作成されます。

Visual Studio Code を使用している場合は、シンタックスハイライトを支援する Solang 拡張機能のインストールを検討してください。Solang 拡張機能が正しく動作するよう、ほかの有効な Solidity 拡張機能は無効にしてください。

新しいプロジェクトの作成

anchor-init project_name –solidity コマンドで新しいプロジェクトを作成します。プロジェクト名を持つ新しいディレクトリが作成されます。Solidity フラグは、Solang を使用することを Anchor に伝えます。プロジェクトの ./solidity ディレクトリには、スタータープログラムが用意されます。コントラクトは次のようになります。

コード
@program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC")
contract test {
    bool private value = true;

    @payer(payer)
    constructor() {
        print("Hello, World!");
    }

    /// A message that can be called on instantiated contracts.
    /// This one flips the value of the stored `bool` from `true`
    /// to `false` and vice versa.
    function flip() public {
            value = !value;
    }

    /// Simply returns the current value of our `bool`.
    function get() public view returns (bool) {
            return value;
    }
}

このプログラムには、プログラムを作成し、状態変数 value を true に初期化し、プログラムログに「Hello, World!」を記録する constructor があります。flip 関数は、呼び出されると状態変数を更新します。get 関数は、状態変数の現在値を返します。いくつかの注意点はあるものの、通常の Solidity スマートコントラクトのように見えます。最大の違いは、アノテーションを使用することです。

アノテーション

アノテーションはアカウント管理に使用されます。@program_id(“...”) アノテーションに注目してください。これは、事前に判明している場合にプログラムのオンチェーンアドレスを指定するために使用します。外部呼び出しを介してコントラクトを呼び出す場合、プログラムには @program_id 表記が必要です。そうでなければ、{program_id: … } 引数を使用して呼び出す必要があります。

コード
@program_id(“...”);

contract Foo {
	function hello() public pure {
		print(“Hello”);
	}
}

contract Foo2 {
	function bye() public pure {
		print(“Bye”);
	}
}

contract Bar {
	function new_foo() external {
		Foo.new();
	}
}

contract Bar2 {
	function new_foo(address new_foo_id) external {
		Foo2.new{program_id: new_foo_id}();
	}
}

新しいプロジェクトを作成した際、提供されたサンプルコントラクトでは、コンストラクターに @payer アノテーションが付いていました。このアノテーションは、プログラムのデータアカウントの初期化費用を支払うアカウントを定義します。@payer(payer) 構文は payer という名前のアカウントを宣言し、コンストラクターを呼び出すたびに必要になります。

コントラクトをインスタンス化するには、実行可能コードを保持するプログラムアカウントと、状態変数を保存するデータアカウントが必要です。データアカウントはクライアント側のコードで作成し、コンストラクターを呼び出すトランザクションに渡せます。または、コンストラクターでデータアカウントを作成できます。少なくとも @payer アノテーションを指定する必要があります。データアカウントを PDA にする場合は、seed と bump を指定する必要があります。@seed アノテーションは PDA の導出に使う seed を指定し、文字列リテラルまたは hex”1234” 形式の16進文字列にできます。seed アノテーションが引数より前にある場合は、bytes、address、または固定長バイト配列型の引数を参照する必要があります。@bump アノテーションは、オフカーブアドレスの生成に使用する値を指定します。bytes1 型の単一バイトでなければなりません。省略可能な @space アノテーションでは、データアカウントのサイズを指定できます。これは uint64 式であり、定数またはコンストラクター引数の一つを使用できます。Solang のドキュメントによると、少なくとも @space は、solang -v コマンドの実行時に示されるサイズにする必要があります。

コード
$ solang compile --target solana -v examples/solana/flipper.sol
...
info: contract flipper uses at least 17 bytes account data
…

プログラムにコンストラクターがない場合、これらのアノテーションを空のコンストラクターと組み合わせられます。Solang のドキュメントには次の例があります。

コード
@program_id("Foo5mMfYo5RhRcWa4NZ2bwFn4Kdhe8rNK5jchxsKrivA")
contract Foo {

    @space(500 + 12)
    @seed("Foo")
    @payer(payer)
    constructor(@seed bytes seed_val, @bump bytes1 bump_val) {
        // ...
    }
}

関数アノテーションは、外部関数に必要なアカウントを宣言するために使用します。

  • @account(foo) は、foo アカウントを読み取り専用アカウントとして宣言します
  • @mutableAccount(bar) は、bar アカウントを変更可能なアカウントとして宣言します
  • @signer(fizz) は、fizz アカウントを読み取り専用の署名者として宣言します
  • @mutableSigner(buzz) は、buzz アカウントを変更可能な署名者として宣言します

コンストラクターで @payer アノテーションを使って宣言したアカウントには、コンストラクター内からアクセスできます。関数アノテーションで宣言したアカウントは、tx.accounts ベクターで利用できます。たとえば、@account(ichigo) として宣言したアカウントへアクセスするには、tx.accounts.ichigo を使用します。これにより、組み込みの AccountInfo 構造体が返されます。この構造体は「アカウントモデルを理解する」セクションで説明したものと同じ構造ですが、命名が少し異なります。

  • key:アカウントのアドレスまたは公開鍵です。型は address です
  • lamports:アカウントの lamport 残高です。型は uint64 です
  • data:アカウントのデータです。型は bytes です
  • owner:アカウントの所有者です。型は address です
  • rent_epoch:アカウントの rent 支払期限となる次の epoch です。型は uint64 です
  • is_signer:アカウントがトランザクションに署名したかどうかを示します。型は bool です
  • is_writable:このトランザクションでアカウントが書き込み可能かどうかを示します。型は bool です
  • executable:アカウントがプログラムかどうかを示します。型は bool です

制限事項

Solang と従来の Ethereum 開発における主な非互換性は次のとおりです。

  • msg.sender は Solana では利用できません。アカウントモデルでは、Rust コントラクトはさまざまなデータアカウントにアクセスできますが、そのうちどれを呼び出し元とみなすのでしょうか。単一のアカウントを呼び出し元として特定できないケースが数多くあります。また、ランタイムには呼び出し元アカウントを取得する仕組みがありません
  • ecrecover() 関数はありませんが、ed25519 署名を確認する signatureVerify() 関数はあります。
  • try-catch 文は機能しません。外部呼び出しまたはコントラクト作成が失敗すると、ランタイムは実行を停止し、トランザクション全体を元に戻します。
  • エラー定義とエラーメッセージ付きの revert はまだ機能しません
  • 関数呼び出しによるネイティブ値の転送は機能しません。
  • 多くの Yul 組み込み機能は利用できません。Solang は大部分の組み込み機能をサポートしていますが、メモリ操作とチェーン操作は実装されていません。
  • ERC-20 形式は現在サポートされていません。SPL Token は Token Program に従って定義されます。Token Program は、Solana でトークンを作成、mint、転送、burn するネイティブな方法です。SplToken ライブラリを使用するには、spl_token.sol ファイルをソースツリーにコピーし、必要な場所でインポートします

さらに、SVM のレジスター幅は 64 ビットであるため、256 ビット整数よりも 64 ビット整数(uint64 や int64 など)が適しています。uint256 や int256 など、64 ビットより広い型を扱う演算は複数の演算に分割されます。そのため処理が遅くなり、より多くのコンピュートユニットを消費します。

アドレスについては、アドレスリテラルを address"36VtvSbE6jVGGQytYWSaDPG7uZphaxEjpJHUUpuUbq4D" 構文で指定する必要があります。Ethereum の16進数構文(0xE0f5206BBD039e7b0592d8918820024e2a7437b9 など)はサポートされていません。Solana の残高と値はすべて 64 ビット幅です。つまり、アドレス用の組み込み関数(.balance()、.transfer()、.send() など)は 64 ビット整数を使用します。

Solang は EVM 開発者が Solana エコシステムに進出するための魅力的な道筋を提供しますが、慎重な検討が必要な制限もいくつかあります。Solana のアカウントベースモデルへの移行は単なる構文上の変更ではなく、スマートコントラクトのロジックが根本的に変わることを意味します。特定の関数、コーディングパターン、EVM 固有の機能は Solang では利用できません。Ethereum スマートコントラクトを Solang に移植しても、大幅な調整なしに動作するとは限りません。適切なエラー定義やエラーメッセージ付きの revert がないなど、機能の欠如は深刻な問題になり得ます。一方で、Solang は絶えず進化しているツールであり、アップデートのたびに Solana における Solidity 開発者体験の改善を目指していることも重要です。Solang には、この体験を向上させる明確な利点がいくつかあります。

利点

こうした制限がある一方で、開発者体験を向上させる組み込み関数や設計上の工夫が数多くあります。たとえば、Solang で開発したコントラクトは Anchor プログラムと連携できます。これは、Anchor プログラムの IDL から Solidity インターフェースを生成することで実現できます。IDL は「Interface Description Language」の略です。基本的には、プログラムのすべての仕様を含む JSON ファイルであり、Anchor プログラムとの連携に必要な情報がすべて含まれています。Anchor は、そのフレームワークを使ってプログラムを開発すると IDL を自動生成します。これは Ethereum の ABI とよく似ています。IDL から Solidity インターフェースを生成するには、solang idl [-output directory] [IDL file] コマンドを使用します。その後、import “...”; 構文でファイルをインポートできます。

Solang は、Solidity コントラクトが Solana 固有の命令と連携するための一連のライブラリである Solana ライブラリを提供しています。トークンの mint、burn、転送には、SPL Token ライブラリを利用できます。ERC-20 および ERC-721 に相当するものと考えられます。また、開発者が Solana の System Program と連携できるよう、System Instructions ライブラリも提供しています。

Solang には、solana でインポートできる組み込み機能もあります。これには AccountMeta 構造体と AccountInfo 構造体が含まれます。AccountMeta 構造体は、外部呼び出し(CPI など)で呼び出し先に渡すアカウントを指定するために使用します。AccountMeta 構造体は次の構造です。

  • pubkey:アカウントのアドレスまたは公開鍵です。型は address です
  • is_writable:呼び出し先がこのアカウントに書き込めるかどうかを示します。型は bool です
  • is_signer:呼び出し先が、このアカウントがトランザクションに署名したとみなせるかどうかを示します。型は bool です

外部呼び出しで accounts 引数を省略すると、Solang コンパイラは AccountMeta 配列を自動生成します。これは、関数が external として宣言されている場合にのみ機能します。そうでない場合は、IDL で指定されたアカウントの順序に従って AccountMeta 配列を手動で作成する必要があります。特定の呼び出しでアカウントが不要な場合は、空のベクター {accounts: []} を渡します。Solang のドキュメントには、AccountMetas 配列の構築方法を示す優れた例があります。

コード
function build_this() external {
	// When calling a constructor from an external function, the data account for the contract
	// 'BeingBuilt' should be passed as the 'BeingBuilt_dataAccount' in the client code.
	BeingBuilt.new("my_seed");
}

function build_that(address data_account, address payer_account) public {
	AccountMeta[3] metas = [
		AccountMeta({
			pubkey: data_account,
      is_signer: true,
      is_writable: true
		}),
    AccountMeta({
    	pubkey: payer_account,
      is_signer: true,
      is_writable: true
    }),
    AccountMeta({
      pubkey: address"11111111111111111111111111111111",
      is_writable: false,
      is_signer: false
    })
  ];
  BeingBuilt.new{accounts: metas}("my_seed");

	// No accounts are needed in this call, so we pass an empty vector.
	BeingBuilt.say_this{accounts: []}("It's summertime!");
}

Solang には、次の処理を行う組み込み関数もあります。

Solang は、EVM 開発者の移行を容易にする豊富なツールセットを備えたコンパイラを提供し、Solana と Ethereum の隔たりを埋めます。制限はあるものの、Anchor プログラムとの連携、Solana 固有ライブラリへのアクセス、組み込み関数など、開発者体験を向上させる複数の機能を備えています。IDL やトークン標準といった馴染みのある概念を統合することで、学習曲線もさらに緩やかになります。gas を気にしたり最適化したりする必要がない点も歓迎すべき利点です。Solang は、Solana と Ethereum の相互運用性に向けた重要な一歩です。高いパフォーマンスを誇る Solana の世界へ進出したい EVM 開発者にとって、Solang は有力なツールとなり得ます。

Neon EVM

Solana 上で構築したい Solidity 開発者にとって、選択肢は Solang だけではありません。Neon EVM は、世界初の並列化可能な EVM を標榜しています。これは Solana 上に構築された、Ethereum と完全互換の環境です。Ethereum dApp を開発者にとって使いやすい方法で Solana 上にスケールさせたい場合に、相乗効果を生むソリューションです。開発者は、使い慣れた言語で記述したスマートコントラクトを再構成せず、使い慣れたツールを使って dApp をデプロイできます。

アーキテクチャ

Neon EVM は、Neon EVM プログラム、Neon Proxy、Neon DAO という3つの主要コンポーネントで構成されています。

Neon EVM は、Ethereum のようなトランザクションを受け取り、EVM のルールに従って Solana 上で処理する Solana プログラムです。Neon EVM に送られるこれらの Ethereum のようなトランザクションは、Neon Transactions と呼ばれます。これらは Ethereum JSON-RPC API に準拠した JSON RPC メソッドのサブセットです。

Neon Proxy により、Ethereum 開発者は最小限の変更で dApp を Neon に移植できます。EVM トランザクションを Solana トランザクションにまとめ、Neon Operators 向けのコンテナ化されたソリューションとして機能します。これらのオペレーターは Neon Proxy サーバーを運用し、NEON で支払いを受け、Solana エコシステム内では SOL で支払います。NEON はユーティリティトークンであると同時にガバナンストークンでもあります。Neon Operators はトランザクション実行に必要な gas 手数料を支払うために NEON を受け取り、所有者は Neon DAO に参加できます。

Neon DAO は、Neon EVM に関する意思決定で NEON トークン保有者に権限を与えるために設計された、コミュニティ主導のガバナンスモデルです。ユーザー、オペレーター、コントリビューター、コア開発者、アプリケーション開発者で構成され、ガバナンスルールとプロトコルの進化について共同で審議します。DAO は、エコシステム、開発、セキュリティに焦点を当てたさまざまな分散型会議を通じて運営されます。各会議では、それぞれの領域について共同で意思決定し、提案を審査します。エコシステム中心の会議は、助成金や取り組みの資金を管理し、エコシステムの持続可能な成長を監督します。開発中心の会議は、Neon プログラムの技術的アップグレードと緊急対応を担当します。セキュリティ中心の会議は、潜在的な脅威から Neon のトレジャリーと Neon プログラムを保護します。

EVM 互換性

Neon EVM は、次の方法で Solana 上の EVM 連携を実現します。

  • Ethereum の JSON-RPC API メソッドの大部分を実装する
  • Ethereum の呼び出しを処理する専用 Proxy を使用する
  • Solana のアーキテクチャによる相違点と制限に適応する

Neon EVM との連携は、ほかの EVM を使用する場合と似ています。開発者は Neon Proxy に対して使い慣れた RPC API メソッドを使用でき、シームレスな開発者体験を得られます。主な機能は次のとおりです。

  • Solidity および Vyper スマートコントラクトに対応し、Metamask、Foundry、Remix などの標準的な Ethereum 開発ツールも利用可能
  • Ethereum Opcode の大部分をそのままサポート
  • タイプ 0/レガシー Ethereum トランザクションリクエストを受け付けます。EIP-1559 トランザクションは現在サポートされていません

もちろん、Neon EVM を Solana 上で正しく動作させるには、いくつかの調整が必要です。主な相違点は次のとおりです。

  • Neon EVM は evm.code で定義されたすべてのプリコンパイル済みコントラクトをサポートします。ただし、bigModExp、bn256Add、bn256ScalarMult、bn256Pairing の呼び出しを含む Solidity コントラクトは実行されません。Neon EVM が将来これらのコントラクトをサポートするには、Solana システムコールの実装が必要です
  • 大部分の opcode はそのままサポートされますが、COINBASE、PREVRANDAO (FKA DIFFICULTY)、GASLIMIT、BASEFEE、GAS はサポートされません。これらはバリアント opcodeと呼ばれ、Neon EVM で使用できるよう調整されています。
  • gas 消費量と手数料の計算は Ethereum と異なります。Solana が決済レイヤーとして機能するため、一般にコストは低くなります
  • gas 計算が異なるため、Solidity の transfer() メソッドと send() メソッドは、Neon EVM ではリエントランシーに対して安全ではありません
  • Solana のアカウントモデルはスマートコントラクトのストレージに影響し、実行可能アカウントと実行不可能アカウントではストレージ機能とアクセス権限が異なります
  • Neon EVM はバージョン付きトランザクションを使用するため、単一トランザクションで使用できるアカウントの最大数は64に制限されます
  • Neon EVM は Solana の Berkley Packet Filter(BPF)を使用し、ヒープメモリの上限は 256 KB です。これによりコントラクト呼び出しのサイズが制限され、メモリ使用量を効果的に管理するための最適化戦略が必要になります
  • block.number や block.timestamp など、時間に基づく関数は動作が異なります。Neon EVM での開発時には、これらを使用しないよう強く注意が促されています

Neon EVM は使い慣れた互換性のある環境を提供しますが、EVM 開発者が Solana への移行と開発を成功させるには、主な相違点を把握して適応する必要があります。

Neon RPC への接続

開発者は Chainlist を使用して、Neon RPC に簡単に接続できます。ここでは、Neon EVM Mainnet または Devnet に接続できます。Mainnet または Devnet のモーダルで ウォレットを接続 をクリックし、ウォレットが表示されたら 承認 をクリックします。

Neon EVM にトランザクションを送信する前に、最適なオペレーターを選択してください。カードの詳細を展開すると、各ネットワークで利用可能な RPC エンドポイントを確認できます。

ウォレット接続時に提示されるデフォルトとは異なるオペレーターを選ぶ場合は、手動で接続する必要があります。Neon EVM のドキュメントには、Foundry、Hardhat、Remix、Truffle を使用して Proxy に接続するための詳細なガイドがあります。デプロイのセクションでは、Foundry を使った接続方法を説明します。

接続後、開発者は Neon Faucet を使用して NEON またはほかの ERC-20 テストトークンを取得できます。request_neon エンドポイントを使用し、プログラムからトークンをリクエストすることもできます。

コード
curl -i -X POST \
	-d '{"wallet": "Your wallet", "amount": 1}' \
	'http://localhost:3333/request_neon'

このコマンドは POST リクエストを送信し、指定したウォレットアドレスでトークンを受け取ります。

トランザクションのライフサイクルと gas 手数料

Neon EVM を介して Ethereum dApp のトランザクションを Solana 上で実行するには、主に3つのステップがあります。

  • ユーザーが Neon RPC エンドポイントに向けて、署名済みの Ethereum のようなトランザクションを開始します
  • トランザクションは Ethereum API を介して Neon Proxy に渡されます。Proxy はトランザクション実行に必要な gas を見積もり、Ethereum のようなトランザクションを Solana トランザクションでラップしてブロードキャストを開始し、ラップ済みトランザクションを Neon EVM に送信します。その結果、Solana のレシートと、それに対応する Neon EVM のトランザクションレシートが生成されます。Neon スマートコントラクトはトランザクションをアンラップし、ユーザーの署名を検証して、Solana ストレージから EVM の状態を読み込みます。トランザクションは Solana の BPF 内で実行されます
  • Solana と Neon EVM がそれぞれの状態を更新し、トランザクションリクエストを完了します

これが、Neon EVM における開始から実行までのトランザクションのライフサイクル全体です。開発者は NeonScan にアクセスして最新のトランザクションとブロックを確認し、アカウント、トークン、ブロック、トランザクションハッシュを照会できます。

開発者は gas 不要のトランザクションも送信できます。これは、最初のトランザクション手数料を賄うだけの NEON トークンを持たないユーザーを支援するために実装されました。開発者は info@neonevm.org に連絡することで、gas 不要トランザクションのスターターパックを取得できます。これらのトランザクションも開発者が選んだ Proxy Operator によって処理されますが、トランザクション費用は Neon が負担します。通常、新しい Neon アカウントごとに最低3件の gas 不要トランザクションが提供されます。

gas 不要トランザクションの流れは次のとおりです。

  • エンドユーザーが dApp を介してトランザクションを開始します
  • dApp が、選択した Proxy Operator に現在の gas 価格をリクエストします。対象となる場合、Proxy Operator は指定された件数の gas 不要トランザクションを Neon アカウントに設定します
  • それらのトランザクションでは、dApp に表示される gas コストがゼロになります
  • エンドユーザーは gas 手数料なしでトランザクションに署名します
  • Proxy Operator がトランザクションを実行し、SOL の gas 手数料は Neon Foundation が支払います

Neon EVM のドキュメントでは、gas 不要トランザクションをリクエストする方法として次の抜粋を示しています。

コード
try {
	// Get gasless transaction if user account is eligible
  const rawGasPrice = await axios.post(rpcApiUrl, {
  	method: 'neon_gasPrice',
    params: [{ from: address }],
    jsonrpc: "2.0",
    id: new Date().getTime()
   })

   tx.gasPrice = rawGasPrice.data?.result;
	} catch (e) {
  	//Else, get standard GAS price
   	setError('Can\'t retrieve gas price for transaction')

    const rawGasPrice = await web3.eth.getGasPrice();

    tx.gasPrice = web3.utils.toHex(rawGasPrice);
} finally {
    setTx(tx)
}

NeonPass

NeonPass は、Solana と Neon EVM の間でトークンを転送するためのツールです。Solana の Associated Token Accounts と Neon EVM の ERC-20 トークンアカウントの間で、資産をシームレスに転送できます。NeonPass は、Neon EVM のインターフェースコントラクトと専用のアカウントストレージを使用します。Solana Program Library(SPL)トークンは、Neon EVM のファクトリーコントラクト内で ERC-20 インターフェースにパッケージ化されます。これにより、SPL を Solidity dApp と互換性のある ERC-20 トークンアカウントに保存できます。NeonPass は、Solana と Neon EVM のアカウント間でトークンを双方向に転送できます。資産をロックして新しい資産を mint する従来のブリッジとは異なり、2つのアカウントタイプ間でトークンを直接移動します。これにより、Solana と Neon EVM のトークンをシームレスに移行できます。

デプロイ

開発者は、Hardhat、Foundry、Truffle、Remix を使用して Neon EVM にデプロイできます。Solang を使用する最も簡単な方法は Anchor を経由することであるため、テストはすべて TypeScript で行われます。しかし、Solidity を愛用する開発者も、ついに Foundry を介して Solidity dApp を Solana でテストし、デプロイできるようになりました。

まず、EVM 互換ウォレットが Neon EVM Devnet に接続されていることを確認します。次に、Neon の Foundry サンプルプロジェクトをクローンし、そのディレクトリに移動します。

コード
git clone https://github.com/neonlabsorg/neon-tutorials
cd neon-tutorials/foundry

次に、Foundry ツールチェーンのインストーラーである Foundryup をインストールし、foundryup を実行して最新の nightly プリコンパイル済みバイナリ(force、cast、anvil、chisel)をインストールします。

コード
curl -L https://foundry.paradigm.xyz | bash
foundryup

必要なライブラリをインストールします。

コード
forge install foundry-rs/forge-std --no-commit
forge install openzeppelin/openzeppelin-contracts --no-commit

次に、ウォレットアカウントの秘密鍵を取得します。たとえば Metamask では、ハンバーガーメニューをクリックして Account Details > Show Private Key に移動すると、秘密鍵を確認できます。パスワードの入力を求められます。確認 をクリックして、アカウントの秘密鍵にアクセスします。この鍵を誰にも共有せず、保護に必要な対策を講じてください。

次に、以下の変数を含む .env ファイルを作成します。

コード
RPC_URL_DEVNET=https://devnet.neonevm.org
CHAIN_ID_DEVNET=245022926
RPC_URL_MAINNET=https://neon-proxy-mainnet.solana.p2p.org
CHAIN_ID_MAINNET=245022934
PRIVATE_KEY=
VERIFIER_URL_BLOCKSCOUT=https://neon-devnet.blockscout.com/api

<YOUR_PRIVATE_KEY> を秘密鍵に置き換え、source .env を実行します。

プロジェクトのコントラクトをコンパイルするには、src ディレクトリに移動して forge build を実行します。コンソールには、コンパイラの実行が成功したことが表示されます。forge test コマンドでコントラクトをテストすることもできます。プロジェクトのコントラクトをデプロイするには、次のコマンドを実行します。

コード
forge create --rpc-url $RPC_URL_DEVNET --private-key $PRIVATE_KEY src/TestERC20/TestERC20.sol:TestERC20 --constructor-args "Test ERC20 Token" "TERC20" --legacy

次のような出力が表示されます。

コード
[⠰] Compiling...
No files changed, compilation skipped
Deployer: 0x4455E84Eaa56a01676365D4f86348B311969a4f4
Deployed to: 0x5537599aa2F97Dd60a66342522a465A7f2e40Ff9
Transaction hash: 0x6de9dab8a526cbac33008056d185b93dff725605efb791bf116b6bece4f0c486

コントラクトを検証するには、次のコマンドを実行します。

コード
forge verify-contract --chain-id $CHAIN_ID_DEVNET  src/TestERC20/TestERC20.sol:TestERC20 --verifier-url $VERIFIER_URL_BLOCKSCOUT --verifier blockscout

<contract_address> をスマートコントラクトのアドレスに置き換えます。Neon の Devnet エクスプローラーである BlockScout 上のコントラクトアドレスを示す URL とともに、OK レスポンスが返されます。.env ファイルを構成し、BlockScout の代わりに Devnet にも対応している NeonScan を使用することもできます。

利点と制限事項

Ethereum と同様の開発者体験を求める開発者には、Neon EVM が適しています。これは、Ethereum のようなトランザクションを送信し、使い慣れたツールを利用できる EVM 互換環境です。NeonPass、EVM opcode の大部分のサポート、gas 不要トランザクションの提供といった機能により、Solana への移行が大幅に容易になります。ただし、Neon EVM も完璧ではありません。Solana のインフラストラクチャに適応するためのスマートコントラクトロジックの変更、Solana の Berkeley Packet Filter(BFP)とアカウントモデルによる制約、特定の opcode とプリコンパイル済みコントラクトに関する制限などがあります。EVM 互換環境から Solana へのデプロイを成功させるには、こうした違いを理解し、適切に対処することが不可欠です。

過去の移行事例

大規模なEthereumプロトコルを非EVMチェーンにデプロイするには、複雑な作業をいくつも完了させる必要があります。具体的には、Solidity以外のエンジニアを確保してコードベースをゼロから再構築し、信頼できる監査パートナーを見つけ、新しいコードベースを再監査し、DAOの決定を強制できるようガバナンスコントラクトを適応させなければなりません。これらには数百万ドルの費用がかかり、数か月にわたる集中的な作業が必要になる可能性があります。ほとんどのプロジェクトにとって現実的ではありません。しかし、過去には実現した事例があります。

Heliumは、モノのインターネット(IoT)デバイスを支える分散型ワイヤレスインフラの構築を目指すLoRaWANネットワークです。これは、長距離でほかのホットスポットに接続する小型基地局のような、低消費電力の小型デバイスであるホットスポットを使用して実現されます。当初は独自のLayer 1(L1)ブロックチェーン上で運用されていましたが、Heliumの開発チームはHIP 70でSolanaへの移行を提案しました。これにより、高水準のセキュリティと低い利用コストを維持しながら、Heliumの稼働率、コンポーザビリティ、ユーザー体験の速度を向上できます。コミュニティは圧倒的多数で提案に賛成し、Heliumは2023年4月にSolanaへ移行しました。HeliumのCOOであるScott Sigel氏は、この移行を退屈なほど平穏な出来事だったと表現しています。ネットワークにもHeliumのインフラにも問題は起きませんでした。エンジニアにとって理想的な移行でした。チームは、ドキュメント内の一連のガイドで移行プロセス全体も解説しています。Heliumの移行は大きな成功を収め、コミュニティに多大なメリットをもたらしました。

この移行は特殊な事例ではありません。世界初の分散型GPUレンダリングプラットフォームであるThe Render Networkも、2023年11月にコアインフラをEthereumからSolanaへ移行するアップグレードに成功しました。コミュニティは、Solanaへ移行するRNP-002に賛成票を投じました。Renderの創設者であるJules Urbach氏は、この移行を画期的な転換点と表現しました。同氏は次のように述べています。「Solanaの驚異的なトランザクション速度、低コスト、Webスケールアーキテクチャへの取り組みは、スケーラブルで分散型のメタバースインフラを構築し続けるRender Networkに最適です」

Renderの移行がユーザーに大きな悪影響を及ぼすことはありませんでした。ユーザーはRenderのUpgrade Assistantを使用して、EthereumからSolanaへ資金をブリッジできます。Ethereumウォレットを接続し、移行するRNDRの数量を指定したうえで、指定したSolanaウォレットにトークンが送付されるのを待つだけです。

Makerは、Ethereumを代表するプロジェクトです。経済的な自立を促進し、世界の金融市場への公平なアクセスを実現するために設計された包括的なプラットフォーム、Maker Platformを通じて、分散型金融の可能性を解き放つことを目指しています。このプラットフォームは、Makerプロジェクトを管理するMakerDAOと、「世界初の偏りのない通貨であり、代表的な分散型ステーブルコイン」であるDAIのためのMakerプロトコルで構成されています。Makerの創設者であるRune Christensen氏は、SolanaのコードベースをフォークしてMakerのアプリチェーンを開発する案について投稿しました。

移行は本質的に複雑です。プロジェクトのインフラ全体をEthereumからSolanaへ移行するには、金銭面、評判面、時間面でコストがかかるにもかかわらず、プロジェクトはSolanaを選んでいます。SolangやNeon EVMなどのツールを使えば、移行は必ずしも複雑である必要はありません。Heliumの移行のように退屈なほど平穏に進められます。また、Render Networkのようにユーザーの資金への悪影響をほとんど、あるいはまったく生じさせずに済みます。SolanaはWebスケール向けに構築された、市場で最も高性能なブロックチェーンです。構築するならここです。そのことに気づくプロジェクトは増え続けています。

まとめ

Solidityはスマートコントラクト開発の共通語です。EVMは登場以来、スマートコントラクト環境の主流であり続けています。しかし、弱点もあります。Webスケールのコンシューマー向けアプリケーションを運用するには、高スループットかつ低レイテンシのネットワークが必要です。Ethereumのシングルスレッドで変動の大きいガスベースの環境では、Heliumのような高スループットの分散型物理インフラネットワーク(DePIN)プロジェクトを支えられません。

こうした課題に対し、Solanaは強力な選択肢となります。Solanaの真のメリットを最大限に活かす最善の方法は、実際にSolana上で構築することです。最近の進展により、SolangやNeon EVMなどのツールを使えば、EVM開発者は使い慣れたツールと言語で移行できます。この記事では、Solanaのアーキテクチャ、Ethereumとの比較、EVM開発者がSolanaで開発を始める方法を包括的に解説しました。Solanaは市場で最も高性能なブロックチェーンです。勢いと注目を集め、信頼性の高いコンシューマー向けアプリケーションも増えています。高速でスケーラブルなブロックチェーンのメリットを今すぐ享受できるのに、なぜEthereumのスケーリングを待つ必要があるのでしょうか。

ここまで読んでくださり、ありがとうございます!Solanaの最新情報を見逃さないよう、下にメールアドレスを入力してください。さらに詳しく知りたいですか?今すぐ私たちのDiscordに参加し、最も高性能なブロックチェーン上で未来を構築しましょう。

関連リソース

Heliusを購読

Solana開発の最新情報や新しい記事の公開通知を受け取れます

拡大画像