Skip to content

Commit 1f893c2

Browse files
Merge branch 'main' into ajl-ntx-tutorial
2 parents 68d82ce + e42d85e commit 1f893c2

4 files changed

Lines changed: 80 additions & 52 deletions

File tree

docs/src/rust-client/counter_contract_tutorial.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -118,15 +118,14 @@ Create a directory named `masm` at the **root** of your `miden-counter-contract`
118118
Initialize the `masm` directory:
119119

120120
```bash
121-
mkdir -p masm/accounts masm/scripts masm/accounts/auth
121+
mkdir -p masm/accounts masm/scripts
122122
```
123123

124124
This will create:
125125

126126
```text
127127
masm/
128128
├── accounts/
129-
│ └── auth/
130129
└── scripts/
131130
```
132131

@@ -149,13 +148,13 @@ The import `std::sys` contains a useful procedure for truncating the operand sta
149148

150149
#### Here's a breakdown of what the `increment_count` procedure does:
151150

152-
1. Pushes `0` onto the stack, representing the index of the storage slot to read.
153-
2. Calls `account::get_item` with the index of `0`.
151+
1. Pushes `COUNTER_SLOT`(=0) onto the stack, representing the index of the storage slot to read.
152+
2. Calls `account::get_item` with the index of `COUNTER_SLOT`.
154153
3. Pushes `1` onto the stack.
155154
4. Adds `1` to the count value returned from `account::get_item`.
156-
5. _For demonstration purposes_, calls `debug.stack` to see the state of the stack
157-
6. Pushes `0` onto the stack, which is the index of the storage slot we want to write to.
158-
7. Calls `account::set_item` which saves the incremented count to storage at index `0`
155+
5. _For demonstration purposes_, calls `debug.stack` to see the state of the stack.
156+
6. Pushes `COUNTER_SLOT` onto the stack again, which is the index of the storage slot we want to write to.
157+
7. Calls `account::set_item` which saves the incremented count to storage at index `COUNTER_SLOT`.
159158
8. Calls `sys::truncate_stack` to truncate the stack to size 16.
160159

161160
Inside of the `masm/accounts/` directory, create the `counter.masm` file:
@@ -164,9 +163,10 @@ Inside of the `masm/accounts/` directory, create the `counter.masm` file:
164163
use.miden::account
165164
use.std::sys
166165
166+
const.COUNTER_SLOT=0
167167
# => []
168168
export.get_count
169-
push.0
169+
push.COUNTER_SLOT
170170
# => [index]
171171
172172
exec.account::get_item
@@ -178,7 +178,7 @@ end
178178
179179
# => []
180180
export.increment_count
181-
push.0
181+
push.COUNTER_SLOT
182182
# => [index]
183183
184184
exec.account::get_item
@@ -190,7 +190,7 @@ export.increment_count
190190
# debug statement with client
191191
debug.stack
192192
193-
push.0
193+
push.COUNTER_SLOT
194194
# [index, count+1]
195195
196196
exec.account::set_item

docs/src/rust-client/custom_note_how_to.md

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -50,32 +50,46 @@ Below is the Miden Assembly code for the note:
5050
use.miden::note
5151
use.miden::contracts::wallets::basic->wallet
5252
53-
# => [HASH_PREIMAGE_SECRET]
54-
begin
53+
# CONSTANTS
54+
# =================================================================================================
5555
56-
# Hashing the secret number
57-
hperm
58-
# => [F,E,D]
59-
# E is digest
56+
const.EXPECTED_DIGEST_PTR=0
57+
const.ASSET_PTR=100
58+
59+
# ERRORS
60+
# =================================================================================================
61+
62+
const.ERROR_DIGEST_MISMATCH="Expected digest does not match computed digest"
6063
61-
dropw swapw dropw
64+
#! Inputs (arguments): [HASH_PREIMAGE_SECRET]
65+
#! Outputs: []
66+
#!
67+
#! Note inputs are assumed to be as follows:
68+
#! => EXPECTED_DIGEST
69+
begin
70+
# => HASH_PREIMAGE_SECRET
71+
# Hashing the secret number
72+
hash
6273
# => [DIGEST]
6374
6475
# Writing the note inputs to memory
65-
push.0 exec.note::get_inputs drop drop
66-
# => [DIGEST]
76+
push.EXPECTED_DIGEST_PTR exec.note::get_inputs drop drop
6777
68-
# Pad stack and load note inputs from memory
69-
padw push.0 mem_loadw
70-
# => [INPUTS, DIGEST]
78+
# Pad stack and load expected digest from memory
79+
padw push.EXPECTED_DIGEST_PTR mem_loadw
80+
# => [EXPECTED_DIGEST, DIGEST]
7181
7282
# Assert that the note input matches the digest
7383
# Will fail if the two hashes do not match
74-
assert_eqw
84+
assert_eqw.err=ERROR_DIGEST_MISMATCH
7585
# => []
7686
77-
# Write the asset in note to memory address 0
78-
push.0 exec.note::get_assets
87+
# ---------------------------------------------------------------------------------------------
88+
# If the check is successful, we allow for the asset to be consumed
89+
# ---------------------------------------------------------------------------------------------
90+
91+
# Write the asset in note to memory address ASSET_PTR
92+
push.ASSET_PTR exec.note::get_assets
7993
# => [num_assets, dest_ptr]
8094
8195
drop
@@ -93,14 +107,16 @@ end
93107

94108
### How the assembly code works:
95109

96-
1. **Passing the Secret:**
110+
1. **Constants and Error Handling:**
111+
The code defines memory pointers (`EXPECTED_DIGEST_PTR` and `ASSET_PTR`) for better code organization and an error message for digest mismatches.
112+
2. **Passing the Secret:**
97113
The secret number is passed as `Note Arguments` into the note.
98-
2. **Hashing the Secret:**
99-
The `hperm` instruction applies a hash permutation to the secret number, resulting in a hash that takes up four stack elements.
100-
3. **Stack Cleanup and Comparison:**
101-
The assembly code extracts the digest, loads the note inputs from memory and checks if the computed hash matches the note’s stored hash.
102-
4. **Asset Transfer:**
103-
If the hash of the number passed in as `Note Arguments` matches the hash stored in the note inputs, the script continues, and the asset stored in the note is loaded from memory and passed to Bobs wallet via the `wallet::receive_asset` function.
114+
3. **Hashing the Secret:**
115+
The `hash` instruction applies a hash permutation to the secret number, resulting in a digest that takes up four stack elements.
116+
4. **Digest Comparison:**
117+
The assembly code loads the expected digest from the note inputs stored in memory and compares it with the computed hash. If they don't match, the transaction fails with a clear error message.
118+
5. **Asset Transfer:**
119+
If the hash of the number passed in as `Note Arguments` matches the hash stored in the note inputs, the script continues, and the asset stored in the note is loaded from memory and passed to Bob's wallet via the `wallet::receive_asset` function.
104120

105121
### 5. Consuming the note
106122

@@ -291,8 +307,7 @@ async fn main() -> Result<(), ClientError> {
291307
// STEP 3: Create custom note
292308
// -------------------------------------------------------------------------
293309
println!("\n[STEP 3] Create custom note");
294-
let mut secret_vals = vec![Felt::new(1), Felt::new(2), Felt::new(3), Felt::new(4)];
295-
secret_vals.splice(0..0, Word::default().iter().cloned());
310+
let secret_vals = vec![Felt::new(1), Felt::new(2), Felt::new(3), Felt::new(4)];
296311
let digest = Hasher::hash_elements(&secret_vals);
297312
println!("digest: {:?}", digest);
298313

masm/notes/hash_preimage_note.masm

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,46 @@
11
use.miden::note
22
use.miden::contracts::wallets::basic->wallet
33

4-
# => [HASH_PREIMAGE_SECRET]
5-
begin
4+
# CONSTANTS
5+
# =================================================================================================
66

7-
# Hashing the secret number
8-
hperm
9-
# => [F,E,D]
10-
# E is digest
7+
const.EXPECTED_DIGEST_PTR=0
8+
const.ASSET_PTR=100
9+
10+
# ERRORS
11+
# =================================================================================================
12+
13+
const.ERROR_DIGEST_MISMATCH="Expected digest does not match computed digest"
1114

12-
dropw swapw dropw
15+
#! Inputs (arguments): [HASH_PREIMAGE_SECRET]
16+
#! Outputs: []
17+
#!
18+
#! Note inputs are assumed to be as follows:
19+
#! => EXPECTED_DIGEST
20+
begin
21+
# => HASH_PREIMAGE_SECRET
22+
# Hashing the secret number
23+
hash
1324
# => [DIGEST]
1425

1526
# Writing the note inputs to memory
16-
push.0 exec.note::get_inputs drop drop
17-
# => [DIGEST]
27+
push.EXPECTED_DIGEST_PTR exec.note::get_inputs drop drop
1828

19-
# Pad stack and load note inputs from memory
20-
padw push.0 mem_loadw
21-
# => [INPUTS, DIGEST]
29+
# Pad stack and load expected digest from memory
30+
padw push.EXPECTED_DIGEST_PTR mem_loadw
31+
# => [EXPECTED_DIGEST, DIGEST]
2232

2333
# Assert that the note input matches the digest
2434
# Will fail if the two hashes do not match
25-
assert_eqw
35+
assert_eqw.err=ERROR_DIGEST_MISMATCH
2636
# => []
2737

28-
# Write the asset in note to memory address 0
29-
push.0 exec.note::get_assets
38+
# ---------------------------------------------------------------------------------------------
39+
# If the check is successful, we allow for the asset to be consumed
40+
# ---------------------------------------------------------------------------------------------
41+
42+
# Write the asset in note to memory address ASSET_PTR
43+
push.ASSET_PTR exec.note::get_assets
3044
# => [num_assets, dest_ptr]
3145

3246
drop

rust-client/src/bin/hash_preimage_note.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use miden_client::{
1919
rpc::{Endpoint, TonicRpcClient},
2020
store::InputNoteRecord,
2121
transaction::{OutputNote, TransactionKernel, TransactionRequestBuilder},
22-
Client, ClientError, Felt, Word,
22+
Client, ClientError, Felt,
2323
};
2424
use miden_objects::account::NetworkId;
2525
use miden_objects::Hasher;
@@ -176,8 +176,7 @@ async fn main() -> Result<(), ClientError> {
176176
// STEP 3: Create custom note
177177
// -------------------------------------------------------------------------
178178
println!("\n[STEP 3] Create custom note");
179-
let mut secret_vals = vec![Felt::new(1), Felt::new(2), Felt::new(3), Felt::new(4)];
180-
secret_vals.splice(0..0, Word::default().iter().cloned());
179+
let secret_vals = vec![Felt::new(1), Felt::new(2), Felt::new(3), Felt::new(4)];
181180
let digest = Hasher::hash_elements(&secret_vals);
182181
println!("digest: {:?}", digest);
183182

0 commit comments

Comments
 (0)