Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 8 additions & 22 deletions examples/auth-component-no-auth/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,22 @@
// extern crate alloc;
// use alloc::vec::Vec;

// Global allocator to use heap memory in no-std environment
#[global_allocator]
static ALLOC: miden::BumpAlloc = miden::BumpAlloc::new();

// Required for no-std crates
#[cfg(not(test))]
#[panic_handler]
fn my_panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}

miden::generate!();
bindings::export!(AuthComponent);

use miden::{active_account, native_account, *};

use crate::bindings::exports::miden::base::authentication_component::Guest;
use miden::{component, Word};

#[component]
struct AuthComponent;

impl Guest for AuthComponent {
fn auth_procedure(_arg: Word) {
#[component]
impl AuthComponent {
pub fn auth_procedure(&mut self, _arg: Word) {
// translated from MASM at
// https://github.com/0xMiden/miden-base/blob/e4912663276ab8eebb24b84d318417cb4ea0bba3/crates/miden-lib/asm/account_components/no_auth.masm?plain=1
let init_comm = active_account::get_initial_commitment();
let curr_comm = active_account::compute_commitment();
let init_comm = self.get_initial_commitment();
let curr_comm = self.compute_commitment();
// check if the account state has changed by comparing initial and final commitments
if curr_comm != init_comm {
// if the account has been updated, increment the nonce
native_account::incr_nonce();
self.incr_nonce();
}
}
}
24 changes: 9 additions & 15 deletions examples/auth-component-rpo-falcon512/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,9 @@
extern crate alloc;

use miden::{
component, felt, hash_words, intrinsics::advice::adv_insert, native_account, tx, Felt, Value,
ValueAccess, Word,
component, felt, hash_words, intrinsics::advice::adv_insert, tx, Felt, Value, ValueAccess, Word,
};

use crate::bindings::exports::miden::base::authentication_component::Guest;

miden::generate!();
bindings::export!(AuthComponent);

/// Authentication component storage/layout.
///
/// Public key is expected to be in the slot 0. Matches MASM constant `PUBLIC_KEY_SLOT=0` in
Expand All @@ -27,13 +21,14 @@ struct AuthComponent {
owner_public_key: Value,
}

impl Guest for AuthComponent {
fn auth_procedure(_arg: Word) {
#[component]
impl AuthComponent {
pub fn auth_procedure(&mut self, _arg: Word) {
let ref_block_num = tx::get_block_number();
let final_nonce = native_account::incr_nonce();
let final_nonce = self.incr_nonce();

// Gather tx summary parts
let acct_delta_commit = native_account::compute_delta_commitment();
let acct_delta_commit = self.compute_delta_commitment();
let input_notes_commit = tx::get_input_notes_commitment();
let output_notes_commit = tx::get_output_notes_commitment();

Expand All @@ -44,14 +39,13 @@ impl Guest for AuthComponent {
// On the advice stack the words are expected to be in the reverse order
tx_summary.reverse();
// Insert tx summary into advice map under key `msg`
adv_insert(msg.clone(), &tx_summary);
adv_insert(msg, &tx_summary);

// Load public key from storage slot 0
let storage = Self::default();
let pub_key: Word = storage.owner_public_key.read();
let pub_key: Word = self.owner_public_key.read();

// Emit signature request event to advice stack,
miden::emit_falcon_sig_to_stack(msg.clone(), pub_key.clone());
miden::emit_falcon_sig_to_stack(msg, pub_key);

// Verify the signature loaded on the advice stack.
miden::rpo_falcon512_verify(pub_key, msg);
Expand Down
2 changes: 1 addition & 1 deletion examples/basic-wallet-tx-script/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const ASSET_START: usize = 8;
const ASSET_END: usize = 12;

#[tx_script]
fn run(arg: Word, account: Account) {
fn run(arg: Word, account: &mut Account) {
let num_felts = adv_push_mapvaln(arg.clone());
let num_felts_u64 = num_felts.as_u64();
assert_eq(Felt::from_u32((num_felts_u64 % 4) as u32), felt!(0));
Expand Down
10 changes: 5 additions & 5 deletions examples/basic-wallet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//
// extern crate alloc;

use miden::{component, native_account, output_note, Asset, NoteIdx};
use miden::{component, output_note, Asset, NoteIdx};

#[component]
struct MyAccount;
Expand All @@ -19,8 +19,8 @@ impl MyAccount {
///
/// # Arguments
/// * `asset` - The asset to be added to the account
pub fn receive_asset(&self, asset: Asset) {
native_account::add_asset(asset);
pub fn receive_asset(&mut self, asset: Asset) {
self.add_asset(asset);
}

/// Moves an asset from the account to a note.
Expand All @@ -31,8 +31,8 @@ impl MyAccount {
/// # Arguments
/// * `asset` - The asset to move from the account to the note
/// * `note_idx` - The index of the note to receive the asset
pub fn move_asset_to_note(&self, asset: Asset, note_idx: NoteIdx) {
let asset = native_account::remove_asset(asset);
pub fn move_asset_to_note(&mut self, asset: Asset, note_idx: NoteIdx) {
let asset = self.remove_asset(asset);
output_note::add_asset(asset, note_idx);
}
}
2 changes: 1 addition & 1 deletion examples/counter-contract/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl CounterContract {
}

/// Increments the counter value stored in the contract's storage map by one.
pub fn increment_count(&self) -> Felt {
pub fn increment_count(&mut self) -> Felt {
let key = Word::from([felt!(0), felt!(0), felt!(0), felt!(1)]);
let current_value: Felt = self.count_map.get(&key);
let new_value = current_value + felt!(1);
Expand Down
4 changes: 2 additions & 2 deletions examples/p2id-note/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ use miden::*;
use crate::bindings::Account;

#[note_script]
fn run(_arg: Word, account: Account) {
fn run(_arg: Word, account: &mut Account) {
let inputs = active_note::get_inputs();
let target_account_id_prefix = inputs[0];
let target_account_id_suffix = inputs[1];

let target_account = AccountId::from(target_account_id_prefix, target_account_id_suffix);
let current_account = active_account::get_id();
let current_account = account.get_id();
assert_eq!(current_account, target_account);

let assets = active_note::get_assets();
Expand Down
18 changes: 9 additions & 9 deletions examples/p2ide-note/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,27 @@

use miden::*;

use crate::bindings::miden::basic_wallet::basic_wallet::receive_asset;
use crate::bindings::Account;

fn consume_assets() {
fn consume_assets(account: &mut Account) {
let assets = active_note::get_assets();
for asset in assets {
receive_asset(asset);
account.receive_asset(asset);
}
}

fn reclaim_assets(consuming_account: AccountId) {
fn reclaim_assets(account: &mut Account, consuming_account: AccountId) {
let creator_account = active_note::get_sender();

if consuming_account == creator_account {
consume_assets();
consume_assets(account);
} else {
panic!();
}
}

#[note_script]
fn run(_arg: Word) {
fn run(_arg: Word, account: &mut Account) {
let inputs = active_note::get_inputs();

// make sure the number of inputs is 4
Expand All @@ -46,16 +46,16 @@ fn run(_arg: Word) {
assert!(block_number >= timelock_height);

// get consuming account id
let consuming_account_id = active_account::get_id();
let consuming_account_id = account.get_id();

// target account id
let target_account_id = AccountId::from(target_account_id_prefix, target_account_id_suffix);

let is_target = target_account_id == consuming_account_id;
if is_target {
consume_assets();
consume_assets(account);
} else {
assert!(reclaim_height >= block_number);
reclaim_assets(consuming_account_id);
reclaim_assets(account, consuming_account_id);
}
}
2 changes: 1 addition & 1 deletion examples/storage-example/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ struct MyAccount {

impl foo::Guest for MyAccount {
fn set_asset_qty(pub_key: Word, asset: Asset, qty: Felt) {
let my_account = MyAccount::default();
let mut my_account = MyAccount::default();
let owner_key: Word = my_account.owner_public_key.read();
if pub_key == owner_key {
my_account.asset_qty_map.set(asset, qty);
Expand Down
9 changes: 8 additions & 1 deletion sdk/base-macros/src/component_macro/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ fn expand_component_struct(
#runtime_boilerplate
#input_struct
#default_impl
impl ::miden::native_account::NativeAccount for #struct_name {}
impl ::miden::active_account::ActiveAccount for #struct_name {}
#link_section
})
}
Expand Down Expand Up @@ -236,7 +238,7 @@ fn expand_component_impl(
if methods.is_empty() {
return Err(syn::Error::new(
call_site_span.into(),
"Component `impl` is missing `pub` methods. A component cannot have emty exports.",
"Component `impl` is missing `pub` methods. A component cannot have empty exports.",
));
}

Expand Down Expand Up @@ -284,6 +286,11 @@ fn expand_component_impl(

Ok(quote! {
::miden::generate!(inline = #inline_literal, with = { #(#custom_with_entries)* });
// Bring account traits into scope so users can call `self.add_asset()`, etc.
#[allow(unused_imports)]
use ::miden::native_account::NativeAccount as _;
#[allow(unused_imports)]
use ::miden::active_account::ActiveAccount as _;
#impl_block
impl #guest_trait_path for #component_type {
#(#guest_methods)*
Expand Down
29 changes: 19 additions & 10 deletions sdk/base-macros/src/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,10 @@ fn augment_generated_bindings(tokens: TokenStream2) -> syn::Result<TokenStream2>
if !collected_methods.is_empty() {
let struct_ident = syn::Ident::new(WRAPPER_STRUCT_NAME, Span::call_site());
let struct_item: ItemStruct = parse_quote! {
/// Wrapper struct providing methods that delegate to imported interface functions.
#[derive(Clone, Copy, Default)]
/// Wrapper struct that contains all the methods from all the account component
/// dependencies of this script. Each account component dependency method is "merged"
/// into this struct.
#[derive(Default)]
pub struct #struct_ident;
};

Expand Down Expand Up @@ -309,9 +311,12 @@ fn load_wit_sources(
manifest_dir.join(path_buf)
};
let normalized = fs::canonicalize(&absolute).unwrap_or(absolute);
let (pkg, sources) = resolve
.push_path(normalized.clone())
.map_err(|err| Error::new(Span::call_site(), err.to_string()))?;
let (pkg, sources) = resolve.push_path(normalized.clone()).map_err(|err| {
Error::new(
Span::call_site(),
format!("failed to load WIT from '{}': {err}", normalized.display()),
)
})?;
packages.push(pkg);
files.extend(sources.paths().map(|p| p.to_owned()));
}
Expand Down Expand Up @@ -429,7 +434,9 @@ fn collect_methods_from_module(
/// resolve correctly when the method is placed at the bindings root level.
fn build_wrapper_method(func: &ItemFn, module_path: &[syn::Ident]) -> syn::Result<ImplItemFn> {
let mut sig = func.sig.clone();
sig.inputs.insert(0, parse_quote!(&self));
// Make every method `&mut self` as a temporary workaround until
// https://github.com/0xMiden/compiler/issues/802 is resolved
sig.inputs.insert(0, parse_quote!(&mut self));

// Qualify type paths in the signature so they resolve from the bindings root
qualify_signature_types(&mut sig, module_path);
Expand Down Expand Up @@ -870,9 +877,11 @@ mod tests {
];
let method = build_wrapper_method(&func, &path).unwrap();

// Method should have &self as first parameter
// Method should have &mut self as first parameter
assert_eq!(method.sig.inputs.len(), 2);
assert!(matches!(method.sig.inputs.first(), Some(FnArg::Receiver(_))));
assert!(
matches!(method.sig.inputs.first(), Some(FnArg::Receiver(r)) if r.mutability.is_some())
);

// Should be public
assert!(matches!(method.vis, syn::Visibility::Public(_)));
Expand Down Expand Up @@ -917,8 +926,8 @@ mod tests {
assert!(result_str.contains("fn receive_asset"));
assert!(result_str.contains("fn send_asset"));

// Methods should have &self parameter
assert!(result_str.contains("& self"));
// Methods should have &mut self parameter
assert!(result_str.contains("& mut self"));
}

#[test]
Expand Down
Loading