Compiling, Deploying and Interacting with Smart Contract using JavaScript
If you have built DAAPs on Ethereum, most likely you must have used Web3.js to build your JavaScript frontend. Ethers.js is a lightweight JavaScript library which can be used as an alternative to Web3.js. In this post/tutorial, I will show how you can use Ethers.js to build a simple DAPP. I hope this helps you to evaluate and get started using Ethers.js for your next project.
Ethers.js has many advantages over web3.js. I would like to concentrate on one main feature that is state and key management in ethers.js. Web3 assumes that there is a local node connected to the application. That node is assumed to store keys, sign transactions, and interact with and read the ethereum blockchain. In reality, this is not the case, most users are not running geth locally. Metamask effectively emulates that environment through a browser application, and so most web3 apps require Metamask to hold keys, sign transactions, and interact with the ethereum mainnet.
Ethers.js takes a different approach that gives developers more flexibility. Ethers.js separates the “node” into two separate roles:
- A “wallet” that holds keys and signs transaction, and
- A “provider” that serves as an anonymous connection to the ethereum network, checking state and sending transactions
Compiling and Deploying a smart contract
For our tutorial we will interact with a ERC20 smart contract. You require nodejs and npm installed in your device
- Create a folder named ethers-template and make another folder named contracts inside ethers-template
mkdir ethers-template && cd ethers-template && mkdir contracts
2. Run the npm init command to create a package.json file, which would store project dependencies:
npm init -y
3. Make a config.json file to hold all your project configuration.
private_key: This private key will be used to deploy the smart contract on the network specified
network: ethers.js supports following network
“homestead” (main network)
“rinkeby”
“ropsten”
“kovan”
“goerli”
ERC20: “0x0b0Ce2d3f67b4482BD830Ac24ECa5E8d022Fd32f” line is optional. If you want to interact with deployed smart contract then you can write the address here.
Name, Symbol, Decimals are related to ERC20 parameters.
4. Install ethers.js using npm
npm install --save ethers
5. For compiling the contract install fs-extra and solc
npm install fs-extra@8.1.0 solc@0.5.11 --save
6. Save below code as erc20.sol in contracts folder
7. Now in order to compile the above code you need solc. Make a new file compile.js and paste the below code.
node compile.js
The above code will read all the smart contracts in contracts directory and save the abi and bytecode as json file. All the json file will be saved in build directory. After compiling we get the following structure.
+ethers-template
+compile.js
+contracts
-erc20.sol
+build
-ERC.json
-SafeMath.json
-package.json
8. Make a new file named deploy.json and paste the below code
While running the deploy file you should give contract name as command line argument.
Note:
1. Default network in the above code is kovan test network.
2. You need to have ether of that network in order to pay the transaction fees of deploying.
3. The contract will be deployed from private key which is specified in config.json
Command to deploy is
node deploy.js <contract_name>
In our case the command will be
node deploy.js ERC20
Output for above code will be:
Loaded wallet 0xC8e1F3B9a0CdFceF9fFd2343B943989A22517b26Deploying ERC20 in kovan...
deployed at 0x77Bb3546f5ee356E4026BaA96b7DDf22141bd77B
Waiting for the contract to get mined...
Contract deployed
You will get the Contract address copy and save this address which will be useful to interact with the deployed smart contract. This address will also be saved/updated in config.json.
Interacting with smart contract
- In this tutorial we are using ES6 to write the code and to convert ES6 to ES5 we will use webpack with babel loader.
Installing dev dependenicies:
npm i webpack webpack-cli @babel/core @babel/plugin-proposal-object-rest-spread @babel/preset-env babel-loader babel-polyfill -D
2. Make a new file app.js and paste the below code. Converted ES5 code of this file will be stored in dist/bundle.js
First we have to specify the provider/network in which we are going to work.
const provider = ethers.getDefaultProvider(config['network']);
In order to interact with smart contract you require two things
1. Smart Contract address and
2. ABI.
In above app.js we are importing address from config file and abi from build
//import the json of the contract which you want to interact
const erc_json = require('./build/ERC20.json');
const config = require('./config.json');
const address = config["ERC20"];
const abi = erc_json.abi;
3. Before making a contract instance we have to make a wallet instance, So that whenever a setter function is called (or a transaction has to be made) there must be a private key to sign these transactions. In ethers.js you just need to make wallet(signer) and all setter functions(transactions) will be signed by this wallet.
const wallet = new ethers.Wallet(config['private_key'] , provider);
You can also make a wallet with help of keystore and mnemonic. If you are gonna interact with smart contract with this wallet then you should pass the provider. If you just want to sign a message with private key then provider is not required.
erc20 = new ethers.Contract( address , abi , wallet );
Above code make a contract instance and you can call the contract functions like this
erc20.functions.function_name_in_smart_contract(parameters);
For Eg: In ERC20 we have a function named transfer which takes address and amount as a parameter. Below code calls the transfer function. Wallet will sign this transaction and publish it to the network specified.
erc20.functions.transfer(address, "1000000000000000000");
NOTE: Whenever you are making a transaction you should have ether in your wallet in order to pay the gas fees.
3. In package.json add below lines in script object
“deploy”: “node compile.js && node deploy.js ERC20”,
“build”: “webpack — mode production”,
After adding the above lines, package.json will look like this
Now whenever you make any changes to the smart contract you have to compile and depoly the changes. Compile and deploy both can be achieved in one command now i.e
npm run deploy
This will automatically change the address and ABI in config and build files.
During the time of interaction you need not change any address or abi, it will be updated automatically.
If you make any changes in app.js then you have to compile it by
npm run build
This will make(or update) dist/bundle.js file.
4. Make a new file named index.html. This page only includes a text input, which takes address and send 1 token to entered address. Transaction hash is appended below the text input and status of current transaction can also be seen in status section.
Now your folder structure should look like this.
build folder is created after running
node complie.js
dist folder is created after running
npm run build
Live version of the site can be found in https://saurav.tech/ethers-template/
Summary
Entire source code of the project can be found here. You can use this repository as a template. Clone it and make the necessary changes and enjoy.
git clone https://github.com/SauravKanchan/ethers-template.git
cd ethers-template
npm i
npm run deploy
npm run build