diff --git a/token/README.md b/token/README.md
index f1509b7..d1aa9f6 100644
--- a/token/README.md
+++ b/token/README.md
@@ -27,6 +27,8 @@ The `.env` file contains a private key and address. This is the account that wil
* [Step 3: Private Transfer](#step3)
* [Step 4: Public to Private Transfer](#step4)
* [Step 5: Private to Public Transfer](#step5)
+* [Step 6: Public Burn](#step6)
+* [Step 7: Private Burn](#step7)
We'll be conducting a transfer between two parties.
@@ -137,3 +139,33 @@ leo run transfer_private_to_public "{
```
When we call `transfer_private_to_public`, we take Bob's private record that contains 110 tokens, and outputs a record owned by Bob with 70 tokens, and calls the finalize function under `transfer_private_to_public` with Alice's address and 40 tokens as arguments. This changes the public mapping under Alice's address to contain 100 public tokens. Again, public mappings are queryable on-chain.
+
+## Public Burn
+
+Let's burn 30 of Alice's public tokens. Switch the private key back to Alice.
+
+```bash
+echo "
+NETWORK=testnet3
+PRIVATE_KEY=APrivateKey1zkp1w8PTxrRgGfAtfKUSq43iQyVbdQHfhGbiNPEg2LVSEXR
+" > .env
+
+leo run burn_public 30u64
+```
+
+The output of the finalize function of `burn_public`, which takes the arguments Alice's address and the amount of tokens to burn publicly. This information is shown on-chain and can be queried on a network.
+
+## Private Burn
+
+Now let's privately burn 20 tokens for Bob. Switch to Bob's private key and privately burn 20 tokens for Bob.
+
+```bash
+echo "
+NETWORK=testnet3
+PRIVATE_KEY=APrivateKey1zkpFo72g7N9iFt3JzzeG8CqsS5doAiXyFvNCgk2oHvjRCzF
+" > .env
+
+leo run burn_private 20u64
+```
+
+The output is a private record.
diff --git a/token/build/main.aleo b/token/build/main.aleo
index 8f45b49..be567e8 100644
--- a/token/build/main.aleo
+++ b/token/build/main.aleo
@@ -12,7 +12,8 @@ mapping account:
function mint_public:
input r0 as address.public;
input r1 as u64.public;
- async mint_public r0 r1 into r2; output r2 as token.aleo/mint_public.future;
+ async mint_public r0 r1 into r2;
+ output r2 as token.aleo/mint_public.future;
finalize mint_public:
input r0 as address.public;
@@ -32,7 +33,8 @@ function mint_private:
function transfer_public:
input r0 as address.public;
input r1 as u64.public;
- async transfer_public self.caller r0 r1 into r2; output r2 as token.aleo/transfer_public.future;
+ async transfer_public self.caller r0 r1 into r2;
+ output r2 as token.aleo/transfer_public.future;
finalize transfer_public:
input r0 as address.public;
@@ -63,7 +65,8 @@ function transfer_private_to_public:
input r2 as u64.public;
sub r0.amount r2 into r3;
cast r0.owner r3 into r4 as token.record;
- async transfer_private_to_public r1 r2 into r5; output r4 as token.record;
+ async transfer_private_to_public r1 r2 into r5;
+ output r4 as token.record;
output r5 as token.aleo/transfer_private_to_public.future;
finalize transfer_private_to_public:
@@ -78,7 +81,8 @@ function transfer_public_to_private:
input r0 as address.public;
input r1 as u64.public;
cast r0 r1 into r2 as token.record;
- async transfer_public_to_private self.caller r1 into r3; output r2 as token.record;
+ async transfer_public_to_private self.caller r1 into r3;
+ output r2 as token.record;
output r3 as token.aleo/transfer_public_to_private.future;
finalize transfer_public_to_private:
@@ -87,3 +91,24 @@ finalize transfer_public_to_private:
get.or_use account[r0] 0u64 into r2;
sub r2 r1 into r3;
set r3 into account[r0];
+
+
+function burn_public:
+ input r0 as u64.public;
+ cast self.caller r0 into r1 as token.record;
+ async burn_public self.caller r0 into r2;
+ output r1 as token.record;
+ output r2 as token.aleo/burn_public.future;
+
+finalize burn_public:
+ input r0 as address.public;
+ input r1 as u64.public;
+ get.or_use account[r0] 0u64 into r2;
+ sub r2 r1 into r3;
+ set r3 into account[r0];
+
+
+function burn_private:
+ input r0 as u64.private;
+ cast self.caller r0 into r1 as token.record;
+ output r1 as token.record;
diff --git a/token/run.sh b/token/run.sh
index 99e76d9..3abb9ad 100755
--- a/token/run.sh
+++ b/token/run.sh
@@ -311,3 +311,96 @@ When we call transfer_private_to_public, we take Bob's private record that conta
######## ########
###############################################################################
"
+
+echo "
+Let's burn 30 of Alice's public tokens. Switch the private key back to Alice.
+
+echo '
+NETWORK=testnet3
+PRIVATE_KEY=APrivateKey1zkp1w8PTxrRgGfAtfKUSq43iQyVbdQHfhGbiNPEg2LVSEXR
+' > .env
+
+leo run burn_public 30u64
+"
+
+echo "
+NETWORK=testnet3
+PRIVATE_KEY=APrivateKey1zkp1w8PTxrRgGfAtfKUSq43iQyVbdQHfhGbiNPEg2LVSEXR
+" > .env
+
+leo run burn_public 30u64
+
+echo "
+When we call burn_public, we take Alice's public record that contains 100 tokens, and outputs a record owned by Alice with 70 tokens, and calls the finalize function under burn_public with Alice's address via "self.caller" and 30 tokens as arguments. This changes the public mapping under Alice's address to contain 70 public tokens. Again, public mappings are queryable on-chain.
+
+###############################################################################
+######## ########
+######## STEP 6: Burn 30 of Alice's public tokens ########
+######## ########
+######## ----------------------------------------- ########
+######## | PUBLIC BALANCES | ########
+######## ----------------------------------------- ########
+######## ----------------------------------------- ########
+######## | Alice | 70 | ########
+######## ----------------------------------------- ########
+######## | Bob | 10 | ########
+######## ----------------------------------------- ########
+######## ########
+######## ----------------------------------------- ########
+######## | PRIVATE BALANCES | ########
+######## ----------------------------------------- ########
+######## ----------------------------------------- ########
+######## | Alice | 20 | ########
+######## ----------------------------------------- ########
+######## | Bob | 70 | ########
+######## ----------------------------------------- ########
+######## ########
+###############################################################################
+"
+
+
+echo "
+Now let's privately burn 20 tokens for Bob. Switch to Bob's private key and privately burn 20 tokens for Bob.
+
+echo '
+NETWORK=testnet3
+PRIVATE_KEY=APrivateKey1zkpFo72g7N9iFt3JzzeG8CqsS5doAiXyFvNCgk2oHvjRCzF
+' > .env
+
+leo run burn_private 20u64
+"
+
+echo "
+NETWORK=testnet3
+PRIVATE_KEY=APrivateKey1zkpFo72g7N9iFt3JzzeG8CqsS5doAiXyFvNCgk2oHvjRCzF
+" > .env
+
+leo run burn_private 20u64
+
+echo "
+When burn_private is called by Bob, the output is a private record where Bob's 20 tokens from his private balance will be deducted.
+
+###############################################################################
+######## ########
+######## STEP 7: Burn 20 of Alice's private tokens ########
+######## ########
+######## ----------------------------------------- ########
+######## | PUBLIC BALANCES | ########
+######## ----------------------------------------- ########
+######## ----------------------------------------- ########
+######## | Alice | 70 | ########
+######## ----------------------------------------- ########
+######## | Bob | 10 | ########
+######## ----------------------------------------- ########
+######## ########
+######## ----------------------------------------- ########
+######## | PRIVATE BALANCES | ########
+######## ----------------------------------------- ########
+######## ----------------------------------------- ########
+######## | Alice | 20 | ########
+######## ----------------------------------------- ########
+######## | Bob | 50 | ########
+######## ----------------------------------------- ########
+######## ########
+###############################################################################
+"
\ No newline at end of file
diff --git a/token/src/main.leo b/token/src/main.leo
index 58a02cd..495236d 100644
--- a/token/src/main.leo
+++ b/token/src/main.leo
@@ -126,4 +126,34 @@ program token.aleo {
let sender_amount: u64 = Mapping::get_or_use(account, sender, 0u64);
Mapping::set(account, sender, sender_amount - amount);
}
+
+ transition burn_public(public amount: u64) -> token {
+ // Produce a burn token record for the token receiver.
+ let burn: token = token {
+ owner: self.caller,
+ amount: amount
+ };
+
+ // Output the burnt record.
+ // Decrement the token amount of the caller publicly
+ return burn then finalize(self.caller, amount);
+ }
+
+ finalize burn_public(public sender: address, public amount: u64) {
+ // Decrements `acount[sender]` by `amount`
+ // If `account[sender]` does not exist, it will be created (Technically should already be created)
+ // If `account[sender] - amount` underflows, `burnt_public` is reverted.
+ let sender_amount: u64 = Mapping::get_or_use(account, sender, 0u64);
+ Mapping::set(account, sender, sender_amount - amount);
+ }
+
+ transition burn_private(amount: u64) -> token {
+ // Produce a burn token record for the token receiver.
+ let burn: token = token {
+ owner: self.caller,
+ amount: amount
+ };
+
+ return burn;
+ }
}