What are we making?
A basic counter app which will have increment and decrement function in solidity and we will be able to interact with these functions using web3.js in our browser
What is Dapp?
A Dapp , or decentralized application, is a software application that runs on a distributed network. It’s not hosted on a centralized server, but instead on a peer-to-peer decentralized network.
What is Solidity Language?
Solidity is a high-level and contract-oriented language used for writing smart contracts. Developed by the core contributors of the Ethereum Blockchain Platform, it is used for designing and implementing smart contracts within the Ethereum Virtual Machine and other blockchain development platforms.
What is Web3.js and why are we using Web3.js?
Web3.js is a collection of libraries that allow you to interact with a local or remote ethereum node using HTTP, IPC, or WebSocket. The web3 JavaScript library interacts with the Ethereum blockchain. It can retrieve user accounts, send transactions, interact with smart contracts, and more.
Prerequisites :
Npm: npm is a package manager for the JavaScript programming language. Link: https://nodejs.org/en/
Ganache: Ganache is a personal blockchain for rapid Ethereum and Corda distributed application development. You can use Ganache across the entire development cycle; enabling you to develop, deploy, and test your Dapps in a safe and deterministic environment. After successfully installing npm install ganache-cli. Command :
npm install ganache-cli
Web3.js Command:
npm install web3
Solcjs: is a Node. js library and command-line tool that is used to compile solidity files. Command:
npm install solc
Getting Started:
The project will be broken down into 3 main files, counter.sol which will be our solidity contract, counter.js which will consist of our deployment code, and counter.html which will connect to the contract using web3js, and have frontend of our app.
Project Structure will be achieved after completing all the steps:
Writing our first contract
Counter.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.4;
contract FirstContract {
int public count = 0;
function incr() public{
count++;
}
function decr() public{
count--;
}
function display() public view returns (int){
return count;
}
}
You can relate solidity with java as it has a similar structure as that of java. As in java we have classes, we have contracts in solidity. A contract is a collection of functions and data that resides at a specific address on the Ethereum blockchain.
So in the above code, we have 3 functions and one public variable which maintains the counter.
By Default, a contract state is read-only unless it is specified as public , so we have made all the functions public.
The view functions are read-only functions, which ensures that state variables cannot be modified after calling them. As the display() function won’t be modifying the variable, it is kept to view function.
Compile code using solc:
solcjs --bin --abi -o ./build counter.sol
As we installed ganache before we need to start ganache. Command:
ganache-cli
Deployment on our local server
Deploy.js
const fs = require('fs');
const Web3 = require('web3');
const web3 = new Web3('http://localhost:8545');
const bytecode = fs.readFileSync('build/counter_sol_FirstContract.bin');
const abi = JSON.parse(fs.readFileSync('build/counter_sol_FirstContract.abi'));(async function () {
const ganacheAccounts = await web3.eth.getAccounts();
const myWalletAddress = ganacheAccounts[0];
const myContract = new web3.eth.Contract(abi);
myContract.deploy({
data: bytecode.toString()
}).send({
from: myWalletAddress,
gas: 5000000
}).then((deployment) => {
console.log('voting was successfully deployed!');
console.log('voting can be interfaced with at this address:');
console.log(deployment.options.address);
}).catch((err) => {
console.error(err);
});
})();
Once done with compiling of solidity code and starting ganache, we need to deploy the above script. The above script is not too complex to understand so calm down.
First 3 lines are basic include statements which will we needed to deploy the script.
The next 2 variables i.e bytecode and abi are the files that were built during the compilation of .sol script. The ABI is a .json file that describes the deployed contract and its functions. It allows us to contextualize the contract and call its functions.bin is simply a compact binary representation of the compiled bytecode. The opcodes aren’t referenced by PUSH, PULL or DELEGATECALL, but their binary representations, which look like random numbers when read by a text editor.
Next few lines takes in different parameters like ganache accounts, wallet address and abi of contract, once deployed we will get contract address which will be used to intract from web3.js
Command to deploy:
node counter.js
The frontend of our Dapp
Counter.html
<!DOCTYPE html>
<html>
<head>
<title>First DApp</title>
</head>
<body>
Increment
<button id="incr">+</button>
<br>
Decrement
<button id="decr">-</button>
<br />
<label id="myLabel"></label>
</body>
<script src="[https://code.jquery.com/jquery-3.6.0.min.js](https://code.jquery.com/jquery-3.6.0.min.js)"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="[https://cdn.jsdelivr.net/npm/web3@1.2.6/dist/web3.min.js](https://cdn.jsdelivr.net/npm/web3@1.2.6/dist/web3.min.js)"></script>
The first half of the Html code is just 2 buttons which are assigned 2 id’s to increment and decrement value. My label will show to display the counter. After that it contains 2 CDN scripts, the first one is JQuery which is used to handle click events and the second is web3js to interact with the contract
<script>
const **web3** = new Web3('[http://localhost:8545'](http://localhost:8545'));
const **myContractAddress** = //paste the address generated during deployment with single quotes;
const **myAbi** = // paste your abi code as it is.
const myContract = new web3.eth.Contract(myAbi, myContractAddress);
const **htmlLabel** = document.getElementById('myLabel');
myContract.methods.display().call().then((jsonRpcResult) => {
htmlLabel.innerHTML = jsonRpcResult;
console.log(jsonRpcResult);
});
$('#incr').click(function () {
myContract.methods **.incr** ().send({from:' **//paste avaiable accounts from ganache**'},function () {
myContract.methods. **display** ().call((error, result) => { htmlLabel.innerHTML = result; console.log(result) })
})
});
$('#decr').click(function () {
myContract.methods. **decr** ().send({from:' **//paste avaiable accounts from ganache**'}, function () {
myContract.methods. **display** ().call((error, result) => { htmlLabel.innerHTML = result; console.log(result) })
})
});
</script>
</html>
Paste the generated contract address during the deployment in myContractAddress variable.
Paste the abi code from abi file which was generated during the compilation of the .sol file.
Htmllabel is just getting the reference of myLabel to update whenever a button is clicked.
Whenever we try to access the functions we need to pass a from variable i.e from which account we are accessing the contract, this can be fetched from ganache cli, paste in any one of the addresses.
Output:
Once done with all the steps open your HTML file in chrome or any other web browser to see your first Dapp Working! Woho!
Congratulations! You on writing your first Dapp, hope you like it. If you need more interesting articles on decentralized web apps do drop your suggestions!
Thanks for reading! 👋👋
Do check my website sagar-gada.tech and GitHub here
*Follow me on * LinkedIn
Top comments (0)