Welcome! This is an automated workshop that will explain how to deploy an ERC20 token on StarkNet and customize it to perform specific functions. The ERC20 standard is described here It is aimed at developers that:
- Understand Cairo syntax
- Understand the ERC20 token standard
This workshop is the third in a series that will cover broad smart contract concepts (writing and deploying ERC20/ERC721, bridging assets, L1 <-> L2 messaging...).
You can find the previous tutorials here:
This tutorial was written by Florian Charlier (@trevis_dev) in collaboration with Henri Lieutaud and Lucas Levy, based on Henri's original ERC20 101 and ERC20 102 tutorials for Solidity.
Interested in helping writing those? Reach out!
Don't expect any kind of benefit from using this, other than learning a bunch of cool stuff about StarkNet, the first general purpose validity rollup on the Ethereum Mainnet.
StarkNet is still in Alpha. This means that development is ongoing, and the paint is not dry everywhere. Things will get better, and in the meanwhile, we make things work with a bit of duct tape here and there!
Once you are done working on this tutorial, your feedback would be greatly appreciated! Please fill this form to let us know what we can do to make it better. And if you struggle to move forward, do let us know! This workshop is meant to be as accessible as possible; we want to know if it's not the case.
Do you have a question? Join our Discord server, register and join channel #tutorials-support
- ERC20 on StarkNet
The tutorial has three components:
- An ERC20 token, ticker
ERC20-101
, that is used to keep track of points - An evaluator contract, that is able to mint and distribute
ERC20-101
points - A second ERC20 token, "Dummy Token", ticker
DTK20
, that is used to make fake payments
It is structured in two parts:
- In the first part (
ERC20
), you will have to deploy an ERC-20 contract. - In the second part (
Exercise
), you will deploy another contract that will itself have to interact with ERC20 tokens.
To do this tutorial you will have to interact with the Evaluator.cairo
contract.
The most convenient way to do this is through Voyager. Please do not forget to connect to your wallet when interacting with the evaluator (see below).
To do an exercise you will have to use the evaluator's contract submit_[erc20|exercise]_solution
functions to provide the address of the contract to verify for your exercise solution. Once it's done you can call the appropriate function on the evaluator to verify the desired exercise(s).
For example, to solve the first exercise the workflow would be the following:
- Deploy a smart contract that answers ex2
- Call
submit_erc20_solution
on the evaluator providing your smart contract address - Call
ex2_test_erc20
on the evaluator contract
Your objective is to gather as many ERC20-101 points as possible. Please note :
- The 'transfer' function of ERC20-101 has been disabled to encourage you to finish the tutorial with only one address
- In order to receive points, you will have to reach the calls to the
validate_and_distribute_points_once
function. - This repo contains two interfaces (
IERC20Solution.cairo
andIExerciceSolution.cairo
). For example, for the first part, your ERC20 contract will have to conform to the first interface in order to validate the exercises; that is, your contract needs to implement all the functions described inIERC20Solution.cairo
. - We really recommend that your read the
Evaluator.cairo
contract in order to fully understand what's expected for each exercise. A high level description of what is expected for each exercise is provided in this readme. - The Evaluator contract sometimes needs to make payments to buy your tokens. Make sure he has enough dummy tokens to do so! If not, you should get dummy tokens from the dummy tokens contract and send them to the evaluator.
Your points will get credited in your wallet; though this may take some time. If you want to monitor your points count in real time, you can also see your balance in voyager!
- Go to the ERC20 counter in voyager, in the "read contract" tab
- Enter your address in decimal in the "balanceOf" function
You can also check your overall progress here
You sent a transaction, and it is shown as "undetected" in voyager? This can mean two things:
- Your transaction is pending, and will be included in a block shortly. It will then be visible in voyager.
- Your transaction was invalid, and will NOT be included in a block (there is no such thing as a failed transaction in StarkNet).
You can (and should) check the status of your transaction with the following URL https://alpha4.starknet.io/feeder_gateway/get_transaction_receipt?transactionHash= , where you can append your transaction hash.
- Set up the environment following these instructions
- Install OpenZeppelin's cairo contracts.
pip install openzeppelin-cairo-contracts
- Linux and macos
for mac m1:
alias cairo='docker run --rm -v "$PWD":"$PWD" -w "$PWD" shardlabs/cairo-cli:latest-arm'
for amd processors
alias cairo='docker run --rm -v "$PWD":"$PWD" -w "$PWD" shardlabs/cairo-cli:latest'
- Windows
docker run --rm -it -v ${pwd}:/work --workdir /work shardlabs/cairo-cli:latest
- Clone the repo on your machine
- Test that you are able to compile the project
starknet-compile contracts/Evaluator.cairo
- To convert data to felt use the
utils.py
script
Open Python in interactive mode after running script
python -i utils.py
>>> str_to_felt('ERC20-101')
1278752977803006783537
Today you will deploy your own ERC20 token on StarkNet!
- Create a git repository and share it with the teacher.
- Set up your environment (2 pts). Note that it requires Python 3.7+. These points will be attributed manually if you do not manage to have your contract interact with the evaluator, or automatically in the first question.
📝 Submissions for this part are given to the Evaluator by calling submit_erc20_solution() 📝 (NOT submit_exercise_solution() ) |
---|
-
Call
ex1_assign_rank()
in the evaluator contract to receive a random ticker for your ERC20 token, as well as an initial token supply (1 pt). You can read your assigned ticker and supply inEvaluator.cairo
by calling gettersread_ticker()
andread_supply()
-
Create an ERC20 token contract with the proper ticker and supply. You can use this implementation as a base (2 pts)
-
Deploy it to the Goerli-alpha testnet (1 pts)
-
Call
submit_erc20_solution()
in the Evaluator to configure the contract you want evaluated (2pts) (Previous 3 points for the ERC20 and the deployment are also attributed at that step)
- Call
ex2_test_erc20()
in the evaluator to check ticker and supply and receive your points (2 pts)
The total amount of points to collect from completing all exercises up to this point is : 8 points
- Create a
get_tokens()
function in your contract, deploy it, and call theex3_test_get_token()
function that distributes tokens to the caller (2 pts). get_tokens()
should mint the caller some of your token. It should return the exact amount it sends so the Evaluator can check that the increase of balance and the amount sent corresponds.
The total amount of points to collect from completing all exercises up to this point is : 10 points
- Create a customer allow listing function. Only allow listed users should be able to call
get_tokens()
. - Create a function
request_allowlist()
that the evaluator will call during the exercise check to be allowed to get tokens. - Create a function
allowlist_level()
that can be called by anyone to know whether an account is allowed to get tokens. - Call
ex4_5_6_test_fencing()
in the evaluator to show- It can't get tokens using
get_tokens()
(1 pt) - It can call
request_allowlist()
and have confirmation that it went through (1 pt) - It can then get tokens using the same
get_tokens()
(2 pt)
- It can't get tokens using
The total amount of points to collect from completing all exercises up to this point is : 14 points
- Create a customer multi tier listing function. Only allow listed users should be able to call
get_token()
; and customers should receive a different amount of tokens based on their level - Create a function
request_allowlist_level()
that the evaluator will call during the exercise check to be allowed to get tokens at a certain tier level - Modify the function
allowlist_level()
so that it returns the allowed level of accounts. - Call
ex7_8_9_test_fencing_levels()
in the evaluator to show- It can't get tokens using
get_tokens()
(1 pt) - It can call
request_allowlist_level(1)
, then callget_tokens()
and get N tokens (2 pt) - It can call
request_allowlist_level(2)
, then callget_tokens()
and get > N tokens (2 pt)
- It can't get tokens using
The total amount of points to collect from completing all exercises up to this point is : 19 points
❗Submissions for this part are given to the Evaluator by calling submit_exercise_solution() ❗(instead of submit_erc20_solution() ) |
---|
- Manually claim tokens on the predeployed claimable ERC20 (DTK tokens) (1 pts)
- Claim your points by calling
ex10_claimed_tokens()
in the evaluator (1 pts)
The total amount of points to collect from completing all exercises up to this point is : 21 points
- Create a contract
ExerciseSolution
that:- Can claim and hold DTK tokens on behalf of the calling address
- Keeps track of addresses who claimed tokens, and how much
- Implements a
tokens_in_custody
function to show these claimed amounts
- Deploy
ExerciseSolution
and submit it to the evaluator withsubmit_exercise_solution()
. - Call
ex11_claimed_from_contract()
in the evaluator to prove your code works (3 pts)
- Create a function
withdraw_all_tokens()
inExerciseSolution
to withdraw the claimed tokens from theExerciseSolution
to the address that initially claimed them - Call
ex12_withdraw_from_contract()
in the evaluator to prove your code works (2 pts)
The total amount of points to collect from completing all exercises up to this point is : 26 points
-
get_tokens() should send the caller some of your tokens. It should return the exact amount it sends so the Evaluator can check that the increase of balance and the amount sent corresponds
-
Use ERC20 function to allow your contract to manipulate your DTKs. Call
ex13_approved_exercise_solution()
to claim points (1 pts)
- Use ERC20 to revoke this authorization. Call
ex14_revoked_exercise_solution()
to claim points (1 pts)
- Create a function
deposit_tokens()
through which a user can deposit DTKs inExerciseSolution
, usingtransferFrom
- Call
ex15_deposit_tokens
in the evaluator to prove your code works (2 pts)
The total amount of points to collect from completing all exercises up to this point is : 30 points
- Create and deploy a new ERC20
ExerciseSolutionToken
to track user deposit. This ERC20 should be mintable and mint authorization given toExerciseSolution
- Deploy
ExerciseSolutionToken
and make sure thatExerciseSolution
knows its address - Update the deposit function on
ExerciseSolution
so that user balances are tokenized: when a deposit is made inExerciseSolution
, tokens are minted inExerciseSolutionToken
and transferred to the address depositing - Call
ex16_17_deposit_and_mint
in the evaluator to prove your code works (4 pts)
- Update the
ExerciseSolution
withdraw function so that it usestransferFrom()
inExerciseSolutionToken
, burns these tokens, and returns the DTKs - Call
ex18_withdraw_and_burn
in the evaluator to prove your code works (2 pts)
The total amount of points to collect from completing all exercises up to this point is : 36 points
Congratulations on reaching the end of the tutorial!
As new exercises could be added, there might be additional points to collect in the future, though. Who knows?