diff --git a/examples/auction/README.md b/examples/auction/README.md index 8a746b6dd7..68ccaa546f 100644 --- a/examples/auction/README.md +++ b/examples/auction/README.md @@ -40,13 +40,14 @@ Users may either specify input values via the command line or provide an input f The `program.json` file contains a private key and address. This is the account that will be used to sign transactions and is checked for record ownership. When executing programs as different parties, be sure to set the `private_key` and `address` fields in `program.json` to the appropriate values. + See `./run.sh` for an example of how to run the program as different parties. The [Aleo SDK](https://github.com/AleoHQ/leo/tree/testnet3) provides a command line interface for generating new accounts. To generate a new account, run ``` -leo account new +aleo account new ``` @@ -64,3 +65,9 @@ See `./run.sh` for an example. ```bash leo run ``` +For example, +```bash +leo run place_bid +leo run resolve +leo run finish +``` diff --git a/examples/broken_bank/README.md b/examples/broken_bank/README.md index 3e1b373cae..409bc8a573 100644 --- a/examples/broken_bank/README.md +++ b/examples/broken_bank/README.md @@ -1,8 +1,83 @@ -# bank.aleo +# Blind Auction -## Build Guide +A "broken" bank written in Leo. -To compile this Aleo program, run: -```bash -aleo build +## Summary + +A first-price sealed-bid auction (or blind auction) is a type of auction in which each participant submits a bid without knowing the bids of the other participants. +The bidder with the highest bid wins the auction. + +In this model, there are two parties: the auctioneer and the bidders. +- **Bidder**: A participant in the auction. +- **Auctioneer**: The party responsible for conducting the auction. + +We make following assumptions about the auction: +- The auctioneer is honest. That is, the auctioneer will resolve **all** bids in the order they are received. The auctioneer will not tamper with the bids. +- There is no limit to the number of bids. +- The auctioneer knows the identity of all bidders, but bidders do not necessarily know the identity of other bidders. + +Under this model, we require that: +- Bidders do not learn any information about the value of other bids. + +### Auction Flow +The auction is conducted in a series of stages. +- **Bidding**: In the bidding stage, bidders submit bids to the auctioneer. They do so by invoking the `place_bid` function. +- **Resolution**: In the resolution stage, the auctioneer resolves the bids in the order they were received. The auctioneer does so by invoking the `resolve` function. The resolution process produces a single winning bid. +- **Finishing**: In this stage, the auctioneer finishes the auction by invoking the `finish` function. This function returns the winning bid to the bidder, which the bidder can then use to claim the item. + +## Vulnerabilities + +You may have already guessed that this program has a few vulnerabilities. Can you find them? + + + +## Language Features and Concepts +- `record` declarations +- `console.assert_eq` +- core functions, e.g. `BHP256::hash` +- record ownership +- loops and bounded iteration +- mappings +- finalize + +## Running the Program + +Leo provides users with a command line interface for compiling and running Leo programs. +Users may either specify input values via the command line or provide an input file in `inputs/`. + +### Configuring Accounts +The `program.json` file contains a private key and address. +This is the account that will be used to sign transactions and is checked for record ownership. +When executing programs as different parties, be sure to set the `private_key` and `address` fields in `program.json` to the appropriate values. + + +See `./run.sh` for an example of how to run the program as different parties. + + +The [Aleo SDK](https://github.com/AleoHQ/leo/tree/testnet3) provides a command line interface for generating new accounts. +To generate a new account, run +``` +leo account new +``` + + +### Providing inputs via the command line. +1. Run +```bash +leo run ... +``` +See `./run.sh` for an example. + + +### Using an input file. +1. Modify `inputs/auction.in` with the desired inputs. +2. Run +```bash +leo run +``` +For example, +```bash +leo run issue +leo run deposit +leo run withdraw ``` diff --git a/examples/broken_bank/inputs/bank.in b/examples/broken_bank/inputs/broken_bank.in similarity index 80% rename from examples/broken_bank/inputs/bank.in rename to examples/broken_bank/inputs/broken_bank.in index 70d1ec3c13..cbac6c3fe4 100644 --- a/examples/broken_bank/inputs/bank.in +++ b/examples/broken_bank/inputs/broken_bank.in @@ -1,8 +1,9 @@ -// The program input for broken_bank/src/main.leo +// Inputs for the `issue` function. [issue] owner: address = aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a; amount: u64 = 1234u64; +// Inputs for the `deposit` function. [deposit] token: Token = Token { owner: aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a, @@ -12,6 +13,7 @@ token: Token = Token { }; amount: u64 = 321u64; +// Inputs for the `withdraw` function. [withdraw] recipient: address = aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a; amount: u64 = 321u64; diff --git a/examples/broken_bank/program.json b/examples/broken_bank/program.json index aa28543c68..a2250a5a3d 100644 --- a/examples/broken_bank/program.json +++ b/examples/broken_bank/program.json @@ -1,5 +1,5 @@ { - "program": "bank.aleo", + "program": "broken_bank.aleo", "version": "0.0.0", "description": "", "development": { diff --git a/examples/broken_bank/run.sh b/examples/broken_bank/run.sh index dc5d137999..43c8318b61 100755 --- a/examples/broken_bank/run.sh +++ b/examples/broken_bank/run.sh @@ -18,7 +18,7 @@ fi # Swap in the private key and address of the bank to program.json. echo "{ - \"program\": \"bank.aleo\", + \"program\": \"broken_bank.aleo\", \"version\": \"0.0.0\", \"description\": \"\", \"development\": { @@ -37,7 +37,7 @@ leo run issue aleo1zeklp6dd8e764spe74xez6f8w27dlua3w7hl4z2uln03re52egpsv46ngg 10 # Swap in the private key and address of the user to program.json. echo "{ - \"program\": \"bank.aleo\", + \"program\": \"broken_bank.aleo\", \"version\": \"0.0.0\", \"description\": \"\", \"development\": { @@ -61,7 +61,7 @@ leo run deposit "{ # Swap in the private key and address of the bank to program.json. echo "{ - \"program\": \"bank.aleo\", + \"program\": \"broken_bank.aleo\", \"version\": \"0.0.0\", \"description\": \"\", \"development\": { diff --git a/examples/broken_bank/src/main.leo b/examples/broken_bank/src/main.leo index dc8e244abd..f53ceee5f0 100644 --- a/examples/broken_bank/src/main.leo +++ b/examples/broken_bank/src/main.leo @@ -1,11 +1,22 @@ +// A token, issued by a bank. +// - 'owner' : The address of the account that owns the record associated with this token. +// - 'gates' : The value associated with the record (always zero). +// - 'amount' : The amount of tokens owned by the account. record Token { owner: address, gates: u64, amount: u64, } +// An on-chain mapping, storing the amount of tokens owned by each account +// The account is stored as a to preserve user privacy. mapping balances: field => u64; +// Returns a new Token. +// - `owner` : The address of the account to issue the token to. +// - `amount`: The amount of tokens to issue. +// Requires that the function caller is the bank. +// The bank's address is aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a. @program function issue(owner: address, amount: u64) -> Token { console.assert_eq(self.caller, aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a); @@ -16,6 +27,10 @@ function issue(owner: address, amount: u64) -> Token { }; } +// Deposits some amount of money into the bank. +// Returns a new Token with the remaining amount of money. +// - `token` : A record containing tokens to deposit. +// - `amount`: The amount of tokens to deposit. @program function deposit(token: Token, amount: u64) -> Token { let difference: u64 = token.amount - amount; @@ -26,6 +41,7 @@ function deposit(token: Token, amount: u64) -> Token { amount: difference, }; + // Compute the hash of the token owner. let hash: field = BHP256::hash(token.owner); finalize(hash, amount); @@ -33,10 +49,19 @@ function deposit(token: Token, amount: u64) -> Token { return remaining; } +// Updates on-chain state by the amount of tokens deposited. +// - `hash` : The hash of the token owner. +// - `amount`: The amount of tokens that were deposited. finalize deposit(hash: field, amount: u64) { increment(balances, hash, amount); } +// Returns a new Token containing the amount of money withdrawn. +// - `recipient`: The address of the account to withdraw the tokens to. +// - `amount` : The amount of tokens to withdraw. +// - `rate` : The compound interest rate. +// - `periods` : The number of periods to compound the interest over. +// Requires that the function caller is the bank. @program function withdraw(recipient: address, amount: u64, rate: u64, periods: u64) -> Token { console.assert_eq(self.caller, aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a); @@ -55,10 +80,17 @@ function withdraw(recipient: address, amount: u64, rate: u64, periods: u64) -> T return token; } +// Updates on-chain state by the amount of tokens withdrawn. +// - `hash` : The hash of the token owner. +// - `amount`: The amount of tokens that were withdrawn. finalize withdraw(hash: field, amount: u64) { decrement(balances, hash, amount); } +// Returns the total amount of tokens after compounding interest. +// - `principal`: The amount of tokens to compound interest over. +// - `rate` : The compound interest rate. +// - `periods` : The number of periods to compound the interest over. function calculate_interest(principal: u64, rate: u64, periods: u64) -> u64 { let amount: u64 = principal; diff --git a/examples/tictactoe/README.md b/examples/tictactoe/README.md index 48243ac1d8..334d73d057 100644 --- a/examples/tictactoe/README.md +++ b/examples/tictactoe/README.md @@ -31,3 +31,9 @@ See `./run.sh` for an example. ```bash leo run ``` +For example, +```bash +leo run new +leo run make_move + +``` diff --git a/examples/tictactoe/inputs/tictactoe.in b/examples/tictactoe/inputs/tictactoe.in index 76c9aa77d0..6973b59374 100644 --- a/examples/tictactoe/inputs/tictactoe.in +++ b/examples/tictactoe/inputs/tictactoe.in @@ -2,10 +2,6 @@ [new] // Inputs for the `make_move` function. -// - `player` : A u8 representing the player making the move. 1 for player 1, 2 for player 2. -// - `row` : A u8 representing the row to make the move in. -// - `column` : A u8 representing the column to make the move in. -// - `board` : A representation of the board state. [make_move] player: u8 = 1u8; row: u8 = 1u8;