Skip to content

Commit 29a4d4b

Browse files
author
Esau
committed
init
1 parent 486aa01 commit 29a4d4b

File tree

4 files changed

+204
-0
lines changed

4 files changed

+204
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "getting_started_contract"
3+
authors = [""]
4+
compiler_version = ">=1.0.0"
5+
type = "contract"
6+
7+
[dependencies]
8+
aztec = { git = "https://github.com/AztecProtocol/aztec-packages/", tag = "v0.87.9", directory = "noir-projects/aztec-nr/aztec" }
9+
uint_note = { git = "https://github.com/AztecProtocol/aztec-packages/", tag = "v0.87.9", directory = "noir-projects/aztec-nr/uint-note" }
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
use aztec::macros::aztec;
2+
3+
#[aztec]
4+
pub contract StarterToken {
5+
use aztec::{
6+
state_vars::public_mutable::PublicMutable, map::Map,
7+
macros::{
8+
functions::{initializer, public},
9+
storage::storage,
10+
},
11+
protocol_types::address::AztecAddress
12+
};
13+
14+
#[storage]
15+
struct Storage<Context> {
16+
balances: Map<AztecAddress, PublicMutable<u128, Context>, Context>,
17+
owner: PublicMutable<AztecAddress, Context>,
18+
}
19+
20+
#[initializer]
21+
#[public]
22+
fn setup() {
23+
// The deployer (msg_sender) becomes the owner
24+
storage.owner.write(context.msg_sender());
25+
}
26+
27+
#[public]
28+
fn mint(to: AztecAddress, amount: u128) {
29+
assert_eq(context.msg_sender(), storage.owner.read());
30+
31+
let recipient_balance = storage.balances.at(to).read();
32+
33+
storage.balances.at(to).write(recipient_balance + amount);
34+
}
35+
36+
#[public]
37+
fn transfer(to: AztecAddress, amount: u128) {
38+
let sender = context.msg_sender();
39+
40+
let sender_balance = storage.balances.at(sender).read();
41+
42+
assert(sender_balance >= amount, "Cannot transfer more than the balance of the user");
43+
44+
storage.balances.at(sender).write(sender_balance - amount);
45+
46+
let recipient_balance = storage.balances.at(to).read();
47+
48+
storage.balances.at(to).write(recipient_balance + amount);
49+
}
50+
51+
#[public]
52+
fn transfer_ownership(new_owner: AztecAddress) {
53+
let maybe_contract_owner = context.msg_sender();
54+
55+
assert_eq(context.msg_sender(), storage.owner.read());
56+
57+
storage.owner.write(new_owner);
58+
}
59+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "getting_started_contract"
3+
authors = [""]
4+
compiler_version = ">=1.0.0"
5+
type = "contract"
6+
7+
[dependencies]
8+
aztec = { git = "https://github.com/AztecProtocol/aztec-packages/", tag = "v0.87.9", directory = "noir-projects/aztec-nr/aztec" }
9+
uint_note = { git = "https://github.com/AztecProtocol/aztec-packages/", tag = "v0.87.9", directory = "noir-projects/aztec-nr/uint-note" }
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
use aztec::macros::aztec;
2+
3+
#[aztec]
4+
pub contract StarterToken {
5+
use aztec::{
6+
state_vars::{private_set::PrivateSet, public_mutable::PublicMutable, map::Map},
7+
messages::logs::note::encode_and_encrypt_note_unconstrained,
8+
note::note_viewer_options::NoteViewerOptions,
9+
macros::{
10+
functions::{initializer, private, public, utility, internal},
11+
storage::storage,
12+
},
13+
protocol_types::address::AztecAddress,
14+
};
15+
16+
#[storage]
17+
struct Storage<Context> {
18+
balances: Map<AztecAddress, PublicMutable<u128, Context>, Context>,
19+
owner: PublicMutable<AztecAddress, Context>,
20+
// ===============
21+
private_balances: Map<AztecAddress, PrivateSet<UintNote, Context>, Context>,
22+
}
23+
24+
#[initializer]
25+
#[public]
26+
fn setup() {
27+
// The deployer (msg_sender) becomes the owner
28+
storage.owner.write(context.msg_sender());
29+
}
30+
31+
#[public]
32+
fn mint(to: AztecAddress, amount: u128) {
33+
_assert_is_owner(context.msg_sender());
34+
35+
let recipient_balance = storage.balances.at(to).read();
36+
37+
storage.balances.at(context.msg_sender()).write(recipient_balance + amount);
38+
}
39+
40+
#[public]
41+
fn transfer(to: AztecAddress, amount: u128) {
42+
let sender = context.msg_sender();
43+
44+
let sender_balance = storage.balances.at(sender).read();
45+
46+
assert(sender_balance >= amount, "Cannot transfer more than the balance of the user");
47+
48+
storage.balances.at(sender).write(sender_balance - amount);
49+
50+
let recipient_balance = storage.balances.at(to).read();
51+
52+
storage.balances.at(to).write(recipient_balance + amount);
53+
}
54+
55+
#[contract_library_function]
56+
fn _assert_is_owner(storage: Storage, maybe_owner: AztecAddress) {
57+
assert_eq(maybe_owner, storage.owner.read());
58+
}
59+
60+
#[public]
61+
fn transfer_ownership(new_owner: AztecAddress) {
62+
let maybe_contract_owner = context.msg_sender();
63+
64+
assert_eq(maybe_owner, storage.owner.read());
65+
66+
storage.owner.write(new_owner);
67+
}
68+
69+
// ===============
70+
71+
#[private]
72+
fn mint_private(to: AztecAddress, amount: u128) {
73+
GettingStarted::at(context.this_address())._assert_is_owner(context.msg_sender()).enqueue(&mut context);
74+
75+
storage.private_balances.at(to)
76+
.insert(UintNote::new(value, to))
77+
.emit(encode_and_encrypt_note(&mut context, to));
78+
}
79+
80+
#[private]
81+
fn transfer_private(to: AztecAddress, amount: u128) {
82+
let sender = context.msg_sender();
83+
84+
// This can be optimized with a preprocessor
85+
// This will fail in a case where the accumulated note value < amount, but we have more notes than what can be read in one iteration.
86+
let notes = storage.private_balances.at(sender).pop_notes(NoteGetterOptions::new());
87+
88+
// This is a very naive approach that just consolidates all the user's notes into one change note.
89+
let mut subtracted = 0 as u128;
90+
for i in 0..notes.len() {
91+
let note = notes.get_unchecked(i);
92+
subtracted = subtracted + note.get_value();
93+
}
94+
95+
assert(subtracted >= amount);
96+
97+
storage.private_balances.at(to)
98+
.insert(UintNote::new(amount, to))
99+
.emit(encode_and_encrypt_note_unconstrained(&mut context, to));
100+
101+
let change = subtracted - amount;
102+
103+
// This possibly creates a change note of 0, but that is okay in our case because we will be consolidating via this method
104+
storage.private_balances.at(sender)
105+
.insert(UintNote::new(change, sender))
106+
.emit(encode_and_encrypt_note_unconstrained(&mut context, sender, sender));
107+
}
108+
109+
#[public]
110+
#[internal]
111+
fn _assert_is_owner(maybe_owner: AztecAddress) {
112+
assert_eq(maybe_owner, storage.owner.read());
113+
}
114+
115+
#[utility]
116+
unconstrained fn balance_of(owner: AztecAddress) -> u128 {
117+
let notes = storage.private_balances.at(owner).view_notes(NoteViewerOptions::new());
118+
119+
let mut amount = 0 as u128;
120+
for i in 0..notes.len() {
121+
let note = notes.get_unchecked(i);
122+
amount = amount + note.get_value();
123+
}
124+
125+
amount
126+
}
127+
}

0 commit comments

Comments
 (0)