📘

Web3でERC20の残高を表示する

2023/02/09に公開

はじめに

Ethereumを使ったスマートコントラクトの勉強をしていて、ERC20を使ってコントラクトをdeployするところまでできました。

今度はフロント側を触ってみたいなと思い、試しにWeb3を使った、ERC20 Tokenの残高を表示するアプリを作ってみました。

準備

ERC20でTokenを発行する

はじめに今回残高を取得するためのERC20 Tokenを発行します。
詳しくは別の記事で紹介していますが、Tokenを発行するだけならERC20 Tokne Generatorとかを使ってもできます。

なお、デプロイする先はテストネットをオススメします。メインネットにデプロイしても良いですが、手数料がかかるので簡単に試すだけならRopstenやRinkeberyなどのテストネット上にデプロイした方が良いです。

ここで、発行したTokneのコントラクトアドレスをメモしておいてください。

infura.ioに登録してAPIキーを取得

自分でノードを建てるなどEthereumネットワークに接続する方法は色々ありますが、ここではEthereumのノードをAPIとして提供してくれるinfura.ioというサービスを利用します。

infura.ioにアクセスしてSign Upしてださい。その後、Dash Boardを開くてEthereumの[Create New Project]からプロジェクトを作成してください。

作成後にSettingsというところで、API Endpointで自身が発行した先のネットワークを選択します。すると、URLが表示されていると思うのでwssから始まる方のURLをコピーしてください。

コード

次にコードを作成していきます。

ここではBoot Strapを使って適当にUIを整えてますが好きに変更してもらって大丈夫です。肝心なWeb3の処理はGetBalance.jsに記載してあるので、コード内の各項目を準備で用意したものに書き換えてください。

index.html
<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/gh/ethereum/web3.js/dist/web3.min.js"></script>
    <script src="https://code.jquery.com/jquery-3.6.0.slim.min.js"
        integrity="sha256-u7e5khyithlIdTpu22PHhENmPcRdFiHRjhAuHcs05RI=" crossorigin="anonymous"></script>
    <script lang="text/javascript" src="./getBalance.js"></script>
    <title>ERC20 Token Balnce</title>
</head>

<body>
    <div class="container pt-5">
        <h1 class="display-4">ERC20 Token Balnce</h1>
        <p>あなたのERC20 Tokenの残高を表示します</p>
        <div class="jumbotron bg-light p-3 rounded-3">
            <div class="container">
                <form>
                    <div class="mb-3">
                        <label for="address" class="form-label">Your Address</label>
                        <input type="text" id="address" class="form-control">
                    </div>
                    <button class="btn btn-outline-dark mx-auto d-block" id="get-button">Get Balance</button>
                </form>
                Your Blance:<br>
                <span class="text-dark lead" id="output"></span>
            </div>
        </div>
    </div>
    <script>
        $('#get-button').click(async (event) => {
            event.preventDefault();
            $('#output').text('Loading...');
            const walletAddress = $('#address').val();
            const balance = await getBalance(walletAddress);
            $('#output').text(balance + '<< Unit >>');
        });
    </script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
        crossorigin="anonymous"></script>
</body>

</html>
getBalance.js
let web3 = new Web3('<< Your infura.io endpoint >>');

//HackToken

let tokenAddress = "<< Your token contract address >>";

let ABI = [
    {
        constant: true,
        inputs: [
            {
                name: "_owner",
                type: "address",
            },
        ],
        name: "balanceOf",
        outputs: [
            {
                name: "balance",
                type: "uint256",
            },
        ],
        payable: false,
        stateMutability: "view",
        type: "function",
    },
    {
        "constant": true,
        "inputs": [],
        "name": "decimals",
        "outputs":
            [
                {
                    "name": "",
                    "type": "uint8"
                }
            ],
        "type": "function"
    },
];

let contract = new web3.eth.Contract(ABI, tokenAddress);

async function getBalance(walletAddress) {
    let balance = await contract.methods.balanceOf(walletAddress).call();
    balance = parseFloat(balance)
    let decimals = await contract.methods.decimals().call();
    decimals = parseFloat(decimals);
    balance = balance / 10 ** decimals
    return balance;
}

Discussion