Skip to content

Commit

Permalink
Bank smart contract working and tested
Browse files Browse the repository at this point in the history
  • Loading branch information
fabcotech committed Jul 30, 2024
1 parent 870d66f commit ceae0b1
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 70 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ and test suites. New code coming in regularly.
toggle ping->pong, and only one other address is authorized to toggle
pong->ping. _Checking sender address_, _Comparing sender address with another
arbitrary address_
- **Bank** : A simple contract can receive coins, and store them into a cell.
_receive TON_, _store TON in a smart contract_

```sh
yarn
Expand All @@ -47,4 +49,7 @@ yarn test tests/PingPong.spec.ts

# Only test ping pong 2
yarn test tests/PingPong2.spec.ts

# Only test bank
yarn test tests/Bank.spec.ts
```
76 changes: 36 additions & 40 deletions contracts/bank.fc
Original file line number Diff line number Diff line change
@@ -1,56 +1,52 @@
#include "imports/stdlib.fc";

;; storage variables
global int ctx_balance;
global cell ctx_balance;

() load_data() impure {
var ds = get_data().begin_parse();
ctx_balance = ds~load_uint(32);
ds.end_parse();
var ds = get_data().begin_parse();
ctx_balance = ds~load_ref();
ds.end_parse();
}

() save_data() impure {
set_data(
() save_data(int coins) impure {
set_data(
begin_cell()
.store_ref(
begin_cell()
.store_uint(ctx_balance, 32)
.end_cell()
);
.store_coins(coins)
.end_cell()
)
.end_cell()
);
}

() recv_internal(int my_balance, int msg_value, cell in_msg_full, slice in_msg_body) impure {
if (in_msg_body.slice_empty?()) {
return ();
}

slice cs = in_msg_full.begin_parse();
int flags = cs~load_uint(4);
if (flags & 1) {
return ();
}

load_data();
~strdump("balance");
~dump(ctx_balance);

int coins_amount = in_msg_body~load_coins();
~strdump("coins_amount");
~dump(coins_amount);

if (coins_amount != 0) {
~strdump("not zero");
ctx_balance += coins_amount;
~strdump("newbalance");
~dump(ctx_balance);
save_data();
return ();
}

load_data();
if (in_msg_body.slice_empty?()) {
return ();
}

slice cs = in_msg_full.begin_parse();
int flags = cs~load_uint(4);
if (flags & 1) {
return ();
}

load_data();
slice current = ctx_balance.begin_parse();
(_, int current_balance) = current.load_coins();

int coins_amount = in_msg_body~load_coins();

if (coins_amount != 0) {
save_data(coins_amount + current_balance);
return ();
}

throw(0xffff);
}

int get_bal() method_id {
load_data();
return ctx_balance;
cell get_bal() method_id {
load_data();
return ctx_balance;
}
34 changes: 18 additions & 16 deletions tests/Bank.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Blockchain, SandboxContract, TreasuryContract } from '@ton/sandbox';
import '@ton/test-utils';
import { Cell, toNano, ContractProvider } from '@ton/core';
import { Cell, toNano } from '@ton/core';
import { compile } from '@ton/blueprint';

import { Bank } from '../wrappers/Bank';
Expand All @@ -19,38 +19,40 @@ describe('[Bank]', () => {
code = await compile('Bank');
blockchain = await Blockchain.create();
user1 = await blockchain.treasury('user1');
bankContract = blockchain.openContract(
Bank.createFromConfig({ balance: 0 }, code)
);
for (let i = 0; i < 3; i += 1) {
bankContract = blockchain.openContract(Bank.createFromConfig(code));
for (let i = 0; i < 10; i += 1) {
transfers.push({
sender: user1 as unknown as SandboxContract<TreasuryContract>,
coins: toNano(BigInt(Math.round(Math.random() * 100))),
coins: BigInt(Math.round(Math.random() * 100)),
});
}
/*
smart contract balance goes
above the 1B limit
*/
transfers.push({
sender: user1 as unknown as SandboxContract<TreasuryContract>,
coins: BigInt('1000000000'),
});
});

it('[Bank] user1 transfers to smart contract', async () => {
const deployResult = await bankContract.sendDeploy(
await bankContract.sendDeploy(
(user1 as SandboxContract<TreasuryContract>).getSender(),
toNano('0.05')
);
let i = 1;
let bi = 0n;
for (const transfer of transfers) {
console.log('transfer.coins');
console.log(transfer.coins);
/* const balance = await bankContract.getBalance();
console.log('balance', balance); */
const bal = await bankContract.getBal();
console.log('bal', bal);
const a = await bankContract.sendTransfer(
bi += transfer.coins;
await bankContract.sendTransfer(
(user1 as SandboxContract<TreasuryContract>).getSender(),
{
value: toNano('0.05'),
coins: transfer.coins,
}
);
expect(true).toBe(true);
const bal = await bankContract.getBal();
expect(bal).toBe(bi);
}
});
});
21 changes: 7 additions & 14 deletions wrappers/Bank.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@ import {
toNano,
} from '@ton/core';

export type BankConfig = {
balance: number;
};

export function bankConfigToCell(config: BankConfig): Cell {
return beginCell().storeUint(config.balance, 32).endCell();
export function bankConfigToCell(): Cell {
return beginCell()
.storeRef(beginCell().storeCoins(toNano('0')).endCell())
.endCell();
}

export class Bank implements Contract {
Expand All @@ -28,8 +26,8 @@ export class Bank implements Contract {
return new Bank(address);
}

static createFromConfig(config: BankConfig, code: Cell, workchain = 0) {
const data = bankConfigToCell(config);
static createFromConfig(Cell, workchain = 0) {
const data = bankConfigToCell();
const init = { code, data };
return new Bank(contractAddress(workchain, init), init);
}
Expand Down Expand Up @@ -62,11 +60,6 @@ export class Bank implements Contract {

async getBal(provider: ContractProvider) {
const result = await provider.get('get_bal', []);
return result.stack.readNumber();
}

async getBalance(provider: ContractProvider) {
const result = await provider.get('get_balance', []);
return result.stack.readNumber();
return result.stack.readCell().beginParse().preloadCoins();
}
}

0 comments on commit ceae0b1

Please sign in to comment.