Working with an ERC20 token contract
The guide will introduce you to working with an ERC20 token contract via the MaticVigil API endpoints.
Please note that this guide deploys and interacts with a ERC20 contract on the Matic sidechain, and not the Ethereum main chain. Creation and transfer of tokens on the Matic sidechain will not have any effect on your asset holdings and positions in DeFi protocols that run on the Ethereum main chain.
These steps are also packaged into a CLI tool designed in Python for you to play around with an example ERC20 contract. Visit the repo to clone and get hacking away.
Alternately, you can keep a note of
- the private key that identifies your user account uniquely on MaticVigil
- the API key uniquely alloted to your user account that allows you to make authenticated HTTP requests to the REST API endpoints generated for your smart contract
...and follow along the code examples as standalone scripts
#
PrerequisitesIt is absolutely critical that you would have gone through at least one of our onboarding guides that will teach you the way MaticVigil handles user accounts, signing up, logging in, deploying contracts etc.
If you haven't, go check them out.
#
To run the Python code snippetsMake sure you have setup a clean virtualenv and run the following command inside the downloaded repo from Github.
#
Before we begin#
A note about contract ownershipThis contract follows the standard implementations as found in the OpenZeppelin github repo, except for one little detail: we have removed the 'minter role' from the contract access control
Instead of
contract ERC20Mintable is ERC20, MinterRole {
we have
contract ERC20Mintable is ERC20 {
in the implementation of the final inherited token contract.
This is done for a couple of specific reasons:
MaticVigil platform has its own design patterns for dealing with the Ethereum account address that should sign all transactions for a specific user. We will soon have a detailed doc dedicated to this specific topic of identity and key management.
Now that there is no restriction based on ownership and roles, you can test out calls to and event logs on the same contract instance through
- our APIs
- via your own web3 code
- Remix IDE
msg.sender
#
A note about - In standard mode, all REST API calls to MaticVigil APIs are converted to native Ethereum transactions that are signed by a fixed address.
- For the Matic mainnet, this address happens to be
0xa3f36A33E66aDEb98e08Fe1Bd96B4C58517C64C4
. Here's a link to the transaction from the examplemint()
section. so you can verify that the above is indeed the address which signs transactions.
- For the Matic mainnet, this address happens to be
Custom signers and proxying features will be introduced in a separate doc.
For example, while calling the
approve()
method through our APIs, themsg.sender
as seen on the contract will be the above address.
#
Running the included CLI script to execute ERC20 functionsInstall the required Python modules.
You have to create a
settings.json
file for the command line script,cli.py
to work. Make a local copy of thesettings.example.json
file included within theerc20/
directory and name itsettings.json
In the setttings.json
file, leave the contractAddress
field to be filled after the Deploy step, and fill up the API endpoints, API key and the identity address associated with your MaticVigil account from ~/.maticvigil/settings.json
. The API endpoints have been filled below as an example for your convenience.
#
Deploy the ERC20 contractYou can find the Solidity source code here.
You can deploy the contract from the web UI or follow the code examples below.
Equivalent command for the CLI tool included
#
Setup a webhook integrationWe will set this up before we proceed any further with sending transactions to the ERC20 contract. Most of the transactions will generate multiple events and it would be nice to see a live update of the events being emitted on the Matic mainnet.
#
Launch the bundled webhook listenerThis will launch a server locally on the port 5554. In the next section, we are going to open up a tunnel to it so that it is accessible remotely to deliver event data payloads.
Find the file webhook_listener.py
here.
#
Launch ngrokngrok is a free service to expose your local web server and quickly test out webhook integrations. Click on the link above to download and setup the tool if you don't have it already.
Then open a tunnel to port 5554, where the local webhook listner is running.
You will see a screen like the following:
Copy the HTTPS forwarding link, https://c019aae8.ngrok.io
in this case.
#
Register ngrok endpoint as webhookNow we register the ngrok link from above as a webhook endpoint. This returns us a ID for this endpoint against which event data and other integrations can be configured.
Equivalent ERC20 CLI tool command
#
Setup the endpoint to receive event dataWe are now going to ask the MaticVigil platform to send us the data associated with events Transfer
and Approval
whenever they are emitted.
Equivalent ERC20 CLI tool command
#
Working with the ERC20 InterfaceWe are going to work with the methods as specified by the interface.
#
MintingIf you check the total supply of tokens of the contract right after deployment, you will find it to be 0.
Equivalent ERC20 CLI tool command
This is a good starting point. Let us mint a bunch of tokens and 'airdrop' to an address. This also increases the total supply of tokens.
Equivalent ERC20 CLI tool command
Remember the webhook setup we did in the earlier section? It should deliver an update on an emitted event, similar to this
You can refer to the previous section on checking the total supply to verify the effects of the minting process.
#
balanceOfCheck the tokens allotted to any Ethereum address on this contract instance. Corresponds to the method function balanceOf(address who) external view returns (uint256);
specified in the standard ERC20 interface.
Equivalent ERC20 CLI tool command
#
ApproveThe ERC20 standard allows a spender account to spend an allowed number of tokens on behalf of msg.sender
.
approve(address spender, uint256 value)
is the relevant method where this feature is implemented.
In the smart contract included in this example, this approves
spender
to spendvalue
tokens at most on behalf of the account address ofmsg.sender
i.e. the account that calls approve() See important notes below for more knowledge.
Refer to the section on msg.sender
to get reacquainted with the identity of msg.sender
when calling MaticVigil APIs in standard mode.
The following example approves an account 0x69609c1dB6D1174a3eeC836f4CE514759c512c31
to transfer at most 1000
tokens on behalf of 0xa3f36A33E66aDEb98e08Fe1Bd96B4C58517C64C4
.
Equivalent ERC20 CLI tool command
The webhook listener should have received a JSON payload corresponding to the Approval
event being emitted.
From a security standpoint, the 'approve' feature carries serious vulnerabilties. We encourage you to research on the same.
#
Check allowanceThe ERC20 contract interface specifies a method
function allowance(address owner, address spender) external view returns (uint256);
This makes it easy for us to check on a dApp whether we should proceed with a transfer if it exceeds the configured allowance.
We will achieve the same via MaticVigil API.
Observe that the REST endpoint exposed via MaticVigil for this specific method is
/<contractaddress>/allowance/{owner}/{spender}
. We are accessing the information as if it were a resource of allowance mappings between owners and spenders.
Equivalent ERC20 CLI tool command
#
Increase allowanceThe method corresponding to this is function increaseAllowance(address spender, uint256 addedValue) public returns (bool)
This is functionally similar to approve()
but mitigates certain security vulnerabilities exposed by it.
Equivalent ERC20 CLI tool command
You will see the updated allowance data being delivered to the webhook listener via MaticVigil integrations
#
Decrease allowanceEquivalent ERC20 CLI tool command
You will see the updated allowance data being delivered to the webhook listener via MaticVigil integrations
#
Working with Metamask/web3 (a dApp experience)Metamask/ web3.py/ web3.js happen to be quite popular approaches among beginners and experienced Ethereum developers alike to interact with smart contracts and prototype iteratively.
On testnets, this is a great way to test out how your smart contracts would behave for users with different identities because it costs nothing to switch account addresses and send out a bunch of transactions from them.
Keeping this in mind, the following is an example that is a follow up to the section on Approval
This example makes it easier since we have removed ownership roles and access control on the contract, so that anyone can play around with it.
#
Transfer tokens on behalfRefer the sections for a refresher if you feel lost.
We assume this scenario:
0x69609c1dB6D1174a3eeC836f4CE514759c512c31
is a user sitting in a distant land who- is authorized to transfer at most 1000 tokens on your behalf.
- not familiar with REST APIs
- does not want to use MaticVigil APIs out of trust issues
- is familiar with Metamask and can load contracts on the Remix IDE to call methods on them
0xa3f36A33E66aDEb98e08Fe1Bd96B4C58517C64C4
is your identity by default when interacting with smart contracts via MaticVigil APIs in beginner-friendly mode
Ensure the account
0xa3f36A33E66aDEb98e08Fe1Bd96B4C58517C64C4
- is allocated enough tokens for a transferFrom call to be valid. Refer to themint()
section to allocate certain number of tokens to this address. For example,python cli.py mint 0xa3f36A33E66aDEb98e08Fe1Bd96B4C58517C64C4 10000
For
transferFrom()
to work, ensure you have set the allowance through callingapprove()
, as demonstrated in this section
How does 0x69609c1dB6D1174a3eeC836f4CE514759c512c31
transfer 500 tokens on behalf of 0xa3f36A33E66aDEb98e08Fe1Bd96B4C58517C64C4
to another account, for example, 0x902Abade63A5CB1b503Fe389aEA5906D18DAAF2b
?
- They switch to the Matic Mainnet
- They load the contract at address
0x4cf160bfb347871d20f06b3ca3542b423d9161f8
(the contract instance used throughout this guide) with the ERC20 token Solidity source code.
- They fill in the input fields for the
transferFrom
method and submits the transaction
The transaction is soon confirmed
The transaction demonstrated can be found on the Matic mainnet with the transaction hash 0x23fcc05a5828cb4a977c83e1684e0196212d3bb5d56612bfbe377a63944ad56f
Explorer link - https://explorer.matic.network/tx/0x23fcc05a5828cb4a977c83e1684e0196212d3bb5d56612bfbe377a63944ad56f
- This should generate two events
Transfer
, corresponding to the actual transferApproval
event indicating the updated allowance after deducting 500 tokens
Remember the webhook listener? Yep, it is still alive. It should have received these two events.