Skip to content

Commit 0869ae2

Browse files
author
Esau
committed
init
1 parent 486aa01 commit 0869ae2

File tree

15 files changed

+284
-1
lines changed

15 files changed

+284
-1
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
target
1+
target
2+
.DS_Store
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "external_call_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+
starter_token = { path = "../nr" }
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use aztec::macros::aztec;
2+
3+
#[aztec]
4+
pub contract ExternalCall {
5+
use aztec::{
6+
macros::functions::private,
7+
protocol_types::address::AztecAddress,
8+
};
9+
10+
use dep::starter_token::StarterToken;
11+
12+
#[private]
13+
fn call_mint_on_other_contract(contract_address: AztecAddress, to: AztecAddress, amount: u128) {
14+
StarterToken::at(contract_address).mint_private(to, amount).call(&mut context);
15+
}
16+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "starter_token_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: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
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,
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_eq(maybe_owner, storage.owner.read());
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+
#[public]
56+
fn transfer_ownership(new_owner: AztecAddress) {
57+
let maybe_contract_owner = context.msg_sender();
58+
59+
assert_eq(maybe_owner, storage.owner.read());
60+
61+
storage.owner.write(new_owner);
62+
}
63+
64+
// ===============
65+
66+
#[private]
67+
fn mint_private(to: AztecAddress, amount: u128) {
68+
GettingStarted::at(context.this_address())._assert_is_owner(context.msg_sender()).enqueue(&mut context);
69+
70+
storage.private_balances.at(to)
71+
.insert(UintNote::new(value, to))
72+
.emit(encode_and_encrypt_note(&mut context, to));
73+
}
74+
75+
#[private]
76+
fn transfer_private(to: AztecAddress, amount: u128) {
77+
let sender = context.msg_sender();
78+
79+
// This can be optimized with a preprocessor
80+
// 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.
81+
let notes = storage.private_balances.at(sender).pop_notes(NoteGetterOptions::new());
82+
83+
// This is a very naive approach that just consolidates all the user's notes into one change note.
84+
let mut subtracted = 0 as u128;
85+
for i in 0..notes.len() {
86+
let note = notes.get_unchecked(i);
87+
subtracted = subtracted + note.get_value();
88+
}
89+
90+
assert(subtracted >= amount);
91+
92+
storage.private_balances.at(to)
93+
.insert(UintNote::new(amount, to))
94+
.emit(encode_and_encrypt_note(&mut context, to));
95+
96+
let change = subtracted - amount;
97+
98+
// This possibly creates a change note of 0, but that is okay in our case because we will be consolidating via this method
99+
storage.private_balances.at(sender)
100+
.insert(UintNote::new(change, sender))
101+
.emit(encode_and_encrypt_note(&mut context, sender, sender));
102+
}
103+
104+
#[public]
105+
#[internal]
106+
fn _assert_is_owner(maybe_owner: AztecAddress) {
107+
assert_eq(maybe_owner, storage.owner.read());
108+
}
109+
110+
#[utility]
111+
unconstrained fn balance_of(owner: AztecAddress) -> u128 {
112+
let notes = storage.private_balances.at(owner).view_notes(NoteViewerOptions::new());
113+
114+
let mut amount = 0 as u128;
115+
for i in 0..notes.len() {
116+
let note = notes.get_unchecked(i);
117+
amount = amount + note.get_value();
118+
}
119+
120+
amount
121+
}
122+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "getting-started",
3+
"version": "1.0.0",
4+
"description": "",
5+
"license": "ISC",
6+
"author": "",
7+
"type": "module",
8+
"scripts": {
9+
"build": "npx tsc",
10+
"start": "npm run build && node dist/src/index.js"
11+
},
12+
"dependencies": {
13+
"@aztec/accounts": "^0.87.9",
14+
"@aztec/aztec.js": "^0.87.9"
15+
},
16+
"devDependencies": {
17+
"typescript": "^5.8.3"
18+
}
19+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { GettingStartedContract } from '../artifacts/GettingStarted.js';
2+
import {
3+
Fr,
4+
createPXEClient,
5+
waitForPXE,
6+
} from '@aztec/aztec.js';
7+
import { getInitialTestAccountsWallets } from '@aztec/accounts/testing';
8+
9+
const pxe = createPXEClient('http://localhost:8080');
10+
await waitForPXE(pxe);
11+
12+
const wallets = await getInitialTestAccountsWallets(pxe);
13+
const deployerWallet = wallets[0];
14+
15+
const contractDeploymentSalt = Fr.random();
16+
const gettingStartedContract = await GettingStartedContract
17+
.deploy(deployerWallet)
18+
.send({ contractAddressSalt: contractDeploymentSalt }).wait();
19+
20+
console.log('Contract Address', gettingStartedContract.contract.address);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"compilerOptions": {
3+
"target": "esnext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
4+
"module": "nodenext", /* Specify what module code is generated. */
5+
"moduleResolution": "nodenext", /* Specify how TypeScript looks up a file from a given module specifier. */
6+
"resolveJsonModule": true, /* Enable importing .json files. */
7+
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
8+
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
9+
"strict": true, /* Enable all strict type-checking options. */
10+
"skipLibCheck": true, /* Skip type checking all .d.ts files. */
11+
"outDir": "./dist"
12+
}
13+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "external_call_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+
starter_token = { path = "../nr" }
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use aztec::macros::aztec;
2+
3+
#[aztec]
4+
pub contract ExternalCall {
5+
use aztec::{
6+
macros::functions::private,
7+
protocol_types::address::AztecAddress,
8+
};
9+
10+
use dep::starter_token::StarterToken;
11+
12+
#[private]
13+
fn call_mint_on_other_contract(contract_address: AztecAddress, to: AztecAddress, amount: u128) {
14+
StarterToken::at(contract_address).mint_private(to, amount).call(&mut context);
15+
}
16+
}

0 commit comments

Comments
 (0)