How to create Dev Protocol Dapp (3/3)

Kawakami
所要時間, 11分
初級

はじめに permalink

みなさん、こんにちわ
Dev Protocolで用意されているライブラリを使って、3回に分けて簡単なDappを作成したいと思います。
今回は3回目の記事になります。前回までをまだ見ていない場合、戻って進めてみることをお勧めします。

今回はトークンにステーキングする処理と、自分のWalletとの接続を作っていきたいと思います

STEP01: 開発環境の用意 permalink

開発環境は前回使用したものを引き続き使っていきます。
今回はwindowオブジェクトでEthereumを扱うため、その型ファイルを作成しましょう。また、HttpProviderの型も使用するためインストールします。

npm install web3-core

下記の型ファイルのコードを src/types/window.d.tsとして保存します


import { HttpProvider } from 'web3-core'

export interface RequestArguments {
readonly method: string,
readonly params?: unknown[] | object
}

export interface Ethereum extends HttpProvider {
request: (args: RequestArguments) => Promise<unknown>
isMetaMask: boolean
chainId: string | undefined
}

declare global {
interface Window {
ethereum?: Ethereum
}
}

window.ethereum は、MetaMaskをブラウザにアドオンした時に挿入される拡張です。
上記の型ファイルは今回のDappで使うものだけを宣言したものです。すべてを知りたい場合は以下より確認することができます
https://eips.ethereum.org/EIPS/eip-1193

今回作成するページについて permalink

今回は前回作成した詳細ページに、ステーキング機能をつけたいと思います。
トークンにあるボタンを押すことで、1DEV、5DEV、10DEVとステーキングが行えるようにします。
tokens page

STEP02: MetaMaskと接続してログインする permalink

所持しているDEVを扱うためには自分のWallet(MetaMask)と接続する必要があります。

MetaMaskとは、Ethereum用のウォレットになります。
MetaMaskはこちらからchrome版をインストールしてください

今回はMetaMaskを利用しますがEthereum用のウォレットは他にもさまざまなものがあります。
Ethereum Walletsを探す

ステーキングするためにはWalletのアドレスが必要になります。
Walletのアドレスを取得するには、MetaMaskにログインする必要があります。
そのためのサンプルコードを用意しました。
下記のコードを src/assets/ts/wallets.tsとして保存してください

/**
* LOGINボタンが押された際のログイン処理
* ログインは、MetaMaskからアドレスを取得できたらログインが行えたこととする
*/

export const clickLoginButton = async function () {
if (!isMetamask()) {
alert("MetaMaskをインストールしてください")
return;
}

if (! await connectMetaMask()) {
alert("MetaMaskとの接続を許可してください")
return;
}

if (! await isMetaMaskLogin()) {
alert("MetaMaskからログインしてください")
return;
}

if (!isMainNet()) {
alert("メインネットに切り替えてください")
return;
}

alert("MetaMaskにログインしました.")

loggedInStyle(this)

window.location.reload();
}

/**
* 画面の初期表示の際にログイン状態を判定したい時に使用する
*/

export const isLogin = async (): Promise<boolean> => {
if (!isMetamask()) {
return false;
}

if (! await isMetaMaskLogin()) {
return false;
}

if (!isMainNet()) {
return false;
}

return true;
}

/**
* ログインボタンのログイン時と未ログイン時のスタイル変更
* @param button
*/

export const loggedInStyle = (button: HTMLButtonElement) => {
button.classList.replace("btn-outline-warning", "btn-outline-success");

button.textContent = "LOGGED IN";
}

/**
* MetaMaskがメインネットワークに接続していくかの判定
*/

function isMainNet() {
return parseInt(window.ethereum.chainId) === 1;
}

/**
* MetaMaskがインストールされているかの判定
*/

function isMetamask (): boolean {
return !! window.ethereum && !! window.ethereum.isMetaMask;
}

/**
* MetaMaskからウォレットのアドレスを取得する
*/

async function getAccount() {
const accounts = await window.ethereum.request({method: 'eth_accounts'}) as string[];

return accounts[0];
}

/**
* ログイン判定
*/

async function isMetaMaskLogin(): Promise<boolean> {
return !! await getAccount();
}

/**
* MetaMaskとコネクトする
*/

async function connectMetaMask(): Promise<boolean> {
try {
await window.ethereum.request({method: 'eth_requestAccounts'})
} catch (e) {
if (e.code === 4001) {
return false
}
}

return true
}

MetaMaskのさらに詳しい使い方は、こちらをご確認ください

コードを設置したらmain.ts に下記のコードを追加します。
これはログインボタンのHTMLElementを取得して、ログインボタンをクリックされた時に、上記で作成したclickLoginButton を呼び出すコードです

// ファイルの先頭に処理を呼び出すImportを追記します
import {clickLoginButton} from "./wallets";

...

// 詳細ページの処理はここから記載する
if (document.getElementById("page-tokens")) {
// if文の下に記載します
const loginButton = document.getElementById("login-button");

loginButton.addEventListener('click', clickLoginButton);

...

STEP03: ステーキングする準備 permalink

Devをステーキングする場合は、Dev Protocolで用意しているライブラリ dev-kitを使います

dev-kitとは、Dev Protocolで用意されているコントラクトをフロントエンドから簡単に実行できるようにしてくれているライブラリです。詳しくはこちらから確認できます

dev-kitをインストールします

npm i -D @devprotocol/dev-kit

また、今回はイーサリアムノードに接続する必要がありますので、web3.jsもインストールします。

web3jsについては、こちらのドキュメントを参照してください

npm install web3

dev-kit でステーキングする場合は以下のように使います

import Web3 from "web3/dist/web3.min";
import {addresses, contractFactory} from "@devprotocol/dev-kit";

// Clientを作成する
const provider = new Web3(window.ethereum)
const clientDev = contractFactory(provider.currentProvider)

// mainネットワークのDevProtocolのアドレスを取得する
const registryContract = clientDev.registry(addresses.eth.main.registry)
const address = await registryContract.token()

// ステーキングする
clientDev.dev(address).deposit([プロパティのアドレス], [ステーキングするDEVの数])

STEP04: ステーキング処理を実装する permalink

それではトークンにあるボタンを押すとステーキングが行なわれるようにコーディングしていきましょう。 前回の main.ts に下記を加えます

import {clickLoginButton} from "./wallets";
import Web3 from "web3/dist/web3.min";
import {addresses, contractFactory} from "@devprotocol/dev-kit";

...

// 詳細ページの処理はここから記載する
if (document.getElementById("page-tokens")) {
...

const tokensHTMLElement = document.getElementById("tokens");

for ( const token of await getTokens(creatorAddress)) {
...
}

// 全てのトークンの全てのボタンを取得する
const buttons = tokensHTMLElement.querySelectorAll('button');

// ボタンにクリックイベントを追加する
for ( const button of buttons) {
button.addEventListener('click', async function () {
const address = this.getAttribute("address")
const amount = this.getAttribute("amount")

await stakeDev(address, amount)
})
}
}

ここからのコードは上記のコードの下に追記するか、別ファイルを用意してImportする形でもよいです

async function stakeDev (propertyAddress: string, amount: string) {
const provider = new Web3(window.ethereum)
const clientDev = contractFactory(provider.currentProvider)

const registryContract = clientDev.registry(addresses.eth.main.registry)

const address = await registryContract.token()

return clientDev.dev(address).deposit(propertyAddress, amount)
}

ここまでのコーディングと、少しの修正を加えボタンを押すと以下のようにMetaMaskが立ち上がります。
※DEV不足のためエラーが表示されています

tokens page
このソースコードは下記より確認することができます
https://github.com/kazu80/tokener-find/tree/master/src

まとめ permalink

以上で、Dev ProtocolDev Protocolで用意されているライブラリを使った簡単なDapp作成は終了となります。
いかがでしたでしょうか。各種ライブラリには、今回紹介していないさまざまな機能も用意されています。
それらの機能に関しても今回のように紹介していきたいと思いますので、楽しみにしてください。

🌈 この記事はお役に立ちましたか?

今後より良いコンテンツをお届けしていくために、ぜひご質問やフィードバックなどいただけると幸いです🌱
フォーラムはこちら

- Dev Protocol は全てOSSとして公開しています。ぜひIssueやPRを送ってください📢 時にバウンティがあります。
Dev ProtocolのGitHubはこちら

- Dev Protocol の改善提案(DIP)プロセスも公開されています。ぜひコメントをお待ちしています🌟
DIPはこちら