Socket
Socket
Sign inDemoInstall

@ethereumjs/tx

Package Overview
Dependencies
53
Maintainers
3
Versions
37
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 4.0.2 to 4.1.0

dist/constants.d.ts

3

dist/index.d.ts
export { FeeMarketEIP1559Transaction } from './eip1559Transaction';
export { AccessListEIP2930Transaction } from './eip2930Transaction';
export { BlobEIP4844Transaction } from './eip4844Transaction';
export { initKZG, kzg } from './kzg/kzg';
export { Transaction } from './legacyTransaction';
export { TransactionFactory } from './transactionFactory';
export * from './types';
export { computeVersionedHash } from './utils/blobHelpers';
//# sourceMappingURL=index.d.ts.map

@@ -17,3 +17,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.TransactionFactory = exports.Transaction = exports.AccessListEIP2930Transaction = exports.FeeMarketEIP1559Transaction = void 0;
exports.computeVersionedHash = exports.TransactionFactory = exports.Transaction = exports.kzg = exports.initKZG = exports.BlobEIP4844Transaction = exports.AccessListEIP2930Transaction = exports.FeeMarketEIP1559Transaction = void 0;
var eip1559Transaction_1 = require("./eip1559Transaction");

@@ -23,2 +23,7 @@ Object.defineProperty(exports, "FeeMarketEIP1559Transaction", { enumerable: true, get: function () { return eip1559Transaction_1.FeeMarketEIP1559Transaction; } });

Object.defineProperty(exports, "AccessListEIP2930Transaction", { enumerable: true, get: function () { return eip2930Transaction_1.AccessListEIP2930Transaction; } });
var eip4844Transaction_1 = require("./eip4844Transaction");
Object.defineProperty(exports, "BlobEIP4844Transaction", { enumerable: true, get: function () { return eip4844Transaction_1.BlobEIP4844Transaction; } });
var kzg_1 = require("./kzg/kzg");
Object.defineProperty(exports, "initKZG", { enumerable: true, get: function () { return kzg_1.initKZG; } });
Object.defineProperty(exports, "kzg", { enumerable: true, get: function () { return kzg_1.kzg; } });
var legacyTransaction_1 = require("./legacyTransaction");

@@ -29,2 +34,4 @@ Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return legacyTransaction_1.Transaction; } });

__exportStar(require("./types"), exports);
var blobHelpers_1 = require("./utils/blobHelpers");
Object.defineProperty(exports, "computeVersionedHash", { enumerable: true, get: function () { return blobHelpers_1.computeVersionedHash; } });
//# sourceMappingURL=index.js.map

8

dist/transactionFactory.d.ts
/// <reference types="node" />
import { ethers } from 'ethers';
import type { AccessListEIP2930TxData, FeeMarketEIP1559TxData, TxData, TxOptions, TypedTransaction } from './types';
import { JsonRpcProvider } from '@ethersproject/providers';
import type { AccessListEIP2930TxData, BlobEIP4844TxData, FeeMarketEIP1559TxData, TxData, TxOptions, TypedTransaction } from './types';
export declare class TransactionFactory {

@@ -12,3 +12,3 @@ private constructor();

*/
static fromTxData(txData: TxData | AccessListEIP2930TxData | FeeMarketEIP1559TxData, txOptions?: TxOptions): TypedTransaction;
static fromTxData(txData: TxData | AccessListEIP2930TxData | FeeMarketEIP1559TxData | BlobEIP4844TxData, txOptions?: TxOptions): TypedTransaction;
/**

@@ -38,4 +38,4 @@ * This method tries to decode serialized data.

*/
static fromEthersProvider(provider: string | ethers.providers.JsonRpcProvider, txHash: string, txOptions?: TxOptions): Promise<TypedTransaction>;
static fromEthersProvider(provider: string | JsonRpcProvider, txHash: string, txOptions?: TxOptions): Promise<TypedTransaction>;
}
//# sourceMappingURL=transactionFactory.d.ts.map

@@ -5,5 +5,6 @@ "use strict";

const util_1 = require("@ethereumjs/util");
const ethers_1 = require("ethers");
const providers_1 = require("@ethersproject/providers");
const eip1559Transaction_1 = require("./eip1559Transaction");
const eip2930Transaction_1 = require("./eip2930Transaction");
const eip4844Transaction_1 = require("./eip4844Transaction");
const fromRpc_1 = require("./fromRpc");

@@ -36,2 +37,5 @@ const legacyTransaction_1 = require("./legacyTransaction");

}
else if (txType === 5) {
return eip4844Transaction_1.BlobEIP4844Transaction.fromTxData(txData, txOptions);
}
else {

@@ -51,20 +55,12 @@ throw new Error(`Tx instantiation with type ${txType} not supported`);

// Determine the type.
let EIP;
switch (data[0]) {
case 1:
EIP = 2930;
break;
return eip2930Transaction_1.AccessListEIP2930Transaction.fromSerializedTx(data, txOptions);
case 2:
EIP = 1559;
break;
return eip1559Transaction_1.FeeMarketEIP1559Transaction.fromSerializedTx(data, txOptions);
case 5:
return eip4844Transaction_1.BlobEIP4844Transaction.fromSerializedTx(data, txOptions);
default:
throw new Error(`TypedTransaction with ID ${data[0]} unknown`);
}
if (EIP === 1559) {
return eip1559Transaction_1.FeeMarketEIP1559Transaction.fromSerializedTx(data, txOptions);
}
else {
// EIP === 2930
return eip2930Transaction_1.AccessListEIP2930Transaction.fromSerializedTx(data, txOptions);
}
}

@@ -104,3 +100,3 @@ else {

static async fromEthersProvider(provider, txHash, txOptions) {
const prov = typeof provider === 'string' ? new ethers_1.ethers.providers.JsonRpcProvider(provider) : provider;
const prov = typeof provider === 'string' ? new providers_1.JsonRpcProvider(provider) : provider;
const txData = await prov.send('eth_getTransactionByHash', [txHash]);

@@ -107,0 +103,0 @@ const normedTx = (0, fromRpc_1.normalizeTxParams)(txData);

/// <reference types="node" />
import { BooleanType, ByteListType, ByteVectorType, ContainerType, ListCompositeType, NoneType, UintBigintType, UnionType } from '@chainsafe/ssz';
import type { FeeMarketEIP1559Transaction } from './eip1559Transaction';
import type { AccessListEIP2930Transaction } from './eip2930Transaction';
import type { BlobEIP4844Transaction } from './eip4844Transaction';
import type { Transaction } from './legacyTransaction';

@@ -76,3 +78,3 @@ import type { Common } from '@ethereumjs/common';

*/
export declare type TypedTransaction = Transaction | AccessListEIP2930Transaction | FeeMarketEIP1559Transaction;
export declare type TypedTransaction = Transaction | AccessListEIP2930Transaction | FeeMarketEIP1559Transaction | BlobEIP4844Transaction;
/**

@@ -89,3 +91,3 @@ * Legacy {@link Transaction} Data

*/
gasPrice?: BigIntLike;
gasPrice?: BigIntLike | null;
/**

@@ -135,3 +137,3 @@ * The transaction's gas limit.

*/
accessList?: AccessListBuffer | AccessList;
accessList?: AccessListBuffer | AccessList | null;
}

@@ -146,3 +148,3 @@ /**

*/
gasPrice?: never;
gasPrice?: never | null;
/**

@@ -158,2 +160,27 @@ * The maximum inclusion fee per gas (this fee is given to the miner)

/**
* {@link BlobEIP4844Transaction} data.
*/
export interface BlobEIP4844TxData extends FeeMarketEIP1559TxData {
/**
* The versioned hashes used to validate the blobs attached to a transaction
*/
versionedHashes?: BufferLike[];
/**
* The maximum fee per data gas paid for the transaction
*/
maxFeePerDataGas?: BigIntLike;
/**
* The blobs associated with a transaction
*/
blobs?: BufferLike[];
/**
* The KZG commitments corresponding to the versioned hashes for each blob
*/
kzgCommitments?: BufferLike[];
/**
* The aggregate KZG proof associated with the transaction
*/
kzgProof?: BufferLike;
}
/**
* Buffer values array for a legacy {@link Transaction}

@@ -222,2 +249,4 @@ */

maxFeePerGas?: string;
maxFeePerDataGas?: string;
versionedHashes?: string[];
}

@@ -244,4 +273,86 @@ export interface JsonRpcTx {

s: string;
maxFeePerDataGas?: string;
versionedHashes?: string[];
}
/** EIP4844 types */
export declare const AddressType: ByteVectorType;
export declare const AccessTupleType: ContainerType<{
address: ByteVectorType;
storageKeys: ListCompositeType<ByteVectorType>;
}>;
export declare const BlobTransactionType: ContainerType<{
chainId: UintBigintType;
nonce: UintBigintType;
maxPriorityFeePerGas: UintBigintType;
maxFeePerGas: UintBigintType;
gas: UintBigintType;
to: UnionType<(ByteVectorType | NoneType)[]>;
value: UintBigintType;
data: ByteListType;
accessList: ListCompositeType<ContainerType<{
address: ByteVectorType;
storageKeys: ListCompositeType<ByteVectorType>;
}>>;
maxFeePerDataGas: UintBigintType;
blobVersionedHashes: ListCompositeType<ByteVectorType>;
}>;
export declare const ECDSASignatureType: ContainerType<{
yParity: BooleanType;
r: UintBigintType;
s: UintBigintType;
}>;
export declare const SignedBlobTransactionType: ContainerType<{
message: ContainerType<{
chainId: UintBigintType;
nonce: UintBigintType;
maxPriorityFeePerGas: UintBigintType;
maxFeePerGas: UintBigintType;
gas: UintBigintType;
to: UnionType<(ByteVectorType | NoneType)[]>;
value: UintBigintType;
data: ByteListType;
accessList: ListCompositeType<ContainerType<{
address: ByteVectorType;
storageKeys: ListCompositeType<ByteVectorType>;
}>>;
maxFeePerDataGas: UintBigintType;
blobVersionedHashes: ListCompositeType<ByteVectorType>;
}>;
signature: ContainerType<{
yParity: BooleanType;
r: UintBigintType;
s: UintBigintType;
}>;
}>;
export declare const KZGCommitmentType: ByteVectorType;
export declare const KZGProofType: ByteVectorType;
export declare const BlobNetworkTransactionWrapper: ContainerType<{
tx: ContainerType<{
message: ContainerType<{
chainId: UintBigintType;
nonce: UintBigintType;
maxPriorityFeePerGas: UintBigintType;
maxFeePerGas: UintBigintType;
gas: UintBigintType;
to: UnionType<(ByteVectorType | NoneType)[]>;
value: UintBigintType;
data: ByteListType;
accessList: ListCompositeType<ContainerType<{
address: ByteVectorType;
storageKeys: ListCompositeType<ByteVectorType>;
}>>;
maxFeePerDataGas: UintBigintType;
blobVersionedHashes: ListCompositeType<ByteVectorType>;
}>;
signature: ContainerType<{
yParity: BooleanType;
r: UintBigintType;
s: UintBigintType;
}>;
}>;
blobKzgs: ListCompositeType<ByteVectorType>;
blobs: ListCompositeType<ByteVectorType>;
kzgAggregatedProof: ByteVectorType;
}>;
export {};
//# sourceMappingURL=types.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isAccessList = exports.isAccessListBuffer = exports.Capability = void 0;
exports.BlobNetworkTransactionWrapper = exports.KZGProofType = exports.KZGCommitmentType = exports.SignedBlobTransactionType = exports.ECDSASignatureType = exports.BlobTransactionType = exports.AccessTupleType = exports.AddressType = exports.isAccessList = exports.isAccessListBuffer = exports.Capability = void 0;
const ssz_1 = require("@chainsafe/ssz");
const constants_1 = require("./constants");
const Bytes20 = new ssz_1.ByteVectorType(20);
const Bytes32 = new ssz_1.ByteVectorType(32);
const Bytes48 = new ssz_1.ByteVectorType(48);
const Uint64 = new ssz_1.UintBigintType(8);
const Uint256 = new ssz_1.UintBigintType(32);
/**

@@ -46,2 +53,44 @@ * Can be used in conjunction with {@link Transaction.supports}

exports.isAccessList = isAccessList;
/** EIP4844 types */
exports.AddressType = Bytes20; // SSZ encoded address
// SSZ encoded container for address and storage keys
exports.AccessTupleType = new ssz_1.ContainerType({
address: exports.AddressType,
storageKeys: new ssz_1.ListCompositeType(Bytes32, constants_1.MAX_VERSIONED_HASHES_LIST_SIZE),
});
// SSZ encoded blob transaction
exports.BlobTransactionType = new ssz_1.ContainerType({
chainId: Uint256,
nonce: Uint64,
maxPriorityFeePerGas: Uint256,
maxFeePerGas: Uint256,
gas: Uint64,
to: new ssz_1.UnionType([new ssz_1.NoneType(), exports.AddressType]),
value: Uint256,
data: new ssz_1.ByteListType(constants_1.MAX_CALLDATA_SIZE),
accessList: new ssz_1.ListCompositeType(exports.AccessTupleType, constants_1.MAX_ACCESS_LIST_SIZE),
maxFeePerDataGas: Uint256,
blobVersionedHashes: new ssz_1.ListCompositeType(Bytes32, constants_1.MAX_VERSIONED_HASHES_LIST_SIZE),
});
// SSZ encoded ECDSA Signature
exports.ECDSASignatureType = new ssz_1.ContainerType({
yParity: new ssz_1.BooleanType(),
r: Uint256,
s: Uint256,
});
// SSZ encoded signed blob transaction
exports.SignedBlobTransactionType = new ssz_1.ContainerType({
message: exports.BlobTransactionType,
signature: exports.ECDSASignatureType,
});
// SSZ encoded KZG Commitment/Proof (48 bytes)
exports.KZGCommitmentType = Bytes48;
exports.KZGProofType = exports.KZGCommitmentType;
// SSZ encoded blob network transaction wrapper
exports.BlobNetworkTransactionWrapper = new ssz_1.ContainerType({
tx: exports.SignedBlobTransactionType,
blobKzgs: new ssz_1.ListCompositeType(exports.KZGCommitmentType, constants_1.MAX_TX_WRAP_KZG_COMMITMENTS),
blobs: new ssz_1.ListCompositeType(new ssz_1.ByteVectorType(constants_1.FIELD_ELEMENTS_PER_BLOB * constants_1.BYTES_PER_FIELD_ELEMENT), constants_1.LIMIT_BLOBS_PER_TX),
kzgAggregatedProof: exports.KZGProofType,
});
//# sourceMappingURL=types.js.map

@@ -0,1 +1,3 @@

/// <reference types="node" />
import type { BlobEIP4844Transaction } from './eip4844Transaction';
import type { AccessList, AccessListBuffer } from './types';

@@ -13,2 +15,28 @@ import type { Common } from '@ethereumjs/common';

}
export declare const blobTxToNetworkWrapperDataFormat: (tx: BlobEIP4844Transaction) => {
message: {
chainId: bigint;
nonce: bigint;
maxPriorityFeePerGas: bigint;
maxFeePerGas: bigint;
gas: bigint;
to: {
selector: number;
value: Buffer | null;
};
value: bigint;
data: Buffer;
accessList: {
address: Buffer;
storageKeys: Buffer[];
}[];
blobVersionedHashes: Buffer[];
maxFeePerDataGas: bigint;
};
signature: {
r: bigint;
s: bigint;
yParity: boolean;
};
};
//# sourceMappingURL=util.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AccessLists = exports.checkMaxInitCodeSize = void 0;
exports.blobTxToNetworkWrapperDataFormat = exports.AccessLists = exports.checkMaxInitCodeSize = void 0;
const util_1 = require("@ethereumjs/util");

@@ -104,2 +104,32 @@ const types_1 = require("./types");

exports.AccessLists = AccessLists;
const blobTxToNetworkWrapperDataFormat = (tx) => {
const to = {
selector: tx.to !== undefined ? 1 : 0,
value: tx.to?.toBuffer() ?? null,
};
return {
message: {
chainId: tx.common.chainId(),
nonce: tx.nonce,
maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
maxFeePerGas: tx.maxFeePerGas,
gas: tx.gasLimit,
to,
value: tx.value,
data: tx.data,
accessList: tx.accessList.map((listItem) => {
return { address: listItem[0], storageKeys: listItem[1] };
}),
blobVersionedHashes: tx.versionedHashes,
maxFeePerDataGas: tx.maxFeePerDataGas,
},
// If transaction is unsigned, signature fields will be initialized to zeroes
signature: {
r: tx.r ?? BigInt(0),
s: tx.s ?? BigInt(0),
yParity: tx.v === BigInt(1) ? true : false,
},
};
};
exports.blobTxToNetworkWrapperDataFormat = blobTxToNetworkWrapperDataFormat;
//# sourceMappingURL=util.js.map
{
"name": "@ethereumjs/tx",
"version": "4.0.2",
"version": "4.1.0",
"description": "A simple module for creating, manipulating and signing Ethereum transactions",

@@ -37,3 +37,3 @@ "keywords": [

"scripts": {
"build": "../../config/cli/ts-build.sh",
"build": "../../config/cli/ts-build.sh && mkdir -p dist/kzg && cp ./src/kzg/* ./dist/kzg",
"clean": "../../config/cli/clean-package.sh",

@@ -55,8 +55,17 @@ "coverage": "../../config/cli/coverage.sh",

"dependencies": {
"@ethereumjs/common": "^3.0.2",
"@ethereumjs/rlp": "^4.0.0",
"@ethereumjs/util": "^8.0.3",
"@chainsafe/ssz": "^0.9.2",
"@ethereumjs/common": "^3.1.0",
"@ethereumjs/rlp": "^4.0.1",
"@ethereumjs/util": "^8.0.4",
"ethereum-cryptography": "^1.1.2",
"ethers": "^5.7.1"
"@ethersproject/providers": "^5.7.2"
},
"peerDependencies": {
"c-kzg": "^1.0.8"
},
"peerDependenciesMeta": {
"c-kzg": {
"optional": true
}
},
"devDependencies": {

@@ -63,0 +72,0 @@ "@types/minimist": "^1.2.0",

@@ -16,2 +16,4 @@ # @ethereumjs/tx

### General
To obtain the latest version, simply require the project using `npm`:

@@ -23,2 +25,27 @@

### KZG Setup
This library supports an experimental version of `EIP-4844` blob transactions (see usage instructions below) starting with `v4.1.0`.
For blob transactions and other KZG related proof functionality (e.g. for EVM precompiles) KZG has to be manually installed and initialized once in a global scope. The functionality is then available for all KZG usages throughout different libraries (Transaction, Block, EVM).
#### Manual Installation
The following two manual installation steps for a KZG library and the trusted setup are needed.
1. Install an additional dependency that supports the `kzg` interface defined in [the kzg interface](./src/kzg/kzg.ts). You can install the default option [c-kzg](https://github.com/ethereum/c-kzg-4844) by simply running `npm install c-kzg`.
2. Download the trusted setup required for the KZG module. It can be found [here](../client/lib/trustedSetups/trusted_setup.txt) within the client package.
#### Global Initialization
Global initialization can then be done like this (using the `c-kzg` module for our KZG dependency):
```typescript
// Make the kzg library available globally
import * as kzg from 'c-kzg'
// Initialize the trusted setup
initKZG(kzg, 'path/to/my/trusted_setup.txt')
```
## Usage

@@ -40,3 +67,3 @@

The `Transaction` constructor receives a parameter of an [`@ethereumjs/common`](https://github.com/ethereumjs/ethereumjs-monorepo/blob/master/packages/common) object that lets you specify the chain and hardfork to be used. If there is no `Common` provided the chain ID provided as a paramter on typed tx or the chain ID derived from the `v` value on signed EIP-155 conforming legacy txs will be taken (introduced in `v3.2.1`). In other cases the chain defaults to `mainnet`.
The `Transaction` constructor receives a parameter of an [`@ethereumjs/common`](https://github.com/ethereumjs/ethereumjs-monorepo/blob/master/packages/common) object that lets you specify the chain and hardfork to be used. If there is no `Common` provided the chain ID provided as a parameter on typed tx or the chain ID derived from the `v` value on signed EIP-155 conforming legacy txs will be taken (introduced in `v3.2.1`). In other cases the chain defaults to `mainnet`.

@@ -47,11 +74,11 @@ Base default HF (determined by `Common`): `merge`

Supported Hardforks:
Hardforks adding features and/or tx types:
| Hardfork | Introduced | Description |
| ---------------- | ---------- | ------------------------------------------------------------------------------------------------------- |
| `spuriousDragon` |  `v2.0.0` |  `EIP-155` replay protection (disable by setting HF pre-`spuriousDragon`) |
| `istanbul` |  `v2.1.1`  | Support for reduced non-zero call data gas prices ([EIP-2028](https://eips.ethereum.org/EIPS/eip-2028)) |
| `muirGlacier` |  `v2.1.2` |  - |
| `berlin` | `v3.1.0` |  `EIP-2718` Typed Transactions, Optional Access Lists Tx Type `EIP-2930` |
| `london` | `v3.2.0` | `EIP-1559` Transactions |
| `berlin` | `v3.1.0` |  `EIP-2718` Typed Transactions, Optional Access Lists Tx Type `EIP-2930` |
| `muirGlacier` |  `v2.1.2` |  - |
| `istanbul` |  `v2.1.1`  | Support for reduced non-zero call data gas prices ([EIP-2028](https://eips.ethereum.org/EIPS/eip-2028)) |
| `spuriousDragon` |  `v2.0.0` |  `EIP-155` replay protection (disable by setting HF pre-`spuriousDragon`) |

@@ -72,2 +99,3 @@ ### Standalone EIPs

- `BlobEIP4844Transaction` ([EIP-4844](https://eips.ethereumorg/EIPS/eip-4844), proto-danksharding)
- `FeeMarketEIP1559Transaction` ([EIP-1559](https://eips.ethereum.org/EIPS/eip-1559), gas fee market)

@@ -77,2 +105,51 @@ - `AccessListEIP2930Transaction` ([EIP-2930](https://eips.ethereum.org/EIPS/eip-2930), optional access lists)

#### Blob Transactions (EIP-4844)
- Class: `BlobEIP4844Transaction`
- Activation: `sharding`
- Type: `5`
This library supports an experimental version of the blob transaction type introduced with [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) as being specified in the [01d3209](https://github.com/ethereum/EIPs/commit/01d320998d1d53d95f347b5f43feaf606f230703) EIP version from February 8, 2023 and deployed along `eip4844-devnet-4` (January 2023), see PR [#2349](https://github.com/ethereumjs/ethereumjs-monorepo/pull/2349).
**Note:** This functionality needs a manual KZG library installation and global initialization, see [KZG Setup](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/tx/README.md#kzg-setup) for instructions.
##### Usage
See the following code snipped for an example on how to instantiate (using the `c-kzg` module for our KZG dependency).
```typescript
import { Chain, Common, Hardfork } from '@ethereumjs/common'
import { BlobEIP4844Transaction, initKZG } from '@ethereumjs/tx'
import * as kzg from 'c-kzg'
initKZG(kzg, 'path/to/my/trusted_setup.txt')
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Shanghai, eips: [4844] })
const txData = {
data: '0x1a8451e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
gasLimit: '0x02625a00',
maxPriorityFeePerGas: '0x01',
maxFeePerGas: '0xff',
maxFeePerDataGas: '0xfff',
nonce: '0x00',
to: '0xcccccccccccccccccccccccccccccccccccccccc',
value: '0x0186a0',
v: '0x01',
r: '0xafb6e247b1c490e284053c87ab5f6b59e219d51f743f7a4d83e400782bc7e4b9',
s: '0x479a268e0e0acd4de3f1e28e4fac2a6b32a4195e8dfa9d19147abe8807aa6f64',
chainId: '0x01',
accessList: [],
type: '0x05',
versionedHashes: ['0xabc...'], // Test with empty array on a first run
kzgCommitments: ['0xdef...'], // Test with empty array on a first run
blobs: ['0xghi...'], // Test with empty array on a first run
}
const tx = BlobEIP4844Transaction.fromTxData(txData, { common })
```
Note that `versionedHashes` and `kzgCommitments` have a real length of 32 bytes and `blobs` have a real length of `4096` bytes and values are trimmed here for brevity.
See the [Blob Transaction Tests](./test/eip4844.spec.ts) for examples of usage in instantiating, serializing, and deserializing these transactions.
#### Gas Fee Market Transactions (EIP-1559)

@@ -245,3 +322,3 @@

The following L2 networks have been tested to work with `@ethereumjs/tx`, see usage examples as well as some notes on pecularities in the issues linked below:
The following L2 networks have been tested to work with `@ethereumjs/tx`, see usage examples as well as some notes on peculiarities in the issues linked below:

@@ -248,0 +325,0 @@ |  L2 Network |  Common name |  Issue |

export { FeeMarketEIP1559Transaction } from './eip1559Transaction'
export { AccessListEIP2930Transaction } from './eip2930Transaction'
export { BlobEIP4844Transaction } from './eip4844Transaction'
export { initKZG, kzg } from './kzg/kzg'
export { Transaction } from './legacyTransaction'
export { TransactionFactory } from './transactionFactory'
export * from './types'
export { computeVersionedHash } from './utils/blobHelpers'
import { bufferToBigInt, toBuffer } from '@ethereumjs/util'
import { ethers } from 'ethers'
import { JsonRpcProvider } from '@ethersproject/providers'
import { FeeMarketEIP1559Transaction } from './eip1559Transaction'
import { AccessListEIP2930Transaction } from './eip2930Transaction'
import { BlobEIP4844Transaction } from './eip4844Transaction'
import { normalizeTxParams } from './fromRpc'

@@ -11,2 +12,3 @@ import { Transaction } from './legacyTransaction'

AccessListEIP2930TxData,
BlobEIP4844TxData,
FeeMarketEIP1559TxData,

@@ -29,3 +31,3 @@ TxData,

public static fromTxData(
txData: TxData | AccessListEIP2930TxData | FeeMarketEIP1559TxData,
txData: TxData | AccessListEIP2930TxData | FeeMarketEIP1559TxData | BlobEIP4844TxData,
txOptions: TxOptions = {}

@@ -44,2 +46,4 @@ ): TypedTransaction {

return FeeMarketEIP1559Transaction.fromTxData(<FeeMarketEIP1559TxData>txData, txOptions)
} else if (txType === 5) {
return BlobEIP4844Transaction.fromTxData(<BlobEIP4844TxData>txData, txOptions)
} else {

@@ -60,19 +64,12 @@ throw new Error(`Tx instantiation with type ${txType} not supported`)

// Determine the type.
let EIP: number
switch (data[0]) {
case 1:
EIP = 2930
break
return AccessListEIP2930Transaction.fromSerializedTx(data, txOptions)
case 2:
EIP = 1559
break
return FeeMarketEIP1559Transaction.fromSerializedTx(data, txOptions)
case 5:
return BlobEIP4844Transaction.fromSerializedTx(data, txOptions)
default:
throw new Error(`TypedTransaction with ID ${data[0]} unknown`)
}
if (EIP === 1559) {
return FeeMarketEIP1559Transaction.fromSerializedTx(data, txOptions)
} else {
// EIP === 2930
return AccessListEIP2930Transaction.fromSerializedTx(data, txOptions)
}
} else {

@@ -111,8 +108,7 @@ return Transaction.fromSerializedTx(data, txOptions)

public static async fromEthersProvider(
provider: string | ethers.providers.JsonRpcProvider,
provider: string | JsonRpcProvider,
txHash: string,
txOptions?: TxOptions
) {
const prov =
typeof provider === 'string' ? new ethers.providers.JsonRpcProvider(provider) : provider
const prov = typeof provider === 'string' ? new JsonRpcProvider(provider) : provider
const txData = await prov.send('eth_getTransactionByHash', [txHash])

@@ -119,0 +115,0 @@ const normedTx = normalizeTxParams(txData)

@@ -0,3 +1,25 @@

import {
BooleanType,
ByteListType,
ByteVectorType,
ContainerType,
ListCompositeType,
NoneType,
UintBigintType,
UnionType,
} from '@chainsafe/ssz'
import {
BYTES_PER_FIELD_ELEMENT,
FIELD_ELEMENTS_PER_BLOB,
LIMIT_BLOBS_PER_TX,
MAX_ACCESS_LIST_SIZE,
MAX_CALLDATA_SIZE,
MAX_TX_WRAP_KZG_COMMITMENTS,
MAX_VERSIONED_HASHES_LIST_SIZE,
} from './constants'
import type { FeeMarketEIP1559Transaction } from './eip1559Transaction'
import type { AccessListEIP2930Transaction } from './eip2930Transaction'
import type { BlobEIP4844Transaction } from './eip4844Transaction'
import type { Transaction } from './legacyTransaction'

@@ -7,2 +29,9 @@ import type { Common } from '@ethereumjs/common'

const Bytes20 = new ByteVectorType(20)
const Bytes32 = new ByteVectorType(32)
const Bytes48 = new ByteVectorType(48)
const Uint64 = new UintBigintType(8)
const Uint256 = new UintBigintType(32)
/**

@@ -110,2 +139,3 @@ * Can be used in conjunction with {@link Transaction.supports}

| FeeMarketEIP1559Transaction
| BlobEIP4844Transaction

@@ -124,3 +154,3 @@ /**

*/
gasPrice?: BigIntLike
gasPrice?: BigIntLike | null

@@ -181,3 +211,3 @@ /**

*/
accessList?: AccessListBuffer | AccessList
accessList?: AccessListBuffer | AccessList | null
}

@@ -193,3 +223,3 @@

*/
gasPrice?: never
gasPrice?: never | null
/**

@@ -206,2 +236,28 @@ * The maximum inclusion fee per gas (this fee is given to the miner)

/**
* {@link BlobEIP4844Transaction} data.
*/
export interface BlobEIP4844TxData extends FeeMarketEIP1559TxData {
/**
* The versioned hashes used to validate the blobs attached to a transaction
*/
versionedHashes?: BufferLike[]
/**
* The maximum fee per data gas paid for the transaction
*/
maxFeePerDataGas?: BigIntLike
/**
* The blobs associated with a transaction
*/
blobs?: BufferLike[]
/**
* The KZG commitments corresponding to the versioned hashes for each blob
*/
kzgCommitments?: BufferLike[]
/**
* The aggregate KZG proof associated with the transaction
*/
kzgProof?: BufferLike
}
/**
* Buffer values array for a legacy {@link Transaction}

@@ -271,2 +327,4 @@ */

maxFeePerGas?: string
maxFeePerDataGas?: string
versionedHashes?: string[]
}

@@ -297,2 +355,56 @@

s: string // DATA, 32 Bytes - ECDSA signature s
maxFeePerDataGas?: string // QUANTITY - max data fee for blob transactions
versionedHashes?: string[] // DATA - array of 32 byte versioned hashes for blob transactions
}
/** EIP4844 types */
export const AddressType = Bytes20 // SSZ encoded address
// SSZ encoded container for address and storage keys
export const AccessTupleType = new ContainerType({
address: AddressType,
storageKeys: new ListCompositeType(Bytes32, MAX_VERSIONED_HASHES_LIST_SIZE),
})
// SSZ encoded blob transaction
export const BlobTransactionType = new ContainerType({
chainId: Uint256,
nonce: Uint64,
maxPriorityFeePerGas: Uint256,
maxFeePerGas: Uint256,
gas: Uint64,
to: new UnionType([new NoneType(), AddressType]),
value: Uint256,
data: new ByteListType(MAX_CALLDATA_SIZE),
accessList: new ListCompositeType(AccessTupleType, MAX_ACCESS_LIST_SIZE),
maxFeePerDataGas: Uint256,
blobVersionedHashes: new ListCompositeType(Bytes32, MAX_VERSIONED_HASHES_LIST_SIZE),
})
// SSZ encoded ECDSA Signature
export const ECDSASignatureType = new ContainerType({
yParity: new BooleanType(),
r: Uint256,
s: Uint256,
})
// SSZ encoded signed blob transaction
export const SignedBlobTransactionType = new ContainerType({
message: BlobTransactionType,
signature: ECDSASignatureType,
})
// SSZ encoded KZG Commitment/Proof (48 bytes)
export const KZGCommitmentType = Bytes48
export const KZGProofType = KZGCommitmentType
// SSZ encoded blob network transaction wrapper
export const BlobNetworkTransactionWrapper = new ContainerType({
tx: SignedBlobTransactionType,
blobKzgs: new ListCompositeType(KZGCommitmentType, MAX_TX_WRAP_KZG_COMMITMENTS),
blobs: new ListCompositeType(
new ByteVectorType(FIELD_ELEMENTS_PER_BLOB * BYTES_PER_FIELD_ELEMENT),
LIMIT_BLOBS_PER_TX
),
kzgAggregatedProof: KZGProofType,
})

@@ -5,2 +5,3 @@ import { bufferToHex, setLengthLeft, toBuffer } from '@ethereumjs/util'

import type { BlobEIP4844Transaction } from './eip4844Transaction'
import type { AccessList, AccessListBuffer, AccessListItem } from './types'

@@ -119,1 +120,31 @@ import type { Common } from '@ethereumjs/common'

}
export const blobTxToNetworkWrapperDataFormat = (tx: BlobEIP4844Transaction) => {
const to = {
selector: tx.to !== undefined ? 1 : 0,
value: tx.to?.toBuffer() ?? null,
}
return {
message: {
chainId: tx.common.chainId(),
nonce: tx.nonce,
maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
maxFeePerGas: tx.maxFeePerGas,
gas: tx.gasLimit,
to,
value: tx.value,
data: tx.data,
accessList: tx.accessList.map((listItem) => {
return { address: listItem[0], storageKeys: listItem[1] }
}),
blobVersionedHashes: tx.versionedHashes,
maxFeePerDataGas: tx.maxFeePerDataGas,
},
// If transaction is unsigned, signature fields will be initialized to zeroes
signature: {
r: tx.r ?? BigInt(0),
s: tx.s ?? BigInt(0),
yParity: tx.v === BigInt(1) ? true : false,
},
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc