diff --git a/CHANGELOG.md b/CHANGELOG.md index a3e07f1e013..0765cfcd936 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1291,3 +1291,44 @@ should use 4.0.1-alpha.0 for testing. - Fixed getPastEventsError (#5819) ## [Unreleased] + +### Changed + +#### web3-core + +- If a transaction object with a `data` property is passed to `txInputOptionsFormatter`, it will now be replaced with `input` (#5915) + +#### web3-errors + +- `gasLimit` is no longer accepted as a parameter for `MissingGasError` and `TransactionGasMismatchError, and is also no longer included in error message (#5915) + +#### web3-eth + +- `signTransaction` will now return `gas` instead of `gasLimit` for returned transaction object regardless of what property name the provider uses (#5915) +- `formatTransaction` will now replace `data` transaction property with `input` (#5915) +- `isTransactionCall` will now check if `value.input` `isHexStrict` if provided (#5915) + +#### web3-eth-contract + +- `getSendTxParams` will now return `input` instead of `data` in returned transaction parameters object (#5915) +- `Contract` constructor will now thrown new `ContractTransactionDataAndInputError` if both `data` and `input` are passed in `ContractInitOptions` for `Contract` constructor (#5915) + +#### web3-types + +- `data` property in `TransactionOutput` was renamed to `input` (#5915) + +### Added + +#### web3-eth-contract + +- `input` is now an acceptable property for `ContractInitOptions` in place of `data` (either can be used, but `input` is used withing the + +### Removed + +#### web3-eth-abi + +- Removed `formatDecodedObject` function (#5934) + +#### web3-eth-contract + +- `data` was removed as a property of `ContractOptions` type (#5915) diff --git a/packages/web3-core/CHANGELOG.md b/packages/web3-core/CHANGELOG.md index 4027adeca3d..b617250546e 100644 --- a/packages/web3-core/CHANGELOG.md +++ b/packages/web3-core/CHANGELOG.md @@ -84,3 +84,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added support of `safe` and `finalized` block tags (#5823) ## [Unreleased] + +### Changed + +- If a transaction object with a `data` property is passed to `txInputOptionsFormatter`, it will now be replaced with `input` (#5915) diff --git a/packages/web3-core/src/formatters.ts b/packages/web3-core/src/formatters.ts index 6c47ac8c141..6a0fc61874e 100644 --- a/packages/web3-core/src/formatters.ts +++ b/packages/web3-core/src/formatters.ts @@ -153,17 +153,17 @@ export const txInputOptionsFormatter = (options: TransactionInput): Mutable { ); }); - it('should replace "data" with "input" if "input" is given and "data" is not', () => { - const result = txInputOptionsFormatter({ ...txInput, input: '0xff0011' }); + it('should replace "input" with "data" if "data" is given and "input" is not', () => { + const result = txInputOptionsFormatter({ ...txInput, data: '0xff0011' }); - expect(result).toEqual(expect.objectContaining({ data: '0xff0011' })); - expect(Object.keys(result)).not.toContain('input'); + expect(result).toEqual(expect.objectContaining({ input: '0xff0011' })); + expect(Object.keys(result)).not.toContain('data'); }); - it('should prefix "data" with "0x" if not already', () => { - expect(txInputOptionsFormatter({ ...txInput, data: 'ff0011' })).toEqual( - expect.objectContaining({ data: '0xff0011' }), + it('should prefix "input" with "0x" if not already', () => { + expect(txInputOptionsFormatter({ ...txInput, input: 'ff0011' })).toEqual( + expect.objectContaining({ input: '0xff0011' }), ); }); - it('should throw error if "data" is not a valid hex string', () => { + it('should throw error if "input" is not a valid hex string', () => { jest.spyOn(utils, 'isHexStrict').mockReturnValue(false); - expect(() => txInputOptionsFormatter({ ...txInput, data: 'ff0011' })).toThrow( - 'The data field must be HEX encoded data.', + expect(() => txInputOptionsFormatter({ ...txInput, input: 'ff0011' })).toThrow( + 'The input field must be HEX encoded data.', ); expect(utils.isHexStrict).toHaveBeenCalledWith('0xff0011'); }); diff --git a/packages/web3-errors/CHANGELOG.md b/packages/web3-errors/CHANGELOG.md index 4d28d5d43e9..ec4ccb461a8 100644 --- a/packages/web3-errors/CHANGELOG.md +++ b/packages/web3-errors/CHANGELOG.md @@ -87,3 +87,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `TransactionRevertWithCustomError` was added to handle custom solidity errors (#5854) ## [Unreleased] + +### Changed + +- `gasLimit` is no longer accepted as a parameter for `MissingGasError` and `TransactionGasMismatchError, and is also no longer included in error message (#5915) diff --git a/packages/web3-errors/src/error_codes.ts b/packages/web3-errors/src/error_codes.ts index 5efc073bbfe..143dfa18a6d 100644 --- a/packages/web3-errors/src/error_codes.ts +++ b/packages/web3-errors/src/error_codes.ts @@ -41,6 +41,7 @@ export const ERR_CONTRACT_MISSING_ADDRESS = 307; export const ERR_CONTRACT_MISSING_FROM_ADDRESS = 308; export const ERR_CONTRACT_INSTANTIATION = 309; export const ERR_CONTRACT_EXECUTION_REVERTED = 310; +export const ERR_CONTRACT_TX_DATA_AND_INPUT = 311; // Transaction error codes export const ERR_TX = 400; diff --git a/packages/web3-errors/src/errors/contract_errors.ts b/packages/web3-errors/src/errors/contract_errors.ts index 84a5a1b66d2..1924d55d2e5 100644 --- a/packages/web3-errors/src/errors/contract_errors.ts +++ b/packages/web3-errors/src/errors/contract_errors.ts @@ -30,8 +30,9 @@ import { ERR_CONTRACT_REQUIRED_CALLBACK, ERR_CONTRACT_RESERVED_EVENT, ERR_CONTRACT_RESOLVER_MISSING, + ERR_CONTRACT_TX_DATA_AND_INPUT, } from '../error_codes'; -import { BaseWeb3Error } from '../web3_error_base'; +import { BaseWeb3Error, InvalidValueError } from '../web3_error_base'; export class Web3ContractError extends BaseWeb3Error { public code = ERR_CONTRACT; @@ -172,3 +173,14 @@ export class ContractExecutionError extends Web3ContractError { ); } } + +export class ContractTransactionDataAndInputError extends InvalidValueError { + public code = ERR_CONTRACT_TX_DATA_AND_INPUT; + + public constructor(value: { data: HexString | undefined; input: HexString | undefined }) { + super( + `data: ${value.data ?? 'undefined'}, input: ${value.input ?? 'undefined'}`, + 'You can\'t have "data" and "input" as properties of a contract at the same time, please use either "data" or "input" instead.', + ); + } +} diff --git a/packages/web3-errors/src/errors/transaction_errors.ts b/packages/web3-errors/src/errors/transaction_errors.ts index 807578a4097..fb2d0fbb804 100644 --- a/packages/web3-errors/src/errors/transaction_errors.ts +++ b/packages/web3-errors/src/errors/transaction_errors.ts @@ -310,17 +310,16 @@ export class MissingGasError extends InvalidValueError { public constructor(value: { gas: Numbers | undefined; - gasLimit: Numbers | undefined; gasPrice: Numbers | undefined; maxPriorityFeePerGas: Numbers | undefined; maxFeePerGas: Numbers | undefined; }) { super( - `gas: ${value.gas ?? 'undefined'}, gasLimit: ${ - value.gasLimit ?? 'undefined' - }, gasPrice: ${value.gasPrice ?? 'undefined'}, maxPriorityFeePerGas: ${ - value.maxPriorityFeePerGas ?? 'undefined' - }, maxFeePerGas: ${value.maxFeePerGas ?? 'undefined'}`, + `gas: ${value.gas ?? 'undefined'}, gasPrice: ${ + value.gasPrice ?? 'undefined' + }, maxPriorityFeePerGas: ${value.maxPriorityFeePerGas ?? 'undefined'}, maxFeePerGas: ${ + value.maxFeePerGas ?? 'undefined' + }`, '"gas" is missing', ); } @@ -331,17 +330,16 @@ export class TransactionGasMismatchError extends InvalidValueError { public constructor(value: { gas: Numbers | undefined; - gasLimit: Numbers | undefined; gasPrice: Numbers | undefined; maxPriorityFeePerGas: Numbers | undefined; maxFeePerGas: Numbers | undefined; }) { super( - `gas: ${value.gas ?? 'undefined'}, gasLimit: ${ - value.gasLimit ?? 'undefined' - }, gasPrice: ${value.gasPrice ?? 'undefined'}, maxPriorityFeePerGas: ${ - value.maxPriorityFeePerGas ?? 'undefined' - }, maxFeePerGas: ${value.maxFeePerGas ?? 'undefined'}`, + `gas: ${value.gas ?? 'undefined'}, gasPrice: ${ + value.gasPrice ?? 'undefined' + }, maxPriorityFeePerGas: ${value.maxPriorityFeePerGas ?? 'undefined'}, maxFeePerGas: ${ + value.maxFeePerGas ?? 'undefined' + }`, 'transaction must specify legacy or fee market gas properties, not both', ); } diff --git a/packages/web3-eth-contract/CHANGELOG.md b/packages/web3-eth-contract/CHANGELOG.md index 825a915cc82..65e1fc40f76 100644 --- a/packages/web3-eth-contract/CHANGELOG.md +++ b/packages/web3-eth-contract/CHANGELOG.md @@ -236,3 +236,17 @@ const transactionHash = receipt.transactionHash; - `decodeErrorData` is no longer exported (method was moved to `web3-eth-abi` and renamed `decodeContractErrorData`) (#5844) ## [Unreleased] + +### Added + +- `input` is now an acceptable property for `ContractInitOptions` in place of `data` (either can be used, but `input` is used withing the + `Contract` class) (#5915) + +### Changed + +- `getSendTxParams` will now return `input` instead of `data` in returned transaction parameters object (#5915) +- `Contract` constructor will now thrown new `ContractTransactionDataAndInputError` if both `data` and `input` are passed in `ContractInitOptions` for `Contract` constructor (#5915) + +### Removed + +- `data` was removed as a property of `ContractOptions` type (#5915) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index bca93dd7c2e..e6581c61585 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -16,7 +16,12 @@ along with web3.js. If not, see . */ import { Web3Context, Web3EventEmitter, Web3PromiEvent, Web3ConfigEvent } from 'web3-core'; -import { ContractExecutionError, SubscriptionError, Web3ContractError } from 'web3-errors'; +import { + ContractExecutionError, + ContractTransactionDataAndInputError, + SubscriptionError, + Web3ContractError, +} from 'web3-errors'; import { createAccessList, call, @@ -293,6 +298,19 @@ export class Contract contextOrReturnFormat?: Web3ContractContext | Web3Context | DataFormat, returnFormat?: DataFormat, ) { + // eslint-disable-next-line no-nested-ternary + const options = isContractInitOptions(addressOrOptionsOrContext) + ? addressOrOptionsOrContext + : isContractInitOptions(optionsOrContextOrReturnFormat) + ? optionsOrContextOrReturnFormat + : undefined; + + if (!isNullish(options) && !isNullish(options.data) && !isNullish(options.input)) + throw new ContractTransactionDataAndInputError({ + data: options.data as HexString, + input: options.input as HexString, + }); + let contractContext; if (isWeb3ContractContext(addressOrOptionsOrContext)) { contractContext = addressOrOptionsOrContext; @@ -340,13 +358,6 @@ export class Contract const address = typeof addressOrOptionsOrContext === 'string' ? addressOrOptionsOrContext : undefined; - // eslint-disable-next-line no-nested-ternary - const options = isContractInitOptions(addressOrOptionsOrContext) - ? addressOrOptionsOrContext - : isContractInitOptions(optionsOrContextOrReturnFormat) - ? optionsOrContextOrReturnFormat - : undefined; - this._parseAndSetJsonInterface(jsonInterface, returnDataFormat); if (!isNullish(address)) { @@ -358,9 +369,8 @@ export class Contract jsonInterface: this._jsonInterface, gas: options?.gas ?? options?.gasLimit, gasPrice: options?.gasPrice, - gasLimit: options?.gasLimit, from: options?.from, - data: options?.data, + input: options?.input ?? options?.data, }; this.syncWithContext = (options as ContractInitOptions)?.syncWithContext ?? false; @@ -465,9 +475,8 @@ export class Contract { gas: this.options.gas, gasPrice: this.options.gasPrice, - gasLimit: this.options.gasLimit, from: this.options.from, - data: this.options.data, + input: this.options.input, provider: this.currentProvider, syncWithContext: this.syncWithContext, }, @@ -479,9 +488,8 @@ export class Contract { gas: this.options.gas, gasPrice: this.options.gasPrice, - gasLimit: this.options.gasLimit, from: this.options.from, - data: this.options.data, + input: this.options.input, provider: this.currentProvider, syncWithContext: this.syncWithContext, }, @@ -498,7 +506,7 @@ export class Contract * * ```ts * myContract.deploy({ - * data: '0x12345...', + * input: '0x12345...', * arguments: [123, 'My String'] * }) * .send({ @@ -535,7 +543,7 @@ export class Contract * * // Simply encoding * myContract.deploy({ - * data: '0x12345...', + * input: '0x12345...', * arguments: [123, 'My String'] * }) * .encodeABI(); @@ -544,7 +552,7 @@ export class Contract * * // Gas estimation * myContract.deploy({ - * data: '0x12345...', + * input: '0x12345...', * arguments: [123, 'My String'] * }) * .estimateGas(function(err, gas){ @@ -559,6 +567,7 @@ export class Contract * The byte code of the contract. */ data?: HexString; + input?: HexString; /** * The arguments which get passed to the constructor on deployment. */ @@ -574,19 +583,19 @@ export class Contract } as AbiConstructorFragment; } - const data = format( + const _input = format( { eth: 'bytes' }, - deployOptions?.data ?? this.options.data, + deployOptions?.input ?? deployOptions?.data ?? this.options.input, DEFAULT_RETURN_FORMAT, ); - if (!data || data.trim() === '0x') { + if (!_input || _input.trim() === '0x') { throw new Web3ContractError('contract creation without any data provided.'); } const args = deployOptions?.arguments ?? []; - const contractOptions = { ...this.options, data }; + const contractOptions: ContractOptions = { ...this.options, input: _input }; return { arguments: args, @@ -631,7 +640,7 @@ export class Contract encodeMethodABI( abi as AbiFunctionFragment, args as unknown[], - format({ eth: 'bytes' }, data as Bytes, DEFAULT_RETURN_FORMAT), + format({ eth: 'bytes' }, _input as Bytes, DEFAULT_RETURN_FORMAT), ), }; } @@ -1040,7 +1049,7 @@ export class Contract let modifiedContractOptions = contractOptions ?? this.options; modifiedContractOptions = { ...modifiedContractOptions, - data: undefined, + input: undefined, from: modifiedContractOptions.from ?? this.defaultAccount ?? undefined, }; diff --git a/packages/web3-eth-contract/src/types.ts b/packages/web3-eth-contract/src/types.ts index 1d021fd8692..48c9ae94560 100644 --- a/packages/web3-eth-contract/src/types.ts +++ b/packages/web3-eth-contract/src/types.ts @@ -79,7 +79,6 @@ export interface ContractOptions { * The gas price in wei to use for transactions. */ readonly gasPrice?: Uint; - readonly gasLimit?: Uint; /** * The address transactions should be made from. */ @@ -87,7 +86,7 @@ export interface ContractOptions { /** * The byte code of the contract. Used when the contract gets {@link Contract.deploy | deployed} */ - readonly data?: Bytes; + readonly input?: Bytes; /** * The {@doclink glossary/json_interface | json interface} object derived from the [ABI](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) of this contract. * @@ -138,6 +137,7 @@ export interface ContractInitOptions { * The maximum gas provided for a transaction (gas limit). */ readonly gas?: Uint; + readonly gasLimit?: Uint; /** * The gas price in wei to use for transactions. */ @@ -150,7 +150,8 @@ export interface ContractInitOptions { * The byte code of the contract. Used when the contract gets {@link Contract.deploy | deployed} */ readonly data?: Bytes; - readonly gasLimit?: Uint; + readonly input?: Bytes; + readonly provider?: SupportedProviders | string; /** * If `true`, the defaults of the contract instance will be updated automatically based on the changes of the context used to instantiate the contract. @@ -168,6 +169,7 @@ export interface NonPayableCallOptions { from?: Address; to?: Address; data?: HexString; + input?: HexString; /** * The maximum gas provided for this call “transaction” (gas limit) */ diff --git a/packages/web3-eth-contract/src/utils.ts b/packages/web3-eth-contract/src/utils.ts index d07eafe8a61..250825eaa30 100644 --- a/packages/web3-eth-contract/src/utils.ts +++ b/packages/web3-eth-contract/src/utils.ts @@ -44,7 +44,7 @@ export const getSendTxParams = ({ options?: PayableCallOptions | NonPayableCallOptions; contractOptions: ContractOptions; }): TransactionCall => { - const deploymentCall = options?.data ?? contractOptions.data; + const deploymentCall = options?.input ?? options?.data ?? contractOptions.input; if (!deploymentCall && !options?.to && !contractOptions.address) { throw new Web3ContractError('Contract address not specified'); @@ -60,15 +60,15 @@ export const getSendTxParams = ({ gas: contractOptions.gas, gasPrice: contractOptions.gasPrice, from: contractOptions.from, - data: contractOptions.data, + input: contractOptions.input, }, options as unknown as Record, ) as unknown as TransactionCall; - if (!txParams.data || abi.type === 'constructor') { + if (!txParams.input || abi.type === 'constructor') { txParams = { ...txParams, - data: encodeMethodABI(abi, params, txParams.data as HexString), + input: encodeMethodABI(abi, params, txParams.input as HexString), }; } @@ -96,14 +96,14 @@ export const getEthTxCallParams = ({ gas: contractOptions.gas, gasPrice: contractOptions.gasPrice, from: contractOptions.from, - data: contractOptions.data, + input: contractOptions.input, }, options as unknown as Record, ) as unknown as TransactionCall; txParams = { ...txParams, - data: encodeMethodABI(abi, params, txParams.data ? toHex(txParams.data) : undefined), + input: encodeMethodABI(abi, params, txParams.input ? toHex(txParams.input) : undefined), }; return txParams; @@ -126,14 +126,14 @@ export const getEstimateGasParams = ({ gas: contractOptions.gas, gasPrice: contractOptions.gasPrice, from: contractOptions.from, - data: contractOptions.data, + input: contractOptions.input, }, options as unknown as Record, ) as unknown as TransactionCall; txParams = { ...txParams, - data: encodeMethodABI(abi, params, txParams.data ? toHex(txParams.data) : undefined), + input: encodeMethodABI(abi, params, txParams.input ? toHex(txParams.input) : undefined), }; return txParams as TransactionWithSenderAPI; @@ -143,6 +143,7 @@ export const isContractInitOptions = (options: unknown): options is ContractInit typeof options === 'object' && !isNullish(options) && [ + 'input', 'data', 'from', 'gas', @@ -181,15 +182,15 @@ export const getCreateAccessListParams = ({ gas: contractOptions.gas, gasPrice: contractOptions.gasPrice, from: contractOptions.from, - data: contractOptions.data, + input: contractOptions.input, }, options as unknown as Record, ) as unknown as TransactionForAccessList; - if (!txParams.data || abi.type === 'constructor') { + if (!txParams.input || abi.type === 'constructor') { txParams = { ...txParams, - data: encodeMethodABI(abi, params, txParams.data as HexString), + input: encodeMethodABI(abi, params, txParams.input as HexString), }; } diff --git a/packages/web3-eth-contract/test/integration/contract_methods.test.ts b/packages/web3-eth-contract/test/integration/contract_methods.test.ts index 1fa72966f00..f63923cdfbe 100644 --- a/packages/web3-eth-contract/test/integration/contract_methods.test.ts +++ b/packages/web3-eth-contract/test/integration/contract_methods.test.ts @@ -134,7 +134,7 @@ describe('contract', () => { it('should run send method of the contract if data is provided at initiation', async () => { const tempContract = new Contract(BasicAbi, { provider: getSystemTestProvider(), - data: BasicBytecode, + input: BasicBytecode, from: acc.address, gas: '1000000', }); diff --git a/packages/web3-eth-contract/test/unit/contract.test.ts b/packages/web3-eth-contract/test/unit/contract.test.ts index 837966176ac..066c324f9ab 100644 --- a/packages/web3-eth-contract/test/unit/contract.test.ts +++ b/packages/web3-eth-contract/test/unit/contract.test.ts @@ -100,7 +100,7 @@ describe('Contract', () => { }); it('should deploy contract', async () => { - const data = `${GreeterBytecode}0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b4d79204772656574696e67000000000000000000000000000000000000000000`; + const input = `${GreeterBytecode}0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b4d79204772656574696e67000000000000000000000000000000000000000000`; const contract = new Contract(GreeterAbi); // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -111,7 +111,7 @@ describe('Contract', () => { expect(tx.gas).toStrictEqual(sendOptions.gas); expect(tx.gasPrice).toBeUndefined(); expect(tx.from).toStrictEqual(sendOptions.from); - expect(tx.data).toStrictEqual(data); // padded data + expect(tx.input).toStrictEqual(input); // padded data const newContract = contract.clone(); newContract.options.address = deployedAddr; @@ -171,7 +171,7 @@ describe('Contract', () => { // } as unknown as Web3PromiEvent); if ( - _tx.data === + _tx.input === '0xa41368620000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000548656c6c6f000000000000000000000000000000000000000000000000000000' ) { // eslint-disable-next-line @@ -196,7 +196,7 @@ describe('Contract', () => { // }); const deployedContract = await contract .deploy({ - data: GreeterBytecode, + input: GreeterBytecode, arguments: ['My Greeting'], }) .send(sendOptions); @@ -223,14 +223,14 @@ describe('Contract', () => { const spyEthCall = jest.spyOn(eth, 'call').mockImplementation((_objInstance, _tx) => { expect(_tx.to).toStrictEqual(deployedAddr); - expect(_tx.data).toBe('0xcfae3217'); + expect(_tx.input).toBe('0xcfae3217'); // eslint-disable-next-line @typescript-eslint/no-unsafe-return return Promise.resolve(encodedArg) as any; // contract class should decode encodedArg }); const deployedContract = await contract .deploy({ - data: GreeterBytecode, + input: GreeterBytecode, arguments: ['My Greeting'], }) .send(sendOptions); @@ -523,7 +523,7 @@ describe('Contract', () => { expect(_block).toBe('latest'); expect(_tx.to).toStrictEqual(deployedAddr); expect(_tx.from).toStrictEqual(sendOptions.from); - expect(_tx.data).toBe( + expect(_tx.input).toBe( '0xa41368620000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000548656c6c6f000000000000000000000000000000000000000000000000000000', ); @@ -589,7 +589,7 @@ describe('Contract', () => { .spyOn(eth, 'createAccessList') .mockImplementation((_objInstance, _tx) => { expect(_tx.to).toStrictEqual(deployedAddr); - expect(_tx.data).toBe('0xcfae3217'); + expect(_tx.input).toBe('0xcfae3217'); expect(_tx.from).toBe(fromAddr); // eslint-disable-next-line @typescript-eslint/no-unsafe-return return Promise.resolve(result) as any; // contract class should decode encodedArg diff --git a/packages/web3-eth/CHANGELOG.md b/packages/web3-eth/CHANGELOG.md index a28be7f778d..f0cd5c85ad6 100644 --- a/packages/web3-eth/CHANGELOG.md +++ b/packages/web3-eth/CHANGELOG.md @@ -107,3 +107,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `getRevertReason` is no longer exported (#5844) ## [Unreleased] + +### Changed + +- `signTransaction` will now return `gas` instead of `gasLimit` for returned transaction object regardless of what property name the provider uses (#5915) +- `formatTransaction` will now replace `data` transaction property with `input` (#5915) +- `isTransactionCall` will now check if `value.input` `isHexStrict` if provided (#5915) diff --git a/packages/web3-eth/src/rpc_method_wrappers.ts b/packages/web3-eth/src/rpc_method_wrappers.ts index 5317e66e603..e9c96af56a5 100644 --- a/packages/web3-eth/src/rpc_method_wrappers.ts +++ b/packages/web3-eth/src/rpc_method_wrappers.ts @@ -19,7 +19,6 @@ along with web3.js. If not, see . /* eslint-disable default-param-last */ import { EthExecutionAPI, - TransactionInfo, TransactionWithSenderAPI, SignedTransactionInfoAPI, Web3BaseWalletAccount, @@ -677,7 +676,7 @@ export async function getTransaction( return isNullish(response) ? response - : format(transactionInfoSchema, response as unknown as TransactionInfo, returnFormat); + : formatTransaction(response, returnFormat, { transactionSchema: transactionInfoSchema }); } /** @@ -854,7 +853,7 @@ export async function getTransactionFromBlock( return isNullish(response) ? response - : format(transactionInfoSchema, response as unknown as TransactionInfo, returnFormat); + : formatTransaction(response, returnFormat, { transactionSchema: transactionInfoSchema }); } /** diff --git a/packages/web3-eth/src/utils/format_transaction.ts b/packages/web3-eth/src/utils/format_transaction.ts index 42468f98c3c..bf5b2894d98 100644 --- a/packages/web3-eth/src/utils/format_transaction.ts +++ b/packages/web3-eth/src/utils/format_transaction.ts @@ -24,7 +24,7 @@ import { FormatType, } from 'web3-utils'; import { Transaction } from 'web3-types'; -import { isNullish } from 'web3-validator'; +import { isNullish, ValidationSchemaInput } from 'web3-validator'; import { TransactionDataAndInputError } from 'web3-errors'; import { transactionSchema } from '../schemas'; @@ -34,6 +34,9 @@ export function formatTransaction< >( transaction: TransactionType, returnFormat: ReturnFormat = DEFAULT_RETURN_FORMAT as ReturnFormat, + options: { transactionSchema: ValidationSchemaInput | typeof transactionSchema } = { + transactionSchema, + }, ): FormatType { let formattedTransaction = mergeDeep({}, transaction as Record) as Transaction; if (!isNullish(transaction?.common)) { @@ -42,16 +45,21 @@ export function formatTransaction< formattedTransaction.common.customChain = { ...transaction.common.customChain }; } - formattedTransaction = format(transactionSchema, formattedTransaction, returnFormat); + formattedTransaction = format(options.transactionSchema, formattedTransaction, returnFormat); if (!isNullish(formattedTransaction.data) && !isNullish(formattedTransaction.input)) throw new TransactionDataAndInputError({ data: bytesToBuffer(formattedTransaction.data).toString('hex'), input: bytesToBuffer(formattedTransaction.input).toString('hex'), }); - else if (!isNullish(formattedTransaction.input)) { - formattedTransaction.data = formattedTransaction.input; - delete formattedTransaction.input; + else if (!isNullish(formattedTransaction.data)) { + formattedTransaction.input = formattedTransaction.data; + delete formattedTransaction.data; + } + + if (!isNullish(formattedTransaction.gasLimit)) { + formattedTransaction.gas = formattedTransaction.gasLimit; + delete formattedTransaction.gasLimit; } return formattedTransaction as FormatType; diff --git a/packages/web3-eth/src/utils/prepare_transaction_for_signing.ts b/packages/web3-eth/src/utils/prepare_transaction_for_signing.ts index d5fd774825d..77d0df3880b 100644 --- a/packages/web3-eth/src/utils/prepare_transaction_for_signing.ts +++ b/packages/web3-eth/src/utils/prepare_transaction_for_signing.ts @@ -38,10 +38,10 @@ const getEthereumjsTxDataFromTransaction = ( ) => ({ nonce: transaction.nonce, gasPrice: transaction.gasPrice, - gasLimit: transaction.gasLimit, + gasLimit: transaction.gasLimit ?? transaction.gas, to: transaction.to, value: transaction.value, - data: transaction.data, + data: transaction.input, type: transaction.type, chainId: transaction.chainId, accessList: ( diff --git a/packages/web3-eth/src/utils/transaction_builder.ts b/packages/web3-eth/src/utils/transaction_builder.ts index 8b518b17155..1a5b98f1340 100644 --- a/packages/web3-eth/src/utils/transaction_builder.ts +++ b/packages/web3-eth/src/utils/transaction_builder.ts @@ -166,15 +166,15 @@ export async function defaultTransactionBuilder { if (!legacyGasPresent && !feeMarketGasPresent) throw new MissingGasError({ gas: transaction.gas, - gasLimit: transaction.gasLimit, gasPrice: transaction.gasPrice, maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, maxFeePerGas: transaction.maxFeePerGas, @@ -268,7 +268,6 @@ export const validateGas = (transaction: InternalTransaction) => { if (legacyGasPresent && feeMarketGasPresent) throw new TransactionGasMismatchError({ gas: transaction.gas, - gasLimit: transaction.gasLimit, gasPrice: transaction.gasPrice, maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, maxFeePerGas: transaction.maxFeePerGas, diff --git a/packages/web3-eth/test/fixtures/prepare_transaction_for_signing.ts b/packages/web3-eth/test/fixtures/prepare_transaction_for_signing.ts index d559da9ac9c..c43d489d3f9 100644 --- a/packages/web3-eth/test/fixtures/prepare_transaction_for_signing.ts +++ b/packages/web3-eth/test/fixtures/prepare_transaction_for_signing.ts @@ -137,7 +137,7 @@ export const validTransactions: [ to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', value: '1000000000', - data: '', + input: '', common, }, '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', @@ -158,7 +158,7 @@ export const validTransactions: [ gas: 21000, to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', value: '1000000000', - data: '', + input: '', common, }, '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', @@ -180,7 +180,7 @@ export const validTransactions: [ to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', value: '0', - data: '', + input: '', common, }, '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', @@ -201,7 +201,7 @@ export const validTransactions: [ gas: 31853, to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', value: '0', - data: '', + input: '', common, }, '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', @@ -223,7 +223,7 @@ export const validTransactions: [ to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', value: '1000000000', - data: '', + input: '', common, }, '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', @@ -244,7 +244,7 @@ export const validTransactions: [ gas: 2000000, to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', value: '1000000000', - data: '', + input: '', common, }, '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', @@ -266,7 +266,7 @@ export const validTransactions: [ to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', value: '0', - data: '', + input: '', common, }, '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', @@ -287,7 +287,7 @@ export const validTransactions: [ gas: 31853, to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', value: '0', - data: '', + input: '', common, }, '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', @@ -309,7 +309,7 @@ export const validTransactions: [ to: '0x3535353535353535353535353535353535353535', from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', value: '1000000000000000000', - data: '', + input: '', common, }, '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', @@ -330,7 +330,7 @@ export const validTransactions: [ gas: 21000, to: '0x3535353535353535353535353535353535353535', value: '1000000000000000000', - data: '', + input: '', common, }, '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', @@ -352,7 +352,7 @@ export const validTransactions: [ to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', value: '1000000000000000000', - data: '0x0123abcd', + input: '0x0123abcd', common, }, '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', @@ -373,7 +373,7 @@ export const validTransactions: [ gas: 50000, to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', value: '1000000000000000000', - data: '0x0123abcd', + input: '0x0123abcd', common, }, '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', @@ -395,7 +395,7 @@ export const validTransactions: [ to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', value: '1000000000000000000', - data: '0x0123abcd', + input: '0x0123abcd', common, }, '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', @@ -416,7 +416,7 @@ export const validTransactions: [ gas: 50000, to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', value: '1000000000000000000', - data: '0x0123abcd', + input: '0x0123abcd', common, }, '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', @@ -438,7 +438,7 @@ export const validTransactions: [ to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', value: '1000000000000000000', - data: '0x0123abcd', + input: '0x0123abcd', common, }, '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', @@ -459,7 +459,7 @@ export const validTransactions: [ gas: 50000, to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', value: '1000000000000000000', - data: '0x0123abcd', + input: '0x0123abcd', common, }, '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', @@ -481,7 +481,7 @@ export const validTransactions: [ to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', value: '1000000000000000000', - data: '0x0123abcd', + input: '0x0123abcd', common, }, '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', @@ -502,7 +502,7 @@ export const validTransactions: [ gas: 50000, to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', value: '1000000000000000000', - data: '0x0123abcd', + input: '0x0123abcd', common, }, '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', @@ -524,7 +524,7 @@ export const validTransactions: [ to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', value: '1000000000000000000', - data: '0x0123abcd', + input: '0x0123abcd', common, }, '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', @@ -545,7 +545,7 @@ export const validTransactions: [ gas: 50000, to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', value: '1000000000000000000', - data: '0x0123abcd', + input: '0x0123abcd', common, }, '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', @@ -567,7 +567,7 @@ export const validTransactions: [ to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', value: '1000000000000000000', - data: '0x0123abcd', + input: '0x0123abcd', common, }, '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', @@ -588,7 +588,7 @@ export const validTransactions: [ gas: 50000, to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', value: '1000000000000000000', - data: '0x0123abcd', + input: '0x0123abcd', common, }, '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', @@ -653,7 +653,7 @@ export const validTransactions: [ to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', value: '1000000000', - data: '', + input: '', common: commonBerlin, accessList, }, @@ -675,7 +675,7 @@ export const validTransactions: [ gas: 27200, to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', value: '1000000000', - data: '', + input: '', common: commonBerlin, accessList, }, @@ -700,7 +700,7 @@ export const validTransactions: [ to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', value: '1000000000', - data: '', + input: '', common: commonLondon, accessList, }, @@ -724,7 +724,7 @@ export const validTransactions: [ gasLimit: '0x6A40', to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', value: '1000000000', - data: '', + input: '', common: commonLondon, accessList, }, @@ -748,7 +748,7 @@ export const validTransactions: [ to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', value: '1000000000', - data: '', + input: '', common: commonLondon, }, '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', @@ -770,7 +770,7 @@ export const validTransactions: [ gasLimit: '0x6A40', to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', value: '1000000000', - data: '', + input: '', common: commonLondon, }, '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', @@ -793,7 +793,7 @@ export const validTransactions: [ to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', value: '1000000000', - data: '', + input: '', common: commonLondon, accessList, }, @@ -816,7 +816,7 @@ export const validTransactions: [ gasLimit: '0x6A40', to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', value: '1000000000', - data: '', + input: '', common: commonLondon, accessList, }, @@ -840,7 +840,7 @@ export const validTransactions: [ to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', value: '1000000000', - data: '', + input: '', common: commonLondon, }, '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', @@ -863,7 +863,7 @@ export const validTransactions: [ to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', value: '1000000000', - data: '', + input: '', common: commonLondon, }, '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', @@ -885,7 +885,7 @@ export const validTransactions: [ gasLimit: '0x6A40', to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', value: '1000000000', - data: '', + input: '', common: commonLondon, }, '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', diff --git a/packages/web3-eth/test/fixtures/validate_transaction_for_signing.ts b/packages/web3-eth/test/fixtures/validate_transaction_for_signing.ts index 10828550fba..7f9f16f1c6a 100644 --- a/packages/web3-eth/test/fixtures/validate_transaction_for_signing.ts +++ b/packages/web3-eth/test/fixtures/validate_transaction_for_signing.ts @@ -372,7 +372,6 @@ export const validateGasData: [ }, new MissingGasError({ gas: undefined, - gasLimit: undefined, gasPrice: undefined, maxPriorityFeePerGas: undefined, maxFeePerGas: undefined, @@ -397,7 +396,6 @@ export const validateGasData: [ }, new MissingGasError({ gas: '0x5208', - gasLimit: '0x5208', gasPrice: undefined, maxFeePerGas: undefined, maxPriorityFeePerGas: undefined, @@ -420,8 +418,7 @@ export const validateGasData: [ s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', }, new MissingGasError({ - gas: undefined, - gasLimit: '0x5208', + gas: '0x5208', gasPrice: undefined, maxFeePerGas: undefined, maxPriorityFeePerGas: undefined, @@ -440,7 +437,6 @@ export const validateGasData: [ chain: 'mainnet', hardfork: 'berlin', chainId: '0x1', - gasLimit: '0x5208', v: '0x25', r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', @@ -485,8 +481,7 @@ export const validateGasData: [ s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', }, new MissingGasError({ - gas: undefined, - gasLimit: '0x5208', + gas: '0x5208', gasPrice: undefined, maxPriorityFeePerGas: undefined, maxFeePerGas: '0x1229298c00', @@ -510,8 +505,7 @@ export const validateGasData: [ s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', }, new MissingGasError({ - gas: undefined, - gasLimit: '0x5208', + gas: '0x5208', gasPrice: undefined, maxPriorityFeePerGas: '0x49504f80', maxFeePerGas: undefined, @@ -539,7 +533,6 @@ export const validateGasData: [ }, new TransactionGasMismatchError({ gas: '0x5208', - gasLimit: '0x5208', gasPrice: '0x4a817c800', maxFeePerGas: '0x1229298c00', maxPriorityFeePerGas: '0x49504f80', @@ -567,7 +560,6 @@ export const validateGasData: [ }, new TransactionGasMismatchError({ gas: '0x5208', - gasLimit: '0x5208', gasPrice: '0x4a817c800', maxFeePerGas: '0x1229298c00', maxPriorityFeePerGas: '0x49504f80', diff --git a/packages/web3-eth/test/integration/web3_eth/sign_transaction.test.ts b/packages/web3-eth/test/integration/web3_eth/sign_transaction.test.ts index 8b971e1ec3d..27be403c7ae 100644 --- a/packages/web3-eth/test/integration/web3_eth/sign_transaction.test.ts +++ b/packages/web3-eth/test/integration/web3_eth/sign_transaction.test.ts @@ -15,7 +15,7 @@ You should have received a copy of the GNU Lesser General Public License along with web3.js. If not, see . */ -import { Transaction } from 'web3-types'; +import { Transaction, TransactionLegacySignedAPI } from 'web3-types'; import { Web3Eth } from '../../../src'; import { closeOpenConnection, @@ -37,30 +37,60 @@ describe('Web3Eth.signTransaction', () => { }); it('should sign a simple value transfer', async () => { + const nonce = await web3Eth.getTransactionCount(tempAcc.address); const transaction: Transaction = { from: tempAcc.address, - nonce: await web3Eth.getTransactionCount(tempAcc.address), + nonce, to: '0x0000000000000000000000000000000000000000', value: '0x1', gas: '0x5208', gasPrice: '0x3b9aca01', }; const response = await web3Eth.signTransaction(transaction); - expect(response).toMatchObject({ raw: expect.any(String), tx: expect.any(Object) }); + expect(response).toMatchObject({ + tx: { + type: BigInt(0), + nonce: BigInt(nonce), + gasPrice: BigInt(1000000001), + gas: BigInt(21000), + value: BigInt(1), + to: transaction.to, + input: '0x', + }, + }); + // Pulling out of toMatchObject to be compatiable with Cypress + expect(response.raw).toMatch(/0[xX][0-9a-fA-F]+/); + expect(typeof (response.tx as TransactionLegacySignedAPI).v).toBe('bigint'); + expect(response.tx.r).toMatch(/0[xX][0-9a-fA-F]+/); + expect(response.tx.s).toMatch(/0[xX][0-9a-fA-F]+/); }); it('should sign a contract deployment', async () => { const greeterContractDeploymentData = '0x60806040523480156200001157600080fd5b5060405162000a6a38038062000a6a8339818101604052810190620000379190620002a4565b80600090805190602001906200004f92919062000057565b505062000359565b828054620000659062000324565b90600052602060002090601f016020900481019282620000895760008555620000d5565b82601f10620000a457805160ff1916838001178555620000d5565b82800160010185558215620000d5579182015b82811115620000d4578251825591602001919060010190620000b7565b5b509050620000e49190620000e8565b5090565b5b8082111562000103576000816000905550600101620000e9565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620001708262000125565b810181811067ffffffffffffffff8211171562000192576200019162000136565b5b80604052505050565b6000620001a762000107565b9050620001b5828262000165565b919050565b600067ffffffffffffffff821115620001d857620001d762000136565b5b620001e38262000125565b9050602081019050919050565b60005b8381101562000210578082015181840152602081019050620001f3565b8381111562000220576000848401525b50505050565b60006200023d6200023784620001ba565b6200019b565b9050828152602081018484840111156200025c576200025b62000120565b5b62000269848285620001f0565b509392505050565b600082601f8301126200028957620002886200011b565b5b81516200029b84826020860162000226565b91505092915050565b600060208284031215620002bd57620002bc62000111565b5b600082015167ffffffffffffffff811115620002de57620002dd62000116565b5b620002ec8482850162000271565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200033d57607f821691505b602082108103620003535762000352620002f5565b5b50919050565b61070180620003696000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063a41368621461003b578063cfae32171461006c575b600080fd5b6100556004803603810190610050919061043f565b61008a565b60405161006392919061052b565b60405180910390f35b6100746101b0565b604051610081919061055b565b60405180910390f35b600060607f0d363f2fba46ab11b6db8da0125b0d5484787c44e265b48810735998bab12b756000846040516100c0929190610672565b60405180910390a182600090805190602001906100de929190610242565b507f7d7846723bda52976e0286c6efffee937ee9f76817a867ec70531ad29fb1fc0e600060405161010f91906106a9565b60405180910390a160016000808054610127906105ac565b80601f0160208091040260200160405190810160405280929190818152602001828054610153906105ac565b80156101a05780601f10610175576101008083540402835291602001916101a0565b820191906000526020600020905b81548152906001019060200180831161018357829003601f168201915b5050505050905091509150915091565b6060600080546101bf906105ac565b80601f01602080910402602001604051908101604052809291908181526020018280546101eb906105ac565b80156102385780601f1061020d57610100808354040283529160200191610238565b820191906000526020600020905b81548152906001019060200180831161021b57829003601f168201915b5050505050905090565b82805461024e906105ac565b90600052602060002090601f01602090048101928261027057600085556102b7565b82601f1061028957805160ff19168380011785556102b7565b828001600101855582156102b7579182015b828111156102b657825182559160200191906001019061029b565b5b5090506102c491906102c8565b5090565b5b808211156102e15760008160009055506001016102c9565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61034c82610303565b810181811067ffffffffffffffff8211171561036b5761036a610314565b5b80604052505050565b600061037e6102e5565b905061038a8282610343565b919050565b600067ffffffffffffffff8211156103aa576103a9610314565b5b6103b382610303565b9050602081019050919050565b82818337600083830152505050565b60006103e26103dd8461038f565b610374565b9050828152602081018484840111156103fe576103fd6102fe565b5b6104098482856103c0565b509392505050565b600082601f830112610426576104256102f9565b5b81356104368482602086016103cf565b91505092915050565b600060208284031215610455576104546102ef565b5b600082013567ffffffffffffffff811115610473576104726102f4565b5b61047f84828501610411565b91505092915050565b60008115159050919050565b61049d81610488565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b838110156104dd5780820151818401526020810190506104c2565b838111156104ec576000848401525b50505050565b60006104fd826104a3565b61050781856104ae565b93506105178185602086016104bf565b61052081610303565b840191505092915050565b60006040820190506105406000830185610494565b818103602083015261055281846104f2565b90509392505050565b6000602082019050818103600083015261057581846104f2565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806105c457607f821691505b6020821081036105d7576105d661057d565b5b50919050565b60008190508160005260206000209050919050565b600081546105ff816105ac565b61060981866104ae565b94506001821660008114610624576001811461063657610669565b60ff1983168652602086019350610669565b61063f856105dd565b60005b8381101561066157815481890152600182019150602081019050610642565b808801955050505b50505092915050565b6000604082019050818103600083015261068c81856105f2565b905081810360208301526106a081846104f2565b90509392505050565b600060208201905081810360008301526106c381846105f2565b90509291505056fea2646970667358221220fe0f28c9f8ef0a13a95934b974e7bc2ca6762b40a5b93ccd6ca2038f454bf52764736f6c634300080e003300000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000017736f6c79656e7420677265656e2069732070656f706c65000000000000000000'; + const nonce = await web3Eth.getTransactionCount(tempAcc.address); const transaction: Transaction = { from: tempAcc.address, - nonce: await web3Eth.getTransactionCount(tempAcc.address), + nonce, data: greeterContractDeploymentData, gas: '0x740b8', gasPrice: '0x3b9aca01', }; const response = await web3Eth.signTransaction(transaction); // eslint-disable-next-line jest/no-standalone-expect - expect(response).toMatchObject({ raw: expect.any(String), tx: expect.any(Object) }); + expect(response).toMatchObject({ + tx: { + type: BigInt(0), + nonce: BigInt(nonce), + gasPrice: BigInt(1000000001), + gas: BigInt(475320), + input: greeterContractDeploymentData, + }, + }); + // Pulling out of toMatchObject to be compatiable with Cypress + expect(response.raw).toMatch(/0[xX][0-9a-fA-F]+/); + expect(typeof (response.tx as TransactionLegacySignedAPI).v).toBe('bigint'); + expect(response.tx.r).toMatch(/0[xX][0-9a-fA-F]+/); + expect(response.tx.s).toMatch(/0[xX][0-9a-fA-F]+/); }); }); diff --git a/packages/web3-eth/test/unit/default_transaction_builder.test.ts b/packages/web3-eth/test/unit/default_transaction_builder.test.ts index 38d4be1c777..a07eae51ee8 100644 --- a/packages/web3-eth/test/unit/default_transaction_builder.test.ts +++ b/packages/web3-eth/test/unit/default_transaction_builder.test.ts @@ -62,7 +62,7 @@ describe('defaultTransactionBuilder', () => { type: '0x0', maxFeePerGas: expectedMaxFeePerGas, maxPriorityFeePerGas: expectedMaxPriorityFeePerGas, - data: '0x0', + data: '0x', nonce: expectedNonce, chain: 'mainnet', hardfork: 'berlin', @@ -210,16 +210,28 @@ describe('defaultTransactionBuilder', () => { }); }); - describe('should populate data', () => { + describe('should populate input', () => { it('should populate with 0x', async () => { + const input = { ...transaction }; + delete input.input; + + const result = await defaultTransactionBuilder({ + transaction: input, + web3Context, + }); + expect(result.input).toBe('0x'); + }); + + it('should prefix with 0x', async () => { const input = { ...transaction }; delete input.data; + input.input = '123'; const result = await defaultTransactionBuilder({ transaction: input, web3Context, }); - expect(result.data).toBe('0x'); + expect(result.input).toBe('0x123'); }); }); diff --git a/packages/web3-eth/test/unit/format_transaction.test.ts b/packages/web3-eth/test/unit/format_transaction.test.ts index bea26fddd18..b61db25bf88 100644 --- a/packages/web3-eth/test/unit/format_transaction.test.ts +++ b/packages/web3-eth/test/unit/format_transaction.test.ts @@ -50,6 +50,14 @@ describe('formatTransaction', () => { for (const sourceType of Object.keys(transactionsDataForNumberTypes)) { for (const destinationType of Object.keys(transactionsDataForNumberTypes)) { it(`should convert "${sourceType}" properties to "${destinationType}"`, () => { + // formatTransaction replaces gasLimit with gas property to follow ETH spec + // https://github.com/ethereum/execution-apis/issues/283 + const expectedFormattedTransaction = + transactionsDataForNumberTypes[destinationType as FMT_NUMBER]; + delete expectedFormattedTransaction.gasLimit; + // formatTransaction replaces data with input to follow ETH spec + delete expectedFormattedTransaction.data; + expect( formatTransaction( transactionsDataForNumberTypes[sourceType as FMT_NUMBER], @@ -58,7 +66,7 @@ describe('formatTransaction', () => { number: destinationType as FMT_NUMBER, }, ), - ).toStrictEqual(transactionsDataForNumberTypes[destinationType as FMT_NUMBER]); + ).toStrictEqual(expectedFormattedTransaction); }); } } @@ -68,12 +76,20 @@ describe('formatTransaction', () => { for (const sourceType of Object.keys(transactionsDataForByteTypes)) { for (const destinationType of Object.keys(transactionsDataForByteTypes)) { it(`should convert "${sourceType}" properties to "${destinationType}"`, () => { + // formatTransaction replaces gasLimit with gas property to follow ETH spec + // https://github.com/ethereum/execution-apis/issues/283 + const expectedFormattedTransaction = + transactionsDataForByteTypes[destinationType as FMT_BYTES]; + delete expectedFormattedTransaction.gasLimit; + // formatTransaction replaces data with input to follow ETH spec + delete expectedFormattedTransaction.data; + expect( formatTransaction(transactionsDataForByteTypes[sourceType as FMT_BYTES], { ...DEFAULT_RETURN_FORMAT, bytes: destinationType as FMT_BYTES, }), - ).toStrictEqual(transactionsDataForByteTypes[destinationType as FMT_BYTES]); + ).toStrictEqual(expectedFormattedTransaction); }); } } diff --git a/packages/web3-eth/test/unit/rpc_method_wrappers/fixtures/get_transaction.ts b/packages/web3-eth/test/unit/rpc_method_wrappers/fixtures/get_transaction.ts index c64bb34d0cc..46e596987a0 100644 --- a/packages/web3-eth/test/unit/rpc_method_wrappers/fixtures/get_transaction.ts +++ b/packages/web3-eth/test/unit/rpc_method_wrappers/fixtures/get_transaction.ts @@ -14,26 +14,28 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with web3.js. If not, see . */ -import { Bytes, Transaction } from 'web3-types'; +import { Bytes, TransactionInfo } from 'web3-types'; -export const mockRpcResponse: Transaction = { - from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', - to: '0x3535353535353535353535353535353535353535', - value: '0x174876e800', - gas: '0x5208', - gasPrice: '0x4a817c800', - type: '0x0', - maxFeePerGas: '0x1229298c00', - maxPriorityFeePerGas: '0x49504f80', - data: '0x', - nonce: '0x4', - chain: 'mainnet', - hardfork: 'berlin', +export const mockRpcResponse: TransactionInfo = { + accessList: [], + blockHash: '0xc9e87d2d1aa23d241fe281b8db7856c497320aa4f1f582a7fcd4fab7d2addf74', + blockNumber: '0xc66332', chainId: '0x1', - gasLimit: '0x5208', - v: '0x25', - r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', - s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + from: '0xcfb162c6de7ee2b49048b270cb5e297da5b6e6c3', + gas: '0x31d00', + gasPrice: '0xa83613262', + hash: '0x5f67b495f9c53b942cb1bfacaf175ad887372d7227454a971f15f5e6a7639ad1', + input: '0x38ed17390000000000000000000000000000000000000000000000147ebc6d689cc81c8c0000000000000000000000000000000000000000000000005b7471df733ea75c00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000cfb162c6de7ee2b49048b270cb5e297da5b6e6c30000000000000000000000000000000000000000000000000000000061134c8f0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000d084b83c305dafd76ae3e1b4e1f1fe2ecccb3988000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000d2877702675e6ceb975b4a1dff9fb7baf4c91ea9', + maxFeePerGas: '0xf2cec3661', + maxPriorityFeePerGas: '0xb2d05e00', + nonce: '0xb8', + r: '0x9d201db7621ee0e204841ea374cca3397c7f1a880c5f83207d8cd7e5b4b9e984', + s: '0x391b00b10782665d8c5138aef912ea77a59024bf7962f4d1faedcc45bf91d568', + to: '0x7a250d5630b4cf539739df2c5dacb4c659f2488d', + transactionIndex: '0xc8', + type: '0x2', + v: '0x0', + value: '0x0', }; /** diff --git a/packages/web3-eth/test/unit/rpc_method_wrappers/get_transaction.test.ts b/packages/web3-eth/test/unit/rpc_method_wrappers/get_transaction.test.ts index d64e7ef59ed..d0a0040b0ec 100644 --- a/packages/web3-eth/test/unit/rpc_method_wrappers/get_transaction.test.ts +++ b/packages/web3-eth/test/unit/rpc_method_wrappers/get_transaction.test.ts @@ -21,7 +21,7 @@ import { ethRpcMethods } from 'web3-rpc-methods'; import { getTransaction } from '../../../src/rpc_method_wrappers'; import { mockRpcResponse, testData } from './fixtures/get_transaction'; -import { formatTransaction } from '../../../src'; +import { formatTransaction, transactionInfoSchema } from '../../../src'; jest.mock('web3-rpc-methods'); @@ -57,6 +57,7 @@ describe('getTransaction', () => { const expectedFormattedResult = formatTransaction( mockRpcResponse, expectedReturnFormat, + { transactionSchema: transactionInfoSchema }, ); (ethRpcMethods.getTransactionByHash as jest.Mock).mockResolvedValueOnce( mockRpcResponse, diff --git a/packages/web3-eth/test/unit/rpc_method_wrappers/get_transaction_from_block.test.ts b/packages/web3-eth/test/unit/rpc_method_wrappers/get_transaction_from_block.test.ts index 08c93b1786a..4ae40862e02 100644 --- a/packages/web3-eth/test/unit/rpc_method_wrappers/get_transaction_from_block.test.ts +++ b/packages/web3-eth/test/unit/rpc_method_wrappers/get_transaction_from_block.test.ts @@ -22,7 +22,7 @@ import { ethRpcMethods } from 'web3-rpc-methods'; import { getTransactionFromBlock } from '../../../src/rpc_method_wrappers'; import { mockRpcResponse, testData } from './fixtures/get_transaction_from_block'; -import { formatTransaction } from '../../../src'; +import { formatTransaction, transactionInfoSchema } from '../../../src'; jest.mock('web3-rpc-methods'); @@ -75,6 +75,7 @@ describe('getTransactionFromBlock', () => { const expectedFormattedResult = formatTransaction( mockRpcResponse, expectedReturnFormat, + { transactionSchema: transactionInfoSchema }, ); const inputBlockIsBytes = isBytes(inputBlock as Bytes); ( diff --git a/packages/web3-types/CHANGELOG.md b/packages/web3-types/CHANGELOG.md index 5c00227f343..675596642a1 100644 --- a/packages/web3-types/CHANGELOG.md +++ b/packages/web3-types/CHANGELOG.md @@ -79,3 +79,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `safe` and `finalized` block tags in `BlockTags` and `BlockTag` types (#5823) ## [Unreleased] + +### Changed + +- `data` property in `TransactionOutput` was renamed to `input` (#5915) diff --git a/packages/web3-types/src/eth_types.ts b/packages/web3-types/src/eth_types.ts index 3115d96c99c..dcacfba0048 100644 --- a/packages/web3-types/src/eth_types.ts +++ b/packages/web3-types/src/eth_types.ts @@ -81,7 +81,7 @@ export type TransactionOutput = { readonly [key: string]: unknown; readonly to?: HexString; // If its a contract creation tx then no address wil be specified. readonly from?: HexString; - readonly data: string; + readonly input: string; readonly gas?: Numbers; readonly gasLimit?: string; readonly nonce: Numbers; @@ -372,7 +372,7 @@ export interface PopulatedUnsignedBaseTransaction { gas?: Numbers; gasPrice: Numbers; type: Numbers; - data: Bytes; + input: Bytes; nonce: Numbers; networkId: Numbers; chain: ValidChains; diff --git a/tools/web3-plugin-example/test/unit/contract_method_wrappers.test.ts b/tools/web3-plugin-example/test/unit/contract_method_wrappers.test.ts index 84732bb2b7d..7de66b31ec8 100644 --- a/tools/web3-plugin-example/test/unit/contract_method_wrappers.test.ts +++ b/tools/web3-plugin-example/test/unit/contract_method_wrappers.test.ts @@ -68,7 +68,7 @@ describe('CustomRpcMethodsPlugin Tests', () => { method: 'eth_call', params: [ { - data: '0x70a082310000000000000000000000008da5e39ec14b57fb9bcd9aa2b4500e909119795d', + input: '0x70a082310000000000000000000000008da5e39ec14b57fb9bcd9aa2b4500e909119795d', to: '0xdAC17F958D2ee523a2206206994597C13D831ec7', }, 'latest', @@ -101,7 +101,7 @@ describe('CustomRpcMethodsPlugin Tests', () => { method: 'eth_sendTransaction', params: [ { - data: '0xa9059cbb0000000000000000000000004f641def1e7845caab95ac717c80416082430d0d000000000000000000000000000000000000000000000000000000000000002a', + input: '0xa9059cbb0000000000000000000000004f641def1e7845caab95ac717c80416082430d0d000000000000000000000000000000000000000000000000000000000000002a', from: sender, gasPrice: expectedGasPrice, maxFeePerGas: undefined,