From 21059cd3a9e6bc0e802cfafab053cc1bd9363f3d Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Sun, 3 Dec 2023 04:18:51 +0100 Subject: [PATCH 1/2] allow smart contract methods to accept parameters even when no ABI was provided --- packages/web3-eth-contract/src/contract.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 197762c3554..bf4f84cdf37 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -114,7 +114,7 @@ type ContractBoundMethod< Abi extends AbiFunctionFragment, Method extends ContractMethod = ContractMethod, > = ( - ...args: Method['Inputs'] + ...args: Abi extends AbiFunctionFragment ? Method['Inputs'] : any ) => Method['Abi']['stateMutability'] extends 'payable' | 'pure' ? PayableMethodObject : NonPayableMethodObject; @@ -371,9 +371,8 @@ export class Contract : returnFormat ?? DEFAULT_RETURN_FORMAT; const address = typeof addressOrOptionsOrContext === 'string' ? addressOrOptionsOrContext : undefined; - this.config.contractDataInputFill = - (options as ContractInitOptions)?.dataInputFill ?? - this.config.contractDataInputFill; + this.config.contractDataInputFill = + (options as ContractInitOptions)?.dataInputFill ?? this.config.contractDataInputFill; this._parseAndSetJsonInterface(jsonInterface, returnDataFormat); if (!isNullish(address)) { @@ -1083,13 +1082,13 @@ export class Contract options: { ...options, dataInputFill: this.config.contractDataInputFill }, contractOptions: modifiedContractOptions, }); - + const transactionToSend = sendTransaction(this, tx, DEFAULT_RETURN_FORMAT, { // TODO Should make this configurable by the user checkRevertBeforeSending: false, contractAbi: this._jsonInterface, }); - + // eslint-disable-next-line no-void void transactionToSend.on('error', (error: unknown) => { if (error instanceof ContractExecutionError) { From 2d6efab2cd735d412948264f17724d5fc6621922 Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Sun, 3 Dec 2023 17:19:47 +0100 Subject: [PATCH 2/2] add a test case --- .../test/unit/contract.test.ts | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/packages/web3-eth-contract/test/unit/contract.test.ts b/packages/web3-eth-contract/test/unit/contract.test.ts index bee7d90999c..e631be978b9 100644 --- a/packages/web3-eth-contract/test/unit/contract.test.ts +++ b/packages/web3-eth-contract/test/unit/contract.test.ts @@ -1378,6 +1378,39 @@ describe('Contract', () => { spyEstimateGas.mockClear(); }); + it('estimateGas should work for contract method even with no ABI', async () => { + const contract = new Contract([], deployedAddr); + + const spyTx = jest.spyOn(eth, 'sendTransaction').mockImplementation(() => { + const newContract = contract.clone(); + newContract.options.address = deployedAddr; + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return Promise.resolve(newContract) as any; + }); + + const spyEstimateGas = jest + .spyOn(eth, 'estimateGas') + .mockImplementationOnce((_objInstance, _tx, _block) => { + expect(_block).toBe('latest'); + expect(_tx.to).toStrictEqual(deployedAddr); + expect(_tx.from).toStrictEqual(sendOptions.from); + expect(_tx.data).toBe( + '0xa41368620000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000548656c6c6f000000000000000000000000000000000000000000000000000000', + ); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return Promise.resolve(BigInt(36916)) as any; + }); + + // This produces an error at runtime. + // This needs investigation and fixing. + const result = await contract.methods.setGreeting().estimateGas(sendOptions); + expect(result).toStrictEqual(BigInt(36916)); + + spyTx.mockClear(); + spyEstimateGas.mockClear(); + }); + it('encodeABI should work for contract method', async () => { const arg = 'Hello';