From bc5652eb668a174d07557c8e7e552b10fe80975c Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 23 Aug 2023 14:18:47 +0000 Subject: [PATCH 1/7] WIP --- docs/docs/dev_docs/contracts/events.md | 61 ++++++++++++++++++- docs/docs/dev_docs/getting_started/cli.md | 2 +- .../src/e2e_public_token_contract.test.ts | 4 ++ 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/docs/docs/dev_docs/contracts/events.md b/docs/docs/dev_docs/contracts/events.md index f6a0c5666e7..3c2f080d815 100644 --- a/docs/docs/dev_docs/contracts/events.md +++ b/docs/docs/dev_docs/contracts/events.md @@ -1,10 +1,67 @@ ## Events +Events in Aztec works similarily to Ethereum events in a sense that they are a way for contracts to communicate with the outside world. +They are emitted by contracts and stored inside AztecNode. +Aztec events are currently represented as raw data and are not ABI encoded. +ABI encoded events are a feature that will be added in the future. + +Unlike on Ethereum, there are 2 types of events: encrypted and unencrypted. + +### Encrypted Events +Encrypted events can only be emitted by private functions and are encrypted using a public key of a recipient. +For this reason it is necessary to register a recipient in the AztecRPC server before encrypting the events for them. +Recipients can be registered using the Aztec CLI or Aztec.js: + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + + +```bash +aztec-cli register-recipient --address 0x147392a39e593189902458f4303bc6e0a39128c5a1c1612f76527a162d36d529 --public-key 0x26e193aef4f83c70651485b5526c6d01a36d763223ab24efd1f9ff91b394ac0c20ad99d0ef669dc0dde8d5f5996c63105de8e15c2c87d8260b9e6f02f72af622 --partial-address 0x200e9a6c2d2e8352012e51c6637659713d336405c29386c7c4ac56779ab54fa7 +``` + + + + +```ts +const aztecAddress = AztecAddress.fromString("0x147392a39e593189902458f4303bc6e0a39128c5a1c1612f76527a162d36d529"); +const publicKey = Point.fromString("0x26e193aef4f83c70651485b5526c6d01a36d763223ab24efd1f9ff91b394ac0c20ad99d0ef669dc0dde8d5f5996c63105de8e15c2c87d8260b9e6f02f72af622"); +const partialAddress = Fr.fromString("0x200e9a6c2d2e8352012e51c6637659713d336405c29386c7c4ac56779ab54fa7"); + +const completeAddress = CompleteAddress.create(aztecAddress, publicKey, partialKey); +await aztecRpc.registerRecipient(completeAddress); +``` + + + + +At this point we only allow emitting note spending info through encrypted events. +In the future we will allow emitting arbitrary information. +(If you currently emit arbitrary information, AztecRPC server will fail to process it and it will not be queryable.) + -### Constraining events ### Unencrypted Events +Unencrypted events are events which can be read by anyone. +They can be emitted by both public and private functions. +It's important for a developer to consider whether it's acceptable for the unencrypted event to be emitted from private functions as it might pose a significant privacy leak. -### Encrypted Events +Once emitted, unencrypted events are stored in AztecNode and can be queried by anyone: + + + +```bash +aztec-cli get-logs --from 5 --limit 1 +``` + + + + +#include_code logs /yarn-project/end-to-end/src/e2e_public_token_contract.test.ts typescript + + + ### Costs diff --git a/docs/docs/dev_docs/getting_started/cli.md b/docs/docs/dev_docs/getting_started/cli.md index b7244e958c6..6272d5f9463 100644 --- a/docs/docs/dev_docs/getting_started/cli.md +++ b/docs/docs/dev_docs/getting_started/cli.md @@ -222,7 +222,7 @@ View result: [ Finally, we can use the CLI's `get-logs` command to retrieve unencrypted logs emitted by the contract: ``` -% aztec-cli get-logs 5 1 +% aztec-cli get-logs --from 5 --limit 1 Logs found: Coins transferred diff --git a/yarn-project/end-to-end/src/e2e_public_token_contract.test.ts b/yarn-project/end-to-end/src/e2e_public_token_contract.test.ts index 6a1e3b79658..a0f77428092 100644 --- a/yarn-project/end-to-end/src/e2e_public_token_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_public_token_contract.test.ts @@ -27,8 +27,12 @@ describe('e2e_public_token_contract', () => { }; const expectLogsFromLastBlockToBe = async (logMessages: string[]) => { + // docs:start:logs + const l2BlockNum = await aztecRpcServer.getBlockNumber(); const unencryptedLogs = await aztecRpcServer.getUnencryptedLogs(l2BlockNum, 1); + + // docs:end:logs const unrolledLogs = L2BlockL2Logs.unrollLogs(unencryptedLogs); const asciiLogs = unrolledLogs.map(log => log.toString('ascii')); From b1a0a11f86f9d2ffab82533c80eac7a2fac98be7 Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 23 Aug 2023 14:21:51 +0000 Subject: [PATCH 2/7] typo --- docs/docs/dev_docs/getting_started/sandbox.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/dev_docs/getting_started/sandbox.md b/docs/docs/dev_docs/getting_started/sandbox.md index 9fde1de0c4b..a3b229a4a72 100644 --- a/docs/docs/dev_docs/getting_started/sandbox.md +++ b/docs/docs/dev_docs/getting_started/sandbox.md @@ -197,7 +197,7 @@ Great!. The Sandbox is running and we are able to interact with it. The next step is to create some accounts. An in-depth explaining about accounts on aztec can be found [here](../../concepts/foundation/accounts/main.md). But creating an account on the Sandbox does 2 things: -1. Deploys an account contract reprepresenting you allowing you to perform actions on the network (deploy contracts, call functions etc). +1. Deploys an account contract representing you allowing you to perform actions on the network (deploy contracts, call functions etc). 2. Adds your encryption keys to the RPC Server allowing it to decrypt and manage your private state. Continue with adding the following to the `index.ts` file in our example: From 790f05355ff8cdc905c2af308d6531047833aa38 Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 23 Aug 2023 14:53:13 +0000 Subject: [PATCH 3/7] WIP --- docs/docs/dev_docs/contracts/events.md | 35 +++++++++++++++++-- .../private_token_contract/src/main.nr | 12 +++++++ .../noir-libs/value-note/src/utils.nr | 4 +++ 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/docs/docs/dev_docs/contracts/events.md b/docs/docs/dev_docs/contracts/events.md index 3c2f080d815..e739868878c 100644 --- a/docs/docs/dev_docs/contracts/events.md +++ b/docs/docs/dev_docs/contracts/events.md @@ -1,5 +1,5 @@ ## Events -Events in Aztec works similarily to Ethereum events in a sense that they are a way for contracts to communicate with the outside world. +Events in Aztec works similarly to Ethereum events in a sense that they are a way for contracts to communicate with the outside world. They are emitted by contracts and stored inside AztecNode. Aztec events are currently represented as raw data and are not ABI encoded. ABI encoded events are a feature that will be added in the future. @@ -40,6 +40,13 @@ At this point we only allow emitting note spending info through encrypted events In the future we will allow emitting arbitrary information. (If you currently emit arbitrary information, AztecRPC server will fail to process it and it will not be queryable.) +To emit encrypted logs first import the `emit_encrypted_log` utility function inside your contract: + +#include_code encrypted_import /yarn-project/noir-libs/value-note/src/utils.nr rust + +Then you can call the function: + +#include_code encrypted /yarn-project/noir-libs/value-note/src/utils.nr rust ### Unencrypted Events @@ -63,12 +70,34 @@ aztec-cli get-logs --from 5 --limit 1 +To emit unencrypted logs first import the `emit_unencrypted_log` utility function inside your contract: + +#include_code unencrypted_import /yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr rust + +Then you can call the function: + +#include_code unencrypted /yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr rust + ### Costs -Explain L1 cost to emit an event. +All the event data is pushed on Ethereum by the sequencer and for this reason the cost of emitting an event is non-trivial. ## Processing events +Both the encrypted and unencrypted events are stored in AztecNode. +Unencrypted logs can be queried by anyone as we described above in the [Unencrypted Events](#unencrypted-events) section. + +Encrypted logs need to first be decrypted: ### Decrypting +One function of AztecRPC server is constantly loading encrypted logs from AztecNode and trying to decrypt them. +When new encrypted logs are obtained, AztecRPC server will try to decrypt them using the private encryption key of all the accounts registered inside AztecRPC server. +If the decryption is successful, AztecRPC server will store the decrypted note inside a database. +If the decryption fails, the specific log will be discarded. + +For the AztecRPC server to successfully process the decrypted note we need to compute note hash and nullifier. +Because we want to support arbitrary ways of computing these values, we allow developers to specify a custom function for computing them inside the relevant contract. +For this reason each contract working with encrypted events needs to implement the `compute_note_hash_and_nullifier` function. + +This is an example implementation inside the `PrivateTokenContract`: -### Stev \ No newline at end of file +#include_code compute_note_hash_and_nullifier /yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr rust \ No newline at end of file diff --git a/yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr index 514377b95a8..4e052976675 100644 --- a/yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr @@ -15,8 +15,13 @@ contract PrivateToken { note_header::NoteHeader, utils as note_utils, }; + + // docs:start:unencrypted_import + use dep::aztec::log::emit_unencrypted_log; + // docs:end:unencrypted_import + // docs:start:storage-import use crate::storage::Storage; // docs:end:storage-import @@ -62,8 +67,13 @@ contract PrivateToken { // Insert new note to a set of user notes and emit the newly created encrypted note preimage via oracle call. let owner_balance = storage.balances.at(owner); send_note(&mut context, owner_balance, amount, owner); + + // docs:start:unencrypted + emit_unencrypted_log(&mut context, "Coins minted"); + // docs:end:unencrypted + // Return private circuit public inputs. All private functions need to return this as it is part of the input of the private kernel.. context.finish() } @@ -116,8 +126,10 @@ contract PrivateToken { // Computes note hash and nullifier. // Note 1: Needs to be defined by every contract producing logs. // Note 2: Having it in all the contracts gives us the ability to compute the note hash and nullifier differently for different kind of notes. + // docs:start:compute_note_hash_and_nullifier unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, preimage: [Field; VALUE_NOTE_LEN]) -> [Field; 4] { let note_header = NoteHeader { contract_address, nonce, storage_slot }; note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, preimage) } + // docs:end:compute_note_hash_and_nullifier } diff --git a/yarn-project/noir-libs/value-note/src/utils.nr b/yarn-project/noir-libs/value-note/src/utils.nr index 23705ba43be..e231a71bf3b 100644 --- a/yarn-project/noir-libs/value-note/src/utils.nr +++ b/yarn-project/noir-libs/value-note/src/utils.nr @@ -1,5 +1,9 @@ use dep::aztec::context::PrivateContext; +// docs:start:encrypted_import + use dep::aztec::log::emit_encrypted_log; + +// docs:end:encrypted_import use dep::aztec::note::note_getter_options::NoteGetterOptions; use dep::aztec::oracle::get_public_key::get_public_key; use dep::aztec::state_vars::set::Set; From b2ac93a7dd010afcf5a5492b8588c6b50689b01b Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 23 Aug 2023 17:13:39 +0200 Subject: [PATCH 4/7] final touches --- docs/docs/dev_docs/contracts/events.md | 9 +++++---- .../end-to-end/src/e2e_public_token_contract.test.ts | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/docs/dev_docs/contracts/events.md b/docs/docs/dev_docs/contracts/events.md index e739868878c..50edc5e5d8a 100644 --- a/docs/docs/dev_docs/contracts/events.md +++ b/docs/docs/dev_docs/contracts/events.md @@ -1,10 +1,10 @@ ## Events Events in Aztec works similarly to Ethereum events in a sense that they are a way for contracts to communicate with the outside world. -They are emitted by contracts and stored inside AztecNode. +They are emitted by contracts and stored inside each instance ofAztecNode. Aztec events are currently represented as raw data and are not ABI encoded. ABI encoded events are a feature that will be added in the future. -Unlike on Ethereum, there are 2 types of events: encrypted and unencrypted. +Unlike on Ethereum, there are 2 types of events supported by Aztec: encrypted and unencrypted. ### Encrypted Events Encrypted events can only be emitted by private functions and are encrypted using a public key of a recipient. @@ -36,6 +36,8 @@ await aztecRpc.registerRecipient(completeAddress); +> **NOTE**: If a note recipient is one of the accounts inside the Aztec RPC, we don't need to register it as a recipient because we already have the public key available. + At this point we only allow emitting note spending info through encrypted events. In the future we will allow emitting arbitrary information. (If you currently emit arbitrary information, AztecRPC server will fail to process it and it will not be queryable.) @@ -95,8 +97,7 @@ If the decryption is successful, AztecRPC server will store the decrypted note i If the decryption fails, the specific log will be discarded. For the AztecRPC server to successfully process the decrypted note we need to compute note hash and nullifier. -Because we want to support arbitrary ways of computing these values, we allow developers to specify a custom function for computing them inside the relevant contract. -For this reason each contract working with encrypted events needs to implement the `compute_note_hash_and_nullifier` function. +Because we want to support arbitrary ways of computing these values, Noir developers need to implement a `compute_note_hash_and_nullifier` function inside their contracts. This is an example implementation inside the `PrivateTokenContract`: diff --git a/yarn-project/end-to-end/src/e2e_public_token_contract.test.ts b/yarn-project/end-to-end/src/e2e_public_token_contract.test.ts index a0f77428092..ad40149332b 100644 --- a/yarn-project/end-to-end/src/e2e_public_token_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_public_token_contract.test.ts @@ -28,7 +28,7 @@ describe('e2e_public_token_contract', () => { const expectLogsFromLastBlockToBe = async (logMessages: string[]) => { // docs:start:logs - + const l2BlockNum = await aztecRpcServer.getBlockNumber(); const unencryptedLogs = await aztecRpcServer.getUnencryptedLogs(l2BlockNum, 1); From 7945e863627612396557dfb54ffb0788538f81c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bene=C5=A1?= Date: Thu, 24 Aug 2023 09:02:19 +0200 Subject: [PATCH 5/7] Apply suggestions from code review Co-authored-by: Michael Connor --- docs/docs/dev_docs/contracts/events.md | 33 +++++++++++-------- docs/docs/dev_docs/getting_started/sandbox.md | 2 +- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/docs/docs/dev_docs/contracts/events.md b/docs/docs/dev_docs/contracts/events.md index 50edc5e5d8a..85be0b523a8 100644 --- a/docs/docs/dev_docs/contracts/events.md +++ b/docs/docs/dev_docs/contracts/events.md @@ -1,8 +1,8 @@ ## Events -Events in Aztec works similarly to Ethereum events in a sense that they are a way for contracts to communicate with the outside world. -They are emitted by contracts and stored inside each instance ofAztecNode. -Aztec events are currently represented as raw data and are not ABI encoded. -ABI encoded events are a feature that will be added in the future. +Events in Aztec work similarly to Ethereum events in the sense that they are a way for contracts to communicate with the outside world. +They are emitted by contracts and stored inside each instance of an AztecNode. +> Aztec events are currently represented as raw data and are not ABI encoded. +> ABI encoded events are a feature that will be added in the future. Unlike on Ethereum, there are 2 types of events supported by Aztec: encrypted and unencrypted. @@ -36,11 +36,11 @@ await aztecRpc.registerRecipient(completeAddress); -> **NOTE**: If a note recipient is one of the accounts inside the Aztec RPC, we don't need to register it as a recipient because we already have the public key available. +> **NOTE**: If a note recipient is one of the accounts inside the Aztec RPC Server, we don't need to register it as a recipient because we already have the public key available. -At this point we only allow emitting note spending info through encrypted events. -In the future we will allow emitting arbitrary information. -(If you currently emit arbitrary information, AztecRPC server will fail to process it and it will not be queryable.) +> At this point the Sandbox only enables the emitting of encrypted note preimages through encrypted events. +> In the future we will allow emitting arbitrary information. +> (If you currently emit arbitrary information, AztecRPC server will fail to decrypt, process and store this data, so it will not be queryable). To emit encrypted logs first import the `emit_encrypted_log` utility function inside your contract: @@ -82,7 +82,13 @@ Then you can call the function: ### Costs -All the event data is pushed on Ethereum by the sequencer and for this reason the cost of emitting an event is non-trivial. +All event data is pushed to Ethereum as calldata by the sequencer and for this reason the cost of emitting an event is non-trivial. + +> Note: the cost of submitting calldata to Ethereum is currently 4 gas per byte. Currently, in the Sandbox, an encypted note has a fixed overhead of 4 field elements (to broadcast an ephemeral public key, a contract address, and a storage slot); plus a variable number of field elements depending on the type of note being emitted. +> A `ValueNote`, for example, currently uses 3 fields elements (plus the fixed overhead of 4). That's roughly `7 * 32 = 224` bytes of information, costing roughly 896 gas. + +> There are plans to compress encrypted note data further. +> There are plans to adopt EIP-4844 blobs to reduce the cost of data submission further. ## Processing events Both the encrypted and unencrypted events are stored in AztecNode. @@ -92,12 +98,13 @@ Encrypted logs need to first be decrypted: ### Decrypting One function of AztecRPC server is constantly loading encrypted logs from AztecNode and trying to decrypt them. -When new encrypted logs are obtained, AztecRPC server will try to decrypt them using the private encryption key of all the accounts registered inside AztecRPC server. -If the decryption is successful, AztecRPC server will store the decrypted note inside a database. +When new encrypted logs are obtained, the AztecRPC server will try to decrypt them using the private encryption key of all the accounts registered inside AztecRPC server. +If the decryption is successful, the AztecRPC server will store the decrypted note inside a database. If the decryption fails, the specific log will be discarded. -For the AztecRPC server to successfully process the decrypted note we need to compute note hash and nullifier. -Because we want to support arbitrary ways of computing these values, Noir developers need to implement a `compute_note_hash_and_nullifier` function inside their contracts. +For the AztecRPC server to successfully process the decrypted note we need to compute the note's 'note hash' and 'nullifier'. +Aztec.nr enables smart contract developers to design custom notes, meaning developers can also customise how a note's note hash and nullifier should be computed. Because of this customisability, and because there will be a potentially-unlimited number of smart contracts deployed to Aztec, an Aztec RPR Server needs to be 'taught' how to compute the custom note hashes and nullifiers for a particular contract. Therefore, developers will need to implement a `compute_note_hash_and_nullifier` function inside their contracts. +Every time a new note is successfully decrypted, the Aztec RPC Server will expect the existence of a `compute_note_hash_and_nullifier` function, which must teach it how to correctly process the new note. This is an example implementation inside the `PrivateTokenContract`: diff --git a/docs/docs/dev_docs/getting_started/sandbox.md b/docs/docs/dev_docs/getting_started/sandbox.md index a3b229a4a72..adf2dbdfd40 100644 --- a/docs/docs/dev_docs/getting_started/sandbox.md +++ b/docs/docs/dev_docs/getting_started/sandbox.md @@ -197,7 +197,7 @@ Great!. The Sandbox is running and we are able to interact with it. The next step is to create some accounts. An in-depth explaining about accounts on aztec can be found [here](../../concepts/foundation/accounts/main.md). But creating an account on the Sandbox does 2 things: -1. Deploys an account contract representing you allowing you to perform actions on the network (deploy contracts, call functions etc). +1. Deploys an account contract -- representing you -- allowing you to perform actions on the network (deploy contracts, call functions etc). 2. Adds your encryption keys to the RPC Server allowing it to decrypt and manage your private state. Continue with adding the following to the `index.ts` file in our example: From b8b984955775065e1bfa0d1e0643cea899971ffe Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 24 Aug 2023 09:05:36 +0200 Subject: [PATCH 6/7] docs: calling Aztec RPC Server consistently --- docs/docs/dev_docs/contracts/events.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/docs/dev_docs/contracts/events.md b/docs/docs/dev_docs/contracts/events.md index 85be0b523a8..199e9c4f216 100644 --- a/docs/docs/dev_docs/contracts/events.md +++ b/docs/docs/dev_docs/contracts/events.md @@ -8,7 +8,7 @@ Unlike on Ethereum, there are 2 types of events supported by Aztec: encrypted an ### Encrypted Events Encrypted events can only be emitted by private functions and are encrypted using a public key of a recipient. -For this reason it is necessary to register a recipient in the AztecRPC server before encrypting the events for them. +For this reason it is necessary to register a recipient in the Aztec RPC Server before encrypting the events for them. Recipients can be registered using the Aztec CLI or Aztec.js: import Tabs from '@theme/Tabs'; @@ -40,7 +40,7 @@ await aztecRpc.registerRecipient(completeAddress); > At this point the Sandbox only enables the emitting of encrypted note preimages through encrypted events. > In the future we will allow emitting arbitrary information. -> (If you currently emit arbitrary information, AztecRPC server will fail to decrypt, process and store this data, so it will not be queryable). +> (If you currently emit arbitrary information, Aztec RPC Server will fail to decrypt, process and store this data, so it will not be queryable). To emit encrypted logs first import the `emit_encrypted_log` utility function inside your contract: @@ -97,12 +97,12 @@ Unencrypted logs can be queried by anyone as we described above in the [Unencryp Encrypted logs need to first be decrypted: ### Decrypting -One function of AztecRPC server is constantly loading encrypted logs from AztecNode and trying to decrypt them. -When new encrypted logs are obtained, the AztecRPC server will try to decrypt them using the private encryption key of all the accounts registered inside AztecRPC server. -If the decryption is successful, the AztecRPC server will store the decrypted note inside a database. +One function of Aztec RPC Server is constantly loading encrypted logs from AztecNode and trying to decrypt them. +When new encrypted logs are obtained, the Aztec RPC Server will try to decrypt them using the private encryption key of all the accounts registered inside Aztec RPC Server. +If the decryption is successful, the Aztec RPC Server will store the decrypted note inside a database. If the decryption fails, the specific log will be discarded. -For the AztecRPC server to successfully process the decrypted note we need to compute the note's 'note hash' and 'nullifier'. +For the Aztec RPC Server to successfully process the decrypted note we need to compute the note's 'note hash' and 'nullifier'. Aztec.nr enables smart contract developers to design custom notes, meaning developers can also customise how a note's note hash and nullifier should be computed. Because of this customisability, and because there will be a potentially-unlimited number of smart contracts deployed to Aztec, an Aztec RPR Server needs to be 'taught' how to compute the custom note hashes and nullifiers for a particular contract. Therefore, developers will need to implement a `compute_note_hash_and_nullifier` function inside their contracts. Every time a new note is successfully decrypted, the Aztec RPC Server will expect the existence of a `compute_note_hash_and_nullifier` function, which must teach it how to correctly process the new note. From b6325d807be11d468610454c2e79e8d1755f2b63 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 24 Aug 2023 09:20:39 +0200 Subject: [PATCH 7/7] docs: using danger keyword --- docs/docs/dev_docs/contracts/events.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/docs/dev_docs/contracts/events.md b/docs/docs/dev_docs/contracts/events.md index 199e9c4f216..5eb174bbf47 100644 --- a/docs/docs/dev_docs/contracts/events.md +++ b/docs/docs/dev_docs/contracts/events.md @@ -54,7 +54,12 @@ Then you can call the function: ### Unencrypted Events Unencrypted events are events which can be read by anyone. They can be emitted by both public and private functions. -It's important for a developer to consider whether it's acceptable for the unencrypted event to be emitted from private functions as it might pose a significant privacy leak. + +:::danger + +Emitting unencrypted events from private function is a significant privacy leak and it should be considered by the developer whether it is acceptable. + +::: Once emitted, unencrypted events are stored in AztecNode and can be queried by anyone: