メインコンテンツへスキップ

Solidityスマート・コントラクトからのERC-20トークンの送金と承認

スマート・コントラクト
トークン
Solidity
erc-20
中級
jdourlens
2020年4月7日
9 分で読めます

前回のチュートリアルでは、イーサリアム・ブロックチェーン上でのSolidityによるERC-20トークンの構造について学びました。この記事では、Solidity言語を使用して、スマート・コントラクトからトークンと対話する方法を見ていきます。

このスマート・コントラクトでは、ユーザーがイーサを新しくデプロイされたERC-20トークンと取引できる、実際のダミーの分散型取引所 (DEX) を作成します。

このチュートリアルでは、前回のチュートリアルで記述したコードをベースとして使用します。私たちのDEXは、コンストラクタでコントラクトのインスタンスを生成し、以下の操作を実行します。

  • トークンからイーサへの交換
  • イーサからトークンへの交換

シンプルなERC20コードベースを追加して、分散型取引所のコードを書き始めましょう。

新しいDEXスマート・コントラクトはERC-20をデプロイし、供給されたすべてのトークンを取得します。

これでDEXが完成し、すべてのトークン準備金が利用可能になりました。このコントラクトには2つの関数があります。

  • buy: ユーザーはイーサを送信し、代わりにトークンを受け取ることができます。
  • sell: ユーザーはトークンを送信し、イーサを取り戻すことができます。

buy関数

buy関数をコーディングしましょう。まず、メッセージに含まれるイーサの量を確認し、コントラクトが十分なトークンを所有していること、およびメッセージにイーサが含まれていることを検証する必要があります。コントラクトが十分なトークンを所有している場合、ユーザーにその数のトークンを送金し、Boughtイベントを発行します。

エラーが発生した場合にrequire関数を呼び出すと、送信されたイーサは直接リバートされ、ユーザーに返還されることに注意してください。

シンプルにするため、1トークンを1 Weiと交換します。

function buy() payable public {
    uint256 amountTobuy = msg.value;
    uint256 dexBalance = token.balanceOf(address(this));
    require(amountTobuy > 0, "You need to send some ether");
    require(amountTobuy <= dexBalance, "Not enough tokens in the reserve");
    token.transfer(msg.sender, amountTobuy);
    emit Bought(amountTobuy);
}

購入が成功した場合、トランザクション内に2つのイベントが表示されるはずです。トークンのTransferイベントとBoughtイベントです。

Two events in the transaction: Transfer and Bought

sell関数

売却を担当する関数では、まずユーザーが事前にapprove関数を呼び出して、その金額を承認している必要があります。送金を承認するには、DEXによってインスタンス化されたERC20Basicトークンをユーザーが呼び出す必要があります。これを実現するには、まずDEXコントラクトのtoken()関数を呼び出して、DEXがtokenというERC20Basicコントラクトをデプロイしたアドレスを取得します。次に、セッション内でそのコントラクトのインスタンスを作成し、そのapprove関数を呼び出します。その後、DEXのsell関数を呼び出して、トークンをイーサにスワップして戻すことができます。たとえば、対話型のBrownieセッションでは次のようになります。

そして、sell関数が呼び出されたとき、呼び出し元のアドレスからコントラクトのアドレスへの送金が成功したかどうかを確認し、イーサを呼び出し元のアドレスに送り返します。

function sell(uint256 amount) public {
    require(amount > 0, "You need to sell at least some tokens");
    uint256 allowance = token.allowance(msg.sender, address(this));
    require(allowance >= amount, "Check the token allowance");
    token.transferFrom(msg.sender, address(this), amount);
    payable(msg.sender).transfer(amount);
    emit Sold(amount);
}

すべてが機能すれば、トランザクション内に2つのイベント(TransferSold)が表示され、トークン残高とイーサ残高が更新されるはずです。

Two events in the transaction: Transfer and Sold


このチュートリアルでは、ERC-20トークンの残高とアローワンスを確認する方法、およびインターフェースを使用してERC20スマート・コントラクトのTransferTransferFromを呼び出す方法を見てきました。

トランザクションを作成した後は、コントラクトに対して行われたトランザクションを待機して詳細を取得する (opens in a new tab)ためのJavaScriptチュートリアルや、ABIがある限り、トークンの送金やその他のイベントによって生成されたイベントをデコードするためのチュートリアル (opens in a new tab)があります。

以下は、このチュートリアルの完全なコードです。