diff --git a/cli/playground.ts b/cli/playground.ts index 0b1837a..896112e 100755 --- a/cli/playground.ts +++ b/cli/playground.ts @@ -3,26 +3,68 @@ import { env } from '../tools/lib/index.ts' import { abis } from '../codegen/abis.ts' import { Storage } from '../codegen/addresses.ts' +import { encodeFunctionData } from 'viem' +import { parseArgs } from '@std/cli/parse-args' -{ - const { request } = await env.wallet.simulateContract({ - address: Storage, - abi: abis.Storage, - functionName: 'store', - args: [42n], - }) +const flags = parseArgs(Deno.args, { + string: ['action'], + alias: { + a: 'action', + }, +}) - const result = await env.wallet.writeContract(request) - console.log('store tx', result) -} +const { action } = flags + +switch (action) { + case 'execute': { + const { request } = await env.wallet.simulateContract({ + address: Storage, + abi: abis.Storage, + functionName: 'store', + args: [42n], + }) -{ - const result = await env.wallet.readContract( - { + const hash = await env.wallet.writeContract(request) + const receipt = await env.wallet.waitForTransactionReceipt({ + hash, + }) + + const res = await env.debugClient.traceTransaction( + receipt.transactionHash, + 'callTracer', + {}, + ) + console.log(JSON.stringify(res)) + break + } + + case 'estimate': { + const res = await env.wallet.estimateContractGas({ address: Storage, abi: abis.Storage, - functionName: 'retrieve', - }, - ) - console.log('retrieve:', result) + functionName: 'store', + args: [42n], + }) + + console.log(res) + break + } + + default: { + const res = await env.debugClient.traceCall( + { + account: env.wallet.account, + to: Storage, + from: Storage, + data: encodeFunctionData({ + abi: abis.Storage, + functionName: 'store', + args: [42n], + }), + }, + 'callTracer', + {}, + ) + console.log(JSON.stringify(res)) + } } diff --git a/cli/playground_2.ts b/cli/playground_2.ts new file mode 100755 index 0000000..02e6481 --- /dev/null +++ b/cli/playground_2.ts @@ -0,0 +1,86 @@ +#!/usr/bin/env -S deno run --env-file --allow-all + +import { env } from '../tools/lib/index.ts' +import { abis } from '../codegen/abis.ts' +import { TerminateTest } from '../codegen/addresses.ts' +import { encodeFunctionData } from 'viem' +import { parseArgs } from '@std/cli/parse-args' + +const flags = parseArgs(Deno.args, { + string: ['action'], + boolean: ['redeploy'], + alias: { + a: 'action', + }, +}) + +const { action } = flags + +switch (action) { + case 'execute': { + const { request } = await env.wallet.simulateContract({ + address: TerminateTest, + abi: abis.TerminateTest, + functionName: 'tryCallAfterTerminate', + args: [flags.redeploy], + }) + + const hash = await env.wallet.writeContract(request) + const receipt = await env.wallet.waitForTransactionReceipt({ + hash, + }) + + const res = await env.debugClient.traceTransaction( + receipt.transactionHash, + 'callTracer', + {}, + ) + console.log(JSON.stringify(res)) + break + } + + case 'estimate': { + const res = await env.wallet.estimateContractGas({ + address: TerminateTest, + abi: abis.TerminateTest, + functionName: 'tryCallAfterTerminate', + args: [flags.redeploy], + }) + + console.log(res) + break + } + + case 'call': { + try { + const res = await env.wallet.readContract({ + address: TerminateTest, + abi: abis.TerminateTest, + functionName: 'tryCallAfterTerminate', + args: [flags.redeploy], + }) + console.log(res) + } catch (err) { + console.log(`Error: ${err}`) + } + + break + } + + default: { + const res = await env.debugClient.traceCall( + { + account: env.wallet.account, + to: TerminateTest, + data: encodeFunctionData({ + abi: abis.TerminateTest, + functionName: 'tryCallAfterTerminate', + args: [flags.redeploy], + }), + }, + 'callTracer', + {}, + ) + console.log(JSON.stringify(res)) + } +} diff --git a/contracts/Storage.sol b/contracts/Storage.sol index 49cb144..ad9a6d2 100644 --- a/contracts/Storage.sol +++ b/contracts/Storage.sol @@ -4,6 +4,10 @@ pragma solidity ^0.8.9; contract Storage { uint256 private storedNumber; + constructor() payable { + storedNumber = 0; + } + function store(uint256 num) public { storedNumber = num; } diff --git a/contracts/TerminateTest.sol b/contracts/TerminateTest.sol new file mode 100644 index 0000000..e3b75cd --- /dev/null +++ b/contracts/TerminateTest.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Child { + uint256 public value; + + constructor(uint256 _value) payable { + value = _value; + } + + function getValue() public view returns (uint256, uint256) { + return (value, address(this).balance); + } + + function terminate() public { + selfdestruct(payable(msg.sender)); + } +} + +contract TerminateTest { + Child public child; + + constructor() payable { + } + + + function terminate() public { + child.terminate(); + } + + function tryCallAfterTerminate(bool redeploy) public returns (uint256, uint256) { + if (redeploy) { + child = new Child{value: 1 ether}(42); + } + child.terminate(); + + try child.getValue() returns (uint256 val, uint256 bal) { + return (val, bal); + } catch Error(string memory reason) { + revert(string.concat("getValue() failed: ", reason)); + } catch (bytes memory data) { + revert(string.concat("getValue() failed with: ", string(data))); + } + } +} diff --git a/tools/deploy.ts b/tools/deploy.ts index a20d9f1..a58659d 100644 --- a/tools/deploy.ts +++ b/tools/deploy.ts @@ -1,5 +1,6 @@ //! Call with deno task deploy [--filter ] +import { parseEther } from 'viem' import { deploy } from './lib/index.ts' /** @@ -25,5 +26,13 @@ import { deploy } from './lib/index.ts' await deploy({ name: 'Storage', args: [], + value: parseEther('1'), + // bytecodeType: 'polkavm', // Specify `pvm` for PVM bytecode deployment +}) + +await deploy({ + name: 'TerminateTest', + args: [], + value: parseEther('10'), // bytecodeType: 'polkavm', // Specify `pvm` for PVM bytecode deployment })