-
Notifications
You must be signed in to change notification settings - Fork 19
state mutability fix #272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
state mutability fix #272
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import { JsonFragment } from "@ethersproject/abi"; | ||
| import { ethers } from "ethers"; | ||
| import { ExtensionContext } from "vscode"; | ||
| import { useContractType } from "../../types"; | ||
| import { getSelectedProvider } from "../networks"; | ||
| import { logger } from "../../lib"; | ||
|
|
||
| export const ImmutableFunctionCall = async ( | ||
| context: ExtensionContext, | ||
| params: any[], | ||
| abi: readonly JsonFragment[], | ||
| useContract: useContractType | ||
| ) => { | ||
| const { abiItemName, contractName, contractAddress } = useContract; | ||
| const contract = new ethers.Contract( | ||
| contractAddress, | ||
| abi, | ||
| getSelectedProvider(context) | ||
| ); | ||
| const result = await contract[abiItemName](...params); | ||
| logger.success(`Calling ${contractName} : ${abiItemName} --> Success!`); | ||
| if (result) { | ||
| logger.log(JSON.stringify(result)); | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| import { ethers } from "ethers"; | ||
| import { ExtensionContext } from "vscode"; | ||
| import { logger } from "../../lib"; | ||
| import { EstimateGas, useContractType } from "../../types"; | ||
| import { getGasEstimates } from "../functions"; | ||
| import { | ||
| getConfiguration, | ||
| getSelectedNetConf, | ||
| getSignedContract, | ||
| } from "../networks"; | ||
|
|
||
| export const MutableFunctionCall = async ( | ||
| context: ExtensionContext, | ||
| state: string, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| params: any[], | ||
| useContract: useContractType | ||
| ) => { | ||
| const MAX_FEE_PER_GAS = 100; | ||
| const { abiItemName, contractAddress, contractName } = useContract; | ||
|
|
||
| const contract = await getSignedContract(context, contractAddress); | ||
|
|
||
| let gasCondition = (await context.workspaceState.get("gas")) as string; | ||
|
|
||
| const gasEstimate: EstimateGas | undefined = await getGasEstimates( | ||
| gasCondition, | ||
| context | ||
| ); | ||
|
|
||
| const maxFeePerGas = | ||
| gasEstimate !== undefined ? gasEstimate.maxFeePerGas : MAX_FEE_PER_GAS; | ||
|
|
||
| const settingsGasLimit = (await getConfiguration().get("gasLimit")) as number; | ||
|
|
||
| const value = | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When we create the input |
||
| state === "payable" ? await context.workspaceState.get("payableValue") : 0; | ||
|
|
||
| const result = await contract[abiItemName as string](...params, { | ||
| value: value, | ||
| gasPrice: ethers.utils.parseUnits(maxFeePerGas.toString(), "gwei"), | ||
| gasLimit: settingsGasLimit, | ||
| }); | ||
|
|
||
| logger.success("Waiting for confirmation..."); | ||
|
|
||
| await result.wait(); | ||
| logger.success("Transaction confirmed!"); | ||
| logger.success(`Calling ${contractName} : ${abiItemName} --> Success!`); | ||
| logger.success( | ||
| `You can see detail of this transaction here. ${ | ||
| getSelectedNetConf(context).blockScanner | ||
| }/tx/${result.hash}` | ||
| ); | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| import { ethers } from "ethers"; | ||
| import * as vscode from "vscode"; | ||
| import { window } from "vscode"; | ||
| import { window, InputBoxOptions } from "vscode"; | ||
| import { | ||
| CompiledJSONOutput, | ||
| GasEstimateOutput, | ||
|
|
@@ -9,7 +9,12 @@ import { | |
| } from "../types/output"; | ||
| import { logger } from "../lib"; | ||
| import { extractPvtKey } from "./wallet"; | ||
| import { INetworkQP, EstimateGas, NetworkConfig } from "../types"; | ||
| import { | ||
| INetworkQP, | ||
| EstimateGas, | ||
| NetworkConfig, | ||
| useContractType, | ||
| } from "../types"; | ||
| import { | ||
| getConstructorInputs, | ||
| getDeployedInputs, | ||
|
|
@@ -19,6 +24,8 @@ import { | |
|
|
||
| import { errors } from "../config/errors"; | ||
| import { selectContract } from "./contracts"; | ||
| import { ImmutableFunctionCall } from "./contractCall/ImmutableFunctionCall"; | ||
| import { MutableFunctionCall } from "./contractCall/mutableFunctionCall"; | ||
|
|
||
| const provider = ethers.providers; | ||
|
|
||
|
|
@@ -86,17 +93,16 @@ const getSelectedProvider = (context: vscode.ExtensionContext) => { | |
|
|
||
| // Contract function calls | ||
| const displayBalance = async (context: vscode.ExtensionContext) => { | ||
|
|
||
| if(getSelectedNetwork(context) === undefined) { | ||
| if (getSelectedNetwork(context) === undefined) { | ||
| logger.log("No network selected. Please select a network."); | ||
| return; | ||
| } | ||
|
|
||
| const address: any = await context.workspaceState.get("account"); | ||
| const nativeCurrencySymbol = | ||
| getSelectedNetConf(context).nativeCurrency.symbol; | ||
| try { | ||
|
|
||
| try { | ||
| getSelectedProvider(context) | ||
| .getBalance(address) | ||
| .then(async (value) => { | ||
|
|
@@ -153,80 +159,47 @@ const callContractMethod = async (context: vscode.ExtensionContext) => { | |
| "contract" | ||
| )) as CompiledJSONOutput; | ||
|
|
||
| if (compiledOutput == undefined) throw errors.ContractNotSelected; | ||
| if (compiledOutput === undefined) throw errors.ContractNotSelected; | ||
|
|
||
| const abi = getAbi(compiledOutput); | ||
| if (abi == undefined) throw new Error("Abi is not defined."); | ||
| if (abi === undefined) throw new Error("Abi is not defined."); | ||
|
|
||
| const abiItem = await getFunctionInputs(context); | ||
| if (abiItem === undefined) throw new Error("Function is not defined."); | ||
|
|
||
| const params_ = abiItem.inputs?.map((e: any) => e.value); | ||
| const params = params_ === undefined ? [] : params_; | ||
|
|
||
| logger.success(`Calling ${compiledOutput.name} : ${abiItem.name} -->`); | ||
|
|
||
| const contractAddres = getDeployedInputs(context).address; | ||
| if (contractAddres === undefined) | ||
| throw new Error("Enter deployed address of selected contract."); | ||
|
|
||
| if (abiItem.stateMutability === "view") { | ||
| selectContract(context); | ||
|
|
||
| const contract = new ethers.Contract( | ||
| contractAddres, | ||
| abi, | ||
| getSelectedProvider(context) | ||
| ); | ||
|
|
||
| const result = await contract[abiItem.name as string](...params); | ||
| logger.success( | ||
| `Calling ${compiledOutput.name} : ${abiItem.name} --> Success!` | ||
| ); | ||
| logger.log(JSON.stringify(result)); | ||
| } else { | ||
| const contract = await getSignedContract(context, contractAddres); | ||
|
|
||
| let result; | ||
|
|
||
| if (abiItem.stateMutability === "nonpayable") { | ||
| const gasCondition = (await context.workspaceState.get( | ||
| "gas" | ||
| )) as string; | ||
|
|
||
| const gasEstimate = await getGasEstimates(gasCondition, context); | ||
| const settingsGasLimit = (await getConfiguration().get( | ||
| "gasLimit" | ||
| )) as number; | ||
| if (gasEstimate !== undefined) { | ||
| const maxFeePerGas = (gasEstimate as EstimateGas).price; | ||
| result = await contract[abiItem.name as string](...params, { | ||
| gasPrice: ethers.utils.parseUnits(maxFeePerGas.toString(), "gwei"), | ||
| gasLimit: settingsGasLimit, | ||
| }); | ||
| } else { | ||
| result = await contract[abiItem.name as string](...params); | ||
| } | ||
| } else { | ||
| const found: any = abiItem.inputs?.find( | ||
| (e: any) => e.type === "uint256" | ||
| ); | ||
| result = await contract[abiItem.name as string](...params, { | ||
| value: found.value, | ||
| }); | ||
| } | ||
| const params_ = abiItem.inputs?.map((e: any) => e.value); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the params should be read inside the mutable & immutable call functions as now the params will contain the payable value. |
||
| const params = params_ === undefined ? [] : params_; | ||
|
|
||
| logger.success("Waiting for confirmation..."); | ||
| const useContract: useContractType = { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do not use variable name |
||
| contractName: compiledOutput.name as string, | ||
| abiItemName: abiItem.name as string, | ||
| contractAddress: contractAddres, | ||
| }; | ||
|
|
||
| logger.success( | ||
| `Calling ${useContract.contractName} : ${useContract.abiItemName} -->` | ||
| ); | ||
|
|
||
| if ( | ||
| abiItem.stateMutability === "view" || | ||
| abiItem.stateMutability === "pure" | ||
| ) { | ||
| await ImmutableFunctionCall(context, params, abi, useContract); | ||
| } | ||
|
|
||
| await result.wait(); | ||
| logger.success("Transaction confirmed!"); | ||
| logger.success( | ||
| `Calling ${compiledOutput.name} : ${abiItem.name} --> Success!` | ||
| ); | ||
| logger.success( | ||
| `You can see detail of this transaction here. ${ | ||
| getSelectedNetConf(context).blockScanner | ||
| }/tx/${result.hash}` | ||
| if ( | ||
| abiItem.stateMutability === "nonpayable" || | ||
| abiItem.stateMutability === "payable" | ||
| ) { | ||
| await MutableFunctionCall( | ||
| context, | ||
| abiItem.stateMutability, | ||
| params, | ||
| useContract | ||
| ); | ||
| } | ||
| } catch (err: any) { | ||
|
|
@@ -337,6 +310,26 @@ const getContractFactoryWithParams = async ( | |
| return myContract; | ||
| }; | ||
|
|
||
| const setPayableValue = async (context: vscode.ExtensionContext) => { | ||
| try { | ||
| const inputBoxOpts: InputBoxOptions = { | ||
| placeHolder: "value", | ||
| ignoreFocusOut: true, | ||
| }; | ||
| const value = await window.showInputBox(inputBoxOpts); | ||
| if (value === undefined) { | ||
| return; | ||
| } | ||
| const valueInWei = ethers.utils.parseEther(value); | ||
| const nativeCurrencySymbol = | ||
| getSelectedNetConf(context).nativeCurrency.symbol; | ||
| await context.workspaceState.update("payableValue", valueInWei.toString()); | ||
| logger.log(`payable value set to: ${value} ${nativeCurrencySymbol}`); | ||
| } catch (error) { | ||
| logger.log("Error: payable value is not saved"); | ||
| } | ||
| }; | ||
|
|
||
| export { | ||
| getConfiguration, | ||
| getNetworkNames, | ||
|
|
@@ -349,4 +342,6 @@ export { | |
| deployContract, | ||
| isTestingNetwork, | ||
| setTransactionGas, | ||
| setPayableValue, | ||
| getSignedContract, | ||
| }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
function names should always start with a smallcap letter.