From 51bdbddb0c2455f1f3d3c63aba4d44ddeed537da Mon Sep 17 00:00:00 2001 From: Yaroslav Bolyukin Date: Tue, 27 Jul 2021 16:47:40 +0000 Subject: [PATCH] test(evm): add contract helpers --- --- /dev/null +++ b/tests/src/eth/util/contractHelpersAbi.json @@ -0,0 +1,142 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "contract", + "type": "address" + } + ], + "name": "allowlistEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "address", + "name": "caller", + "type": "address" + } + ], + "name": "allowed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "contractOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "sponsoringEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "bool", + "name": "isAllowed", + "type": "bool" + } + ], + "name": "toggleAllowed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bool", + "name": "enabled", + "type": "bool" + } + ], + "name": "toggleAllowlist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bool", + "name": "enabled", + "type": "bool" + } + ], + "name": "toggleSponsoring", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file --- /dev/null +++ b/tests/src/eth/util/helpers.d.ts @@ -0,0 +1 @@ +declare module 'solc'; \ No newline at end of file --- a/tests/src/eth/util/helpers.ts +++ b/tests/src/eth/util/helpers.ts @@ -3,6 +3,9 @@ // file 'LICENSE', which is part of this source code package. // +// eslint-disable-next-line @typescript-eslint/triple-slash-reference +/// + import { ApiPromise } from '@polkadot/api'; import { addressToEvm, evmToAddress } from '@polkadot/util-crypto'; import Web3 from 'web3'; @@ -10,6 +13,12 @@ import { IKeyringPair } from '@polkadot/types/types'; import { expect } from 'chai'; import { getGenericResult } from '../../util/helpers'; +import * as solc from 'solc'; +import config from '../../config'; +import privateKey from '../../substrate/privateKey'; +import contractHelpersAbi from './contractHelpersAbi.json'; + +export const GAS_ARGS = { gas: 0x10000000, gasPrice: '0x01' }; let web3Connected = false; export async function usingWeb3(cb: (web3: Web3) => Promise | T): Promise { @@ -28,6 +37,16 @@ } } +type Web3HttpMarker = {web3Http: true}; + +export async function usingWeb3Http(cb: (web3: Web3 & Web3HttpMarker) => Promise | T): Promise { + const provider = new Web3.providers.HttpProvider(config.frontierUrl); + const web3: Web3 & Web3HttpMarker = new Web3(provider) as any; + web3.web3Http = true; + + return await cb(web3); +} + export function collectionIdToAddress(address: number): string { if (address >= 0xffffffff || address < 0) throw new Error('id overflow'); const buf = Buffer.from([0x17, 0xc4, 0xe6, 0x45, 0x3c, 0xc4, 0x9a, 0xaa, 0xae, 0xac, 0xa8, 0x94, 0xe6, 0xd9, 0x68, 0x3e, @@ -126,4 +145,80 @@ const bytes = addressToEvm(eth); const string = '0x' + Buffer.from(bytes).toString('hex'); return Web3.utils.toChecksumAddress(string); +} + +export function compileContract(name: string, src: string) { + const out = JSON.parse(solc.compile(JSON.stringify({ + language: 'Solidity', + sources: { + [`${name}.sol`]: { + content: ` + // SPDX-License-Identifier: UNLICENSED + pragma solidity ^0.8.6; + + ${src} + `, + }, + }, + settings: { + outputSelection: { + '*': { + '*': ['*'], + }, + }, + }, + }))).contracts[`${name}.sol`][name]; + + return { + abi: out.abi, + object: '0x' + out.evm.bytecode.object, + }; +} + +export async function deployFlipper(web3: Web3 & Web3HttpMarker, deployer: string) { + const compiled = compileContract('Flipper', ` + contract Flipper { + bool value = false; + function flip() public { + value = !value; + } + function getValue() public view returns (bool) { + return value; + } + } + `); + const Flipper = new web3.eth.Contract(compiled.abi, undefined, { + data: compiled.object, + from: deployer, + ...GAS_ARGS, + }); + const flipper = await Flipper.deploy({ data: compiled.object }).send({from: deployer}); + + return flipper; +} + +export async function deployCollector(web3: Web3 & Web3HttpMarker, deployer: string) { + const compiled = compileContract('Collector', ` + contract Collector { + uint256 collected; + function giveMoney() public payable { + collected += msg.value; + } + function getCollected() public view returns (uint256) { + return collected; + } + } + `); + const Collector = new web3.eth.Contract(compiled.abi, undefined, { + data: compiled.object, + from: deployer, + ...GAS_ARGS, + }); + const collector = await Collector.deploy({ data: compiled.object }).send({ from: deployer }); + + return collector; +} + +export function contractHelpers(web3: Web3, caller: string) { + return new web3.eth.Contract(contractHelpersAbi as any, '0x842899ECF380553E8a4de75bF534cdf6fBF64049', {from: caller, ...GAS_ARGS}); } \ No newline at end of file -- gitstuff