git.delta.rocks / unique-network / refs/commits / 2ace66dc79b6

difftreelog

source

tests/src/contracts.test.ts9.0 KiBsourcehistory
1import chai from "chai";2import chaiAsPromised from 'chai-as-promised';3import usingApi, { submitTransactionAsync, submitTransactionExpectFailAsync } from "./substrate/substrate-api";4import fs from "fs";5import { Abi, BlueprintPromise as Blueprint, CodePromise, ContractPromise as Contract } from "@polkadot/api-contract";6import { IKeyringPair } from "@polkadot/types/types";7import { ApiPromise, Keyring } from "@polkadot/api";8import { ApiTypes, SubmittableExtrinsic } from "@polkadot/api/types";9import privateKey from "./substrate/privateKey";1011chai.use(chaiAsPromised);12const expect = chai.expect;13import { BigNumber } from 'bignumber.js';14import { findUnusedAddress } from './util/helpers';1516const value = 0;17const gasLimit = 3000n * 1000000n;18const endowment = `1000000000000000`;19const marketContractAddress = '5CYN9j3YvRkqxewoxeSvRbhAym4465C57uMmX5j4yz99L5H6';2021function deployBlueprint(alice: IKeyringPair, code: CodePromise): Promise<Blueprint> {22  return new Promise<Blueprint>(async (resolve, reject) => {23    const unsub = await code24      .createBlueprint()25      .signAndSend(alice, (result) => {26        if (result.status.isInBlock || result.status.isFinalized) {27          // here we have an additional field in the result, containing the blueprint28          resolve(result.blueprint);29          unsub();30        }31      })32  });33}3435function deployContract(alice: IKeyringPair, blueprint: Blueprint) : Promise<any> {36  return new Promise<any>(async (resolve, reject) => {37    const endowment = 1000000000000000n;38    const initValue = true;3940    const unsub = await blueprint.tx41    .new(endowment, gasLimit, initValue)42    .signAndSend(alice, (result) => {43      if (result.status.isInBlock || result.status.isFinalized) {44        unsub();45        resolve(result);46      }47    });    48  });49}5051async function prepareDeployer(api: ApiPromise) {52  // Find unused address53  const deployer = await findUnusedAddress(api);5455  // Transfer balance to it56  const keyring = new Keyring({ type: 'sr25519' });57  const alice = keyring.addFromUri(`//Alice`);58  let amount = new BigNumber(endowment);59  amount = amount.plus(1e15);60  const tx = api.tx.balances.transfer(deployer.address, amount.toFixed());61  await submitTransactionAsync(alice, tx);6263  return deployer;64}6566export async function deployFlipper(api: ApiPromise): Promise<[Contract, IKeyringPair]> {67  const metadata = JSON.parse(fs.readFileSync('./src/flipper/metadata.json').toString('utf-8'));68  const abi = new Abi(metadata);6970  const deployer = await prepareDeployer(api);7172  const wasm = fs.readFileSync('./src/flipper/flipper.wasm');7374  const code = new CodePromise(api, abi, wasm);7576  const blueprint = await deployBlueprint(deployer, code);77  const contract = (await deployContract(deployer, blueprint))['contract'] as Contract;7879  const initialGetResponse = await getFlipValue(contract, deployer);80  expect(initialGetResponse).to.be.true;8182  return [contract, deployer];83}8485async function getFlipValue(contract: Contract, deployer: IKeyringPair) {86  const result = await contract.query.get(deployer.address, value, gasLimit);8788  if(!result.result.isSuccess) {89    throw `Failed to get flipper value`;90  }91  return (result.result.asSuccess.data[0] == 0x00) ? false : true;92}9394describe('Contracts', () => {95  it(`Can deploy smart contract Flipper, instantiate it and call it's get and flip messages.`, async () => {96    await usingApi(async api => {97      const [contract, deployer] = await deployFlipper(api);98      const initialGetResponse = await getFlipValue(contract, deployer);99100      const bob = privateKey("//Bob");101      const flip = contract.exec('flip', value, gasLimit);102      await submitTransactionAsync(bob, flip);103104      const afterFlipGetResponse = await getFlipValue(contract, deployer);105      expect(afterFlipGetResponse).not.to.be.eq(initialGetResponse, 'Flipping should change value.');106    });107  });108109  it(`Whitelisted account can call contract.`, async () => {110    await usingApi(async api => {111      const bob = privateKey("//Bob");112113      const [contract, deployer] = await deployFlipper(api);114115      let expectedFlipValue = await getFlipValue(contract, deployer);116117      const flip = contract.exec('flip', value, gasLimit);118      await submitTransactionAsync(bob, flip);119      expectedFlipValue = !expectedFlipValue;120      const afterFlip = await getFlipValue(contract,deployer);121      expect(afterFlip).to.be.eq(expectedFlipValue, `Anyone can call new contract.`);122123      const deployerCanFlip = async () => {124        expectedFlipValue = !expectedFlipValue;125        const deployerFlip = contract.exec('flip', value, gasLimit);126        await submitTransactionAsync(deployer, deployerFlip);127        const aliceFlip1Response = await getFlipValue(contract, deployer);128        expect(aliceFlip1Response).to.be.eq(expectedFlipValue, `Deployer always can flip.`);129      };130      await deployerCanFlip();131132      const enableWhiteListTx = api.tx.nft.toggleContractWhiteList(contract.address, true);133      const enableResult = await submitTransactionAsync(deployer, enableWhiteListTx);134      const flipWithEnabledWhiteList = contract.exec('flip', value, gasLimit);135      await expect(submitTransactionExpectFailAsync(bob, flipWithEnabledWhiteList)).to.be.rejected;136      const flipValueAfterEnableWhiteList = await getFlipValue(contract, deployer);137      expect(flipValueAfterEnableWhiteList).to.be.eq(expectedFlipValue, `Enabling whitelist doesn't make it possible to call contract for everyone.`);138139      await deployerCanFlip();140141      const addBobToWhiteListTx = api.tx.nft.addToContractWhiteList(contract.address, bob.address);142      const addBobResult = await submitTransactionAsync(deployer, addBobToWhiteListTx);143      const flipWithWhitelistedBob = contract.exec('flip', value, gasLimit);144      await submitTransactionAsync(bob, flipWithWhitelistedBob);145      expectedFlipValue = !expectedFlipValue;146      const flipAfterWhiteListed = await getFlipValue(contract,deployer);147      expect(flipAfterWhiteListed).to.be.eq(expectedFlipValue, `Bob was whitelisted, now he can flip.`);148149      await deployerCanFlip();150151      const removeBobFromWhiteListTx = api.tx.nft.removeFromContractWhiteList(contract.address, bob.address);152      const removeBobResult = await submitTransactionAsync(deployer, removeBobFromWhiteListTx);153      const bobRemoved = contract.exec('flip', value, gasLimit);154      await expect(submitTransactionExpectFailAsync(bob, bobRemoved)).to.be.rejected;155      const afterBobRemoved = await getFlipValue(contract, deployer);156      expect(afterBobRemoved).to.be.eq(expectedFlipValue, `Bob can't call contract, now when he is removeed from white list.`);157158      await deployerCanFlip();159160      const disableWhiteListTx = api.tx.nft.toggleContractWhiteList(contract.address, false);161      const disableWhiteListResult = await submitTransactionAsync(deployer, disableWhiteListTx);162      const whiteListDisabledFlip = contract.exec('flip', value, gasLimit);163      await submitTransactionAsync(bob, whiteListDisabledFlip);164      expectedFlipValue = !expectedFlipValue;165      const afterWhiteListDisabled = await getFlipValue(contract,deployer);166      expect(afterWhiteListDisabled).to.be.eq(expectedFlipValue, `Anyone can call contract with disabled whitelist.`);167168    });169  });170171  it('Can initialize contract instance', async () => {172    await usingApi(async (api) => {173      const metadata = JSON.parse(fs.readFileSync('./src/flipper/metadata.json').toString('utf-8'));174      const abi = new Abi(metadata);175      const newContractInstance = new Contract(api, abi, marketContractAddress);176      expect(newContractInstance).to.have.property('address');177      expect(newContractInstance.address.toString()).to.equal(marketContractAddress);178    });179  });180181  it.skip('Can transfer balance using smart contract.', async () => {182    await usingApi(async api => {183      // const [alicesBalanceBefore, bobsBalanceBefore] = await getBalance(api, [alicesPublicKey, bobsPublicKey]);184      // const wasm = fs.readFileSync('./src/balance-transfer-contract/calls.wasm');185      // const contract = compactAddLength(u8aToU8a(wasm));186187      // const metadata = JSON.parse(fs.readFileSync('./src/balance-transfer-contract/metadata.json').toString('utf-8'));188      // const abi = new Abi(api.registry as any, metadata);189190      // const alicesPrivateKey = privateKey('//Alice');191192      // const contractHash = await deployContract(api, contract, alicesPrivateKey);193194      // // const args = abi.constructors[0]();195      // const instanceAccountId = await instantiateContract(api, contractHash, /*args,*/ alicesPrivateKey);196      // const contractInstance = new ContractPromise(api, abi, instanceAccountId);197      // const bob = new GenericAccountId(api.registry, bobsPublicKey);198199      // const transfer = contractInstance.exec('balance_transfer', 0, 1000000000000n, [bob, new u128(api.registry, 1000000)]);200      // await submitTransactionAsync(alicesPrivateKey, transfer);201202      // const [alicesBalanceAfter, bobsBalanceAfter] = await getBalance(api, [alicesPublicKey, bobsPublicKey]);203204      // expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;205      // expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;206    });207  });208});