In the previous chapters, you have learned the basics of Smart Contracts and how to deploy them onto the blockchain. So far, all interactions with the Smart Contracts have been through the Remix IDE. While the Remix IDE provides an easy way for developers to test their Smart Contracts, it is not suitable for use by end users. To allow end users to interact with your Smart Contracts, you need to build front end that hides the complexity of interacting with the Smart Contracts in the back end. For this purpose, you need an API.
In this chapter, you will learn how to interact with Smart Contracts using the web3.js APIs. Using the web3.js APIs, you can build front ends (such as web pages, Node.js applications, etc.) to interact with Smart Contracts.
What Is web3.js?
web3-eth – For the Ethereum blockchain and smart contracts
web3-shh – For the whisper protocol to communicate p2p and broadcast
web3-bzz – For the swarm protocol, the decentralized file storage
web3-utils – Contains useful helper functions for DApp developers.
For this book, we will only focus on the first module, the web3-eth.
Installing web3.js
Installing web3.js requires Node.js. Specifically, you will make use of npm to download the web3.js APIs onto your local computer.
Tip
For more information on installing Node.js, check out the following page: https://nodejs.org/en/download/ .
Tip
Creating the package.json file will prevent npm from showing pages of warning and error messages when you install web3.js.
The --save option informs npm to modify the package.json file and add the web3.js as a dependency for the application.
The web3projects folder should now have a folder named node_modules. Within this node_modules folder, you will see a number of folders, all of which make up the suites of APIs that is web3.js.
Testing the web3.js Using MetaMask
Tip
Installing the serve application globally using the -g option may require sudo permission. Alternatively, you can also install it locally within the current directory without using the -g option.
The preceding command installs a web server on the local computer. Typing the serve command in any directory will enable the directory to serve its content through the web server.
Using the Chrome browser (with MetaMask installed), load the following URL: http://localhost:5000/TestWeb3.html.
If you load this page through HTTP on a browser with MetaMask installed, MetaMask will automatically inject the web3 object. This web3 object allows you to interact with an Ethereum node. In this case, it connects to the MetaMask extension on your Chrome browser.
When the user has approved the request to connect to the accounts, you can now get the account address and display it in the alert box.
The account object always returns the account you selected in the MetaMask extension in the browser. You can also get the name of the provider using the web3 object.
Testing the web3.js Without MetaMask
A good solution would be to manually connect to another Ethereum node, such as Ganache. And that’s what you will do next.
Note
Refer to Chapter 7 if you are not familiar with Ganache.
Load the page directly using any web browser.
Load the page using HTTP on any non-MetaMask supported web browser.
Tip
For security reasons, MetaMask would only inject the web3 object if the page is loaded using HTTP.
To get the current account address, you could simply specify web3.eth.accounts[0].
Deploying Contracts Using web3.js
Connect to the Ethereum node.
Get the primary account associated with the node.
Declare a variable containing the bytecode of the contract and another variable containing the ABI of the contract.
Use the web3.eth.contract() function to create a contract using the ABI of the contract.
Use the web3.eth.estimateGas() function to estimate the gas required to deploy the contract onto the blockchain.
Once the gas estimate is obtained, use the new() function to deploy the contract. You need to pass in the following – the account to use for deploying the contract, the bytecode of the contract, and the gas estimate (maximum amount of gas allowed).
Once the contract is deployed, you can now print out the address of the contract
In this example, the contract address is 0x044063558d41F47cC9e1CE4B8637638a278D30aA.
Interacting with a Contract Using web3.js
In the previous section, you saw how you used web3.js to deploy a Smart Contract onto the Ethereum blockchain. Besides using it to deploy contract, web3.js is often used to build front ends so that users can interact with your Smart Contract directly. And hence in this section, you will learn how to use web3.js to interact with your newly deployed contract. For our illustration, we shall build a web front end.
Notice that you pass in a callback function to the notarize() function so that when the transaction is confirmed by the user, you can get the transaction hash, which is then displayed in the label at the bottom of the page.
When the result is returned back to you, you will display it in the label.
Sending Ethers to Smart Contracts
Our ProofOfExistence contract provides a free service to let people notarize their documents on the blockchain (users just need to pay for gas required to write data onto the blockchain).
In a real commercial setting, you might want to charge for this service. For example, anytime a user wants to write to the blockchain, you want to charge a service fee. In the following example, you will modify the contract so that calls to the notarize() function require a payment of 1 Ether.
The require() function in Solidity allows you to check for certain condition. In this particular example, it checks that the call to the notarize() function is accompanied with exactly 1 Ether. If not, the transaction will fail and all unused gas will be refunded back to the caller. Note that you must add the payable keyword to the end of the function declaration.
When the contract is deployed, copy the address of the new contract. The address for the modified contract is now 0x3e3d5b0282c49d8e9e211b8fdc9225ec43d482c2.
The ABI of the new contract. The notarize() function now has a new signature, so the ABI must be updated.
The address of the newly deployed contract.
A JSON string containing the amount of Ether to be sent to the contract. Here, we specified that the maximum amount of gas required is 300000 (all unused gas will be refunded), and it is to be deducted from the account in the Ethereum node (such as MetaMask or Ganache). Finally, the amount of Ether to be sent to the contract is specified in Wei (1000000000000000000 Wei is equivalent to 1 Ether).
Observe that you will be sending 1 Ether to the contract, and the gas fee is 0.0003 Ether (based on the estimated 300,000 gas and gas price of 1 Gwei per unit). Click CONFIRM.
Tip
1 Ether = 1,000,000,000 Gwei, so 300,000 gas would cost 300,000,000,000,000 Gwei, which is equal to 0.0003 Ether. You can vary the price of gas in MetaMask by clicking the Edit button in Figure 8-11 and then clicking the Advanced tab (see Figure 8-12).
Summary
In this chapter, you learned how to use the web3.js APIs to interact with your Smart Contracts. You learned how to deploy Smart Contracts programmatically using web3.js. In addition, you also used the web3.js to build a web front end, and you saw how you can send Ethers to a Smart Contract.