簡単な方法でERC20トークンを作成する方法
公開: 2022-03-11この記事の目的は、ERC20トークンをできるだけ短時間で作成する方法を示すことです。
基本から始めましょう: ERC20トークンとは何ですか?
近年、ERC20トークン仕様はイーサリアムトークンの事実上の標準になりました。 言い換えれば、今日出回っているほとんどのイーサリアム契約はERC20に準拠しています。 この記事では、独自のイーサリアムトークンを作成する方法について詳しく説明しますが、始める前に、ERC20標準を詳しく見てみましょう。
ERC20トークンがこれほど魅力的で成功している理由は何ですか? 関係するいくつかの要因があります:
- このチュートリアルでわかるように、ERC20トークンはシンプルで簡単にデプロイできます。
- ブロックチェーンベースのマーケットプレイスと暗号ウォレットは、管理するトークンの範囲と通信するために単一の標準化されたコマンドセットを必要とするため、ERC20標準は重大な問題を解決します。 これには、異なるトークン間の相互作用ルール、およびトークン購入ルールが含まれます。
- これは、イーサリアムトークンの標準化を提供する最初の人気のある仕様でした。 決して最初ではありませんでしたが、その人気のおかげですぐに業界標準になりました。
他のイーサリアムトークンと同様に、ERC20トークンはスマートコントラクトとして実装され、分散型の方法でイーサリアム仮想マシン(EVM)上で実行されます。
Solidity:スマートコントラクトプログラミング言語
イーサリアムのスマートコントラクトはSolidityで書かれています。 代替言語はありますが、この目的でそれらを使用する人はほとんどいません。 SolidityはJavaScriptに似ているため、JavaScript、またはJavaやその他のCのような言語についてある程度の知識がある場合は、実際にSolidityを十分に習得する前であっても、Solidityのコードの一部がそうであることを問題なく理解できます。それ。
簡単なERC20コントラクトの作成をすぐに開始できるはずなので、ここから楽しみが始まります。 これは単純なタスクであり、この記事ではERC20トークンを1時間以内に作成してデプロイする方法を説明するのに十分なほど単純です。
このデモンストレーションで作成するトークンは、必要最低限のERC20実装であり、あまり多くのベルやホイッスルはありません。 しかし、私は現実の世界で多くの同様に単純なトークンを見てきました、そしてそれらは非常にうまくいく傾向があります。
ERC20トークン標準の概要
ERC20とは何ですか?
簡単に言えば、ERC20標準は、他の契約、ウォレット、またはマーケットプレイスとの統合を可能にするために、すべてのERC20トークンによって実装される一連の機能を定義します。 この一連の関数はかなり短く、基本的です。
function totalSupply() public view returns (uint256); function balanceOf(address tokenOwner) public view returns (uint); function allowance(address tokenOwner, address spender) public view returns (uint); function transfer(address to, uint tokens) public returns (bool); function approve(address spender, uint tokens) public returns (bool); function transferFrom(address from, address to, uint tokens) public returns (bool);
ERC20機能を使用すると、外部ユーザー、たとえば暗号ウォレットアプリは、ユーザーの残高を確認し、適切な承認を得て、あるユーザーから別のユーザーに資金を転送できます。
スマートコントラクトは、2つの明確に定義されたイベントを定義します。
event Approval(address indexed tokenOwner, address indexed spender, uint tokens); event Transfer(address indexed from, address indexed to, uint tokens);
これらのイベントは、ユーザーがアカウントからトークンを引き出す権限を付与されたとき、およびトークンが実際に転送された後に呼び出されるか、発行されます。
標準のERC20機能に加えて、多くのERC20トークンには追加のフィールドもあり、書面でなくても実際には、ERC20標準の事実上の一部になっているものもあります。 このようなフィールドの例をいくつか示します。
string public constant name; string public constant symbol; uint8 public constant decimals;
ERC20とSolidityの命名法に関するいくつかのポイントは次のとおりです。
-
public
関数は、コントラクト自体の外部からアクセスできます view
は基本的に一定を意味します。つまり、コントラクトの内部状態は関数によって変更されません。-
event
は、クライアント(アプリケーションフロントエンドなど)がコントラクト内の特定の発生について通知を受けることを可能にするSolidityの方法です。
すでに基本的なJava/JavaScriptスキルを持っている場合、ほとんどのSolidity言語構成は明確である必要があります。
SolidityでのERC20トークンの書き込み
基本の概要を説明し、ERC20トークンを作成するために必要なことを説明したので、次はロジックの作成を開始します。
まず、2つのマッピングオブジェクトを定義する必要があります。 これは、連想配列またはキー/値配列のSolidityの概念です。
mapping(address => uint256) balances; mapping(address => mapping (address => uint256)) allowed;
式mapping(address => uint256)
は、キーがaddress
型(アカウントアドレスを示すために使用される数値)であり、値がuint256
型(トークンの残高を格納するために通常使用される256ビット整数)である連想配列を定義します。
最初のマッピングオブジェクトであるbalances
は、各所有者アカウントのトークン残高を保持します。
2番目のマッピングオブジェクトであるallowed
には、特定のアカウントからの引き出しが承認されたすべてのアカウントと、それぞれに許可された引き出し額が含まれます。
ご覧のとおり、許可されたマッピングの値フィールドは、それ自体が、承認された引き出し合計に対するアカウントアドレスをプロットするマッピングです。
これらのマッピングは、他のすべてのコントラクトフィールドとともにブロックチェーンに格納され、マイニングされて、変更がすべてのネットワークユーザーノードに伝播されます。
ブロックチェーンストレージは高価であり、契約のユーザーは何らかの方法で料金を支払う必要があります。 したがって、常にストレージサイズを最小化し、ブロックチェーンに書き込むようにする必要があります。
必要なデータ構造が整ったので、ERC20ロジックを適切な関数に実際に記述し始めることができます。
ICOトークンの数の設定
ICOトークンの数をどのように設定しますか? さて、ICOトークンの最大数を設定する方法はいくつかありますが、この問題自体は長い議論の価値があるかもしれません。
ECR20チュートリアルのニーズに応じて、最も簡単なアプローチを使用します。契約作成時にトークンの合計量を設定し、最初にすべてを「契約所有者」、つまりスマートコントラクトを展開したアカウントに割り当てます。
uint256 totalSupply_; constructor(uint256 total) public { totalSupply_ = total; balances[msg.sender] = _totalSupply; }
コンストラクターは、コントラクトがデプロイされた直後にイーサリアムによって自動的に呼び出される特別な関数です。 これは通常、コントラクトのデプロイアカウントによって渡されたパラメーターを使用してトークンの状態を初期化するために使用されます。
msg
は、Ethereum自体によって宣言および設定されるグローバル変数です。 契約を履行するための重要なデータが含まれています。 ここで使用しているフィールド: msg.sender
には、現在のコントラクト関数を実行するイーサリアムアカウントが含まれています。
デプロイするアカウントのみがコントラクトのコンストラクターに入ることができます。 契約が開始されると、この関数は使用可能なトークンを「契約所有者」アカウントに割り当てます。
合計トークン供給を取得する
function totalSupply() public view returns (uint256) { return totalSupply_; }
この関数は、所有者に関係なく、このコントラクトによって割り当てられたすべてのトークンの数を返します。
所有者のトークンバランスを取得する
function balanceOf(address tokenOwner) public view returns (uint) { return balances[tokenOwner]; }
balanceOf
は、所有者のアドレスで識別されるアカウントの現在のトークン残高を返します。
トークンを別のアカウントに転送する
function transfer(address receiver, uint numTokens) public returns (bool) { require(numTokens <= balances[msg.sender]); balances[msg.sender] = balances[msg.sender] — numTokens; balances[receiver] = balances[receiver] + numTokens; emit Transfer(msg.sender, receiver, numTokens); return true; }
その名前が示すように、 transfer
関数は、 numTokens
の量のトークンを所有者の残高から別のユーザーまたはreceiver
者の残高に移動するために使用されます。 転送する所有者はmsg.sender
、つまり関数を実行する所有者です。これは、トークンの所有者のみがトークンを他の所有者に転送できることを意味します。

述語をアサートするSolidityの方法はrequire
。 この場合、転送アカウントには転送を実行するのに十分な残高があります。 require
ステートメントが失敗した場合、トランザクションはブロックチェーンに書き込まれる変更なしですぐにロールバックされます。
終了する直前に、関数はERC20イベントTransfer
を起動し、登録されたリスナーがその完了に反応できるようにします。
トークンを引き出すための委任を承認する
この関数は、トークンマーケットプレイスのシナリオで最もよく使用されます。
function approve(address delegate, uint numTokens) public returns (bool) { allowed[msg.sender][delegate] = numTokens; emit Approval(msg.sender, delegate, numTokens); return true; }
approve
とは、所有者、つまりmsg.sender
がデリゲートアカウント(場合によってはマーケットプレイス自体)を承認して、自分のアカウントからトークンを引き出し、他のアカウントに転送できるようにすることです。
ご覧のとおり、この関数は、所有者がマーケットプレイスでトークンを提供しているシナリオで使用されます。 これにより、マーケットプレイスは事前の承認を待たずにトランザクションを完了することができます。
この関数は、実行の最後にApproval
イベントを発生させます。
引き出しが承認されたトークンの数を取得する
function allowance(address owner, address delegate) public view returns (uint) { return allowed[owner][delegate]; }
この関数は、 approve
関数で設定されているように、所有者によって現在承認されているトークンの数を特定のデリゲートに返します。
デリゲートによるトークンの転送
transferFrom
関数は、前に説明したapprove
関数のピアです。 これにより、引き出しが承認された代理人は、所有者の資金を第三者の口座に送金することができます。
function transferFrom(address owner, address buyer, uint numTokens) public returns (bool) { require(numTokens <= balances[owner]); require(numTokens <= allowed[owner][msg.sender]); balances[owner] = balances[owner] — numTokens; allowed[owner][msg.sender] = allowed[from][msg.sender] — numTokens; balances[buyer] = balances[buyer] + numTokens; Transfer(owner, buyer, numTokens); return true; }
関数開始時の2つのrequire
ステートメントは、トランザクションが正当であること、つまり、所有者が転送するのに十分なトークンを持っていること、およびデリゲートが(少なくとも) numTokens
を撤回することを承認していることを確認することです。
この関数は、所有者から購入者にnumTokens
の金額を転送するだけでなく、デリゲートの許容値からnumTokens
を減算します。 これにより、基本的に、与えられた手当を持つデリゲートは、それをいくつかの別々の引き出しに分割することができます。これは、典型的な市場の行動です。
ここで停止して、有効なERC20実装を作成できます。 ただし、産業用強度トークンが必要なため、さらに一歩進んでいきたいと考えています。 これには、コードをもう少し安全にする必要がありますが、基本的ではないにしても、トークンを比較的単純に保つことができます。
SafeMathSolidityライブラリ
SafeMathは、ハッカーが契約を破ることが知られている1つの方法である整数オーバーフロー攻撃に対処することを目的としたSolidityライブラリです。 このような攻撃では、ハッカーは、関連する整数を最大値を超えて取得するパラメーターを渡すことにより、コントラクトに誤った数値を使用するように強制します。
SafeMathは、算術アクションを実行する前にオーバーフローをテストすることでこれを防ぎ、オーバーフロー攻撃の危険性を排除します。 ライブラリは非常に小さいため、契約サイズへの影響は最小限であり、パフォーマンスは発生せず、ストレージコストのペナルティもほとんどありません。
SafeMathをコードに追加しましょう:
library SafeMath { // Only relevant functions function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a — b; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c >= a); return c; } }
SafeMathは、 assert
ステートメントを使用して、渡されたパラメーターの正確さを検証します。 失敗をassert
した場合、関数の実行はすぐに停止され、すべてのブロックチェーンの変更がロールバックされます。
次に、ライブラリをSolidityコンパイラに導入する次のステートメントを追加しましょう。
using SafeMath for uint256;
次に、最初に使用した単純な算術をSafeMath関数に置き換えます。
balances[msg.sender] = balances[msg.sender].sub(numTokens); balances[receiver] = balances[receiver].add(numTokens); balances[buyer] = balances[buyer].add(numTokens); balances[owner] = balances[owner].sub(numTokens);
すべて一緒に梱包する
Solidityでは、スマートコントラクトの機能とイベントは、コントラクトと呼ばれるエンティティにラップされ、サイレントに「ブロックチェーンクラス」に変換できます。 以下は、コードの要点を含め、作成したERC20互換のコントラクトです。 名前と記号のフィールドは自由に変更できます。 ほとんどのトークンは10進値を18に保つので、同じことを行います。
イーサリアム契約の展開
契約をブロックチェーンに展開する時が来ました。 展開後、契約はネットワークに参加しているすべてのノードに転送されます。 コントラクトに加えられたすべての変更は、参加しているすべてのノードに伝播されます。
イーサリアムの開発者は通常、Truffleなどのデプロイメントツールを使用します。 Truffleでさえ、この記事の限られたニーズには行き過ぎであり、Remixと呼ばれる単純なオンラインツールで十分です。
これを使用するには、ブラウザにMetaMaskプラグインをインストールし、Rinkeby(Ethereumテストネットワーク)アカウントに少なくともいくつかのRinkebyEtherが含まれている必要があります。 これらは比較的単純な手順であるため、詳細については説明しません。
どちらもお持ちでない場合は、MetaMaskとRinkebyにアクセスして、ダウンロードリンクを確認し、インストールと使用方法を明確にしてください。
すべての構成要素が揃ったので、Remixに進み、プラグマ行とSafeMathライブラリを含む上記のコードをオンラインエディターに貼り付けます。
次に、右側の「実行」という2番目のタブに移動し、「デプロイ」をクリックします。 トランザクションの確認を求めるMetaMaskポップアップが表示されます。 もちろん、承認します。
- 緑のボックス:Rinkebyを使用していることを確認してください
- 青いボックス:トークンの合計供給量を設定します
- 赤いボックス:デプロイ!
要旨:https://gist.github.com/giladHaimov/8e81dbde10c9aeff69a1d683ed6870be#file-basicerc20-sol
おめでとうございます! 真のイーサリアムプロフェッショナルのように、最初のERC20トークンをデプロイしました。 約束通り、トークンはシンプルで軽量でありながら完全に機能し、ERC20標準に準拠しており、MathSafeで保護されています。 ブロックチェーン全体で購入、支払い、転送する準備ができています。
スマートコントラクトについてはこれですべてですか?
いいえ、近いわけではありません。簡単なデモンストレーションは表面をほとんど傷つけず、スマートコントラクト開発の1つの側面のみを扱っているためです。
スマートコントラクトは、ビジネスロジック、ユーザーインタラクションのモデリング、トークンの作成と書き込みを許可するかどうか、コントラクトに導入するライフサイクルの変更、通常は管理者レベルの機能の必要性に応じて、はるかに複雑になる可能性があります。管理者が承認した一連の機能など。 あなたは絵を手に入れます。
それでも、ここで行ったことを再現できれば、それは知識を拡大し、必要に応じてより複雑な契約に移行するための強固な基盤となります。