From 101c3a04cd2816f6d81ba9dde76bc6bfaa830622 Mon Sep 17 00:00:00 2001 From: Oleksii Kosynskyi Date: Mon, 24 Jun 2024 22:35:01 -0400 Subject: [PATCH 1/8] Add populate tx method --- packages/web3-eth-contract/src/contract.ts | 18 +++++++++++++++++- packages/web3-eth-contract/src/types.ts | 17 ++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index c4be775b31f..26d93b5ce70 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -1268,7 +1268,23 @@ export class Contract send: (options?: PayableTxOptions | NonPayableTxOptions): ContractMethodSend => this._contractMethodSend(methodAbi, abiParams, internalErrorsAbis, options), - + populateTransaction: ( + options?: PayableTxOptions | NonPayableTxOptions, + contractOptions?: ContractOptions, + ) => { + let modifiedContractOptions = contractOptions ?? options; + modifiedContractOptions = { + ...modifiedContractOptions, + input: undefined, + from: modifiedContractOptions?.from ?? this.defaultAccount ?? undefined, + }; + return getSendTxParams({ + abi, + params, + options: { ...options, dataInputFill: this.config.contractDataInputFill }, + contractOptions: modifiedContractOptions as ContractOptions, + }); + }, estimateGas: async ( options?: PayableCallOptions | NonPayableCallOptions, returnFormat: ReturnFormat = this diff --git a/packages/web3-eth-contract/src/types.ts b/packages/web3-eth-contract/src/types.ts index cc2e0c4aec7..1b28d786ab2 100644 --- a/packages/web3-eth-contract/src/types.ts +++ b/packages/web3-eth-contract/src/types.ts @@ -28,13 +28,15 @@ import { DataFormat, DEFAULT_RETURN_FORMAT, FormatType, + TransactionCall, } from 'web3-types'; import { NewHeadsSubscription, SendTransactionEvents } from 'web3-eth'; import { LogsSubscription } from './log_subscription.js'; export type NonPayableTxOptions = NonPayableCallOptions; export type PayableTxOptions = PayableCallOptions; -export { ContractAbiWithSignature, EventLog, ContractOptions } from 'web3-types'; +import type { ContractOptions } from 'web3-types'; +export type { ContractAbiWithSignature, EventLog, ContractOptions } from 'web3-types'; export interface ContractEventOptions { /** @@ -177,6 +179,10 @@ export interface NonPayableMethodObject FormatType, SendTransactionEvents >; + populateTransaction( + tx?: PayableTxOptions | NonPayableTxOptions, + contractOptions?: ContractOptions, + ): TransactionCall; /** * Returns the amount of gas consumed by executing the method locally without creating a new transaction on the blockchain. @@ -375,6 +381,15 @@ export interface PayableMethodObject { SendTransactionEvents >; + /** + * + * @param tx + * @param contractOptions + */ + populateTransaction( + tx?: PayableTxOptions | NonPayableTxOptions, + contractOptions?: ContractOptions, + ): TransactionCall; /** * Returns the amount of gas consumed by executing the method locally without creating a new transaction on the blockchain. * The returned amount can be used as a gas estimate for executing the transaction publicly. The actual gas used can be From fd92410ac14efb4dfb9bdc4f11e3a9f83808895a Mon Sep 17 00:00:00 2001 From: Oleksii Kosynskyi Date: Mon, 24 Jun 2024 22:35:51 -0400 Subject: [PATCH 2/8] Update types.ts --- packages/web3-eth-contract/src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web3-eth-contract/src/types.ts b/packages/web3-eth-contract/src/types.ts index 1b28d786ab2..8f4bf564ca4 100644 --- a/packages/web3-eth-contract/src/types.ts +++ b/packages/web3-eth-contract/src/types.ts @@ -31,11 +31,11 @@ import { TransactionCall, } from 'web3-types'; import { NewHeadsSubscription, SendTransactionEvents } from 'web3-eth'; +import type { ContractOptions } from 'web3-types'; import { LogsSubscription } from './log_subscription.js'; export type NonPayableTxOptions = NonPayableCallOptions; export type PayableTxOptions = PayableCallOptions; -import type { ContractOptions } from 'web3-types'; export type { ContractAbiWithSignature, EventLog, ContractOptions } from 'web3-types'; export interface ContractEventOptions { From 8a90647df8a3194452546842d8dc0c20c27ef1a1 Mon Sep 17 00:00:00 2001 From: Oleksii Kosynskyi Date: Wed, 26 Jun 2024 21:46:25 -0400 Subject: [PATCH 3/8] fix populate tx --- packages/web3-eth-contract/src/contract.ts | 10 +- packages/web3-types/src/eth_types.ts | 115 +++++++++++---------- 2 files changed, 66 insertions(+), 59 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 26d93b5ce70..de82667dd14 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -1272,18 +1272,24 @@ export class Contract options?: PayableTxOptions | NonPayableTxOptions, contractOptions?: ContractOptions, ) => { - let modifiedContractOptions = contractOptions ?? options; + let modifiedContractOptions = contractOptions ?? this.options; modifiedContractOptions = { ...modifiedContractOptions, input: undefined, from: modifiedContractOptions?.from ?? this.defaultAccount ?? undefined, }; - return getSendTxParams({ + const tx = getSendTxParams({ abi, params, options: { ...options, dataInputFill: this.config.contractDataInputFill }, contractOptions: modifiedContractOptions as ContractOptions, }); + // @ts-ignore + if (tx.dataInputFill) { + // @ts-ignore + delete tx.dataInputFill; + } + return tx; }, estimateGas: async ( options?: PayableCallOptions | NonPayableCallOptions, diff --git a/packages/web3-types/src/eth_types.ts b/packages/web3-types/src/eth_types.ts index 5c628994c8d..9c83e92d0d5 100644 --- a/packages/web3-types/src/eth_types.ts +++ b/packages/web3-types/src/eth_types.ts @@ -47,6 +47,7 @@ export enum BlockTags { PENDING = 'pending', SAFE = 'safe', FINALIZED = 'finalized', + COMMITTED = 'committed', } export type BlockTag = `${BlockTags}`; @@ -138,8 +139,8 @@ export interface Withdrawals { } export interface BlockOutput { - readonly gasLimit: bigint | number; - readonly gasUsed: bigint | number; + readonly gasLimit: bigint | number; + readonly gasUsed: bigint | number; readonly size: bigint | number; readonly timestamp: bigint | number; readonly number?: bigint | number; @@ -152,54 +153,54 @@ export interface BlockOutput { // Added properties readonly blobGasUsed?: bigint | number; - readonly excessBlobGas?: bigint | number; - readonly extraData?: Bytes; - readonly hash?: HexString32Bytes; - readonly logsBloom?: Bytes; - readonly nonce?: bigint | number; - readonly parentBeaconBlockRoot?: HexString32Bytes; - readonly receiptsRoot?: HexString32Bytes; - readonly sha3Uncles: HexString32Bytes[]; - readonly stateRoot?: HexString32Bytes; - readonly transactionsRoot?: HexString32Bytes; - readonly withdrawalsRoot?: HexString32Bytes; - readonly mixHash?: HexString32Bytes; - readonly uncles?: Uncles; - readonly withdrawals?: Withdrawals[]; + readonly excessBlobGas?: bigint | number; + readonly extraData?: Bytes; + readonly hash?: HexString32Bytes; + readonly logsBloom?: Bytes; + readonly nonce?: bigint | number; + readonly parentBeaconBlockRoot?: HexString32Bytes; + readonly receiptsRoot?: HexString32Bytes; + readonly sha3Uncles: HexString32Bytes[]; + readonly stateRoot?: HexString32Bytes; + readonly transactionsRoot?: HexString32Bytes; + readonly withdrawalsRoot?: HexString32Bytes; + readonly mixHash?: HexString32Bytes; + readonly uncles?: Uncles; + readonly withdrawals?: Withdrawals[]; } export interface BlockHeaderOutput { - readonly baseFeePerGas?: Numbers; - readonly blobGasUsed?: Numbers; - readonly difficulty?: Numbers; - readonly excessBlobGas?: Numbers; - readonly extraData?: Bytes; - readonly gasLimit: Numbers; - readonly gasUsed: Numbers; - readonly hash?: HexString32Bytes; - readonly logsBloom?: Bytes; - readonly miner?: HexString; - readonly nonce?: Numbers; - readonly number?: Numbers; - readonly parentBeaconBlockRoot?: HexString32Bytes; - readonly parentHash?: HexString32Bytes; - readonly receiptsRoot?: HexString32Bytes; - readonly sha3Uncles: HexString32Bytes[]; - readonly stateRoot?: HexString32Bytes; - readonly timestamp: Numbers; - readonly transactionsRoot?: HexString32Bytes; - readonly withdrawalsRoot?: HexString32Bytes; - - // These fields are returned when the RPC client is Nethermind, - // but aren't available in other clients such as Geth - readonly author?: Address; - readonly totalDifficulty?: Numbers; - readonly size?: Numbers; - readonly excessDataGas?: Numbers; - readonly mixHash?: HexString32Bytes; - readonly transactions?: TransactionOutput[]; - readonly uncles?: Uncles; - readonly withdrawals?: Withdrawals[]; + readonly baseFeePerGas?: Numbers; + readonly blobGasUsed?: Numbers; + readonly difficulty?: Numbers; + readonly excessBlobGas?: Numbers; + readonly extraData?: Bytes; + readonly gasLimit: Numbers; + readonly gasUsed: Numbers; + readonly hash?: HexString32Bytes; + readonly logsBloom?: Bytes; + readonly miner?: HexString; + readonly nonce?: Numbers; + readonly number?: Numbers; + readonly parentBeaconBlockRoot?: HexString32Bytes; + readonly parentHash?: HexString32Bytes; + readonly receiptsRoot?: HexString32Bytes; + readonly sha3Uncles: HexString32Bytes[]; + readonly stateRoot?: HexString32Bytes; + readonly timestamp: Numbers; + readonly transactionsRoot?: HexString32Bytes; + readonly withdrawalsRoot?: HexString32Bytes; + + // These fields are returned when the RPC client is Nethermind, + // but aren't available in other clients such as Geth + readonly author?: Address; + readonly totalDifficulty?: Numbers; + readonly size?: Numbers; + readonly excessDataGas?: Numbers; + readonly mixHash?: HexString32Bytes; + readonly transactions?: TransactionOutput[]; + readonly uncles?: Uncles; + readonly withdrawals?: Withdrawals[]; } export interface ReceiptInput { @@ -553,13 +554,13 @@ export interface Eip712TypedData { /** * To contain the gas Fee Data to be used with EIP-1559 transactions. * EIP-1559 was applied to Ethereum after London hardfork. - * + * * Typically you will only need `maxFeePerGas` and `maxPriorityFeePerGas` for a transaction following EIP-1559. * However, if you want to get informed about the fees of last block, you can use `baseFeePerGas` too. - * - * + * + * * @see https://eips.ethereum.org/EIPS/eip-1559 - * + * */ export interface FeeData { /** @@ -569,20 +570,20 @@ export interface FeeData { /** * The baseFeePerGas returned from the last available block. - * + * * If EIP-1559 is not supported, this will be `undefined` - * - * However, the user will only pay (the future baseFeePerGas + the maxPriorityFeePerGas). + * + * However, the user will only pay (the future baseFeePerGas + the maxPriorityFeePerGas). * And this value is just for getting informed about the fees of last block. */ readonly baseFeePerGas?: Numbers; /** * The maximum fee that the user would be willing to pay per-gas. - * + * * However, the user will only pay (the future baseFeePerGas + the maxPriorityFeePerGas). * And the `maxFeePerGas` could be used to prevent paying more than it, if `baseFeePerGas` went too high. - * + * * If EIP-1559 is not supported, this will be `undefined` */ readonly maxFeePerGas?: Numbers; @@ -593,4 +594,4 @@ export interface FeeData { * If EIP-1559 is not supported, this will be `undefined` */ readonly maxPriorityFeePerGas?: Numbers; -} \ No newline at end of file +} From 842601987b324856926a083d49e11ec932efb146 Mon Sep 17 00:00:00 2001 From: Oleksii Kosynskyi Date: Wed, 26 Jun 2024 21:47:30 -0400 Subject: [PATCH 4/8] fix lint --- packages/web3-eth-contract/src/contract.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index de82667dd14..a67e825bdbf 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -1282,11 +1282,11 @@ export class Contract abi, params, options: { ...options, dataInputFill: this.config.contractDataInputFill }, - contractOptions: modifiedContractOptions as ContractOptions, + contractOptions: modifiedContractOptions, }); - // @ts-ignore + // @ts-expect-error remove unnecessary field if (tx.dataInputFill) { - // @ts-ignore + // @ts-expect-error remove unnecessary field delete tx.dataInputFill; } return tx; From a6511392801b0663c7c5d4a913addb4a4b720b4b Mon Sep 17 00:00:00 2001 From: Oleksii Kosynskyi Date: Thu, 4 Jul 2024 12:28:32 -0400 Subject: [PATCH 5/8] add test --- .../test/unit/contract.test.ts | 44 ++++++++++++++++--- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/packages/web3-eth-contract/test/unit/contract.test.ts b/packages/web3-eth-contract/test/unit/contract.test.ts index d35dbdefb48..ecd501b3565 100644 --- a/packages/web3-eth-contract/test/unit/contract.test.ts +++ b/packages/web3-eth-contract/test/unit/contract.test.ts @@ -16,13 +16,20 @@ along with web3.js. If not, see . */ import * as eth from 'web3-eth'; -import { ValidChains, Hardfork, AccessListResult, Address, ETH_DATA_FORMAT , DEFAULT_RETURN_FORMAT } from 'web3-types'; +import { + ValidChains, + Hardfork, + AccessListResult, + Address, + ETH_DATA_FORMAT, + DEFAULT_RETURN_FORMAT, +} from 'web3-types'; import { Web3ContractError } from 'web3-errors'; -import { Web3Context , Web3ConfigEvent } from 'web3-core'; +import { Web3Context, Web3ConfigEvent } from 'web3-core'; import { Web3ValidatorError } from 'web3-validator'; import { AbiItem } from 'web3-utils'; import { stringify } from 'flatted'; -import {Abi} from '../fixtures/AbiItem' +import { Abi } from '../fixtures/AbiItem'; import { Contract } from '../../src'; import { sampleStorageContractABI } from '../fixtures/storage'; import { GreeterAbi, GreeterBytecode } from '../shared_fixtures/build/Greeter'; @@ -485,7 +492,7 @@ describe('Contract', () => { // calling with wrong parameters should throw try { // eslint-disable-next-line @typescript-eslint/no-unsafe-call - await(deployedContract.methods.setGreeting as any)(arg, 'test').send(sendOptions); + await (deployedContract.methods.setGreeting as any)(arg, 'test').send(sendOptions); expect(true).toBe(false); } catch (error) { // eslint-disable-next-line jest/no-conditional-expect @@ -499,7 +506,7 @@ describe('Contract', () => { // calling with wrong parameters should throw try { // eslint-disable-next-line @typescript-eslint/no-unsafe-call - await(deployedContract.methods.setGreeting as any)(arg, true, 'test').send( + await (deployedContract.methods.setGreeting as any)(arg, true, 'test').send( sendOptions, ); expect(true).toBe(false); @@ -1842,5 +1849,32 @@ describe('Contract', () => { const contract = new Contract(GreeterAbi, web3Context); expect(contract.config).toStrictEqual(web3Context.config); }); + + it('should populate method to tx object', () => { + const expectedProvider = 'http://127.0.0.1:8545'; + const web3Context = new Web3Context({ + provider: expectedProvider, + config: { handleRevert: true, defaultTransactionType: '0x2' }, + }); + const contract = new Contract( + GreeterAbi, + '0x00000000219ab540356cBB839Cbe05303d7705F1', + web3Context, + ); + + const tx = contract.methods + .greet() + .populateTransaction({ from: '0x00000000219ab540356cBB839Cbe05303d7705F2' }); + expect(tx).toEqual({ + to: '0x00000000219AB540356cBb839cbe05303D7705F1', + gas: undefined, + gasPrice: undefined, + from: '0x00000000219ab540356cBB839Cbe05303d7705F2', + input: undefined, + maxPriorityFeePerGas: undefined, + maxFeePerGas: undefined, + data: '0xcfae3217', + }); + }); }); }); From 8b4852a8d1233f3d46e2a68798801d4ab1dc1561 Mon Sep 17 00:00:00 2001 From: Oleksii Kosynskyi Date: Thu, 4 Jul 2024 12:29:50 -0400 Subject: [PATCH 6/8] changelog --- CHANGELOG.md | 12 ++++++++++++ packages/web3-eth-contract/CHANGELOG.md | 7 ++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 783691404b9..1005aa0b64a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2564,3 +2564,15 @@ If there are any bugs, improvements, optimizations or any new feature proposal f - `getName` reverse resolution ## [Unreleased] + +### Fixed + +#### web3-eth + +- Fixed geth issue when running a new instance, transactions will index when there are no blocks created (#7098) + +### Added + +#### web3-eth-contract + +- `populateTransaction` was added to contract methods (#7124) diff --git a/packages/web3-eth-contract/CHANGELOG.md b/packages/web3-eth-contract/CHANGELOG.md index 8e275470925..0c6432b6c22 100644 --- a/packages/web3-eth-contract/CHANGELOG.md +++ b/packages/web3-eth-contract/CHANGELOG.md @@ -386,4 +386,9 @@ Documentation: - `defaultReturnFormat` was added to all methods that have `ReturnType` param. (#6947) -## [Unreleased] \ No newline at end of file +## [Unreleased] + +### Added + +- `populateTransaction` was added to contract methods (#7124) + From 5860326d56ea9a8618147ef9664ed8b441db8089 Mon Sep 17 00:00:00 2001 From: Oleksii Kosynskyi Date: Mon, 8 Jul 2024 10:50:04 -0400 Subject: [PATCH 7/8] regenerate changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1005aa0b64a..9550099eb8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2573,6 +2573,10 @@ If there are any bugs, improvements, optimizations or any new feature proposal f ### Added +#### web3 + + #### web3-eth-contract - `populateTransaction` was added to contract methods (#7124) +- Contract has `setTransactionMiddleware` and `getTransactionMiddleware` for automatically passing to `sentTransaction` for `deploy` and `send` functions (#7138) From 35dd5841343f3e2a18c03a3936ea4aa93399c3ce Mon Sep 17 00:00:00 2001 From: Oleksii Kosynskyi Date: Mon, 8 Jul 2024 10:56:16 -0400 Subject: [PATCH 8/8] fix logs --- CHANGELOG.md | 1 + packages/web3/CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9550099eb8a..8eba8930d2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2575,6 +2575,7 @@ If there are any bugs, improvements, optimizations or any new feature proposal f #### web3 +- `web3.eth.Contract` will get transaction middleware and use it, if `web3.eth` has transaction middleware. (#7138) #### web3-eth-contract diff --git a/packages/web3/CHANGELOG.md b/packages/web3/CHANGELOG.md index fb638a0d56b..d95a14cc116 100644 --- a/packages/web3/CHANGELOG.md +++ b/packages/web3/CHANGELOG.md @@ -387,4 +387,4 @@ Documentation: #### web3 -- `web3.eth.Contract` will get transaction middleware and use it, if `web3.eth` has transaction middleware. (#7138) \ No newline at end of file +- `web3.eth.Contract` will get transaction middleware and use it, if `web3.eth` has transaction middleware. (#7138)