basic_bank.adl
1 2 program basic_bank.alpha { 3 // A token, issued by a bank. 4 // - 'owner' : The address of the account that owns the record associated with this token. 5 // - 'amount' : The amount of tokens owned by the account. 6 record Token { 7 owner: address, 8 amount: u64, 9 } 10 11 // An on-chain mapping, storing the amount of tokens owned by each account 12 // The account is stored as a to preserve user privacy. 13 mapping balances: field => u64; 14 15 // Returns a new Token. 16 // - `owner` : The address of the account to issue the token to. 17 // - `amount`: The amount of tokens to issue. 18 // Requires that the function caller is the bank. 19 // The bank's address is ax1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a. 20 transition issue(owner: address, amount: u64) -> Token { 21 assert_eq(self.caller, ax1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a); 22 return Token { 23 owner: owner, 24 amount: amount, 25 }; 26 } 27 28 // Deposits some amount of money into the bank. 29 // Returns a new Token with the remaining amount of money. 30 // - `token` : A record containing tokens to deposit. 31 // - `amount`: The amount of tokens to deposit. 32 async transition deposit(token: Token, amount: u64) -> (Token, Future) { 33 let difference: u64 = token.amount - amount; 34 35 let remaining: Token = Token { 36 owner: token.owner, 37 amount: difference, 38 }; 39 40 // Compute the hash of the token owner. 41 let hash: field = BHP256::hash_to_field(token.owner); 42 43 return (remaining, finalize_deposit(hash, amount)); 44 } 45 46 // Updates on-chain state by the amount of tokens deposited. 47 // - `hash` : The hash of the token owner. 48 // - `amount`: The amount of tokens that were deposited. 49 async function finalize_deposit(hash: field, amount: u64) { 50 let current_amount: u64 = Mapping::get_or_use(balances, hash, 0u64); 51 Mapping::set(balances, hash, current_amount + amount); 52 } 53 54 // Returns a new Token containing the amount of money withdrawn. 55 // - `recipient`: The address of the account to withdraw the tokens to. 56 // - `amount` : The amount of tokens to withdraw. 57 // - `rate` : The compound interest rate. 58 // - `periods` : The number of periods to compound the interest over. 59 // Requires that the function caller is the bank. 60 async transition withdraw(recipient: address, amount: u64, rate: u64, periods: u64) -> (Token, Future) { 61 assert_eq(self.caller, ax1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a); 62 let hash: field = BHP256::hash_to_field(recipient); 63 64 let total: u64 = calculate_interest(amount, rate, periods); 65 66 let token: Token = Token { 67 owner: recipient, 68 amount: total, 69 }; 70 71 return (token, finalize_withdraw(hash, amount)); 72 } 73 74 // Updates on-chain state by the amount of tokens withdrawn. 75 // - `hash` : The hash of the token owner. 76 // - `amount`: The amount of tokens that were withdrawn. 77 async function finalize_withdraw(hash: field, amount: u64) { 78 let current_amount: u64 = Mapping::get_or_use(balances, hash, 0u64); 79 Mapping::set(balances, hash, current_amount - amount); 80 } 81 82 // Returns the total amount of tokens after compounding interest. 83 // - `principal`: The amount of tokens to compound interest over. 84 // - `rate` : The compound interest rate. 85 // - `periods` : The number of periods to compound the interest over. 86 function calculate_interest(principal: u64, rate: u64, periods: u64) -> u64 { 87 let amount: u64 = principal; 88 89 for i:u64 in 0u64..100u64 { 90 if i < periods { 91 amount += (amount * rate) / 10000u64; 92 } 93 } 94 95 return amount; 96 } 97 }