Challenge UNCHAIN vol.7 – ETH-dApp完了 –

さて、LEARNの第1回「ETH-dApp」のラストSection 4!

No Title

Learn / ETH-dApp このプロジェクトでは、イーサリアムネットワーク上にスマートコントラクトを実装して、スマートコントラクトとやりとりできる独自のWebアプリケーションを構築します。 プロジェクトを進めるには以下の技術が必要です。 いますべてを理解している必要はありません。 …

Lesson 1. 抽選機能を追加

抽選機能

    uint256 private seed;

コントラクトのprivate変数にseedを持たる

        seed = (block.timestamp + block.difficulty) % 100;

コンストラクタ内で初期化。

waveファンクション内でseedが50以下(100で割ってるから・・・51%かな)であれば送金しないというロジックに。

    seed = (block.difficulty + block.timestamp + seed) % 100;
    console.log("Random # generated: %d", seed);
    if (seed <= 50) {
      console.log("%s did not win.", msg.sender);
      return;
    }

seedの生成には、ハッカーからの攻撃を防ぐためにも、ランダム性を強化することで対処する。

そもそもコードはブロックチェーン上に公開されてしまうので、信頼できる乱数生成のアルゴリズムを作ることが重要。


3回目でやっと勝てたので、残高が変わったのがわかる

$ npx hardhat run scripts/run.js 
Compiled 1 Solidity file successfully
Wave Portal ver 0.1.3 with lottery.
Contract deployed to: xxxxx
Contract balance: 0.1
We have 0 total waves!
xxxxx waved w/ message The 1st messsage!
Random # generated: 48
xxxxx did not win.
Contract balance: 0.1
We have 1 total waves!
xxxxx waved w/ message The 2nd message!!
Random # generated: 27
xxxxx did not win.
Contract balance: 0.1
We have 2 total waves!
xxxxx waved w/ message The 3rd message!!!
Random # generated: 83
xxxxx won.
Contract balance: 0.0999
We have 3 total waves!
[
  [
    'xxxxx',
    'The 1st messsage!',
    BigNumber { value: "1673445731" },
    waver: 'xxxxx',
    msg: 'The 1st messsage!',
    timestamp: BigNumber { value: "1673445731" }
  ],
  [
    'xxxxx',
    'The 2nd message!!',
    BigNumber { value: "1673445732" },
    waver: 'xxxxx',
    msg: 'The 2nd message!!',
    timestamp: BigNumber { value: "1673445732" }
  ],
  [
    'xxxxx',
    'The 3rd message!!!',
    BigNumber { value: "1673445733" },
    waver: 'xxxxx',
    msg: 'The 3rd message!!!',
    timestamp: BigNumber { value: "1673445733" }
  ]
]

クールダウン機能を追加

    mapping(address => uint256) public lastWavedAt;

mappingを使って、ハッシュテーブルのような形で最終抽選日をアドレスごとに持たせる。

※本物のハッカーは、アドレス分散させて攻撃してきそうだけど、、、

        require(
            lastWavedAt[msg.sender] + 15 minutes < block.timestamp,
            "Wait 15m"
        );

waveの一番最初にチェックを記載。

15分経ってない場合は、15分待てというエラー。

$ npx hardhat run scripts/run.js 
Wave Portal ver 0.1.3 with lottery.
Contract deployed to: xxxxx
Contract balance: 0.1
We have 0 total waves!
xxxxx waved w/ message The 1st messsage!
Random # generated: 88
xxxxx won.
Contract balance: 0.0999
We have 1 total waves!
xxxxx waved w/ message The 2nd message!!
Random # generated: 87
xxxxx won.
Contract balance: 0.0998
We have 2 total waves!
xxxxx waved w/ message The 3rd message!!!
Random # generated: 63
xxxxx won.
Contract balance: 0.0997
We have 3 total waves!
Error: VM Exception while processing transaction: reverted with reason string 'Wait 15m'
    at WavePortal.wave (contracts/WavePortal.sol:29)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at runNextTicks (node:internal/process/task_queues:65:3)
    at listOnTimeout (node:internal/timers:528:9)
    at processTimers (node:internal/timers:502:7)
    at HardhatNode._mineBlockWithPendingTxs (/home/ec2-user/environment/ETH-dApp/my-wave-portal/node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:1815:23)
    at HardhatNode.mineBlock (/home/ec2-user/environment/ETH-dApp/my-wave-portal/node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:504:16)
    at EthModule._sendTransactionAndReturnHash (/home/ec2-user/environment/ETH-dApp/my-wave-portal/node_modules/hardhat/src/internal/hardhat-network/provider/modules/eth.ts:1522:18)
[
  [
    'xxxxx',
    'The 1st messsage!',
    BigNumber { value: "1673445851" },
    waver: 'xxxxx',
    msg: 'The 1st messsage!',
    timestamp: BigNumber { value: "1673445851" }
  ],
  [
    'xxxxx',
    'The 2nd message!!',
    BigNumber { value: "1673445852" },
    waver: 'xxxxx',
    msg: 'The 2nd message!!',
    timestamp: BigNumber { value: "1673445852" }
  ],
  [
    'xxxxx',
    'The 3rd message!!!',
    BigNumber { value: "1673445853" },
    waver: 'xxxxx',
    msg: 'The 3rd message!!!',
    timestamp: BigNumber { value: "1673445853" }
  ]
]

「Wait 15m」エラーが出ているのを確認。

ここは3回目のメッセージを送ったアドレスを使って再度waveを呼び出し、try/catchでエラーだけ出力してみた。

ということで、Lesson 1は終了。

Lesson 2. UI改善とサーバホスティング

UI改善

UI改善については、そこまで本気になる必要は無いので、自社サイトに寄せてこんな感じにして完了。

サーバホスティング

Vercelというサービスを使うと良いとのこと。

Vercel: Develop. Preview. Ship. For the best frontend teams

Vercel is the platform for frontend developers, providing the speed and reliability innovators need to create at the moment of inspiration. Build when inspiration strikes Free developers from time-consuming, unnecessary processes that slow your work, so you and your team can focus on creating.

Vercel is the platform for frontend developers, providing the speed and reliability innovators need to create at the moment of inspiration.

Vercelはフロントエンド開発者のためのプラットフォームで、スピードと信頼性を提供することで、すぐに創れるようになると。

どんな機能かはわからないけど、、、一旦サインアップ完了。

で、まずは、ここで一旦GitHubに一通りプッシュします。

※当然、プライベートキーとかの重要な情報には注意して・・・

Dashboardから「Add New…」>「Project」を選択。

Git Repositoryを選択してDeploy。

あら・・・エラーだ。。。

色々検索した結果、そもそものNode.jsのバージョンが違っていた模様。

ProjectのSettings>GeneralのNode.js Versionを16.xにして再実行することでエラー解消。

まさか無料でドメインは変えられないよな、と思って試してみたら簡単にできるようで・・・

すごいなこのサービスは。

Create your first dApp.

Solidity + Alchemy + React.js + Vercelを利用したWave Portal。

faviconとか変えてみたけど、og:imageとかはそのままだったので、こんな感じで出てしまったけど、ま、いいか。

ということで、最初のコンテンツは完了!!!

あ、これでNFTがもらえるかな????