This is a workshop for building compliant and privacy-preserving tokens on the Aleo blockchain.
By the end of the workshop, developers should learn:
-
Why Aleo is uniquely positioned to enable compliant private payments and transactions
-
How to create a basic token in Leo
-
How to implement public/private
transferandmintfunctions for that token
If you're new to developing or just want to try out the Leo language, check out the Leo Playground. It's a web-based IDE that's designed to allow developers to build, deploy, and execute programs, all in the browser! It comes with an editor, Github integrations, and a number of utilities to manage programs and interface with the network.
For more experienced developers, the Leo team also maintains plugins for a number of different editors. For specifics on how to install for your favorite editor, check out the Dev Env guide for more information
You'll also need to have the Leo CLI (and Rust) installed locally. Check out the Installation guide for more information.
You'll need some Testnet tokens to deploy your program onchain. Head over to INSERT_LINK_HERE to acquire some.
This is the Leo project where you will be doing all of your coding. Some basic features have been included, including a record type for private balances and a mapping to keep track of public balances
In addition, the function signatures/headers have already been provided for you, as well as a list of features you will need to fill in for each function.
The workshop_ofac.aleo program is designed to mimic an onchain compliance check. It contains a simple mapping of mock "OFAC-sanctioned addresses" and a transition function to validate addresses against that mapping.
This program is already deployed on Testnet, and is added as a remote network dependency in the token_template Leo project. It is here purely for reference. You should NOT need to edit/use anything in workshop_ofac/ or edit your token_template/ dependencies.
First, we're going to build a token program in Leo by filling in the provided template code. The program will include:
-
mint_public&mint_privatefunctions -
transfer_public&transfer_privatefunctions -
Compliance checks against the
sanctionedmapping inworkshop_ofac.aleo
Choose what your token program will be named! This should be longer than 10 characters to avoid additional network fees. It should also not conflict with any existing program on the network.
Once you've decided on a name, change the name of the program at the top of main.leo. Additionally, change the "program" field in the program.json file to match the name of your new program. These two fields MUST match or your program will not compile correctly.
This feature mints new tokens by updating the public mapping value for the recipient. In line with Aleo's async model, it is split into two separate functions:
This is an async transition that is executed offchain and has its corresponding zero-knowledge proof verified onchain.
-
First, you should call the
address_check()function fromworkshop_ofac.aleo. This has already been done for you in the template. -
You should then pass the returned
Futureto themint_public_onchainfunction alongside the other appropriate fields.
This is an async function that is executed onchain.
-
First, await the
address_check : Future. This has already been done for you in the template. -
Set the value for
recipientin thebalancesmapping to the current value plusamount.
This feature mints new tokens by initializing a new private record with the specified amount of tokens for the recipient. In line with Aleo's async model, it is split into two separate functions:
This is an async transition that is executed offchain and has its corresponding zero-knowledge proof verified onchain.
-
First, you should call the
address_check()function fromworkshop_ofac.aleo. -
Next, initialize a
Tokenrecord with therecipientas the owner and theamountas the amount. -
Return the
Tokenrecord and pass theFutureto themint_private_onchainfunction.
This is an async function that is executed onchain.
- Await the
address_check : Future
This feature publicly transfers tokens between two users by deducting the transfer amount from the sender's balance in the public mapping and adding the same value to the recipient's balance
This is an async transition that is executed offchain and has its corresponding zero-knowledge proof verified onchain.
-
First, you should call the
address_check()function fromworkshop_ofac.aleo. -
You should then pass the returned
Futureto thetransfer_public_onchainfunction alongside the other appropriate fields.- For the
senderfield, you can useself.signerto specify the address that initialized the function call
- For the
This is an async function that is executed onchain.
-
First, await the
address_check : Future. -
Next, set the value for
senderin thebalancesmapping to the sender's current value minusamount -
Finally, set the value for
recipientin thebalancesmapping to the recipient's current value plusamount
This feature privately transfers tokens between two users by consuming the sender's Token record and producing two
new Token records. The first is owned by the recipient with the amount sent, and the second is owned by the sender with any leftover amount.
This is an async transition that is executed offchain and has its corresponding zero-knowledge proof verified onchain.
-
First, you should call the
address_check()function fromworkshop_ofac.aleo. -
Next, initialize a
Tokenrecord with therecipientas the owner and theamountas the amount -
Initialize another
Tokenrecord with thesenderas the owner and the remaining balance as the amount -
Return both
Tokenrecords and pass theFutureto themint_private_onchainfunction
This is an async function that is executed onchain.
- Await the
address_check : Future.
Now that you've built and tested your program, you're ready to deploy your program to Testnet. This is where you'll need the Testnet credits mentioned earlier.
After deploying, you should now be able to interact with your deployed program onchain.
-
Publicly mint 100 tokens to your address
-
Publicly transfer those tokens to
<WORKSHOP_ADDRESS> -
Privately mint an additional 100 tokens to your address
-
Privately transfer those tokens to
<WORKSHOP_ADDRESS>
