5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

hhattoのひとりアドベントカレンダーAdvent Calendar 2021

Day 16

Nuxt3とdev-kitでDApp開発を始めてみる

Last updated at Posted at 2021-12-16

はじめに

Nuxt3がリリースされたので、@devprotocol/dev-kitと組み合わせて、DApp開発してみます。

環境

MacOSX 11.6 (Intel Mac)
Node.js v14.17.6
nuxt3 3.0.0-27324955.23397e6 (latest指定)
@devprotocol/dev-kit 5.9.0
ethers 5.5.2

開発

インストール

Nuxt3や必要なパッケージをあらかじめインストールしておきます。

$ npx nuxi init nuxt3-app
$ cd nuxt3-app
$ yarn
$ yarn dev

http://localhost:3000 でアプリケーションが起動します。

TypeScript使うならこれ必要?(もしかしたら実行しなくてもいいかも)

$ yarn nuxi typecheck

その他必要なパッケージもインストール

$ yarn add ethers @devprotocol/dev-kit

アプリケーションを書いてみる

dev-kitのリポジトリにあるexamplesのget-property-info.jsを組み込んでみます。

特定のプロパティアドレスを指定して、その合計ステーキング数と報酬数(どちらも単位はDEV)を表示する感じです。

その他の前提としてはEthereumのmainnetを使うことにします。

app.vue を以下のように変更します。(ソースコード内のコメントは後から追加しました。)

<template>
  <div>
    <NuxtWelcome />
  </div>
</template>

<script>
import { ethers } from "ethers";
import { contractFactory, addresses } from "@devprotocol/dev-kit";

export default {
  data() {
    const config = useRuntimeConfig();
    console.log(config, config.WEB3_PROVIDER_URL);
    return {
      config,
    };
  },
  async mounted() {
    // メインネットを使う
    const provider = new ethers.providers.JsonRpcProvider(
      this.config.WEB3_PROVIDER_URL
    );
    const network = await provider.ready;
    console.log(network);
    const contract = contractFactory(provider);

    // 対象のプロパティアドレス
    const propertyAddress = "0xac1AC9d00314aE7B4a7d6DbEE4860bECedF92309";

    // コントラクトの準備
    const registryContractAddress = addresses.eth.main.registry;
    const lockupContractAddress = await contract
      .registry(registryContractAddress)
      .lockup();

    // ステーキング数取得
    const propertyStakingAmount = await contract
      .lockup(lockupContractAddress)
      .getPropertyValue(propertyAddress);
    const stakingAmount = ethers.BigNumber.from(propertyStakingAmount).div(
      new ethers.BigNumber.from(10).pow(18)
    );
    console.log(
      `${propertyAddress}'s staking amount is ${stakingAmount.toBigInt()} DEV`
    );

    // 報酬数取得
    const propertyRewards = await contract
      .lockup(lockupContractAddress)
      .calculateRewardAmount(propertyAddress);
    const reward = ethers.BigNumber.from(propertyRewards[0]).div(
      new ethers.BigNumber.from(10).pow(36)
    );
    console.log(`${propertyAddress}'s rewards is ${reward.toBigInt()} DEV`);
  },
};
</script>

nuxt.config.tsは以下

import { defineNuxtConfig } from "nuxt3";

// https://v3.nuxtjs.org/docs/directory-structure/nuxt.config
export default defineNuxtConfig({
    build: {
        transpile: ["@ethersproject", "ethers"],
    },
    publicRuntimeConfig: {
        WEB3_PROVIDER_URL:
            "https://eth-mainnet.alchemyapi.io/v2/XXXX",
    },
});

https://eth-mainnet.alchemyapi.io/v2/XXXXは自分で作成したAlchemyのキーとかローカルのEthereumノード使ってね。

で、起動するとエラー発生

Uncaught SyntaxError: import not found: default bignumber.js:9:7

nuxt.config.tsを以下のようにvite.optimizeDepsにエラーが発生しているパッケージを追加していく.
色々対応して別のエラーまで進んだ.

import { defineNuxtConfig } from "nuxt3";

// https://v3.nuxtjs.org/docs/directory-structure/nuxt.config
export default defineNuxtConfig({
    build: {
        transpile: ["@ethersproject", "ethers"],
    },
    vite: {
        optimizeDeps: {
            include: ["bn.js", "js-sha3", "hash.js", "aes-js", "scrypt-js", "bech32"],
        },
    },
    publicRuntimeConfig: {
        WEB3_PROVIDER_URL:
            "https://eth-mainnet.alchemyapi.io/v2/XXXX",
    },
});

ここまでで一旦 git init && git add XXX && git commit しておく。

エラー解析からのさらに開発進める

もう一度起動してエラーの内容をみる.

Uncaught (in promise) TypeError: (intermediate value).BigNumber.from is not a constructor

なんと! new 不要だったのか!!このexamples私が追加したのですが、new不要だったようです。
修正。

diff --git a/app.vue b/app.vue
index baf5fbd..2ecdda9 100644
--- a/app.vue
+++ b/app.vue
@@ -34,7 +34,7 @@ export default {
       .lockup(lockupContractAddress)
       .getPropertyValue(propertyAddress);
     const stakingAmount = ethers.BigNumber.from(propertyStakingAmount).div(
-      new ethers.BigNumber.from(10).pow(18)
+      ethers.BigNumber.from(10).pow(18)
     );
     console.log(
       `${propertyAddress}'s staking amount is ${stakingAmount.toBigInt()} DEV`
@@ -44,7 +44,7 @@ export default {
       .lockup(lockupContractAddress)
       .calculateRewardAmount(propertyAddress);
     const reward = ethers.BigNumber.from(propertyRewards[0]).div(
-      new ethers.BigNumber.from(10).pow(36)
+      ethers.BigNumber.from(10).pow(36)
     );
     console.log(`${propertyAddress}'s rewards is ${reward.toBigInt()} DEV`);
   },

うまく動いたっぽい!!
コンソールに出力されてる。

0xac1AC9d00314aE7B4a7d6DbEE4860bECedF92309's staking amount is 28645 DEV app.vue:40:13
0xac1AC9d00314aE7B4a7d6DbEE4860bECedF92309's rewards is 16377 DEV app.vue:50:3

最終調整

最後に表示を整える。最終的に以下のようなコードになった。

<template>
  <div>
    <p>property address: {{ propertyAddress }}</p>
    <p>staking: {{ staking?.toBigInt() }} DEV</p>
    <p>rewards: {{ reward?.toBigInt() }} DEV</p>
  </div>
</template>

<script>
import { ethers } from "ethers";
import { contractFactory, addresses } from "@devprotocol/dev-kit";

export default {
  data() {
    const config = useRuntimeConfig();
    console.log(config, config.WEB3_PROVIDER_URL);
    return {
      config,
      propertyAddress: "0xac1AC9d00314aE7B4a7d6DbEE4860bECedF92309",
      staking: undefined,
      reward: undefined,
    };
  },
  async mounted() {
    // use main net
    const registryContractAddress = addresses.eth.main.registry;
    const provider = new ethers.providers.JsonRpcProvider(
      this.config.WEB3_PROVIDER_URL
    );
    const network = await provider.ready;
    console.log(network);
    const contract = contractFactory(provider);
    const lockupContractAddress = await contract
      .registry(registryContractAddress)
      .lockup();

    const propertyStakingAmount = await contract
      .lockup(lockupContractAddress)
      .getPropertyValue(this.propertyAddress);
    const stakingAmount = ethers.BigNumber.from(propertyStakingAmount).div(
      ethers.BigNumber.from(10).pow(18)
    );
    console.log(
      `${
        this.propertyAddress
      }'s staking amount is ${stakingAmount.toBigInt()} DEV`
    );

    const propertyRewards = await contract
      .lockup(lockupContractAddress)
      .calculateRewardAmount(this.propertyAddress);
    const reward = ethers.BigNumber.from(propertyRewards[0]).div(
      ethers.BigNumber.from(10).pow(36)
    );
    console.log(
      `${this.propertyAddress}'s rewards is ${reward.toBigInt()} DEV`
    );

    this.staking = stakingAmount;
    this.reward = reward;
  },
};
</script>

でブラウザから見るとこんな感じ。

スクリーンショット 2021-12-16 23.32.21.png

おわりに

Nuxt3でDApp開発できそうです。いい感じです。

以下リポジトリにソースコードがありますので、参考まで。

5
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?