By the end of this tutorial you will be able to do the following:
-Create your own custom ERC-20 token,
– Deploy a faucet smart contract on any of the Ethereum-compatible blockchain networks (Polygon, Rinkeby, Arbitrum, Kovan…)
For start, deploy four token on Rinkeby testnet.
Get some test Ether from on the Rinkeby network, and follow the steps.
Go to https://faucet.rinkeby.io/
There you can get test Ether by posting a tweet or a Facebook post containing your Metamask address. If you are worrying about privacy, this is a legitimate concern as anybody will now be able to link your Twitter or Facebook with your ETH address. Once somebody knows your address they can see all your purchases on the public blockchain. If you buy something embarrassing like a membership for an adult site then your friends could know that, so it is better to create alternative Twitter account to request free ETH.
Once you have recieved free ETH for testing, change the network on Metamask to “Rinkeby Test” and go to https://remix.ethereum.org/
Remix is a browser-based compiler and IDE that enables users to build Ethereum contracts with Solidity language and to deploy it on Ethereum like blockchains.
Click on create new file.
Name your file MyToken.sol, and paste the following code in it.
// SPDX-License-Identifier: UNLISCENSED
pragma solidity 0.8.4;
contract SampleBEP20Token {
string public name = "MYCOIN";
string public symbol = "MYC";
uint256 public totalSupply = 1000000000000000000000000; // 1 million tokens
uint8 public decimals = 18;
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed _from, address indexed _to, uint256 _value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(
address indexed _owner,
address indexed _spender,
uint256 _value
);
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
/**
* @dev Constructor that gives msg.sender all of existing tokens.
*/
constructor() {
balanceOf[msg.sender] = totalSupply;
}
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address _to, uint256 _value)
public
returns (bool success)
{
require(balanceOf[msg.sender] >= _value);
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
emit Transfer(msg.sender, _to, _value);
return true;
}
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address _spender, uint256 _value)
public
returns (bool success)
{
allowance[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address _from,
address _to,
uint256 _value
) public returns (bool success) {
require(_value <= balanceOf[_from]);
require(_value <= allowance[_from][msg.sender]);
balanceOf[_from] -= _value;
balanceOf[_to] += _value;
allowance[_from][msg.sender] -= _value;
emit Transfer(_from, _to, _value);
return true;
}
}
This is a code for HRZ token.
As you can see, HerzCoin is a BEP-20 which is a token standard on Binance Smart Chain that extends ERC-20, the most common Ethereum token standard.
In the code all you need to change is bolded text. Enter the name of your token and a ticker for your token.
Lines 6 and 7.
string public name = “MYCOIN“;
string public symbol = “MYC“;
After you have chosen the name and ticker for your coin you can deploy it to Rinkeby testnet. You can also change total supply, by changing line 8 in smart contract.
Currently it is at one million tokens.
uint256 public totalSupply = 1000000000000000000000000; // 1 million tokens
After you have entered your token name and symbol, you can right click MyToken.sol file in Remix IDE and compile it.
Solidity icon in the upper left corner should turn green, and when you hover with mouse over it it will say compilation succesful.
After that click on the Etherium icon which is just below the Solidity icon.
Prior to deploying your contract on Rinkeby testnet, you need to change the enviroment to Injected Web3, and choose contract so that it states Sample BEP20 token – MyToken.sol.
After that, click on the Deploy button.
Next you will get a Metamask pop-up to confirm the deployment of the smart contract on Rinkeby.
I had problems with Brave browser, so if you do not get a Metamask pop up try changing your browser to Chrome or Firefox.
After confirming the transaction, you will get a notification in Metamask that your contract is deployed.
This smart contract creates 1 million tokens which are sent to its creator address.
To see your coins, in your Metamaks wallet you need to click on Ad token.
Copy and paste your Token contract address, symbol and a decimal in Metamask.
Your decimal is 2. If you enter another decimal you will have problems seeing exact number of your tokens.
Smart contract for your token can be found under the “deployed contracts” ticker in Remix IDE.
You should see that you have one millions new tokens in your Metamask wallet, with your ticker and symbol.
Congratulations, you have successfully deployed your first token on the Rinkeby testnet.
If you want to deploy this token to Polygon or Etherium you will need to have some MATIC or ETH to pay for gas fees.
In the time of this writing MATIC mainnet faucets give you enough MATIC to deploy smart contracts on Polygon, but if you want to deploy your coin on ETH you will have to buy some ETH from exchanges like Coinbase.
Here are two Matic mainnet faucets you can use to deploy your token to Polygon mainnet;
https://macncheese.finance/matic-polygon-mainnet-faucet.php
You can get 0.001 MATIC from the faucet at this point in time.
Next thing you need to do is to make a faucet for your token so that anyone on the Internet can claim it. Faucets are created in order to spread the adoption of crypto.
Navigate to the Remix IDE.
Create a new file called Faucet.sol and add the following contents to the file:
// SPDX-License-Identifier: UNLISCENSED
pragma solidity ^0.8.4;
interface IERC20 {
/**
* @dev returns the tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev returns the decimal places of a token
*/
function decimals() external view returns (uint8);
/**
* @dev transfers the `amount` of tokens from caller's account
* to the `recipient` account.
*
* returns boolean value indicating the operation status.
*
* Emits a {Transfer} event
*/
function transfer(address recipient, uint256 amount)
external
returns (bool);
}
contract SMTFaucet {
// The underlying token of the Faucet
IERC20 token;
// The address of the faucet owner
address owner;
// For rate limiting
mapping(address=>uint256) nextRequestAt;
// No.of tokens to send when requested
uint256 faucetDripAmount = 1;
// Sets the addresses of the Owner and the underlying token
constructor (address _smtAddress, address _ownerAddress) {
token = IERC20(_smtAddress);
owner = _ownerAddress;
}
// Verifies whether the caller is the owner
modifier onlyOwner{
require(msg.sender == owner,"FaucetError: Caller not owner");
_;
}
// Sends the amount of token to the caller.
function send() external {
require(token.balanceOf(address(this)) > 1,"FaucetError: Empty");
require(nextRequestAt[msg.sender] < block.timestamp, "FaucetError: Try again later");
// Next request from the address can be made only after 5 minutes
nextRequestAt[msg.sender] = block.timestamp + (5 minutes);
token.transfer(msg.sender,faucetDripAmount * 10**token.decimals());
}
// Updates the underlying token address
function setTokenAddress(address _tokenAddr) external onlyOwner {
token = IERC20(_tokenAddr);
}
// Updates the drip rate
function setFaucetDripAmount(uint256 _amount) external onlyOwner {
faucetDripAmount = _amount;
}
// Allows the owner to withdraw tokens from the contract.
function withdrawTokens(address _receiver, uint256 _amount) external onlyOwner {
require(token.balanceOf(address(this)) >= _amount,"FaucetError: Insufficient funds");
token.transfer(_receiver,_amount);
}
}
This code is from Betterprogramming.pub, and you do not need to change anything to make it function.
Right click on Faucet.sol and compile it.
Once compiled, click on the Etherium icon to deploy smart contract.
Change the enviroment to Injected Web3 and contract to SMTFaucet – faucet.sol.
Next thing you need to do is to enter the address of your token and the addres of the faucet owner. Click on the dropdown menu next to Deploy button.
Now you need to enter your Token addres into SMTADDRES field, and your own Metamask wallet addres next to your own OWNERADDRESS field.
After you have done that, you can click on the Deploy button, Metamask will pop up, and after you confirm the transaction you have deployed faucet for your token on Rinkeby testnet.
Next thing you need to do is to verify your smart contract deployed contract on Rinkeby.
This is important so that other users can interact with your contract so that they can withdraw funds from it.
Copy your contract and search for it on Rinkeby (ETH) Blockchain Explorer. If you decide to deploy your coin on Etherium you need to find it and verify it on Etherscan. If you have deployed your contract on Polygon look it up on Polygonscan.
When you click on contract, you will get the message “Are you the contract creator? Verify and Publish your contract source code today!
Click on it and enter the necessary details.
After you have started to verify your contract, you will nedd to enter some basic information.
For Compiler Type enter Solidity (Single file).
You will be asked to provide Open Source License Type, and Compiler Version.
Under licence type, enter No Licence.
Compiler Version must be the same you used in Remix IDE.
In this case, it should be 0.8.4+commit.c7e474f2.
After filling all the fields, click continue.
All you need to do next is to fill out the field Enter the Solidity Contract Code below.
Just copy paste your faucet code from Remix IDE and paste it there, and go to Verify and Publish button.
This is the code you have to copy and paste again.
// SPDX-License-Identifier: UNLISCENSED
pragma solidity ^0.8.4;
interface IERC20 {
/**
* @dev returns the tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev returns the decimal places of a token
*/
function decimals() external view returns (uint8);
/**
* @dev transfers the `amount` of tokens from caller's account
* to the `recipient` account.
*
* returns boolean value indicating the operation status.
*
* Emits a {Transfer} event
*/
function transfer(address recipient, uint256 amount)
external
returns (bool);
}
contract SMTFaucet {
// The underlying token of the Faucet
IERC20 token;
// The address of the faucet owner
address owner;
// For rate limiting
mapping(address=>uint256) nextRequestAt;
// No.of tokens to send when requested
uint256 faucetDripAmount = 1;
// Sets the addresses of the Owner and the underlying token
constructor (address _smtAddress, address _ownerAddress) {
token = IERC20(_smtAddress);
owner = _ownerAddress;
}
// Verifies whether the caller is the owner
modifier onlyOwner{
require(msg.sender == owner,"FaucetError: Caller not owner");
_;
}
// Sends the amount of token to the caller.
function send() external {
require(token.balanceOf(address(this)) > 1,"FaucetError: Empty");
require(nextRequestAt[msg.sender] < block.timestamp, "FaucetError: Try again later");
// Next request from the address can be made only after 5 minutes
nextRequestAt[msg.sender] = block.timestamp + (5 minutes);
token.transfer(msg.sender,faucetDripAmount * 10**token.decimals());
}
// Updates the underlying token address
function setTokenAddress(address _tokenAddr) external onlyOwner {
token = IERC20(_tokenAddr);
}
// Updates the drip rate
function setFaucetDripAmount(uint256 _amount) external onlyOwner {
faucetDripAmount = _amount;
}
// Allows the owner to withdraw tokens from the contract.
function withdrawTokens(address _receiver, uint256 _amount) external onlyOwner {
require(token.balanceOf(address(this)) >= _amount,"FaucetError: Insufficient funds");
token.transfer(_receiver,_amount);
}
}
Now your smart contract should be verified and any blockchain user can interact with it and ask for some of your tokens.
The faucet has four methods:
send()— This function sends 1 of your custom tokens to the requesting wallet. It should be noted that a mapping (nextRequestAt) has been declared to implement a basic rate limit mechanism. There should be at least an interval of five minutes in between two subsequent calls made from a single wallet.setTokenAddress(address) — This method can be used by the faucet owner/admin to update the underlying token address. For example, if we are launching a new version of the token, we can pass the new token address to this method so that the faucet starts dripping the new token instead of the old one. This is somewhat similar to the “Adapter method” that is followed in the Upgradable contracts.setFaucetDripAmount(uint256) — Using this method, the owner can increase or decrease the number of tokens sent per request. The default value is 1 token.withdrawTokens(address,uint256) — The faucet owner can use this to withdraw the tokens from the smart contract.
Aside from the send() method, the other three functions can only be called by the faucet owner.
Next thing you need is to deposit some tokens into the faucet contract.
In your Metamask you have one million custom tokens you just created, so send how much you like to the faucet.
To do that, just copy the address of your faucet and send your custom tokens to that faucet address.
Faucet will drip 1 token at an interval of five minutes to the requesting wallet address, until the funds ran out. Then you will need to send more coins to the faucet.
As the faucet is verified, you can ask one of your friends to claim your custom coins from the faucet.
Send the addres of the faucet to your friend so that he can find it on Rinkeby (ETH) Blockchain Explorer and interact with it.
He should connect his wallet to Rinkeby (ETH) Blockchain Explorer and then click on the Write button underneath the send method.
When you connect to Polygonscan, you can click on the Write button underneath the send method, and your Metamask will pop up asking you to pay for the gas fees. When you confirm the transaction, faucet will send you a coin.
Congratulations, you have successfully deployed your first faucet on the Rinkeby testnet.










