⛓️

Decentralized Applications (DApps)

2024/03/28に公開

Introduction

Mastering EthereumDecentralized Applications (DApps)を読んでいた際、オークションDAppのソースコード(auction_dapp)が古く、そのままでは動かなかったので、コードのアップデートやリファクタリングを行った。

本記事は2024/03時点のメモ。Swarm/Whisperの挙動は検討中。

環境の前提として、以下記事参照。
https://zenn.dev/conny/articles/213934adf8ea03

Challenge

  • Swarm/Whisperへのエンドポイントに依存した実装になっている。
  • 単一障害点となる可能性があるので、より完全な非中央集権化されたアプリケーションにしたい。

Development

Backend

特に修正不要だった。

version
$ truffle version
Truffle v5.11.5 (core: 5.11.5)
Ganache v7.9.1
Solidity v0.5.16 (solc-js)
Node v18.3.0
Web3.js v1.10.0
compile
$ truffle compile

Compiling your contracts...
===========================
> Compiling ./contracts/AuctionRepository.sol
> Compiling ./contracts/DeedRepository.sol
> Compiling ./contracts/ERC721/DeprecatedERC721.sol
> Compiling ./contracts/ERC721/ERC721.sol
> Compiling ./contracts/ERC721/ERC721Basic.sol
> Compiling ./contracts/ERC721/ERC721BasicToken.sol
> Compiling ./contracts/ERC721/ERC721Holder.sol
> Compiling ./contracts/ERC721/ERC721Receiver.sol
> Compiling ./contracts/ERC721/ERC721Token.sol
> Compiling ./contracts/Migrations.sol
> Compiling ./contracts/utils/AddressUtils.sol
> Compiling ./contracts/utils/math/Math.sol
> Compiling ./contracts/utils/math/SafeMath.sol
> Artifacts written to /Users/yuichirokondo/Workspace/Web3/auction_dapp/backend/build/contracts
> Compiled successfully using:
   - solc: 0.5.16+commit.9c3226ce.Emscripten.clang
migrate
$ truffle migrate --network ganache

Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.


Starting migrations...
======================
> Network name:    'ganache'
> Network id:      5777
> Block gas limit: 6721975 (0x6691b7)


1_initial_migration.js
======================

   Deploying 'Migrations'
   ----------------------
   > transaction hash:    0x7036c2139553229612302089c4755730ce624a36e69596a6b7ac0d14cc8eea9d
   > Blocks: 0            Seconds: 0
   > contract address:    0x1D81C57FD8f33C36E246Cf13D7Af29b54dd06a7C
   > block number:        1
   > block timestamp:     1709882400
   > account:             0x633592b50220e1E87b106BfBF3A45F4D9157E7DA
   > balance:             99.999235437625
   > gas used:            226537 (0x374e9)
   > gas price:           3.375 gwei
   > value sent:          0 ETH
   > total cost:          0.000764562375 ETH

   > Saving migration to chain.
   > Saving artifacts
   -------------------------------------
   > Total cost:      0.000764562375 ETH


2_deploy_contracts.js
=====================

   Deploying 'AuctionRepository'
   -----------------------------
   > transaction hash:    0xd51654619cab51a67a1d998dbbbb7ea5eda1161a8b44a9ce306ad82fbb0c90ab
   > Blocks: 0            Seconds: 0
   > contract address:    0x29a412B146aAe61A0256707065cb94Bd4fcC6c8b
   > block number:        3
   > block timestamp:     1709882400
   > account:             0x633592b50220e1E87b106BfBF3A45F4D9157E7DA
   > balance:             99.992158969101747614
   > gas used:            2179788 (0x2142cc)
   > gas price:           3.177688086 gwei
   > value sent:          0 ETH
   > total cost:          0.006926686357605768 ETH


   Deploying 'DeedRepository'
   --------------------------
   > transaction hash:    0x0cf04f8cf287f551f3dff93f3abff49547503f6c9941ef80f11a72823664ad1f
   > Blocks: 0            Seconds: 0
   > contract address:    0xC3daB6B7c84b0342607D5904b7214b7F1E3DAad6
   > block number:        4
   > block timestamp:     1709882400
   > account:             0x633592b50220e1E87b106BfBF3A45F4D9157E7DA
   > balance:             99.986355183038938641
   > gas used:            1843691 (0x1c21eb)
   > gas price:           3.147916903 gwei
   > value sent:          0 ETH
   > total cost:          0.005803786062808973 ETH

   > Saving migration to chain.
   > Saving artifacts
   -------------------------------------
   > Total cost:     0.012730472420414741 ETH

Summary
=======
> Total deployments:   3
> Final cost:          0.013495034795414741 ETH

Frontend

MetaMaskは2021年頃web3オブジェクトではなくwindow.ethereumオブジェクトを提供するようになったらしいので[1]、その修正。
https://github.com/Connie18/auction_dapp/blob/main/frontend/src/main.js

それに伴い、その他細かい修正。
例えば、fromWeiutils.fromWeiに修正など。

Content Delivery

Fleek

バックエンド側でtruffleでコンパイルしたコントラクトのjsonを動的にフロントエンド側にコピーできる仕組みを導入することで、Fleekにおけるデプロイを可能にしている。(今回はとりあえずshx cpを使っているが、本来はGulp的なものに統合した方がいいかもしれない。)
https://github.com/Connie18/auction_dapp/blob/main/frontend/package.json#L10-L14

Image Upload

Swarmじゃなくて、IPFSにしてみるのもありかも。
js-ipfsとか使えばユーザのブラウザ側で画像をアップロードできそう。その場合ゲートウェイが不要となる。

https://github.com/ipfs/js-ipfs/

Result

IPFS上に展開されている。

https://solitary-limit-4701.on.fleek.co/

Discussion

Backend

DEEDREPOSITORY_ADDRESSAUCTIONREPOSITORY_ADDRESSさえ変更すれば、WalletでBackend(ブロックチェーン)を切り替えられる。例えば、MetaMaskでネットワークを切り替えて、ローカルでGanacheを起動していればそれを使えるし、EthereumのTestnetやMainnetを使うこともできる。

DAppにおいてバックエンドを意味するブロックチェーンを切り替えることができるように設計することは、いくつかの利点がある。

  1. ブロックチェーンの選択肢: 複数のブロックチェーン間での移行を可能にすることで、異なるネットワークの特徴(例えば、トランザクションコスト、速度、コミュニティのサポートなど)を活用できる。

  2. 将来の柔軟性: 技術の進化に伴い、新しいブロックチェーンが現れた場合や、より良いソリューションが利用可能になった場合に、容易に移行できる。

  3. 冗長性と耐障害性: もし一つのブロックチェーンに問題が生じた場合に、別のブロックチェーンにスムーズに切り替えることで、アプリケーションの稼働を継続できる。

スマートコントラクトのアドレスを外部から与えることができれば、異なるブロックチェーン環境や異なるスマートコントラクトのインスタンスに接続する柔軟性を持たせることができ、これは特に以下のような場合に有効であると考えられる。

  • 開発、テスト、本番環境を分けて管理したい場合。
  • ユーザーが自由に異なるブロックチェーンネットワークを選択できるようにしたい場合。
  • プロジェクトがブロックチェーンのアップグレードやマイグレーションを計画している場合。

ただし、このような設計を採用する際には、異なるブロックチェーン間でのインターフェイスの互換性、セキュリティ対策、データ整合性の保持などの追加的な考慮が必要となる。設計の複雑さが増すため、プロジェクトの要件やリソースに応じて、このアプローチが最適かどうかを判断する必要がある。

DApps

Auction DAppも一見、ほぼ完全に非中央集権化されたアプリケーションに見えるが、実際に使うことを考えると、以下のように中央集権的なシステムに依存する分が出てくる。

  • Wallet
    • ブロックチェーン接続時にInfuraのようなゲートウェイが必要。
  • 名前解決
    • IPNS
      • IPFSだけだとどうしてもユーザビリティが低いので、ユーザーフレンドリーな名前を使えるようにしたい。ただ、その場合、DNSLinkが必要となり、DNSに依存してしまう。
      • FleekもIPFS上にコンテンツをデリバリした場合、自動でIPNSが設定されるっぽい。
    • ENS
      • .ethドメインにアクセスする際にスマートコントラクトが必要なので、フルノードが必要になる。ただ、全てのユーザがフルノードを持つのは厳しいので、Infuraのようなゲートウェイが必要になってしまう。

ユーザビリティを優先すると、どのような手法を取っても、結局、ゲートウェイやDNSのような中央集権的なシステムに依存してしまう。現状、何か良い方法はないのだろうか。。?

ただ、ユーザビリティを考えると無理に全てを分散型にする必要もないのかもしれない。トレードオフもありそう。
どこかで線引きをするとしたら、ユーザビリティを優先してエンドユーザーがゲートウェイなどを使うのを許容するのはアリ?バックエンドとフロントエンドが分散システムであれば十分かも?

Reference

脚注
  1. No Longer Injecting web3.js ↩︎

Discussion