For this tutorial we are going to deploy 3 smart contracts:
- basic contract
- erc20 contract
- erc721 contract
Setup project
Install hardhat
npm init -y
npm install hardhat
start hardhat project
- Start project with
npx hardhat
. - Choose 'Create a basic sample project' from options
- Download dependencies asked for download, if you missed them, then download them by running
npm install @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers
Add contracts to deploy
Inside contracts
directory put the the contracts you want to deploy.
I am putting 3 contracts as:
1. Basic contract (contracts/Greeter.sol)
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "hardhat/console.sol";
contract Greeter {
string private greeting;
constructor(string memory _greeting) {
console.log("Deploying a Greeter with greeting:", _greeting);
greeting = _greeting;
}
function greet() public view returns (string memory) {
return greeting;
}
function setGreeting(string memory _greeting) public {
greeting = _greeting;
}
}
2. erc20 contract (contracts/PopatToken.sol)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract Popat is ERC20, ERC20Burnable, Ownable {
constructor() ERC20("Popat", "PT") {}
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
}
As we are importing openzepplin files in our contract, hence we are going to install the OpenZepplin npm package in our project as:
npm install @openzeppelin/contracts
3. erc721 contract (contract/PikachuNFT.sol)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
contract Pikachu is ERC721, ERC721Burnable, Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
constructor() ERC721("Pikachu", "PK") {}
function safeMint(address to) public onlyOwner {
_safeMint(to, _tokenIdCounter.current());
_tokenIdCounter.increment();
}
}
Modify hardhat configuration (hardhat.confi.js
):
1. Configure solidity versions
Hardhat supports projects that use different, incompatible versions of solc. You can configure Hardhat to use compiler versions compatible with those files like this:
module.exports = {
solidity: {
compilers: [
{
version: "0.8.4",
},
{
version: "0.6.7",
}
]
}
}
This setup means that a file with a pragma solidity ^0.8.0, ^0.8.1, ..., ^0.8.4 will be compiled with solc 0.8.4 and a file with a pragma solidity ^0.6.0, ..., ^0.6.7 will be compiled with solc 0.6.7
2. Define network configuration
module.exports = {
defaultNetwork: 'rinkeby',
networks: {
rinkeby: {
url: // NETWORK_ENDPOINT_RINKEBY,
accounts: // [ACCOUNT_0_PRIVATE_KEY, ACCOUNT_1_PRIVATE_KEY]
}
namedAccounts: {
account0: 0,
account1: 1
}
}
In each network you define, put node-endpoint-url through which you are going to connect with the network as the value of url
field, the most popular endpoint provider is: https://infura.io/
Get the private keys of the accounts from which you want to deploy the contract and put them as array as value of accounts
field
In namedAccounts
field, you have to define name of account, which you will use while writing deploy code. Value of each account-name is the index-of-account's private-key inside <network-name>.accounts: []
array
3. Define ethereum-api key
module.exports = {
solidity: {
etherscan: {
apiKey: // ETHERSCAN_API_KEY
}
}
4. Import npm packages required in config file
require("@nomiclabs/hardhat-waffle");
require('hardhat-deploy');
The final configuration file on is look like this:
// hardhat.config.js
require("@nomiclabs/hardhat-waffle");
require('hardhat-deploy');
require('dotenv').config()
module.exports = {
solidity: {
compilers: [
{
version: "0.8.4"
}
]
},
defaultNetwork: 'rinkeby',
networks: {
rinkeby: {
url: process.env.NETWORK_ENDPOINT_RINKEBY,
accounts: [process.env.ACCOUNT_0_PRIVATE_KEY, process.env.ACCOUNT_1_PRIVATE_KEY]
}
},
namedAccounts: {
account0: 0,
account1: 1
},
etherscan: {
apiKey: process.env.ETHERSCAN_API_KEY
}
};
You have to install dotenv package to use environment variables as used in above file, else you can also put values directly if your repository is not public.
Deploy Contracts
Install hardhat-deploy plugin as npm install hardhat-deploy
and import it inside 'hardhat.config.js' file as:
require('hardhat-deploy')
Put all deploy scripts under 'deploy' folder so deploy-plugin can detect and execute them
1. Deploy script for Basic contract
// deploy/0_greeter.js
module.exports = async ({getNamedAccounts, deployments}) => {
const {deploy} = deployments;
const {account0, account1} = await getNamedAccounts();
await deploy('Greeter', {
from: account0,
args: ['Mahesh is Learning HardHat!'],
log: true,
});
};
2. Deploy script for erc20 cotract
// deploy/1_popatToken.js
module.exports = async({getNamedAccounts, deployments}) => {
const { deploy } = deployments
const { account0 } = await getNamedAccounts()
await deploy('Popat', {
from: account0,
args: [],
log: true
})
}
3. Deploy script for erc721 contract
// deploy/2_pikchuNFT.js
module.exports = async ({deployments, getNamedAccounts}) => {
const {deploy} = deployments
const {account0} = await getNamedAccounts()
await deploy('Pikachu', {
from: account0,
args: [],
log: true
})
}
As you can see deploy scripts are same for all type of cotracts, the deploy scripts finds the contract by looking at the name of cotract defined inside .sol
file.
E.g. In Greeter.sol file we defined contract name as contract Greeter {
, hence we are using that same contract name inside deploy script as await deploy('Greeter', {
Now, we are ready for the deployment and verification π
Deploy contracts
npx hardhat deploy # deploy contracts to defaulNetwork
# OR
npx hardhat --network rinkeby deploy # deploy contrats to a specific network
Vefify Contracts
npx hardhat etherscan-verify
You can see the progress and contract-addresses in the console when you execute above deploy and vefication commands.
My simple tutorial ends here. Happy Coding ! π
Top comments (0)