- 07 Feb 2022
- 4 Minutes to read
-
Print
-
DarkLight
ERC-20 token
- Updated on 07 Feb 2022
- 4 Minutes to read
-
Print
-
DarkLight
ERC-20 tokens are blockchain-based assets, issued on all EVM compatible blockchain networks such as Polygon, that have value and can be sent and received. These tokens are fungible, meaning they can be exchanged with another token of the same type because they have identical properties and there is an equal value. For example, the ERC-20 token of Alice is exactly the same as the ERC-20 token of Bob. They can exchange their token without consequences.
Examples of fungible assets are currencies, stocks of a company, bonds, gold and other precious metals.
The ERC-20 smart contract is the perfect standard to organize a crowdsale and let companies raise funds to launch their project.
ERC-20 smart contract features
An ERC-20 smart contract is used to create fungible tokens and bring them to the blockchain. This process is called minting. It also keeps track of the total supply as well as the balances of users as they exchange their tokens.
The ERC-20 smart contract on the SettleMint platform has the following features:
- Custom name, symbol and initial supply that can be chosen by the user.
- Minting capabilities that let the admin of the smart contract mint (i.e create) new tokens.
- Pausable capabilities that let the admin pause the contract in case of emergency.
- Burnable capabilities that let users burn (i.e destroy) their token.
By default, the account that deploys the ERC-20 smart contract gets 1,000,000 tokens. You can change this behaviour by modifying the “constructor” in “GenericToken.sol”. If you do not mint tokens in the constructor, make sure to mint some after the deployment.
contract GenericToken is ERC20, ERC20Burnable, Pausable, AccessControl {
constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
_mint(msg.sender, 1000000 * 10**decimals());
}
Deploying an ERC-20 smart contract
To set the name and symbol for your token, go to the “deploy” folder and in “00_Deploy_GenericToken.ts”, change the values in “args” in the “deploy” function.
await deploy('GenericToken', {
from: deployer,
args: ['GenericToken', 'GT'],
log: true,
});
As soon as you are happy with the changes you made, just click on “deploy” in the “task runner” of the IDE and after a few seconds, your ERC-20 smart contract should be deployed on the network of your choice.
The “GenericToken.ts” script in the “test” folder showcases all the functionalities of the ERC-20 standard. It shows you how to use the smart contract in your dapp.
Integration with the Graph Middleware
Working with the data stored on chain and on IPFS is not trivial. In the SettleMint platform we provide you with a middleware solution that allows you to index and query this data easily and efficiently.
At the hard of the middleware solution is the indexer module from The Graph that you can run on your own EVM compatible nodes (both public and consortium networks), your own IPFS node, and fully preconfigured, managed and integrated with the smart contract sets.
We provide two indexing libraries, one by the OpenZeppelin team for all the common smart contracts in their smart contract library, and one by the SettleMint team to extend the capabilities of the OpenZeppelin one, and to provide indexing of the specifics the SettleMint smart contract sets.
The OpenZeppelin set contains the following indexing modules:
- accesscontrol
- erc1155
- erc1967upgrade
- erc20
- erc721
- governor
- ownable
- pausable
- timelock
- voting
The SettleMint set contains the following indexing modules:
- erc721ipfs: to extend the erc721 from openzeppelin to index IPFS metadata of your erc721 tokens
- crowdsale/vestingvault/vestingwallet: to index and expose all the data for the crowdsale contract set
- forwarder: for the ERC20 Meta transactions forwarder data
- statemachinemetadata: to index IPFS metadata for state machines
These are available in the subgraph
folder in your IDE. You can create your own modules for any other data you want to index, or for custom smart contracts not part of the default sets. And you can modify the existing ones if you want to index things a bit different.
How to use the indexing modules
Inside the root of the smart contract set, you will find a file called subgraph.config.template.json
that contains the raw configuration. The important section is the datasources section.
Here we defined the smart contracts with their name (the name of the artifact created in the 'deployments' folder when running the deploy
task) and in the modules array all the indexing modules we want to activate for this smart contract.
You will notice the startblock and address to be 0. These will be filled in using the graph:config
task based on the hardhat deployments.
So, to start, tweak the subgraph.config.template.json
file to your liking, and run the graph:config
task. This will generate subgraph.config.json
for the next steps.
The following tasks need to be run afterwards:
graph:compile
-> usessubgraph.config.json
to generate the graphql schema and subgraph configurationgraph:codegen
-> generates the AssemblyScript types for your contracts ABI based on the output ofgraph:compile
graph:build
-> compiles the WASM files based on the outpts generated bygraph:codegen
graph:deploy
-> deploys the WASM files to IPFS and updates the middleware to start or update the indexing
To make this a bit easier, the graph:all
task executes all these steps in the right order.
Indexing can take a while, but in seconds you can query the middleware for your data.
Writing your own indexing modules
To make a module you need the following:
- Primitives to generate a graphql schema:
subgraph/datasource/x.gql.json
-> In order to allow composability, the schema are not defined in the graphql format but rather in a dedicated json format which is can be assembled and compiled to graphql. - Template to generate a subgraph manifest:
subgraph/datasource/x.yaml
-> This file lists all the events that the datasources should listen to, and links that to the corresponding indexing logic. - Indexing logic:
subgraph/datasources/x.ts
and (optionally)subgraph/fetch/x.ts
-> This is the core logic that processes the events and to index the onchain activity.
To learn more, check out https://github.com/OpenZeppelin/openzeppelin-subgraphs