Draft of Rholang Wallet code

Draft of Rholang Wallet code

  // Creates a coat check service contract MakeCoatCheck(ret) = { new (portIn, portOut):iopair, hanger in { ret!(*portOut) | for (@method, ack, ...@rest <= portIn) { match method { // Initially checks the coat case "new" => match rest { case (initialCoat) => new ticket in { ack!(*ticket) | // Hang the coat on the hanger corresponding // to the ticket @(*ticket | *hanger)!(initialCoat) } } // Retrieves the coat case "get" => match rest { case (ticket) => { // Find the right hanger for (@coat <! @(*ticket | *hanger)) { // Return the coat ack!(coat) } } } // Replaces the old coat with a new one. case "set" => match rest { case (store, @newCoat) => { // Throw away the existing coat for (_ <- @(*ticket | *hanger)) { // Hang up the new one @(*ticket | *hanger)!(newCoat) | ack!() } } } } } } } // Attenuation of coat check for sealing and unsealing contract MakeSealerUnsealer(ret) = { new (sealerIn, sealerOut):iopair, (unsealerIn, unsealerOut):iopair, mapRet in { ret!(*sealerOut, *unsealerOut) | MakeCoatCheck(ccRet) | for (cc <- ccRet) { for (@value, ret <= sealerIn) { cc!("new", *ret, value) } | for (ticket, ret <= unsealerIn) { cc!("get", *ret, *ticket) } } } } // MakeSealerUnsealer usage new ret in { MakeSealerUnsealer(ret) | for (sign, validate <- ret) { new signatureRet in { sign("Hello", signatureRet) | for (signature <- signatureRet) { new ack in { // Hangs if signature is invalid validate(signature, ack) | for (_ <- ack) { // Act on signed message } } } } } } contract MakeMint(ret) = { new suRet in { MakeSealerUnsealer(suRet) | for (sealer, unsealer <- suRet) { new (makeWalletIn, makeWalletOut):iopair in { for (@initialBalance, walletRet <= makeWalletIn) { new (walletIn, walletOut):iopair, balance, (decrIn, decrOut):iopair in { balance!(initialBalance) | for (@amount, ack <= decrIn) { for (@currentBalance <- balance) { if (amount <= currentBalance) { balance!(currentBalance - amount) ack!(true) } else { balance!(currentBalance) ack!(false) } } } | for (@method, methodRet, ...args <= walletIn) { match method { case "getBalance" => { for (@currentBalance <! balance) { methodRet!(currentBalance) } } case "sprout" => { makeWalletOut!(0, methodRet) } case "getDecr" => { sealer!(decrOut, methodRet) } case "deposit" => { args match { (amount, src) => new decrRet in { @src!("getDecr", decrRet) | for (srcDecr <- decrRet) new unsealedRet in { unsealer!(srcDecr, unsealedRet) | for (unsealed <- unsealedRet; @currentBalance <- balance) new ack in { unsealed(amount, ack) | for (@result <- ack) { if (result) { balance!(currentBalance + amount) } else { balance!(currentBalance) } | methodRet!() } } } } } } } } } | walletRet!(walletOut) } | ret!(*makeWalletOut) } } } } // Usage new mintRet in { // Create a new currency/token/mint MakeMint(mintRet) | for (mint <- mintRet) new wallet1Ret, wallet2Ret in { // Call mint with an initial balance to mint some money // and put it in the wallet mint(100, wallet1Ret) | mint(200, wallet2Ret) | for (wallet1 <- wallet1Ret; wallet2 <- wallet2Ret) { // Move 50 tokens from wallet1 to wallet2 new ack in { wallet2!("deposit", 50, wallet1, ack) | for (_ <- ack) new balanceRet in { wallet2!("getBalance", balanceRet) | for (@balance <- balanceRet) { // Prints 250 system!("print", balance) } } } } } }