Web3テクノロジースタック丨EVMを使用してフルスタックdappを構築する方法を教えます

Web3テクノロジースタック丨EVMを使用してフルスタックdappを構築する方法を教えます

React、Ethers.js、Solidity、Hardhat を使用してフルスタック dApp を構築する

このチュートリアルでは、Ethereum 仮想マシン (EVM) を活用して、Ethereum、Polygon、Avalanche、Celo など多数のブロックチェーン ネットワーク上でフルスタック アプリケーションを構築できる Web3 テクノロジー スタックについて学習します。

このプロジェクトのコードはここにあります。このチュートリアルのビデオ コースはここにあります。 web3スタックの定義も参照してください‌

私は最近、Edge & Node に開発者リレーションエンジニアとして入社し、Ethereum でのスマート コントラクト開発に深く取り組んでいます。私は、Solidity を使用してフルスタック dApp を構築するのに最適なスタックを特定しました。

▶︎ クライアントサイドフレームワーク - React

▶︎ Ethereum 開発環境 — Hardhat‌

▶︎ Ethereum ネットワーク クライアント ライブラリ - Ethers.js‌

▶︎ API レイヤー - グラフ プロトコル

しかし、これを学習するときに私が抱えた問題は、これらのそれぞれについて個別にかなり良いドキュメントがあったものの、これらすべてをまとめて、それらが互いにどのように機能するかを理解する方法については何もなかったことです。 scaffold-eth (Ethers、Hardhat、The Graph も含まれています) のような非常に優れたテンプレートがいくつかありますが、始めたばかりの人にとっては多すぎるかもしれません。

最新のリソース、ライブラリ、ツールを使用してフルスタックの Ethereum アプリケーションを構築する方法を示すエンドツーエンドのガイドが必要でした。

私が興味を持っているものは次のとおりです。

  1. Ethereum スマート コントラクトをローカル、テスト、メインネットに作成、デプロイ、テストする方法

  2. ローカル、テスト、本番環境/ネットワークを切り替える方法

  3. React、Vue、Svelte、Angular などのさまざまなフロントエンド環境を使用してコントラクトに接続し、対話する方法

これらすべてを理解するのにしばらく時間を費やし、かなり満足できるスタックを使い始めた後、このスタックに興味があるかもしれない他の人々のためだけでなく、私自身の将来の参考のためにも、このスタックを使用してフルスタックの Ethereum アプリケーションを構築およびテストする方法を書き留めておくのはよいことだと思いました。この記事がその参考資料です。


各パーツ


使用する主なパーツと、それらがスタックにどのように適合するかを確認しましょう。

1. イーサリアム開発環境

スマート コントラクトを構築する場合、ライブ環境を扱わずにコントラクトをデプロイし、テストを実行し、Solidity コードをデバッグする方法が必要になります。

また、Solidity コードをクライアント アプリケーション (この場合は React アプリケーション) で実行できるコードにコンパイルする方法も必要です。これがどのように機能するかについては、後で詳しく説明します。

Hardhat は、フルスタック開発用に設計された Ethereum 開発環境およびフレームワークであり、このチュートリアルで使用するフレームワークです。

エコシステム内の他の同様のツールとしては、Ganache、Truffle、Foundry などがあります。

2. Ethereum ネットワーク クライアント ライブラリ

React アプリケーションでは、デプロイされたスマート コントラクトと対話する方法が必要です。新しいトランザクションを送信するだけでなく、データを読み取る方法も必要になります。

ethers.js は、React、Vue、Angular、Svelte などのクライアント側 JavaScript アプリケーションから Ethereum ブロックチェーンとそのエコシステムと対話するための完全かつコンパクトなライブラリを目指しています。これが私たちが使用するライブラリです。

エコシステムにおけるもう一つの人気のある選択肢はweb3.jsです

3. メタマスク

Metamask はアカウント管理の処理を支援し、現在のユーザーをブロックチェーンに接続します。 MetaMask を使用すると、ユーザーはサイトのコンテキストからアカウントとキーを分離しながら、さまざまな方法で管理できます。

ユーザーが MetaMask ウォレットを接続すると、開発者は、Web3 互換ブラウザのユーザーを MetaMask ユーザーとして認識する、グローバルに利用可能な Ethereum API (window.ethereum) と対話できるようになります。また、トランザクションの署名を要求するたびに、MetaMask はユーザーに可能な限りわかりやすい方法でプロンプトを表示します。

4. 反応する

React は、Web アプリケーション、ユーザー インターフェイス、UI コンポーネントを構築するためのフロントエンド JavaScript ライブラリです。これは Facebook と多くの個人開発者および企業によって管理されています。

React とそのメタフレームワークの広大なエコシステム (Next.js、Gatsby、Redwood、Blitz.js など) は、従来の SPA、静的サイト ジェネレーター、サーバー側レンダリング、およびこれら 3 つを組み合わせたものなど、あらゆるタイプのデプロイメント ターゲットをサポートしています。 React はフロントエンドの分野で引き続き優位に立っているようで、少なくとも近い将来はそうあり続けると思います。

5. グラフ

Ethereum のようなブロックチェーン上に構築されたほとんどのアプリケーションでは、チェーンから直接データを読み取るのは困難で時間がかかるため、以前は個人や企業が独自の集中型インデックス サーバーを構築し、それらのサーバーから API リクエストを処理していました。これには多大なエンジニアリングおよびハードウェア リソースが必要となり、分散化に必要なセキュリティ プロパティが損なわれます。

Graph は、ブロックチェーン データをクエリするためのインデックス プロトコルであり、完全に分散化されたアプリケーションの作成を可能にし、この問題を解決して、アプリケーションが使用できる豊富な GraphQL クエリ レイヤーを提供します。このガイドでは、アプリケーションのサブグラフは構築しませんが、後のチュートリアルで構築します。

The Graph を使用してブロックチェーン API を構築する方法については、「Ethereum での GraphQL API の構築」をご覧ください。


私たちが構築するもの


このチュートリアルでは、いくつかの基本的なスマート コントラクトを構築、デプロイ、接続します。

  1. イーサリアムブロックチェーン上でメッセージを作成および更新する契約

  2. トークンを発行するための契約。これにより、契約の所有者はトークンを他の人に送信したり、トークンの残高を読んだりすることができ、新しいトークンの所有者はトークンを他の人に送信することもできます。

また、ユーザーが次のことができる React フロントエンドも構築します。

  1. ブロックチェーンにデプロイされたコントラクトからの挨拶を読む

  2. 更新のご挨拶

  3. 新しく発行されたトークンを自分のアドレスから別のアドレスに送信する

  4. トークンを受け取ったら、そのトークンを他の人に送信できるようにします

  5. ブロックチェーンにデプロイされた契約からトークン残高を読み取る

前提条件

  • ローカルマシンにNode.jsがインストールされている

  • ブラウザにインストールされたChrome拡張機能MetaMask

このガイドでは、チュートリアル全体を通してテスト ネットワーク上で偽の/テストの Ether を使用するため、Ethereum を所有する必要はありません。


始める


まず、新しい React アプリケーションを作成します。

npx create-react-app react-dapp

次に、新しいディレクトリに移動し、NPM または Yarn を使用して ethers.js と hardhat をインストールします。

npm install ethers hardhat @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers

Ethereum開発環境をインストールして設定する

次に、Hardhat を使用して新しい Ethereum 開発環境を初期化します。

npx hardhat

? What do you want to do? Create a sample project
? Hardhat project root:

ルート ディレクトリに次のセクションが作成されているはずです。

  • hardhat.config.js - Hardhat のセットアップ全体 (つまり、構成、プラグイン、カスタム タスク) がこのファイルに含まれています。

  • scrips - 実行時にスマートコントラクトをデプロイする sample-script.js というスクリプトを含むフォルダー

  • test - サンプルのテスト スクリプトを含むフォルダー contracts - サンプルの Solidity スマート コントラクトを含むフォルダー

MetaMask 構成の問題により、HardHat 構成のチェーン ID を 1337 に更新する必要があります。また、コンパイルされたコントラクト成果物の場所を React アプリケーションの src ディレクトリに更新する必要があります。

これらの更新を行うには、hardhat.config.js を開き、module.exports を次のように更新します。

module.exports = {
solidity: "0.8.4",
paths: {
artifacts: './src/artifacts',
},
networks: {
hardhat: {
chainId: 1337
}
}
};


当社のスマートコントラクト


次に、contracts/Greeter.sol で提供されているサンプル契約を見てみましょう。

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "hardhat/console.sol";


contract Greeter {
string greeting;

constructor(string memory _greeting) {
console.log("Deploying a Greeter with greeting:", _greeting);
greeting = _greeting;
}

function greet() public view returns (string memory) {
return greeting;
}

function setGreeting(string memory _greeting) public {
console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
greeting = _greeting;
}
}

これは非常に基本的なスマート コントラクトです。デプロイされると、Greeting 変数が設定され、挨拶を返すために呼び出すことができる関数 (greet) が公開されます。

また、ユーザーが挨拶を更新できるようにする関数 (setGreeting) も公開します。これらのメソッドは、Ethereum ブロックチェーンにデプロイされると、ユーザーが操作できるようになります。


Ethereumブロックチェーンの読み取りと書き込み


スマート コントラクトと対話する方法には、読み取りと書き込み/トランザクションの 2 つがあります。私たちのコントラクトでは、greet は読み取りと見なすことができ、setGreeting は書き込み/トランザクションと見なすことができます。

トランザクションを書き込むとき、または初期化するときには、トランザクションをブロックチェーンに書き込むために料金を支払う必要があります。これを行うには、ガスを支払う必要があります。ガスは、Ethereum ブロックチェーン上でトランザクションを正常に実行し、契約を実行するために必要な料金または価格です。

ブロックチェーンからデータを読み取るだけで、何も変更または更新しない限り、トランザクションを実行する必要はなく、そのためのガスやコストも発生しません。呼び出した関数は接続しているノードによってのみ実行されるため、料金は発生せず、読み取りは無料です。

React アプリケーションでは、ethers.js ライブラリ、コントラクト アドレス、および hardhat によってコントラクトから作成される ABI の組み合わせを使用して、スマート コントラクトと対話します。

ABI とは何ですか? ABI は、Application Binary Interface の略です。これは、クライアント アプリケーションと、対話するスマート コントラクトがデプロイされる Ethereum ブロックチェーン間のインターフェイスと考えることができます。

ABI は通常、HardHat などの開発フレームワークによって Solidity スマート コントラクトからコンパイルされます。スマート コントラクトの ABI は、Etherscan でもよく見つかります。


ABI のコンパイル


スマート コントラクトの基礎を理解し、ABI が何であるかがわかったので、プロジェクト用の ABI をコンパイルしてみましょう。

これを行うには、コマンド ラインに移動して次のコマンドを実行します。

npx hardhat compile

これで、src ディレクトリに「artifacts」という新しいフォルダーが表示されるはずです。

arthits/contracts/Greeter.json ファイルには、プロパティの 1 つとして ABI が含まれています。 ABI を使用する必要がある場合は、JavaScript ファイルからインポートできます。

import Greeter from './artifacts/contracts/Greeter.sol/Greeter.json'

次のようにして ABI を参照できます。

console.log("Greeter ABI: ", Greeter.abi)

Ethers.js では人間が読める ABI も有効になりますが、このチュートリアルではそれについては説明しません。


ローカルネットワーク/ブロックチェーンを展開して使用する


次に、スマート コントラクトをローカル ブロックチェーンにデプロイしてテストしてみましょう。

ローカル ネットワークにデプロイするには、まずローカル テスト ノードを起動する必要があります。これを行うには、CLI を開いて次のコマンドを実行します。

npx hardhat node

このコマンドを実行すると、アドレスと秘密鍵のリストが表示されます。

これらは、スマート コントラクトをデプロイしてテストするために使用できる、作成された 20 個のテスト アカウントとアドレスです。各アカウントには 10,000 テスト イーサもロードされました。後ほど、テスト アカウントを MetaMask にインポートして使用できるようにする方法を学習します。

次に、契約をテスト ネットワークにデプロイする必要があります。まず、scripts/sample-script.js の名前を scripts/deploy.js に更新します。

これで、デプロイメント スクリプトを実行し、ローカル ネットワークにデプロイするフラグを CLI に提供できます。

npx hardhat run scripts/deploy.js --network localhost

このスクリプトを実行すると、スマート コントラクトがローカル テスト ネットワークにデプロイされ、対話を開始できるようになります。

契約が展開されると、ローカル ネットワークを開始したときに作成した最初のアカウントが使用されました。

CLI の出力を見ると、次のようなものが表示されるはずです。

Greeter deployed to: 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0

このアドレスは、クライアント アプリケーションでスマート コントラクトと通信するために使用します。このアドレスはクライアント アプリケーションから接続するときに必要となるため、使用可能な状態にしておいてください。

スマート コントラクトにトランザクションを送信するには、npx ハードハット ノードの実行時に作成したアカウントの 1 つを使用して MetaMask ウォレットに接続する必要があります。 CLI でログアウトした契約のリストに、アカウント番号秘密鍵が表示されます。

➜ react-dapp git:(main) npx hardhat node
Started HTTP and WebSocket JSON-RPC server at http://127.0.0.1:8545/

Accounts
========
Account #0: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 (10000 ETH)
Private Key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80

...

このアカウントを MetaMask にインポートして、そこで利用可能な Eth テスト コインの一部を使い始めることができます。

これを行うには、まずMetaMaskを開いてテストネットワークを有効にします。

次に、ネットワークを Localhost 8545 に更新します。

次に、MetaMask で、アカウント メニューから [アカウントのインポート] をクリックします。

CLI 経由でログアウトした秘密キーの 1 つをコピーして貼り付け、[インポート] をクリックします。アカウントがインポートされると、アカウントに Eth が表示されます。

スマート コントラクトがデプロイされ、使用するアカウントができたので、React アプリケーションからスマート コントラクトとのやり取りを開始できます。


Reactクライアントの接続


このチュートリアルでは、CSS などを使用して優れた UI を構築することについては気にせず、コア機能に 100% 焦点を当てて、すぐに使い始めることができるようにします。そこから、必要に応じて見栄えを良くすることができます。

それでは、React アプリケーションで達成したい 2 つの目標を確認してみましょう。

  1. スマートコントラクトから現在の挨拶の値を取得する

  2. ユーザーが挨拶の値を更新できるようにします

これを知った上で、どうすればいいのでしょうか?これを実現するには、次のことを行う必要があります。

  1. 入力フィールドと入力値を管理するためのローカル状態を作成する(挨拶の更新)

  2. アプリケーションがユーザーのMetaMaskアカウントに接続してトランザクションに署名できるようにします

  3. スマートコントラクトの読み取りと書き込みのための関数を作成する

これを行うには、src/App.js を開き、次のコードで更新して、greeterAddress の値をスマート コントラクトのアドレスに設定します。

import './App.css';
import { useState } from 'react';
import { ethers } from 'ethers'
import Greeter from './artifacts/contracts/Greeter.sol/Greeter.json'

// Update with the contract address logged out to the CLI when it was deployed
const greeterAddress = "your-contract-address"

function App() {
// store greeting in local state
const [greeting, setGreetingValue] = useState()

// request access to the user's MetaMask account
async function requestAccount() {
await window.ethereum.request({ method: 'eth_requestAccounts' });
}

// call the smart contract, read the current greeting value
async function fetchGreeting() {
if (typeof window.ethereum !== 'undefined') {
const provider = new ethers.providers.Web3Provider(window.ethereum)
const contract = new ethers.Contract(greeterAddress, Greeter.abi, provider)
try {
const data = await contract.greet()
console.log('data: ', data)
} catch (err) {
console.log("Error: ", err)
}
}
}

// call the smart contract, send an update
async function setGreeting() {
if (!greeting) return
if (typeof window.ethereum !== 'undefined') {
await requestAccount()
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner()
const contract = new ethers.Contract(greeterAddress, Greeter.abi, signer)
const transaction = await contract.setGreeting(greeting)
await transaction.wait()
fetchGreeting()
}
}

return (
<div className="App">
<header className="App-header">
<button onClick={fetchGreeting}>Fetch Greeting</button>
<button onClick={setGreeting}>Set Greeting</button>
<input onChange={e => setGreetingValue(e.target.value)} placeholder="Set greeting" />
</header>
</div>
);
}

export default App;

テストするには、React サーバーを起動します。

npm start

アプリケーションが読み込まれると、現在の挨拶を取得し、コンソールにログアウトできるようになります。 MetaMask ウォレットで契約に署名し、Ether テスト コインを使用することで、挨拶を更新することもできます。


ライブテストネットワークを展開して使用する


Ropsten、Rinkeby、Kovan などの Ethereum テスト ネットワークがいくつかあり、メインネットにデプロイしなくても、パブリックにアクセス可能なバージョンの契約を取得するためにデプロイすることもできます。このチュートリアルでは、Ropsten テスト ネットワークにデプロイします。

まず、MetaMask ウォレットを更新して、Ropsten ネットワークに接続します。

次に、このテスト ファウセットにアクセスして、このチュートリアルの残りの部分で使用するテスト Ether を自分に送信します。

Infura や Alchemy などのサービスにサインアップすることで、Ropsten (またはその他のテスト ネットワーク) にアクセスできます (このチュートリアルでは Infura を使用します)。

Infura または Alchemy でアプリケーションを作成すると、次のようなエンドポイントが作成されます。

https://ropsten.infura.io/v3/your-project-id

デプロイメントに使用するアカウントのウォレット アドレスを含めるには、Infura または Alchemy アプリケーション構成で ALLOWLIST ETHEREUM ADDRESSES を必ず設定してください。

テスト ネットワークに展開するには、追加のネットワーク情報を使用してハードハット構成を更新する必要があります。設定する必要があるものの一つは、展開元のウォレットの秘密鍵です。

秘密鍵を取得するには、MetaMask からエクスポートします。

この値をアプリケーション内でハードコーディングするのではなく、環境変数のようなものとして設定することをお勧めします。

次に、次の構成でネットワーク プロパティを追加します。

module.exports = {
defaultNetwork: "hardhat",
paths: {
artifacts: './src/artifacts',
},
networks: {
hardhat: {},
ropsten: {
url: "https://ropsten.infura.io/v3/your-project-id",
accounts: [`0x${your-private-key}`]
}
},
solidity: "0.8.4",
};

デプロイするには、次のスクリプトを実行します。

npx hardhat run scripts/deploy.js --network ropsten

契約がデプロイされると、契約とのやり取りを開始できるようになります。これで、Etherscan Ropstenテストネットエクスプローラーでライブ契約を表示できるようになります。


トークンの発行


スマート コントラクトの最も一般的な使用例の 1 つはトークンの作成です。その方法を見てみましょう。これらすべてがどのように機能するかをより深く理解したら、もう少し速く進むことができます。

メインのコントラクト ディレクトリに Token.sol という新しいファイルを作成します。

次に、次のスマート コントラクトで Token.sol を更新します。

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "hardhat/console.sol";

contract Token {
string public name = "Nader Dabit Token";
string public symbol = "NDT";
uint public totalSupply = 1000000;
mapping(address => uint) balances;

constructor() {
balances[msg.sender] = totalSupply;
}

function transfer(address to, uint amount) external {
require(balances[msg.sender] >= amount, "Not enough tokens");
balances[msg.sender] -= amount;
balances[to] += amount;
}

function balanceOf(address account) external view returns (uint) {
return balances[account];
}
}

このトークン契約はデモンストレーション目的のみであり、ERC20 に準拠していないことに注意してください。ここではERC20トークンを紹介します

この契約により、「Nader Dabit Token」と呼ばれる新しいトークンが作成され、供給量が 1,000,000 に設定されます。

次に、契約書をコンパイルします。

npx hardhat compile

次に、scripts/deploy.js のデプロイ スクリプトを更新して、この新しいトークン コントラクトを含めます。

const hre = require("hardhat");

async function main() {
const [deployer] = await hre.ethers.getSigners();

console.log(
"Deploying contracts with the account:",
deployer.address
);

const Greeter = await hre.ethers.getContractFactory("Greeter");
const greeter = await Greeter.deploy("Hello, World!");

const Token = await hre.ethers.getContractFactory("Token");
const token = await Token.deploy();

await greeter.deployed();
await token.deployed();

console.log("Greeter deployed to:", greeter.address);
console.log("Token deployed to:", token.address);
}

main()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});

これで、この新しいコントラクトをローカルまたは Ropsten ネットワークにデプロイできるようになりました。

npx hardhat run scripts/deploy.js --network localhost

契約がデプロイされると、これらのトークンを他のアドレスに送信できるようになります。

これを実行するには、動作させるために必要なクライアント コードを更新します。

import './App.css';
import { useState } from 'react';
import { ethers } from 'ethers'
import Greeter from './artifacts/contracts/Greeter.sol/Greeter.json'
import Token from './artifacts/contracts/Token.sol/Token.json'

const greeterAddress = "your-contract-address"
const tokenAddress = "your-contract-address"

function App() {
const [greeting, setGreetingValue] = useState()
const [userAccount, setUserAccount] = useState()
const [amount, setAmount] = useState()

async function requestAccount() {
await window.ethereum.request({ method: 'eth_requestAccounts' });
}

async function fetchGreeting() {
if (typeof window.ethereum !== 'undefined') {
const provider = new ethers.providers.Web3Provider(window.ethereum)
console.log({ provider })
const contract = new ethers.Contract(greeterAddress, Greeter.abi, provider)
try {
const data = await contract.greet()
console.log('data: ', data)
} catch (err) {
console.log("Error: ", err)
}
}
}

async function getBalance() {
if (typeof window.ethereum !== 'undefined') {
const [account] = await window.ethereum.request({ method: 'eth_requestAccounts' })
const provider = new ethers.providers.Web3Provider(window.ethereum);
const contract = new ethers.Contract(tokenAddress, Token.abi, provider)
const balance = await contract.balanceOf(account);
console.log("Balance: ", balance.toString());
}
}

async function setGreeting() {
if (!greeting) return
if (typeof window.ethereum !== 'undefined') {
await requestAccount()
const provider = new ethers.providers.Web3Provider(window.ethereum);
console.log({ provider })
const signer = provider.getSigner()
const contract = new ethers.Contract(greeterAddress, Greeter.abi, signer)
const transaction = await contract.setGreeting(greeting)
await transaction.wait()
fetchGreeting()
}
}

async function sendCoins() {
if (typeof window.ethereum !== 'undefined') {
await requestAccount()
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const contract = new ethers.Contract(tokenAddress, Token.abi, signer);
const transation = await contract.transfer(userAccount, amount);
await transation.wait();
console.log(`${amount} Coins successfully sent to ${userAccount}`);
}
}

return (
<div className="App">
<header className="App-header">
<button onClick={fetchGreeting}>Fetch Greeting</button>
<button onClick={setGreeting}>Set Greeting</button>
<input onChange={e => setGreetingValue(e.target.value)} placeholder="Set greeting" />

<br />
<button onClick={getBalance}>Get Balance</button>
<button onClick={sendCoins}>Send Coins</button>
<input onChange={e => setUserAccount(e.target.value)} placeholder="Account ID" />
<input onChange={e => setAmount(e.target.value)} placeholder="Amount" />
</header>
</div>
);
}

export default App;

次に、アプリケーションを実行します。

npm start

「残高を取得」をクリックすると、コンソールにログアウトしたアカウントに 1,000,000 コインがあることが確認できるはずです。

「トークンのインポート」をクリックすると、MetaMask でそれらを表示することもできます。

次に、「カスタム トークン」をクリックしてトークン コントラクト アドレスを入力し、カスタム トークンを追加します。 (トークンの小数点以下の桁数を尋ねられた場合は、0 を選択してください) これで、トークンがウォレットで利用できるようになります。

次に、これらのコインを別のアドレスに送信してみます。

これを行うには、別のアカウントのアドレスをコピーし、更新された React UI を使用してそのアドレスに送信します。トークンの金額を確認すると、元の金額からアドレスに送信した金額を差し引いた金額と等しくなります。


ERC20トークン


ERC20 トークン標準は、すべての ERC20 トークンに適用される一連のルールを定義し、トークン同士が簡単にやり取りできるようにします。 ERC20 を使用すると、Ethereum ブロックチェーン上の他のトークンと相互運用可能な独自のトークンを簡単に作成できます。

ERC20 標準を使用して独自のトークンを構築する方法を見てみましょう。

まず、OpenZepplin スマート コントラクト ライブラリをインストールし、そこに基本 ERC20 トークンをインポートします。

npm install @openzeppelin/contracts

次に、ERC20 コントラクトを拡張(または継承)してトークンを作成します。

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract NDToken is ERC20 {
constructor(string memory name, string memory symbol) ERC20(name, symbol) {
_mint(msg.sender, 100000 * (10 ** 18));
}
}

コンストラクターを使用するとトークンの名前とシンボルを設定でき、_mint 関数を使用するとトークンを作成し、その量を設定できます。

デフォルトでは、ERC20 は小数点以下の桁数を 18 に設定しているため、_mint 関数では 100,000 に 10 の 18 乗を掛けて、小数点以下の桁数がそれぞれ 18 のトークンを合計 100,000 個発行します (1 Eth が 10 から 18 の wei で構成されるのと同様)。

デプロイするには、コンストラクター値 (名前とシンボル) を渡す必要があるため、デプロイ スクリプトで次の操作を実行できます。

const NDToken = await hre.ethers.getContractFactory("NDToken");
const ndToken = await NDToken.deploy("Nader Dabit Token", "NDT");

元の ERC20 トークンを拡張すると、トークンは次の機能をすべて継承します。

function name() public view returns (string)
function symbol() public view returns (string)
function decimals() public view returns (uint8)
function totalSupply() public view returns (uint256)
function balanceOf(address _owner) public view returns (uint256 balance)
function transfer(address _to, uint256 _value) public returns (bool success)
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
function approve(address _spender, uint256 _value) public returns (bool success)
function allowance(address _owner, address _spender) public view returns (uint256 remaining)

デプロイされると、これらの関数のいずれかを使用して新しいスマート コントラクトと対話できるようになります。 ERC20トークンの別の例については、[Solidity by example)( https://solidity-by-example.org/app/erc20/)をご覧ください。


結論は


さて、ここでは多くのことを説明しましたが、私にとってこれはこのスタックを使い始めるための基本/中核であり、これらすべてを学習している人としてだけでなく、将来必要になるかもしれない何かを参照する必要がある場合にも、私が持っていたいものです。たくさんのことを学べたことを願っています。

MetaMask に加えて複数のウォレットをサポートしたい場合は、Web3Modal をチェックしてください。Web3Modal を使用すると、非常にシンプルでカスタマイズ可能な構成で、アプリに複数のプロバイダーのサポートを簡単に実装できます。

今後のチュートリアルとガイドでは、より複雑なスマート コントラクトの開発と、それらをサブグラフとしてデプロイしてその上に GraphQL API を公開し、ページネーションや全文検索などの機能を実装する方法について詳しく説明します。

また、IPFS や Web3 データベースなどのテクノロジーを使用して、分散型でデータを保存する方法についても説明します。


<<:  中国初のデジタル人民元路上駐車スペースが深センで開設

>>:  グレイスケール・ビットコイン・トラストのマイナスプレミアムは26.5%となり、過去最低を記録した。ビットコインETFは新たな戦場となるか?

推薦する

AntboxカップマイニングショーコンペティションBCHグランプリがあなたを待っています

2018年3月、BitmainはANTBOX(モバイルマイニングファーム)を立ち上げました。 ANT...

暗号通貨の90%が下落する中、老後まで付き合えるのはビットコインだけ?

CoinMarketCap の Web サイトが提供する情報から、新しい競合コインがほぼ毎日登場し...

Coinbase、新たな暗号資産への扉を開く新サービス「アセットセンター」を開始

サンフランシスコを拠点とする暗号通貨取引所Coinbaseは、同社が現在使用している煩雑な上場プロセ...

合併後の時代:イーサリアムは BTC を超えるか?

「イーサリアムの合併が完了しました!これはイーサリアムのエコシステムにとって重要な瞬間です。合併の...

フォーブス: ブロックチェーンと分散化

2030 年の明るい日曜日の朝、あなたは牛乳を買うために地元の食料品店に立ち寄りました。手を振るだけ...

3分でビットコインの取引方法を学ぶことができます

株式、先物、ファンド取引とは異なり、ビットコイン取引はT+0モデル(1日以内の売買無制限)を採用して...

13万人を騙し20億ドルを儲ける:中国系アメリカ人を装ったネズミ講

毎年、何万人もの中国人がアメリカンドリームを夢見て故郷を離れ、アメリカへ渡っています。しかし、毎年、...

ビットコインの市場シェアは過去最低の70%に落ち込んだ。ピーター・トッドは、マイナーによる51%攻撃を防ぐためにPoWの変更を検討することを提案している

ビットコインのスケーリングの苦戦により、投資家がヘッジのために代替コインに目を向けるようになり、暗号...

ウクライナ、ブロックチェーン選挙システム導入のため法律改正準備

クレイジー解説:ウクライナはブロックチェーン選挙システムについて複数の計画を発表しているが、最終的に...

ジャスティン・サンが業界の真のトレンドセッターであることは認めざるを得ない

数日前、ある記事を読んだのですが、その中で今でも鮮明に覚えている一文がありました。「勤勉さの点では、...

バイビットの給与管理者が大量のUSDTを盗んだ、シンガポールの裁判所が暗号通貨の財産的属性を説明

仮想通貨取引所バイビットは、社内で給与の支払いを担当していたホー氏を、自らが密かに所有・管理していた...

ビットコイン準備法が4年間の暗号通貨サイクルを破る可能性がある理由

ドナルド・トランプ次期大統領が就任初日にビットコイン準備金を宣言する大統領令に署名するか、任期中に準...

DEVCON2: Greg Colvin 博士のビデオ解説により、Ethereum 仮想マシンが悲鳴を上げる!

記者:リディアGreg Colvin 博士は、ANSI/ISO C++ 標準委員会の委員です。会議で...