Using ethers.js to develop the Ethereum Web wallet 4 — Sending tokens (tokens

Ethereum decentralized web wallet development series, will start from scratch to develop a wallet that can be actually used, this series of articles is the combination of theory and practice, a total of four: Create wallet account, import and export account Keystore file, display wallet information and initiate signature transaction, send Token(Token), this is the fourth chapter, Token(Token, Token) is a major feature of Ethereum, since the development of wallet, send Token function is essential.

Contract ABI information

First of all, we need to understand that when conducting Token transfer, we are actually calling the transfer function of the contract, and to call the function of the contract, we need to know the ABI information of the contract.

Secondly, when we say Token, we actually refer to the contract that conforms to the ERC20 standard interface, which is defined as follows:

contract ERC20Interface {

    string public constant name = "Token Name";
    string public constant symbol = "SYM";
    uint8 public constant decimals = 0;

    function totalSupply() public constant returns (uint);

    function balanceOf(address tokenOwner) public constant returns (uint balance);

    function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
    function approve(address spender, uint tokens) public returns (bool success);

    function transfer(address to, uint tokens) public returns (bool success);
    function transferFrom(address from, address to, uint tokens) public returns (bool success);


    event Transfer(address indexed from, address indexed to, uint tokens);
    event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}
Copy the code

The ABI stands for Application Binary Interface, which is the description of the contract Interface. Therefore, with the contract Interface definition, it is easy to compile the ABI information, such as copying the ABI directly from the compile TAB in Remix below.

The generated ABI description looks something like this:

{[..."constant": true."inputs": []."name": "totalSupply"."outputs": [{"name": ""."type": "uint256"}]."payable": false."stateMutability": "view"."type": "function"
	},
	{
		"constant": true."inputs": [{"name": "tokenOwner"."type": "address"}]."name": "balanceOf"."outputs": [{"name": "balance"."type": "uint256"}]."payable": false."stateMutability": "view"."type": "function"},... ]Copy the code

It is a JSON array. Each element in the array is a description of the function interface, which is required to comply with the external call contract. For example, an interface description usually contains the following fields:

  • Name: The name of the function event
  • Type: the value can be function, constructor, fallback, or event
  • Inputs: Inputs to a function. Each parameter object contains the following properties:
    • Name: parameter name
    • Type: Canonical type of the parameter.
  • Outputs: a series of objects similar to inputs, which can be omitted if no value is returned in inputs.
  • Constant: true indicates that the function declares itself not to change the value of the state variable.
  • Payable: true means the function can receive ether, otherwise means it can’t.

The next step in constructing the contract object is to use the ABI.

Constructing a contract object

Ethers.js constructs the Contract object as simple as supplying three arguments to the ethers.contract constructor as follows:

 varabi = [...] ;var addr = "0x...";
 var contract = new ethers.Contract(address, abi, provider);

Copy the code

The address of the contract can be obtained after the contract is deployed. The concept of ERC20 and the deployment of the Token contract will not be discussed here.

Only can be a function that calls the Token contract using the Contract object.

Obtain Token balance and transfer Token

Obtain Token balance

To obtain the Token balance, the UI is as follows:

In HTML, the tags are defined as follows:

    <tr>
      <th>TT Token:</th>
      <td>
          <input type="text" readonly="readonly" class="readonly" id="wallet-token-balance" value="0.0" /></div>
      </td>
    </tr>
Copy the code

The corresponding logical code is also very simple:

     var tokenBalance = $('#wallet-token-balance');
     // Call the contract method directly
    contract.balanceOf(activeWallet.address).then(function(balance){
        tokenBalance.val(balance);
    });
Copy the code

Transfer Token

The UI effect of Token transfer is as follows:

The HTML code of the interface is as follows:

<h3>Transfer token:</h3>
<table>
    <tr>
        <th>Send to:</th>
        <td><input type="text" placeholder="(target address)" id="wallet-token-send-target-address" /></td>
    </tr>
    <tr>
        <th>Amount:</th>
        <td><input type="text" placeholder="(amount)" id="wallet-token-send-amount" /></td>
    </tr>
    <tr>
        <td> </td>
        <td>
            <div id="wallet-token-submit-send" class="submit disable">send</div>
        </td>
    </tr>
</table>
Copy the code

The above defines two text input fields and a “send” button. In the logical processing part, transferring the Token is a method of invoking the contract, although it is similar to retrieving the balance. However, transferring the Token requires initiating a transaction, so gas consumption needs to be measured. Run the (key) code when you hit Send:

var inputTargetAddress = $('#wallet-token-send-target-address');
var inputAmount = $('#wallet-token-send-amount');
var submit = $('#wallet-token-submit-send');

var targetAddress = ethers.utils.getAddress(inputTargetAddress.val());
var amount = inputAmount.val();

submit.click(function() {
// Calculate the gas consumption required for transfer first. This step has a default value and is not required.
    contract.estimate.transfer(targetAddress, amount)
      .then(function(gas) {

          // Must be associated with a signed wallet object
          let contractWithSigner = contract.connect(activeWallet);

          // Initiate a transaction. The first two arguments are arguments to the function. The third argument is the transaction argument
          contractWithSigner.transfer(targetAddress, amount, {
              gasLimit: gas,
              // use 2gwei
              gasPrice: ethers.utils.parseUnits("2"."gwei"),
            }).then(function(tx) {
                console.log(tx);
                // This section describes how to refresh the Token balance above and reset the input box
            });  
      });
}
Copy the code

In the ethers.js API, Wallet is the implementation class of signer (abstract class). In the ethers.js API, Wallet is the implementation class of Signer.

All functions that change the blockchain data need to be associated with the signer, and in the case of view functions only the provider needs to be connected.

Ethers. Js Contract provides a very convenient way: Contract. Estimate. The functionName to calculate predict gasLimit trading.

When initiating a transaction, we can provide an optional Overrides parameter, in which we can specify gasLimit and gasPrice of the transaction. If we do not specify this parameter, the value obtained by contract.estimate will be used as gasLimit by default. And the value of provider.getgasPrice () to specify gasPrice.

Complete source code please subscribe to simple block chain technology small column view, ha ha, is there a little chicken thief, creation is not easy ah. Click on the link for a full video lecture.

Reference: ethers.js

Blockchain in Simple terms – systematic learning of blockchain to create the best blockchain technology blog.

Blockchain knowledge planet most professional technology q&A community, join the community can also communicate with more than 300 blockchain technology enthusiasts in the wechat group.