8 min read
Overview
A developer stack is a bag of technologies a developer possesses. For example, MEAN (MongoDB, Express.js, AngularJS/Angular, and Node.js) and MERN (MongoDB, Express.js, React, and Node.js) are common web developer stacks. Similarly, today we will learn more about the web3 developer stack and the tech included.
Prefer a video walkthrough? Follow along with Radek and learn about the Web3 developer stack in 26 minutes.
Prerequisites
- Node.js installed on your system.
- Text editor.
- Terminal aka Command-Line.
- Willingness to learn.
The Developer Stack
If we can imagine web3 as a car then, web3 libraries/dApps are the car's chassis, smart contracts/blockchain are the internal hardware components, wallets which act as the driver’s license, and the node is the fuel that is needed to run the car. Let’s break them down one by one.
- Web3 libraries/dApps:
Web3 libraries help us interface with the blockchain easily, make transactions, and interact with smart contracts. Using a web3 library we can develop decentralized applications that reside on the blockchain or interact with it, such as web3.js, ethers.js, and web3.py. Learn how to work with different web3 libraries in the ‘Web3 SDKs’ section of our guides.
2. Smart contracts:
Smart contracts are pieces of code that reside on the blockchain. They work within the blockchain and are immutable. Smart contracts are written mainly in Solidity. The majority of developers use Remix IDE to write, compile, and deploy the contracts. However, tools like Truffle, Hardhat, and Brownie are handy when a local development environment is needed. Learn about smart contracts in-depth in the Solidity section of our guides.
3. Nodes/Web3 providers:
Nodes or Web3 providers are needed to get the data from the blockchain; nodes run a copy of the blockchain. Nodes are an essential part of the web3 developer stack as without nodes, a web3 library cannot interact with smart contracts. They’re like the gateway to the blockchain realm. QuickNode runs powerful nodes worldwide. Using this global network, you can get lightning-fast access to blockchain data and send faster transactions.
4. Wallets:
A Wallet address on a blockchain is the identity of an individual and also holds the owner's various cryptocurrencies. Whenever we want to do a write operation on the blockchain, we need to verify the transaction and pay a fee to the network; this is facilitated using the wallet—for example, MetaMask. You can integrate QuickNode with MetaMask by following this guide here. Or instead create your own ETH address/wallet in either JavaScript, Python, Ruby, Go, or PHP.
Now, let’s try to understand these techs with an example. We’ll deploy a smart contract that gets the live price of ETH-USD from Chainlink’s price feed contract.
The wallet
The Chainlink price feed contract, which we’ll use as an interface in our contract, is deployed on the Kovan Testnet. That means we’ll need to deploy our contract on the Kovan Testnet.
To get started, you will need the MetaMask browser extension to create an ETH wallet and some test ETH, which you can get by going to the Kovan Faucet. You'll need to select Kovan Test Network on your MetaMask wallet and copy the wallet address, go to the faucet page, log in with GitHub or GitLab, paste the wallet address into the text field in the faucet, then click "Send me KETH!".
You can check if you received the test ETH or not by pasting the address into the Kovan Etherscan. If the transaction has been confirmed you should see your balance displayed here.
The contract
Head over to the Ethereum Remix IDE and make a new Solidity file, for example, ethprice.sol.
Paste the following code into your new Solidity script:
pragma solidity ^0.6.7;
import "https://github.com/smartcontractkit/chainlink/blob/master/evm-contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";
contract ethprice {
AggregatorV3Interface internal priceFeed;
constructor() public {
priceFeed = AggregatorV3Interface(0x9326BFA02ADD2366b30bacB125260Af641031331);
}
function getLatestPrice() public view returns (int) {
(
uint80 roundID,
int price,
uint startedAt,
uint timeStamp,
uint80 answeredInRound
) = priceFeed.latestRoundData();
return price;
}
}
Explanation of the code above:
Line 1: Specifying SPDX license type, which is an addition after Solidity ^0.6.8.
Whenever the source code of a smart contract is made available to the public, these licenses can help resolve/avoid copyright issues. If you do not wish to specify any license type, you can use a special license UNLICENSED or simply skip the whole comment (it won’t result in an error, just a warning).
Line 2: Declaring the Solidity version.
Line 4: Importing the Chainlink contract AggregatorV3Interface.sol for price feed.
Line 6: Starting our contract named ethprice.
Line 8: Importing the AggregatorV3Interface contract as priceFeed.
Line 10-12: Initializing the constructor interface for AggregatorV3Interface contract with its address, and storing it in priceFeed variable. Doing this we can refer to the AggregatorV3Interface as priceFeed in our contract.
Line 14: Declaring a function getLatestPrice() for type public, which means that it can be accessed outside of the scope of this function and from other contracts. Stating the mutability as view defines that this function will only view and not write or modify any data on the blockchain. The return keyword along with int indicates that the function will return a value in the form of an integer.
Line 16-20: Declaring five variables roundID, price, startedAt, timeStamp, answeredInRound of type integer. These variables are used by the Chainlink contract to store the values returned.
Line 21: Using the function latestRoundData() of Chainlink’s AggregatorV3Interface contract, which we imported as priceFeed. This function will give us the values like price, timestamp of when the price was updated, and store it in variables which we saw in the previous point.
Line 22: Returning the value of price to getLatestPrice() function, so when the getLatestPrice() function is called it’ll return the value of price.
Compile the smart contract by first clicking on the second icon (Solidity icon) on the left menu and then clicking on “Compile ethprice.sol”.
You may see some warnings after compiling the contract. That is because we didn’t use all the variables of method latestRoundData. The function wants all the five variables to be passed into it. We're just asking for the price, which means it'll throw warnings at us, but we shouldn't have anything to worry about. Ensure to copy the ABI using the ABI button and save it; we’ll need it later to interact with the contract.
Now to deploy the contract click on the third icon from the left menu and select injected Web3 from the dropdown under “Environment”. Then click on “Deploy”(make sure to choose Kovan Testnet on MetaMask before deploying the contract). Approve the transaction from MetaMask.
Now that your contract is deployed, you can locate it under the "Deployed Contracts" section, copy the address of the deployed contract by clicking on the copy button and save it; we’ll need it later to interact with the contract.
The Node
We’ll need a Kovan node to interact with our contract, which is deployed on the Kovan blockchain. We’ll sign up for a free QuickNode plan and copy the HTTP PROVIDER URL that we’ll need later to connect to the blockchain.
The Web3 library
We’ll now write a short JavaScript program using the ethers.js library to interact with our deployed contract.
We’ll install ethers using npm (node package manager), which comes with node.js; learn more about ethers.js in the guide on How to connect to Ethereum network with ethers.js. Open your terminal/cmd, make a new project directory, and then make that directory your current working directory.
mkdir priceDapp
cd priceDapp
Let’s install ethers now:
The most common issue at this step is an internal failure with `node-gyp`. You can follow node-gyp installation instructions here.
Note: You will need to have your python version match one of the compatible versions listed in the instructions above if you encounter the node-gyp issue.
Another common issue is a stale cache; clear your npm cache by simply typing the below into your terminal window:
npm cache clean
If you followed the above steps, ethers.js should be installed now.
Create a JavaScript file `price.js`, and copy-paste the following in it:
var ethers = require('ethers');
var url = 'ADD_YOUR_ETHEREUM_NODE_URL’;
var provider = new ethers.providers.JsonRpcProvider(url);
var address = 'CONTRACT_ADDRESS_FROM_REMIX';
var abi = [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "getLatestPrice",
"outputs": [
{
"internalType": "int256",
"name": "",
"type": "int256"
}
],
"stateMutability": "view",
"type": "function"
}
];
var contract = new ethers.Contract(address,abi,provider);
contract.getLatestPrice().then((result) =>{
console.log("$" +result.toNumber()/100000000);
});
Go ahead and replace `ADD_YOUR_ETHEREUM_NODE_URL` with your QuickNode HTTP provider and `CONTRACT_ADDRESS_FROM_REMIX` with the address of the deployed contract from the above section.
Explanation of the code above:
Line 1: Importing the ethers library.
Line 2: Storing our Quicknode’s URL in the url variable.
Line 3: Instantiating new ethers.providers.JsonRpcProvider instance and storing it in the provider variable.
Line 4: Storing the contract address in the address variable.
Line 5-24: Storing the ABI we got from the previous step in the abi variable.
Line 25: Initializing a contract instance in ethers and connecting it to our deployed contract using the address,abi, and provider.
Line 27: Using the getLatestPrice() from our contract to retrieve ETH’s price in USD and storing it in the result variable.
Line 28: The value from the smart contract is in Big Number, so we’ll need to convert the result to a number and divide it by100000000 to get the value in thousands. Printing the final value to console along with a string $.
Save the file, and run it in your terminal/cmd:
node price
You should now see the latest value of ETH in USD:
Note: The price of ETH/USD can change during your execution; the price in the image above is when this guide was written.
Conclusion
Congratulations :D You’ve taken your first step towards becoming a Web3 developer. We learned what wallets, smart contracts, web3 libraries and nodes are. You also deployed a smart contract and interacted with the contract using ethers.js and QuickNode!
Subscribe to our newsletter for more articles and guides on Ethereum. If you have any feedback, feel free to reach out to us via Twitter. You can always chat with us on our Discord community server, featuring some of the coolest developers you’ll ever meet :)