|
| 1 | +import { |
| 2 | + SmartContract, |
| 3 | + method, |
| 4 | + state, |
| 5 | + PublicKey, |
| 6 | + UInt64, |
| 7 | +} from '../../../../index.js'; |
| 8 | +import * as Mina from '../../mina.js'; |
| 9 | +import assert from 'assert'; |
| 10 | +import { ExampleContract } from './ExampleContract.js'; |
| 11 | +import { settle, transfer } from './utils.js'; |
| 12 | + |
| 13 | +const Local = await Mina.LocalBlockchain({ proofsEnabled: false }); |
| 14 | +Mina.setActiveInstance(Local); |
| 15 | + |
| 16 | +const [ |
| 17 | + sender, |
| 18 | + receiver1, |
| 19 | + receiver2, |
| 20 | + receiver3, |
| 21 | + contractAccountA, |
| 22 | + contractAccountB, |
| 23 | +] = Local.testAccounts; |
| 24 | + |
| 25 | +const contractA = new ExampleContract(contractAccountA); |
| 26 | +const contractB = new ExampleContract(contractAccountB); |
| 27 | +contractA.offchainState.setContractInstance(contractA); |
| 28 | +contractB.offchainState.setContractInstance(contractB); |
| 29 | + |
| 30 | +console.time('deploy contract'); |
| 31 | +const deployTx = Mina.transaction(sender, async () => { |
| 32 | + await contractA.deploy(); |
| 33 | + await contractB.deploy(); |
| 34 | +}); |
| 35 | +await deployTx.sign([sender.key, contractAccountA.key, contractAccountB.key]); |
| 36 | +await deployTx.prove(); |
| 37 | +await deployTx.send().wait(); |
| 38 | +console.timeEnd('deploy contract'); |
| 39 | + |
| 40 | +console.time('create accounts'); |
| 41 | +const accountCreationTx = Mina.transaction(sender, async () => { |
| 42 | + await contractA.createAccount(sender, UInt64.from(1000)); |
| 43 | + await contractA.createAccount(receiver2, UInt64.from(1000)); |
| 44 | + await contractB.createAccount(sender, UInt64.from(1500)); |
| 45 | +}); |
| 46 | +await accountCreationTx.sign([sender.key]); |
| 47 | +await accountCreationTx.prove(); |
| 48 | +await accountCreationTx.send().wait(); |
| 49 | +console.timeEnd('create accounts'); |
| 50 | + |
| 51 | +console.time('settle'); |
| 52 | +await settle(contractA, sender); |
| 53 | +await settle(contractB, sender); |
| 54 | +console.timeEnd('settle'); |
| 55 | + |
| 56 | +assert((await contractA.getSupply()).toBigInt() == 1000n); |
| 57 | +assert((await contractB.getSupply()).toBigInt() == 1500n); |
| 58 | + |
| 59 | +console.log('Initial balances:'); |
| 60 | +console.log( |
| 61 | + 'Contract A, Sender: ', |
| 62 | + (await contractA.offchainState.fields.accounts.get(sender)).value.toBigInt() |
| 63 | +); |
| 64 | +console.log( |
| 65 | + 'Contract B, Sender: ', |
| 66 | + (await contractB.offchainState.fields.accounts.get(sender)).value.toBigInt() |
| 67 | +); |
| 68 | +assert((await contractA.getBalance(sender)).toBigInt() == 1000n); |
| 69 | +assert((await contractB.getBalance(sender)).toBigInt() == 1500n); |
| 70 | + |
| 71 | +console.time('transfer'); |
| 72 | +await transfer(contractA, sender, receiver1, UInt64.from(100)); |
| 73 | +await settle(contractA, sender); |
| 74 | +await transfer(contractA, sender, receiver2, UInt64.from(200)); |
| 75 | +await settle(contractA, sender); |
| 76 | +await transfer(contractA, sender, receiver3, UInt64.from(300)); |
| 77 | +await transfer(contractB, sender, receiver1, UInt64.from(200)); |
| 78 | +console.timeEnd('transfer'); |
| 79 | + |
| 80 | +console.time('settle'); |
| 81 | +await settle(contractA, sender); |
| 82 | +await settle(contractB, sender); |
| 83 | +console.timeEnd('settle'); |
| 84 | + |
| 85 | +console.log('After Settlement balances:'); |
| 86 | +console.log( |
| 87 | + 'Contract A, Sender: ', |
| 88 | + (await contractA.offchainState.fields.accounts.get(sender)).value.toBigInt() |
| 89 | +); |
| 90 | +console.log( |
| 91 | + 'Contract A, Receiver 1: ', |
| 92 | + ( |
| 93 | + await contractA.offchainState.fields.accounts.get(receiver1) |
| 94 | + ).value.toBigInt() |
| 95 | +); |
| 96 | +console.log( |
| 97 | + 'Contract A, Receiver 2: ', |
| 98 | + ( |
| 99 | + await contractA.offchainState.fields.accounts.get(receiver2) |
| 100 | + ).value.toBigInt() |
| 101 | +); |
| 102 | +console.log( |
| 103 | + 'Contract A, Receiver 3: ', |
| 104 | + ( |
| 105 | + await contractA.offchainState.fields.accounts.get(receiver3) |
| 106 | + ).value.toBigInt() |
| 107 | +); |
| 108 | + |
| 109 | +console.log( |
| 110 | + 'Contract B, Sender: ', |
| 111 | + (await contractB.offchainState.fields.accounts.get(sender)).value.toBigInt() |
| 112 | +); |
| 113 | +console.log( |
| 114 | + 'Contract B, Receiver 1: ', |
| 115 | + ( |
| 116 | + await contractB.offchainState.fields.accounts.get(receiver1) |
| 117 | + ).value.toBigInt() |
| 118 | +); |
| 119 | +assert((await contractA.getBalance(sender)).toBigInt() == 400n); |
| 120 | +assert((await contractA.getBalance(receiver1)).toBigInt() == 100n); |
| 121 | +assert((await contractA.getBalance(receiver2)).toBigInt() == 200n); |
| 122 | +assert((await contractA.getBalance(receiver3)).toBigInt() == 300n); |
| 123 | + |
| 124 | +assert((await contractB.getBalance(sender)).toBigInt() == 1300n); |
| 125 | +assert((await contractB.getBalance(receiver1)).toBigInt() == 200n); |
| 126 | + |
| 127 | +console.time('advance contract A state but leave B unsettled'); |
| 128 | +await transfer(contractA, sender, receiver1, UInt64.from(150)); // 250, 250, 200, 300 |
| 129 | +await transfer(contractA, receiver2, receiver3, UInt64.from(20)); // 250, 250, 180, 320 |
| 130 | +await settle(contractA, sender); |
| 131 | + |
| 132 | +await transfer(contractA, receiver1, receiver2, UInt64.from(50)); // 250, 200, 230, 320 |
| 133 | +await transfer(contractA, receiver3, sender, UInt64.from(50)); // 300, 200, 230, 270 |
| 134 | +await settle(contractA, sender); |
| 135 | + |
| 136 | +await transfer(contractB, sender, receiver1, UInt64.from(5)); |
| 137 | +console.timeEnd('advance contract A state but leave B unsettled'); |
| 138 | + |
| 139 | +assert((await contractA.getSupply()).toBigInt() == 1000n); |
| 140 | +assert((await contractB.getSupply()).toBigInt() == 1500n); |
| 141 | + |
| 142 | +console.log('Final balances:'); |
| 143 | +console.log( |
| 144 | + 'Contract A, Sender: ', |
| 145 | + (await contractA.offchainState.fields.accounts.get(sender)).value.toBigInt() |
| 146 | +); |
| 147 | +console.log( |
| 148 | + 'Contract A, Receiver 1: ', |
| 149 | + ( |
| 150 | + await contractA.offchainState.fields.accounts.get(receiver1) |
| 151 | + ).value.toBigInt() |
| 152 | +); |
| 153 | +console.log( |
| 154 | + 'Contract A, Receiver 2: ', |
| 155 | + ( |
| 156 | + await contractA.offchainState.fields.accounts.get(receiver2) |
| 157 | + ).value.toBigInt() |
| 158 | +); |
| 159 | +console.log( |
| 160 | + 'Contract A, Receiver 3: ', |
| 161 | + ( |
| 162 | + await contractA.offchainState.fields.accounts.get(receiver3) |
| 163 | + ).value.toBigInt() |
| 164 | +); |
| 165 | + |
| 166 | +console.log( |
| 167 | + 'Contract B, Sender: ', |
| 168 | + (await contractB.offchainState.fields.accounts.get(sender)).value.toBigInt() |
| 169 | +); |
| 170 | +console.log( |
| 171 | + 'Contract B, Receiver: ', |
| 172 | + ( |
| 173 | + await contractB.offchainState.fields.accounts.get(receiver1) |
| 174 | + ).value.toBigInt() |
| 175 | +); |
| 176 | + |
| 177 | +assert((await contractA.getBalance(sender)).toBigInt() == 300n); |
| 178 | +assert((await contractA.getBalance(receiver1)).toBigInt() == 200n); |
| 179 | +assert((await contractA.getBalance(receiver2)).toBigInt() == 230n); |
| 180 | +assert((await contractA.getBalance(receiver3)).toBigInt() == 270n); |
| 181 | + |
| 182 | +// The 5 token transfer has not been settled |
| 183 | +assert((await contractB.getBalance(sender)).toBigInt() == 1300n); |
| 184 | +assert((await contractB.getBalance(receiver1)).toBigInt() == 200n); |
0 commit comments