Last active
March 11, 2025 14:57
-
-
Save asterite/0821b58e82e1a7adbdfce14fcecaeef5 to your computer and use it in GitHub Desktop.
ecdsa_k_account_contract after macro expansion
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use aztec::macros::aztec; | |
pub contract EcdsaKAccount { | |
use authwit::{ | |
account::AccountActions, | |
auth_witness::get_auth_witness, | |
entrypoint::{app::AppPayload, fee::FeePayload}, | |
}; | |
use aztec::{ | |
context::private_context::PrivateContext, | |
encrypted_logs::log_assembly_strategies::default_aes128::note::encode_and_encrypt_note, | |
macros::{functions::{initializer, noinitcheck, private, view}, storage::storage}, | |
state_vars::private_immutable::PrivateImmutable, | |
}; | |
use ecdsa_public_key_note::EcdsaPublicKeyNote; | |
struct Storage<Context> { | |
public_key: PrivateImmutable<EcdsaPublicKeyNote, Context>, | |
} | |
impl<Context> Storage<Context> { | |
fn init(context: Context) -> Storage<Context> { | |
Storage::<Context> { public_key: PrivateImmutable::new(context, 1) } | |
} | |
} | |
fn constructor( | |
inputs: aztec::context::inputs::private_context_inputs::PrivateContextInputs, | |
signing_pub_key_x: [u8; 32], | |
signing_pub_key_y: [u8; 32], | |
) -> return_data protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { | |
{ | |
let mut args_hasher: aztec::hash::ArgsHasher = aztec::hash::ArgsHasher::new(); | |
let signing_pub_key_x_serialized: [[Field; 1]; 32] = | |
signing_pub_key_x.map(|x: u8| -> [Field; 1] x.serialize()); | |
for i in 0..signing_pub_key_x.len() { | |
args_hasher.add_multiple(signing_pub_key_x_serialized[i]); | |
} | |
let signing_pub_key_y_serialized: [[Field; 1]; 32] = | |
signing_pub_key_y.map(|x: u8| -> [Field; 1] x.serialize()); | |
for i in 0..signing_pub_key_y.len() { | |
args_hasher.add_multiple(signing_pub_key_y_serialized[i]); | |
} | |
let mut context: PrivateContext = PrivateContext::new(inputs, args_hasher.hash()); | |
aztec::macros::functions::initialization_utils::assert_initialization_matches_address_preimage_private( | |
context, | |
); | |
let storage: Storage<&mut PrivateContext> = Storage::init(&mut context); | |
/* Safety: comment added by `nargo expand` */ | |
unsafe { | |
aztec::discovery::discover_new_notes( | |
context.this_address(), | |
_compute_note_hash_and_nullifier, | |
) | |
}; | |
let this: protocol_types::address::aztec_address::AztecAddress = context.this_address(); | |
let pub_key_note: EcdsaPublicKeyNote = | |
EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this); | |
storage.public_key.initialize(pub_key_note).emit(encode_and_encrypt_note( | |
&mut context, | |
this, | |
this, | |
)); | |
aztec::macros::functions::initialization_utils::mark_as_initialized_private( | |
&mut context, | |
); | |
context.finish() | |
} | |
} | |
fn entrypoint( | |
inputs: aztec::context::inputs::private_context_inputs::PrivateContextInputs, | |
app_payload: AppPayload, | |
fee_payload: FeePayload, | |
cancellable: bool, | |
) -> return_data protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { | |
{ | |
let mut args_hasher: aztec::hash::ArgsHasher = aztec::hash::ArgsHasher::new(); | |
args_hasher.add_multiple(app_payload.serialize()); | |
args_hasher.add_multiple(fee_payload.serialize()); | |
args_hasher.add(cancellable as Field); | |
let mut context: PrivateContext = PrivateContext::new(inputs, args_hasher.hash()); | |
aztec::macros::functions::initialization_utils::assert_is_initialized_private( | |
&mut context, | |
); | |
let storage: Storage<&mut PrivateContext> = Storage::init(&mut context); | |
/* Safety: comment added by `nargo expand` */ | |
unsafe { | |
aztec::discovery::discover_new_notes( | |
context.this_address(), | |
_compute_note_hash_and_nullifier, | |
) | |
}; | |
let actions: AccountActions<&mut PrivateContext> = | |
AccountActions::init(&mut context, is_valid_impl); | |
actions.entrypoint(app_payload, fee_payload, cancellable); | |
context.finish() | |
} | |
} | |
fn verify_private_authwit( | |
inputs: aztec::context::inputs::private_context_inputs::PrivateContextInputs, | |
inner_hash: Field, | |
) -> return_data protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { | |
{ | |
let mut args_hasher: aztec::hash::ArgsHasher = aztec::hash::ArgsHasher::new(); | |
args_hasher.add(inner_hash as Field); | |
let mut context: PrivateContext = PrivateContext::new(inputs, args_hasher.hash()); | |
assert( | |
(context.inputs.call_context.is_static_call == true), | |
"Function verify_private_authwit can only be called statically", | |
); | |
let storage: Storage<&mut PrivateContext> = Storage::init(&mut context); | |
/* Safety: comment added by `nargo expand` */ | |
unsafe { | |
aztec::discovery::discover_new_notes( | |
context.this_address(), | |
_compute_note_hash_and_nullifier, | |
) | |
}; | |
let actions: AccountActions<&mut PrivateContext> = | |
AccountActions::init(&mut context, is_valid_impl); | |
let mut return_hasher: aztec::hash::ArgsHasher = aztec::hash::ArgsHasher::new(); | |
let macro__returned__values: Field = actions.verify_private_authwit(inner_hash); | |
return_hasher.add(macro__returned__values as Field); | |
context.set_return_hash(return_hasher); | |
context.finish() | |
} | |
} | |
#[contract_library_method] | |
fn is_valid_impl(context: &mut PrivateContext, outer_hash: Field) -> bool { | |
let storage: Storage<&mut PrivateContext> = Storage::init(context); | |
let public_key: EcdsaPublicKeyNote = storage.public_key.get_note(); | |
/* Safety: comment added by `nargo expand` */ | |
let witness: [Field; 64] = unsafe { get_auth_witness(outer_hash) }; | |
let mut signature: [u8; 64] = [0; 64]; | |
for i in 0..64 { | |
signature[i] = witness[i] as u8; | |
} | |
let outer_hash_bytes: [u8; 32] = outer_hash.to_be_bytes(); | |
let hashed_message: [u8; 32] = sha256::sha256::digest(outer_hash_bytes); | |
std::ecdsa_secp256k1::verify_signature( | |
public_key.x, | |
public_key.y, | |
signature, | |
hashed_message, | |
) | |
} | |
#[abi(storage)] | |
pub global STORAGE_LAYOUT_EcdsaKAccount: StorageLayout<13> = StorageLayout::<13> { | |
contract_name: "EcdsaKAccount", | |
fields: StorageLayoutFields { | |
public_key: aztec::state_vars::storage::Storable { slot: 1 }, | |
}, | |
}; | |
#[abi(notes)] | |
global EcdsaPublicKeyNote_EXPORTS_3258495142: (Field, str<18>, EcdsaPublicKeyNoteFields_3258495142) = ( | |
0, "EcdsaPublicKeyNote", | |
EcdsaPublicKeyNoteFields_3258495142 { | |
x: aztec::note::note_field::NoteField { index: 0, nullable: false }, | |
owner: aztec::note::note_field::NoteField { index: 64, nullable: false }, | |
y: aztec::note::note_field::NoteField { index: 32, nullable: false }, | |
}, | |
); | |
pub struct verify_private_authwit_parameters { | |
inner_hash: Field, | |
} | |
pub struct constructor_parameters { | |
signing_pub_key_x: [u8; 32], | |
signing_pub_key_y: [u8; 32], | |
} | |
pub struct entrypoint_parameters { | |
app_payload: AppPayload, | |
fee_payload: FeePayload, | |
cancellable: bool, | |
} | |
#[abi(functions)] | |
pub struct verify_private_authwit_abi { | |
parameters: verify_private_authwit_parameters, | |
return_type: Field, | |
} | |
#[abi(functions)] | |
pub struct constructor_abi { | |
parameters: constructor_parameters, | |
} | |
#[abi(functions)] | |
pub struct entrypoint_abi { | |
parameters: entrypoint_parameters, | |
} | |
pub struct EcdsaKAccount { | |
target_contract: protocol_types::address::aztec_address::AztecAddress, | |
} | |
impl EcdsaKAccount { | |
fn constructor( | |
self, | |
signing_pub_key_x: [u8; 32], | |
signing_pub_key_y: [u8; 32], | |
) -> aztec::context::call_interfaces::PrivateVoidCallInterface<11> { | |
let mut serialized_args: [Field] = &[]; | |
let signing_pub_key_x_serialized: [[Field; 1]; 32] = | |
signing_pub_key_x.map(|x: u8| -> [Field; 1] x.serialize()); | |
for i in 0..signing_pub_key_x.len() { | |
serialized_args = | |
serialized_args.append(signing_pub_key_x_serialized[i].as_slice()); | |
} | |
let signing_pub_key_y_serialized: [[Field; 1]; 32] = | |
signing_pub_key_y.map(|x: u8| -> [Field; 1] x.serialize()); | |
for i in 0..signing_pub_key_y.len() { | |
serialized_args = | |
serialized_args.append(signing_pub_key_y_serialized[i].as_slice()); | |
} | |
let selector: protocol_types::abis::function_selector::FunctionSelector = | |
3065569528.from_field(); | |
aztec::context::call_interfaces::PrivateVoidCallInterface::new( | |
self.target_contract, | |
selector, | |
"constructor", | |
serialized_args, | |
false, | |
) | |
} | |
fn entrypoint( | |
self, | |
app_payload: AppPayload, | |
fee_payload: FeePayload, | |
cancellable: bool, | |
) -> aztec::context::call_interfaces::PrivateVoidCallInterface<10> { | |
let mut serialized_args: [Field] = &[]; | |
serialized_args = serialized_args.append(app_payload.serialize().as_slice()); | |
serialized_args = serialized_args.append(fee_payload.serialize().as_slice()); | |
serialized_args = serialized_args.push_back(cancellable as Field); | |
let selector: protocol_types::abis::function_selector::FunctionSelector = | |
669466802.from_field(); | |
aztec::context::call_interfaces::PrivateVoidCallInterface::new( | |
self.target_contract, | |
selector, | |
"entrypoint", | |
serialized_args, | |
false, | |
) | |
} | |
fn at(addr: protocol_types::address::aztec_address::AztecAddress) -> EcdsaKAccount { | |
EcdsaKAccount { target_contract: addr } | |
} | |
fn verify_private_authwit( | |
self, | |
inner_hash: Field, | |
) -> aztec::context::call_interfaces::PrivateStaticCallInterface<22, Field> { | |
let mut serialized_args: [Field] = &[]; | |
serialized_args = serialized_args.push_back(inner_hash as Field); | |
let selector: protocol_types::abis::function_selector::FunctionSelector = | |
3346549015.from_field(); | |
aztec::context::call_interfaces::PrivateStaticCallInterface::new( | |
self.target_contract, | |
selector, | |
"verify_private_authwit", | |
serialized_args, | |
) | |
} | |
fn interface() -> EcdsaKAccount { | |
EcdsaKAccount { | |
target_contract: protocol_types::address::aztec_address::AztecAddress::zero(), | |
} | |
} | |
fn storage_layout() -> StorageLayoutFields { | |
STORAGE_LAYOUT_EcdsaKAccount.fields | |
} | |
} | |
#[contract_library_method] | |
pub fn storage_layout() -> StorageLayoutFields { | |
STORAGE_LAYOUT_EcdsaKAccount.fields | |
} | |
#[contract_library_method] | |
pub fn at(addr: protocol_types::address::aztec_address::AztecAddress) -> EcdsaKAccount { | |
EcdsaKAccount { target_contract: addr } | |
} | |
#[contract_library_method] | |
pub fn interface() -> EcdsaKAccount { | |
EcdsaKAccount { | |
target_contract: protocol_types::address::aztec_address::AztecAddress::zero(), | |
} | |
} | |
/// Unpacks an array into a note corresponding to `note_type_id` and then computes its note hash | |
/// (non-siloed) and inner nullifier (non-siloed) assuming the note has been inserted into the note hash | |
/// tree with `nonce`. | |
/// | |
/// The signature of this function notably matches the `aztec::discovery::ComputeNoteHashAndNullifier` type, | |
/// and so it can be used to call functions from that module such as `discover_new_notes`, `do_process_log` | |
/// and `process_private_note_log`. | |
/// | |
/// This function is automatically injected by the `#[aztec]` macro. | |
#[contract_library_method] | |
unconstrained fn _compute_note_hash_and_nullifier( | |
packed_note: BoundedVec<Field, 16>, | |
storage_slot: Field, | |
note_type_id: Field, | |
contract_address: protocol_types::address::aztec_address::AztecAddress, | |
nonce: Field, | |
) -> Option<aztec::discovery::NoteHashAndNullifier> { | |
if (note_type_id == aztec::note::note_interface::NoteType::get_id()) { | |
let expected_len: u32 = 5; | |
let actual_len: u32 = packed_note.len(); | |
assert( | |
(actual_len == expected_len), | |
f"Expected packed note of length {expected_len} but got {actual_len} for note type id {note_type_id}", | |
); | |
let note: EcdsaPublicKeyNote = | |
aztec::utils::array::subarray::subarray(packed_note.storage(), 0).unpack(); | |
let note_hash: Field = note.compute_note_hash(storage_slot); | |
let note_hash_for_nullify: Field = aztec::note::utils::compute_note_hash_for_nullify( | |
aztec::note::retrieved_note::RetrievedNote::<EcdsaPublicKeyNote> { | |
note: note, | |
contract_address: contract_address, | |
metadata: aztec::note::note_metadata::SettledNoteMetadata::new(nonce).into(), | |
}, | |
storage_slot, | |
); | |
let inner_nullifier: Field = | |
note.compute_nullifier_unconstrained(note_hash_for_nullify); | |
Option::some( | |
aztec::discovery::NoteHashAndNullifier { | |
note_hash: note_hash, | |
inner_nullifier: inner_nullifier, | |
}, | |
) | |
} else { | |
Option::none() | |
} | |
} | |
unconstrained fn process_log( | |
log_plaintext: BoundedVec<Field, 18>, | |
tx_hash: Field, | |
unique_note_hashes_in_tx: BoundedVec<Field, 64>, | |
first_nullifier_in_tx: Field, | |
recipient: protocol_types::address::aztec_address::AztecAddress, | |
) { | |
let context: aztec::context::unconstrained_context::UnconstrainedContext = | |
aztec::context::unconstrained_context::UnconstrainedContext::new(); | |
let contract_address: protocol_types::address::aztec_address::AztecAddress = | |
context.this_address(); | |
aztec::discovery::private_logs::do_process_log( | |
contract_address, | |
log_plaintext, | |
tx_hash, | |
unique_note_hashes_in_tx, | |
first_nullifier_in_tx, | |
recipient, | |
_compute_note_hash_and_nullifier, | |
); | |
} | |
unconstrained fn sync_notes() { | |
aztec::oracle::note_discovery::sync_notes(); | |
} | |
pub struct EcdsaPublicKeyNoteFields_3258495142 { | |
x: aztec::note::note_field::NoteField, | |
y: aztec::note::note_field::NoteField, | |
owner: aztec::note::note_field::NoteField, | |
} | |
pub struct StorageLayoutFields { | |
public_key: aztec::state_vars::storage::Storable, | |
} | |
pub struct StorageLayout<let N: u32> { | |
contract_name: str<N>, | |
fields: StorageLayoutFields, | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment