見出し画像

【完全保存版】6つの観点から考えるイーサリアムとSolanaの違い

ここでは、私が実際にSolanaを触ってみて感じた、イーサリアムとSolanaの違い6つの観点から紹介していきます。

1 スマートコントラクトとプログラム

0 はじめに

Solanaでは「プログラム」という概念があります。

説明する時には、「スマートコントラクトのようなものです。」と説明することが多いです。

でも、結構違うんです。

違いを考えてみましょう。

1 イーサリアムの場合

では仮に、イーサリアムで3つのトークンコントラクトを作ってみましょう。

その場合、こんな感じになります。

似たようなコード(もしくは同じコード)であっても3つともデプロイが必要です。

もちろん、「OpenZeppelin」などのライブラリがあるため、デプロイ自体は簡単です。

ただし、デプロイをする以上、エンジニアはコードに対する責任を持つことになります。(と私は考えます。)

また、「OpenZeppelin」から自分でコードを変更した場合、それが脆弱性がないと言い切るのはとても難しいです。

(「OpenZeppelin」のコードに脆弱性があるかどうかは別の話です。)

2 Solanaの場合(プログラム)

一方、Solanaの場合、トークンを作りたい時にはデプロイは不要です。

なぜならすでに「TokenProgram」というプログラムが存在しているからです。(最新は「Token2022」)

https://spl.solana.com/token

これは、すでにあるコードを複製するという話ではありません。

上のように、すでにあるプログラムに対して、アカウントを作成することでトークンを作成します。

そのため、「トークン」を作る場合には、プログラムを知らなくても作ることができます。

個々のエンジニアが変更することがなく、プログラム自体も監査を受けているため、プログラム自体の安全性が高いと考えられます。

2 コードと値の分離について

1 イーサリアムの場合

イーサリアムの場合、コード同じアカウントに入っています。

(下の場合、「storage hash」が値の部分です。)

https://ethereum.org/ja/developers/docs/accounts/

最も、イーサリアムでは「アップグレーダブル(更新可能)コントラクト」というものも存在します。

この場合は、コードと値が分離されます。

実際は、下のようにそれぞれ別のコントラクトから構成されており、イーサリアムでもコードと値の分離は可能ではあります。

https://note.com/standenglish/n/ne6b09a489f5c

2 Solanaの場合

Solanaの場合はデフォルトとして、コードと値が分離しています。

なお、そのため、デフォルトでアップグレーダブル(更新可能)になります。

もちろん、更新可能でないように設定することも可能です。

https://note.com/standenglish/n/nf08754a6e475

これがあるからこそ、プログラム部分は誰かが作り、監査が完了している安全なものを使うということができます。

そのプログラムに対し、データ用のアカウントをつければ良いからです。

3 アドレスとアカウントの関係

イーサリアムに慣れていると、アドレスとアカウントを混同することがあると思います。

その理由の一つとして、「アドレスはあるけどアカウントがない」という状態が存在しないからだと考えられます。

しかし、Solanaの場合はそれが考えられます。

https://explorer.solana.com/address/RU1aD3Sx71NUWnoXvuVuHG9ifzcxbB3bfCmw9dB1acN/domains?cluster=devnet

1 イーサリアムの場合

そもそもの余談として、イーサリアムには「EOA」「コントラクトアカウント」があります。

EOAはいわゆるウォレットで、コントラクトアカウントはいわゆるスマートコントラクトです。

メタマスクなどで作った方はイメージができると思いますが、EOAはどんどん自由に作れます。

https://note.com/standenglish/n/nc68a1d4b934c

そして、EOAの場合は、「nonce(トランザクションを何回実行した?)」「balance(残高)」を持ちます。

https://note.com/standenglish/n/nc68a1d4b934c

2 Solanaの場合

一方、Solanaの場合は、下のように構成されます。

イーサリアムと違い、この1種類だけです。

「Data」の部分にコードか値のどちらかが入り、コードの場合は「Executable」が「true(Yesの意味)」になります。

https://note.com/standenglish/n/nf08754a6e475

そして、こちらのLamportsSOLの最小単位です。

イーサリアムで言うところのweiに相当します。

そして、ここが大事なところですが、アカウントには「owner(所有者)」があります。

ちなみに、意外なことかもしれませんが、ウォレットの場合、この「owner」はあなたではなく、「System Program」と言うプログラムです。

https://solscan.io/account/RU1aD3Sx71NUWnoXvuVuHG9ifzcxbB3bfCmw9dB1acN?cluster=devnet

そして、所有者があなたではなく、「System Program」なので、アカウントを使用するとき、「レント」と言う賃料を払う必要があります。

(最も、今は一定以上のLamportsを入れておくと、「レント免除」と言う免除の仕組みになっていますが、ここではその内容は省きます。)

そのため、アカウントには、一定以上の「Lamport」を入れる必要があります。

そのため、作ったばかりのアドレスはただの「アドレス」であり、「アカウント」ではありません。

一定数預けることが必要なため、イーサリアムのように、無限にアカウントを作ることができなくなっています。

3’ トークン送付の際の大きな違い

1 イーサリアムの場合

トークン送付の際はこんな感じで送っています。

というよりも、これ以外に何かあるの?という感じですよね。

2 Solanaの場合

Solanaの場合もそうかというと、実は違うんです。

実際はこんな感じになります。

実は、トークンの保存はウォレットではなく、そのミントアカウント用にあたらしいアカウントを作成します。(関連トークンアカウント

そのため、関連トークンアカウント同士で受け取ることになります。

この辺りは、やってみる方がイメージがつくと思うので、ぜひやってみてください。

4 nonce管理とrecetly Blockhash

1 イーサリアムの場合

イーサリアムではnonceでトランザクションの管理を行います。

トランザクションがブロックに含まれると、nonceが1増え、再送処理を防いでくれます。

しかし、nonce管理では、実務上、大きな課題もあります。

例えば、下のnonce:201がいつまで経ってもブロックに取り込まれないとします。

すると、nonce:202以降のトランザクションが進まなくなってしまいます。

ちなみに、実務上ではこの時、同じnonce値で被せて再実行することが多いと思います。

これにより、仮に後から最初のnonce:201のトランザクションが実行された場合も、そのnonceは実行済みなので、適切に失敗します。

2 Solanaの場合

まずは、順序についてです。

Solanaの場合、バリデータの中から、あらかじめ決められたスケジュールに沿って、リーダーが決まっています。

https://solscan.io/validator#leader

トランザクションの順番は、そのリーダーが受信した順番に依存します。

https://note.com/standenglish/n/n765cde148be0

これに、PoHと言う仕組みの事情が加わり、実は、Solanaでは、短期間における順序の正しさは保証されていません。

これはnonceを採用していないことの欠点だと私は思います。

https://note.com/standenglish/n/nb84aff06f075?magazine_key=m4b49800d8ae2

一方、nonce管理をしていないので、「前のnonceが詰まっているから進まない」とならないのはメリットだと思います。

一方、イーサリアムにない良い点として、トランザクション実行時に「Recent Blockhash(最近のブロックハッシュ)」を含めます。

https://note.com/standenglish/n/n132801de0941

そして、トランザクションの有効期限は、この「Recent Blockhash」から「150」ブロックまでとされています。(1〜2分)

これにより、その150先のブロックの後に実行されたトランザクションは、必ず失敗することになります。

https://solana.com/docs/advanced/confirmation

イーサリアムの場合、ブロックに含まれず、だいぶ時間が経ってから実行される場合があります。

実務視点では、これは成功も失敗も決定していない期間が続くことになり、整合性の問題が出てきます。

それが発生しないのは大きなメリットだと考えられます。

5 秘密鍵の存在について

比較するのは若干違いますが、「秘密鍵がない」という観点から、コントラクトアカウントとPDAを比較してみましょう。

1 イーサリアムの場合

イーサリアムの場合、右のように、デプロイを行うアドレスnonce値からアドレスが導かれます。

この過程で、秘密鍵、公開鍵がないので、秘密鍵は存在しません。

https://zenn.dev/alchemystdudent/books/fb780c706e21f1/viewer/338e66

ただ、ここからが私の推測なのですが、たまたま秘密鍵が存在してしまうことはありえないのか?とずっと疑問を持っています。

秘密鍵⇨公開鍵⇨アドレスの順番に決まっていきますが、たまたまそれを満たしてしまう秘密鍵は存在しうるのではと考えています。

もちろん、確率的に無視して構わないので、考慮する必要はないかもですが、私はずっと疑問に思っていました。

2 Solanaの場合

SolanaにはPDA(プログラム派生アドレス)というものがあります。

正確にはアカウントではありませんが、そこは一旦無視します。

これは、秘密鍵がないと、仕組み上言い切ることができます。

PDAはプログラムIDシードという任意の値を使って導かれます。

しかし、それがたまたま、Solanaが使っている楕円曲線である「ED25519」上の値であることがありえます

その場合、秘密鍵が何かはわかりませんが、必ず存在します。

このように、曲線上になってしまった場合には、「bump」という値を使ってずらす仕組みをとっています。

そのため、秘密鍵がないと言い切ることができます。

6 ガス代について

地味な部分ですが、ガス代の計算方法が若干違います。

地味なのですが、Solanaの考えを語る上で良い部分だと思ったので書いていきます。

1 イーサリアムの場合

イーサリアムの場合、トランザクションを実行するときに、このようにGasLimitを設定することがあります。

これで使用するガスの最大量を設定します。

最も設定しないことも多いです。

https://stackoverflow.com/questions/70622074/set-gas-limit-on-contract-method-in-ethers-js

一方、イーサリアムではこれをあまり気にしない場合が多いです。

なぜなら、かかるガス代は上限値ではなく、実際に使用したガス量で決まるからです。

これは納得がいきやすいですね。

https://etherscan.io/tx/0xd6549661661a4ad9d929fd8f160b76aac85fc059f598f366ee7cd82e04e52211

2 Solanaの場合

一方、Solanaの場合、gasLimitに相当するものComputeUnitLimitです。

ここまではだいたい同じです。

https://solana.com/developers/guides/advanced/how-to-request-optimal-compute

でもここからが違います。

実際に消費される手数料は、この「ComputeUnitLimit」が使われます。

つまり、実際に使われた量ではなく、最大値として設定された量が手数料に使われます。

https://note.com/standenglish/n/n8462f010695c

私は最初、これはイーサリアムの方が良いと思いました。

なぜなら、ざるに上限を設定しても、実際に消費されるガス代は使われた分だけだからです。

ただ、今では、ブロックチェーンというエコシステムのことを考えた場合Solanaのやり方の方がいいかもと思うようになりました。

例えば、上のように、実際に使うのが1万くらいであっても、600万を確保されてしまえば、その分他のトランザクションが入らなくなります。

そのため、確保した分は手数料をもらいますというのがSolanaの考えなのではと考えました。

以上が私が印象に残っているイーサリアムとSolanの違いでした。

皆さんの理解の一助になれば幸いです。

サポートをしていただけたらすごく嬉しいです😄 いただけたサポートを励みに、これからもコツコツ頑張っていきます😊