Skip to main content

Execution

We will write a couple of tests which will help us understand some basics about interacting with the contract. After writing each test you should run the correct script from the previous section (node or browser one) to see if it works correctly.

⚖️ Current state and current balance

Let's start with reading the contract's state. Add the following code to should read pst state and balance data test. If you've set other addresses or balances in the initial state you will of course need to change them accordingly.

expect(await pst.currentState()).toEqual(initialState);
expect((await pst.currentBalance('GH2IY_3vtE2c0KfQve9_BHoIPjZCS8s5YmSFS_fppKI')).balance).toEqual(1000);
expect((await pst.currentBalance('33F0QHcb22W7LwWR1iRC8Az1ntZG09XQ03YWuw2ABqA')).balance).toEqual(230);

We are using SDK's currentState method which reads the current state of our contract. We are also using PST's specific method - currentBalance which takes the target wallet as an argument and read its current balance. Underneath, it simply returns the "view" of the state, computed by the Warp - ie. the object that is a derivative of a current state and some specific smart contract business logic. Remember when we were writing actions possible to make with our contract in the contract source? This is where we see it in action!

💰 Minting tokens - write interaction

Let's move to the next test. Add the following code to should properly mint tokens test.

await pst.writeInteraction({
function: 'mint',
qty: 2000,
});

expect((await pst.currentState()).balances[walletAddress]).toEqual(2000);

We are using SDK's writeInteraction method which creates, signs and posts transactions with specific input to Arweave and returns a transaction id. We will call the mint function which should mint specific amount of FC tokens to the previously generated caller's wallet.

As we posted a transaction which changes the contract's state, we need to mine a block. Fortunately - as we've mentioned in previous chapter - the Warp instance obtained from Warp.forLocal() makes this for us automatically after each writeInteraction call.

💸 Transfering tokens

Let's test the core contract function - transfer. It should correctly subtract an indicated amount of tokens from the caller's wallet and add it to the target wallet. Here we can usea dedicated PST method - transfer which calls the transfer function by using the writeInteraction method. We will then, again, mine a block and check the contract's state after the change. Add the following code to should properly transfer tokens test.

await pst.transfer({
target: 'GH2IY_3vtE2c0KfQve9_BHoIPjZCS8s5YmSFS_fppKI',
qty: 555,
});
});

🏜️ Dry-writes

One last test to write. It will introduce us to the SDK's method - dryWrite. It loads the contract state, creates a 'dummy' transaction and applies the given input on top of the current contract's state. This way, you can verify how a specific interaction will result before posting it to Arweave. You can view its API here. We will pass optional parameter - caller's address - which will override the caller evaluated from the wallet connected to the contract. Write following code in should properly perform dry write with overwritten caller test.

    const { address: overwrittenCaller } = await warp.testing.generateWallet();
await pst.transfer({
target: overwrittenCaller,
qty: 1000,
});

const result: InteractionResult<PstState, unknown> = await pst.dryWrite(
{
function: 'transfer',
target: 'GH2IY_3vtE2c0KfQve9_BHoIPjZCS8s5YmSFS_fppKI',
qty: 333,
},
overwrittenCaller
);

expect(result.state.balances[walletAddress]).toEqual(
2000 + 333 - 555 - 1000
);
expect(
result.state.balances['GH2IY_3vtE2c0KfQve9_BHoIPjZCS8s5YmSFS_fppKI']
).toEqual(1000 + 555 + 333);
expect(result.state.balances[overwrittenCaller]).toEqual(1000 - 333);
});

🎊 Conclusion

We have just learned some key SmartWeave concepts. We have also ascertained that our contract will work correctly. We are ready to deploy the contract!