diff --git a/docs/pages/aztec-nr/introduction-to-private-smart-contracts/account-contract.md b/docs/pages/aztec-nr/introduction-to-private-smart-contracts/account-contract.md index 90f8a5d..cd9f48c 100644 --- a/docs/pages/aztec-nr/introduction-to-private-smart-contracts/account-contract.md +++ b/docs/pages/aztec-nr/introduction-to-private-smart-contracts/account-contract.md @@ -1,2 +1,3 @@ # Account Contract +(i don't think this is a good example, it doesn't illustrate a lot and is too complicated. a simple game might be better, to provide a non-token example, but i can't think of a good simple example. something like battleship would be good but that'd probably require semaphores and arrays (or building those manually), so that's not great.) \ No newline at end of file diff --git a/docs/pages/aztec-nr/introduction-to-private-smart-contracts/index.md b/docs/pages/aztec-nr/introduction-to-private-smart-contracts/index.md index e69de29..32dfefe 100644 --- a/docs/pages/aztec-nr/introduction-to-private-smart-contracts/index.md +++ b/docs/pages/aztec-nr/introduction-to-private-smart-contracts/index.md @@ -0,0 +1,12 @@ +note: + we assume you already know what a smart contract is and are familiar with solidity. if you do not not, head to https://docs.soliditylang.org/en/v0.8.30/introduction-to-smart-contracts.html. + we also assume you have basic knowledge of what a zero knowledge proof is and what noir looks like - if you do not, head to ???? (noir docs)? + +A Solidity smart contract on Ethereum has `external` functions anyone can call, but everything about executing them is public information to the entire internet: when they were called, who called them, and with what parameters. additionally, all contract state is also public: eg anyone can query the token balance of any account at any time. sharing an ethereum address with someone means also sharing all past and future onchain activity with them forever. aztec extends smart contracts by adding privacy to them. + +an aztec contract has public external functions, and these work just like in ethereum. but it also has _private_ external functions, which don't reveal anything: the caller, all parameters, even the fact that the contract was executed, these all remain hidden. aztec contracts can also have _private_ state, which is stored encrypted onchain so that only account with the corresponding keys can read it. but despite none of this information being revealed, private functions can still be verified for correct execution via zero knowledge proofs. + +note: + in solidity 'public' and 'private' specify function visibility, along with 'external' and 'internal' (https://docs.soliditylang.org/en/latest/contracts.html#function-visibility). in aztec, the terms 'public' and 'private' **always** refer to whether information is public (i.e. known to all) or private (i.e. known to some) - never to function visibility. aztec contracts do have both 'external' and 'internal' functions however, and their meaning is the exact same as in solidity (i.e. whether a function can be called from the outside or not). + +private smart contracts are quite different from regular smart contracts, because building private applications is hard. there are many considerations to be had when building such an application, and the design and tradeoff space is very large. aztecnr provides multiple utilities to make this task easier \ No newline at end of file diff --git a/docs/pages/aztec-nr/introduction-to-private-smart-contracts/private-token-contract.md b/docs/pages/aztec-nr/introduction-to-private-smart-contracts/private-token-contract.md index 92cce42..73cfd20 100644 --- a/docs/pages/aztec-nr/introduction-to-private-smart-contracts/private-token-contract.md +++ b/docs/pages/aztec-nr/introduction-to-private-smart-contracts/private-token-contract.md @@ -1,2 +1,96 @@ # Private Token Contract +aztec contracts have both private and public functions. let's start with the public part, building an equivalent erc20 token: + +```rust +#[aztec] +contract token { + // declare state variables + #[storage] + struct Storage { + // use map to create a publicmutable state variable for each user. a public mutable value is one that is publicly + // known (not private), and which can be mutated (changed) - other kinds of state variables exist. this public + // mutable holds u128 (unsigned 128 bit integers), for the token balance of each account + // + // the equivalent solidity declaration is + // mapping(address => uint128) private balances; + balances: Map
>, + } + + // declare an event for token transfers + // + // the equivalent solidity declaration is + // event Transfer(address from, address to, uint128 amount); + #[event] + struct Transfer { + from: Address, + to: Address, + amount: u128, + } + + // declare an external public function for transferring tokens. + // + // the equivalent solidity declaration is + // function transfer(address to, uint128 amount) external + #[external(public)] + fn transfer(to: address, amount: u128) { + // read the sender's current balance + let current_sender_balance = self.storage.balances.at(self.msg_sender).read(); + // subtract amount and store again + self.storage.balances.at(self.msg_sender).write(current_sender_balance.sub(amoun)); + + // same for the recipient, but adding + let current_recipient_balance = self.storage.balances.at(to).read(); + self.storage.balances.at(to).write(current_recipient_balance.add(amoun)); + + // emit an event + self.emit(Transfer { self.msg_sender, to, amount }); + } + + // meta: consider also writing a balance_of getter +} +``` + +now add the capacity private balance (use the balance set library to avoid immediately exposing notes and private set). + +```rust +#[aztec] +contract token { + #[storage] + struct Storage { + balances: Map>, + // use map to create a balance set state variable for each user. whenever a user is sent tokens private, a note + // is created and added to this set, and the aggregate of all notes makes up their balance. + private_balances: Map