The guide will introduce you to working with an ERC20 token contract via the EthVigil API endpoints.
These steps are also packaged into a CLI tool designed in Python for you to play around with a pre-supplied 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 EthVigil
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
It is absolutely critical that you would have gone through at least one of our onboarding guides that will teach you the way EthVigil handles user accounts, signing up, logging in, deploying contracts etc.
This 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:
EthVigil 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
In standard mode on our alpha/beta platforms, all REST API calls to EthVigil APIs are converted to native Ethereum transactions that are signed by a fixed address.
Custom signers and proxying features will be introduced in a separate doc.
For the Görli testnet, this address happens to be 0x3dc7d43d5f180661970387a4f89c7e715b567512. Here's a link to the transaction from the example mint() section. so you can verify that the above is indeed the address which signs transactions.
For example, while calling the approve() method through our APIs, the msg.sender as seen on the contract will be the above address.
We 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 Görli testnet.
Did you know the EthVigil Beta instance runs on the Görli testnet?
This 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.
ngrok 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.
./ngrok http 5554
You will see a screen like the following:
Copy the HTTPS forwarding link, https://c019aae8.ngrok.io in this case.
Now 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.
from eth_account.messages import defunct_hash_message
Check 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.
The 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 spend value tokens at most on behalf of the account address of msg.sender i.e. the account that calls approve()
See important notes below for more knowledge.
The following example approves an account 0x774246187E1E2205C5920898eEde0945016080Df to transfer at most 1000 tokens on behalf of 0x3dc7d43d5f180661970387a4f89c7e715b567512.
The 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 EthVigil API.
Observe that the REST endpoint exposed via EthVigil 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.
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.
We assume this scenario: 0x774246187E1E2205C5920898eEde0945016080Df 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 EthVigil APIs out of trust issues
is familiar with Metamask and can load contracts on the Remix IDE to call methods on them
0x3dc7d43d5f180661970387a4f89c7e715b567512 is your identity by default when interacting with smart contracts via EthVigil APIs in beginner-friendly mode
Ensure the account 0x3dc7d43d5f180661970387a4f89c7e715b567512 - is allocated enough tokens for a transferFrom call to be valid. Refer to the mint() section to allocate certain number of tokens to this address. For example,
python cli.py mint 0x3dc7d43d5f180661970387a4f89c7e715b567512 10000
How does he transfer 500 tokens on behalf of 0x3dc7d43d5f180661970387a4f89c7e715b567512 to another account, for example, 0x902Abade63A5CB1b503Fe389aEA5906D18DAAF2b?
He switches to the Goerli network
He loads the contract at address 0x60d26696a483e238b536eda1650b736bbb58b554 (the contract instance used throughout this guide) with the ERC20 token Solidity source code.
He fills 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 Gorli testnet with the transaction hash 0x3acd9d5924748f1d889ea0944230b7f5ed98e43cfc326a38763eeeae339cba52