@ethereumjs/tx
Advanced tools
Comparing version 3.0.2 to 3.1.0
@@ -9,3 +9,65 @@ # Changelog | ||
## 3.1.0 - 2021-03-18 | ||
### Berlin HF Support | ||
This release comes with full support for the `berlin` hardfork by updating the library to support typed transactions ([EIP-2718](https://eips.ethereum.org/EIPS/eip-2718)). The first supported transaction type is the `AccessListEIP2930Transaction` ([EIP-2930](https://eips.ethereum.org/EIPS/eip-2930)) which adds optional access lists to the mix and is activated along with the `berlin` hardfork. | ||
`EIP-2930` transactions can be instantiated with: | ||
```typescript | ||
import Common from '@ethereumjs/common' | ||
import { AccessListEIP2930Transaction } from '@ethereumjs/tx' | ||
const common = new Common({ chain: 'mainnet', hardfork: 'berlin' }) | ||
const txData = { | ||
"data": "0x1a8451e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", | ||
"gasLimit": "0x02625a00", | ||
"gasPrice": "0x01", | ||
"nonce": "0x00", | ||
"to": "0xcccccccccccccccccccccccccccccccccccccccc", | ||
"value": "0x0186a0", | ||
"v": "0x01", | ||
"r": "0xafb6e247b1c490e284053c87ab5f6b59e219d51f743f7a4d83e400782bc7e4b9", | ||
"s": "0x479a268e0e0acd4de3f1e28e4fac2a6b32a4195e8dfa9d19147abe8807aa6f64", | ||
"chainId": "0x01", | ||
"accessList": [ | ||
{ | ||
"address": "0x0000000000000000000000000000000000000101", | ||
"storageKeys": [ | ||
"0x0000000000000000000000000000000000000000000000000000000000000000", | ||
"0x00000000000000000000000000000000000000000000000000000000000060a7" | ||
] | ||
} | ||
], | ||
"type": "0x01" | ||
} | ||
const tx = AccessListEIP2930Transaction.fromTxData(txData, { common }) | ||
``` | ||
Please note that the default HF is still set to `istanbul`. You therefore need to explicitly set the `hardfork` parameter for instantiating a `Transaction` instance with a `berlin` HF activated. | ||
The now called "legacy" transactions are still supported and can be used as before by using the `Transaction` class. If the type of a tx is only known at runtime there is a new `TransactionFactory` class introduced for your convenience. This factory class decides on the tx type based on the input data and uses the corresponding tx type class for instantiation. | ||
For more guidance on how to use the new tx types and the tx factory have a look at the [README](./README.md) of this library which has received an extensive update along with this release. | ||
#### EthereumJS Libraries - Typed Transactions Readiness | ||
If you are using this library in conjunction with other EthereumJS libraries make sure to minimally have the following library versions installed for typed transaction support: | ||
- `@ethereumjs/common` `v2.2.0` | ||
- `@ethereumjs/tx` `v3.1.0` | ||
- `@ethereumjs/block` `v3.2.0` | ||
- `@ethereumjs/blockchain` `v5.2.0` | ||
- `@ethereumjs/vm` `v5.2.0` | ||
### EIP-2718/EIP-2930 Changes | ||
- Base implementation of both EIPs, PR [#1048](https://github.com/ethereumjs/ethereumjs-monorepo/pull/1048) | ||
- Tx Renaming / Improve backwards-compatibility, PR [#1138](https://github.com/ethereumjs/ethereumjs-monorepo/pull/1138) | ||
- Improvements and additional tests, PR [#1141](https://github.com/ethereumjs/ethereumjs-monorepo/pull/1141) | ||
- Further improvements and small fixes, PR [#1144](https://github.com/ethereumjs/ethereumjs-monorepo/pull/1144) | ||
## 3.0.2 - 2021-02-16 | ||
@@ -16,2 +78,3 @@ | ||
- Fixes `tx.isSigned()` always returning true when using the `Tx.fromValuesArray()` static constructor, see PR [#1077](https://github.com/ethereumjs/ethereumjs-monorepo/pull/1077) | ||
- The `Common` instance passed is now copied to avoid side-effects towards the outer common instance on HF updates, PR [#1088](https://github.com/ethereumjs/ethereumjs-monorepo/pull/1088) | ||
@@ -18,0 +81,0 @@ ## 3.0.1 - 2021-01-20 |
@@ -1,2 +0,4 @@ | ||
export { default as Transaction } from './transaction'; | ||
export { default as Transaction } from './legacyTransaction'; | ||
export { default as AccessListEIP2930Transaction } from './eip2930Transaction'; | ||
export { default as TransactionFactory } from './transactionFactory'; | ||
export * from './types'; |
@@ -13,5 +13,9 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var transaction_1 = require("./transaction"); | ||
Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return transaction_1.default; } }); | ||
var legacyTransaction_1 = require("./legacyTransaction"); | ||
Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return legacyTransaction_1.default; } }); | ||
var eip2930Transaction_1 = require("./eip2930Transaction"); | ||
Object.defineProperty(exports, "AccessListEIP2930Transaction", { enumerable: true, get: function () { return eip2930Transaction_1.default; } }); | ||
var transactionFactory_1 = require("./transactionFactory"); | ||
Object.defineProperty(exports, "TransactionFactory", { enumerable: true, get: function () { return transactionFactory_1.default; } }); | ||
__exportStar(require("./types"), exports); | ||
//# sourceMappingURL=index.js.map |
@@ -1,3 +0,7 @@ | ||
import { AddressLike, BNLike, BufferLike } from 'ethereumjs-util'; | ||
/// <reference types="node" /> | ||
/// <reference types="bn.js" /> | ||
import { BN, AddressLike, BNLike, BufferLike } from 'ethereumjs-util'; | ||
import Common from '@ethereumjs/common'; | ||
import { default as Transaction } from './legacyTransaction'; | ||
import { default as AccessListEIP2930Transaction } from './eip2930Transaction'; | ||
/** | ||
@@ -30,6 +34,13 @@ * The options for initializing a Transaction. | ||
} | ||
/** | ||
* An object with an optional field with each of the transaction's values. | ||
*/ | ||
export interface TxData { | ||
export declare type AccessListItem = { | ||
address: string; | ||
storageKeys: string[]; | ||
}; | ||
export declare type AccessListBufferItem = [Buffer, Buffer[]]; | ||
export declare type AccessListBuffer = AccessListBufferItem[]; | ||
export declare type AccessList = AccessListItem[]; | ||
export declare function isAccessListBuffer(input: AccessListBuffer | AccessList): input is AccessListBuffer; | ||
export declare function isAccessList(input: AccessListBuffer | AccessList): input is AccessList; | ||
export declare type TypedTransaction = Transaction | AccessListEIP2930Transaction; | ||
export declare type TxData = { | ||
/** | ||
@@ -71,4 +82,29 @@ * The transaction's nonce. | ||
s?: BNLike; | ||
}; | ||
/** | ||
* An object with an optional field with each of the transaction's values. | ||
*/ | ||
export interface AccessListEIP2930TxData extends TxData { | ||
/** | ||
* The transaction's chain ID | ||
*/ | ||
chainId?: BNLike; | ||
/** | ||
* The access list which contains the addresses/storage slots which the transaction wishes to access | ||
*/ | ||
accessList?: AccessListBuffer | AccessList; | ||
/** | ||
* The transaction type | ||
*/ | ||
type?: BNLike; | ||
} | ||
/** | ||
* Buffer values array for EIP2930 transaction | ||
*/ | ||
export declare type AccessListEIP2930ValuesArray = [Buffer, Buffer, Buffer, Buffer, Buffer, Buffer, Buffer, AccessListBuffer, Buffer?, Buffer?, Buffer?]; | ||
declare type JsonAccessListItem = { | ||
address: string; | ||
storageKeys: string[]; | ||
}; | ||
/** | ||
* An object with all of the transaction's values represented as strings. | ||
@@ -86,2 +122,10 @@ */ | ||
value?: string; | ||
chainId?: string; | ||
accessList?: JsonAccessListItem[]; | ||
type?: string; | ||
} | ||
/** | ||
* A const defining secp256k1n/2 | ||
*/ | ||
export declare const N_DIV_2: BN; | ||
export {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.N_DIV_2 = exports.isAccessList = exports.isAccessListBuffer = void 0; | ||
var ethereumjs_util_1 = require("ethereumjs-util"); | ||
function isAccessListBuffer(input) { | ||
if (input.length === 0) { | ||
return true; | ||
} | ||
var firstItem = input[0]; | ||
if (Array.isArray(firstItem)) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
exports.isAccessListBuffer = isAccessListBuffer; | ||
function isAccessList(input) { | ||
return !isAccessListBuffer(input); // This is exactly the same method, except the output is negated. | ||
} | ||
exports.isAccessList = isAccessList; | ||
/** | ||
* A const defining secp256k1n/2 | ||
*/ | ||
exports.N_DIV_2 = new ethereumjs_util_1.BN('7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0', 16); | ||
//# sourceMappingURL=types.js.map |
@@ -1,2 +0,4 @@ | ||
export { default as Transaction } from './transaction'; | ||
export { default as Transaction } from './legacyTransaction'; | ||
export { default as AccessListEIP2930Transaction } from './eip2930Transaction'; | ||
export { default as TransactionFactory } from './transactionFactory'; | ||
export * from './types'; |
@@ -13,5 +13,9 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var transaction_1 = require("./transaction"); | ||
Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return transaction_1.default; } }); | ||
var legacyTransaction_1 = require("./legacyTransaction"); | ||
Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return legacyTransaction_1.default; } }); | ||
var eip2930Transaction_1 = require("./eip2930Transaction"); | ||
Object.defineProperty(exports, "AccessListEIP2930Transaction", { enumerable: true, get: function () { return eip2930Transaction_1.default; } }); | ||
var transactionFactory_1 = require("./transactionFactory"); | ||
Object.defineProperty(exports, "TransactionFactory", { enumerable: true, get: function () { return transactionFactory_1.default; } }); | ||
__exportStar(require("./types"), exports); | ||
//# sourceMappingURL=index.js.map |
@@ -1,3 +0,7 @@ | ||
import { AddressLike, BNLike, BufferLike } from 'ethereumjs-util'; | ||
/// <reference types="node" /> | ||
/// <reference types="bn.js" /> | ||
import { BN, AddressLike, BNLike, BufferLike } from 'ethereumjs-util'; | ||
import Common from '@ethereumjs/common'; | ||
import { default as Transaction } from './legacyTransaction'; | ||
import { default as AccessListEIP2930Transaction } from './eip2930Transaction'; | ||
/** | ||
@@ -30,6 +34,13 @@ * The options for initializing a Transaction. | ||
} | ||
/** | ||
* An object with an optional field with each of the transaction's values. | ||
*/ | ||
export interface TxData { | ||
export declare type AccessListItem = { | ||
address: string; | ||
storageKeys: string[]; | ||
}; | ||
export declare type AccessListBufferItem = [Buffer, Buffer[]]; | ||
export declare type AccessListBuffer = AccessListBufferItem[]; | ||
export declare type AccessList = AccessListItem[]; | ||
export declare function isAccessListBuffer(input: AccessListBuffer | AccessList): input is AccessListBuffer; | ||
export declare function isAccessList(input: AccessListBuffer | AccessList): input is AccessList; | ||
export declare type TypedTransaction = Transaction | AccessListEIP2930Transaction; | ||
export declare type TxData = { | ||
/** | ||
@@ -71,4 +82,29 @@ * The transaction's nonce. | ||
s?: BNLike; | ||
}; | ||
/** | ||
* An object with an optional field with each of the transaction's values. | ||
*/ | ||
export interface AccessListEIP2930TxData extends TxData { | ||
/** | ||
* The transaction's chain ID | ||
*/ | ||
chainId?: BNLike; | ||
/** | ||
* The access list which contains the addresses/storage slots which the transaction wishes to access | ||
*/ | ||
accessList?: AccessListBuffer | AccessList; | ||
/** | ||
* The transaction type | ||
*/ | ||
type?: BNLike; | ||
} | ||
/** | ||
* Buffer values array for EIP2930 transaction | ||
*/ | ||
export declare type AccessListEIP2930ValuesArray = [Buffer, Buffer, Buffer, Buffer, Buffer, Buffer, Buffer, AccessListBuffer, Buffer?, Buffer?, Buffer?]; | ||
declare type JsonAccessListItem = { | ||
address: string; | ||
storageKeys: string[]; | ||
}; | ||
/** | ||
* An object with all of the transaction's values represented as strings. | ||
@@ -86,2 +122,10 @@ */ | ||
value?: string; | ||
chainId?: string; | ||
accessList?: JsonAccessListItem[]; | ||
type?: string; | ||
} | ||
/** | ||
* A const defining secp256k1n/2 | ||
*/ | ||
export declare const N_DIV_2: BN; | ||
export {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.N_DIV_2 = exports.isAccessList = exports.isAccessListBuffer = void 0; | ||
const ethereumjs_util_1 = require("ethereumjs-util"); | ||
function isAccessListBuffer(input) { | ||
if (input.length === 0) { | ||
return true; | ||
} | ||
const firstItem = input[0]; | ||
if (Array.isArray(firstItem)) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
exports.isAccessListBuffer = isAccessListBuffer; | ||
function isAccessList(input) { | ||
return !isAccessListBuffer(input); // This is exactly the same method, except the output is negated. | ||
} | ||
exports.isAccessList = isAccessList; | ||
/** | ||
* A const defining secp256k1n/2 | ||
*/ | ||
exports.N_DIV_2 = new ethereumjs_util_1.BN('7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0', 16); | ||
//# sourceMappingURL=types.js.map |
{ | ||
"name": "@ethereumjs/tx", | ||
"version": "3.0.2", | ||
"version": "3.1.0", | ||
"description": "A simple module for creating, manipulating and signing Ethereum transactions", | ||
@@ -34,4 +34,4 @@ "main": "dist/index.js", | ||
"dependencies": { | ||
"@ethereumjs/common": "^2.0.0", | ||
"ethereumjs-util": "^7.0.8" | ||
"@ethereumjs/common": "^2.2.0", | ||
"ethereumjs-util": "^7.0.9" | ||
}, | ||
@@ -42,3 +42,2 @@ "devDependencies": { | ||
"@ethereumjs/eslint-config-defaults": "^2.0.0", | ||
"@types/bn.js": "^4.11.6", | ||
"@types/minimist": "^1.2.0", | ||
@@ -72,8 +71,8 @@ "@types/node": "^11.13.4", | ||
"type": "git", | ||
"url": "https://github.com/ethereumjs/ethereumjs-vm.git" | ||
"url": "https://github.com/ethereumjs/ethereumjs-monorepo.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/ethereumjs/ethereumjs-vm/issues?q=is%3Aissue+label%3A%22package%3A+tx%22" | ||
"url": "https://github.com/ethereumjs/ethereumjs-monorepo/issues?q=is%3Aissue+label%3A%22package%3A+tx%22" | ||
}, | ||
"homepage": "https://github.com/ethereumjs/ethereumjs-vm/tree/master/packages/tx#readme", | ||
"homepage": "https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/tx#readme", | ||
"contributors": [ | ||
@@ -80,0 +79,0 @@ { |
112
README.md
@@ -20,5 +20,73 @@ # @ethereumjs/tx | ||
- [Example](./examples/transactions.ts) | ||
## Introduction | ||
To instantiate a tx it is not recommended to use the constructor directly. Instead each tx type comes with the following set of static constructor methods which helps on instantiation depending on the input data format: | ||
- `public static fromTxData(txData: TxData, opts: TxOptions = {})`: instantiate from a data dictionary | ||
- `public static fromSerializedTx(serialized: Buffer, opts: TxOptions = {})`: instantiate from a serialized tx | ||
- `public static fromValuesArray(values: Buffer[], opts: TxOptions = {})`: instantiate from a values array | ||
See one of the code examples on the tx types below on how to use. | ||
All types of transaction objects are frozen with `Object.freeze()` which gives you enhanced security and consistency properties when working with the instantiated object. This behavior can be modified using the `freeze` option in the constructor if needed. | ||
## Transaction Types | ||
This library supports the following transaction types ([EIP-2718](https://eips.ethereum.org/EIPS/eip-2718)): | ||
- `AccessListEIP2930Transaction` ([EIP-2930](https://eips.ethereum.org/EIPS/eip-2930), optional access lists) | ||
- `Transaction`, the Ethereum standard tx up to `berlin`, now referred to as legacy txs with the introduction of tx types | ||
Please note that for now you have to manually set the `hardfork` in `Common` to `berlin` to allow for typed tx instantiation, since the current `Common` release series v2 (tx type support introduced with `v2.2.0`) still defaults to `istanbul` for backwards-compatibility reasons. | ||
#### Access List Transactions (EIP-2930) | ||
- Class: `AccessListEIP2930Transaction` | ||
- Activation: `berlin` | ||
This is the recommended tx type starting with the activation of the `berlin` HF, see the following code snipped for an example on how to instantiate: | ||
```typescript | ||
import Common from '@ethereumjs/common' | ||
import { AccessListEIP2930Transaction } from '@ethereumjs/tx' | ||
const common = new Common({ chain: 'mainnet', hardfork: 'berlin' }) | ||
const txData = { | ||
"data": "0x1a8451e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", | ||
"gasLimit": "0x02625a00", | ||
"gasPrice": "0x01", | ||
"nonce": "0x00", | ||
"to": "0xcccccccccccccccccccccccccccccccccccccccc", | ||
"value": "0x0186a0", | ||
"v": "0x01", | ||
"r": "0xafb6e247b1c490e284053c87ab5f6b59e219d51f743f7a4d83e400782bc7e4b9", | ||
"s": "0x479a268e0e0acd4de3f1e28e4fac2a6b32a4195e8dfa9d19147abe8807aa6f64", | ||
"chainId": "0x01", | ||
"accessList": [ | ||
{ | ||
"address": "0x0000000000000000000000000000000000000101", | ||
"storageKeys": [ | ||
"0x0000000000000000000000000000000000000000000000000000000000000000", | ||
"0x00000000000000000000000000000000000000000000000000000000000060a7" | ||
] | ||
} | ||
], | ||
"type": "0x01" | ||
} | ||
const tx = AccessListEIP2930Transaction.fromTxData(txData, { common }) | ||
``` | ||
A mechanism to generate access lists from tx data based on a certain network state is not part of this library. | ||
### Legacy Transactions | ||
- Class: `Transaction` | ||
- Activation: `chainstart` (with modifications along the road, see HF section below) | ||
Legacy transaction are still valid transaction within Ethereum `mainnet` but will likely be deprecated at some point. | ||
See this [example script](./examples/transactions.ts) or the following code example on how to use. | ||
```typescript | ||
import { Transaction } from '@ethereumjs/tx' | ||
@@ -48,4 +116,24 @@ | ||
Properties of a `Transaction` object are frozen with `Object.freeze()` which gives you enhanced security and consistency properties when working with the instantiated object. This behavior can be modified using the `freeze` option in the constructor if needed. | ||
### Transaction Factory | ||
If you only know on runtime which tx type will be used within your code or if you want to keep your code transparent to tx types, this library comes with a `TransactionFactory` for your convenience which can be used as follows: | ||
```typescript | ||
import Common from '@ethereumjs/common' | ||
import { TransactionFactory } from '@ethereumjs/tx' | ||
const common = new Common({ chain: 'mainnet', hardfork: 'berlin' }) | ||
const txData = {} // Use data from the different tx type examples | ||
const tx = TransactionFactory.fromTxData(txData, { common }) | ||
``` | ||
The correct tx type class for instantiation will then be chosen on runtime based on the data provided as an input. | ||
`TransactionFactory` supports the following static constructor methods: | ||
- `public static fromTxData(txData: TxData | AccessListEIP2930TxData, txOptions: TxOptions = {}): TypedTransaction` | ||
- `public static fromSerializedData(data: Buffer, txOptions: TxOptions = {}): TypedTransaction` | ||
- `public static fromBlockBodyData(data: Buffer | Buffer[], txOptions: TxOptions = {})` | ||
## Fake Transaction | ||
@@ -77,18 +165,16 @@ | ||
The `Transaction` constructor receives a parameter of an [`@ethereumjs/common`](https://github.com/ethereumjs/ethereumjs-vm/blob/master/packages/common) object that lets you specify the chain and hardfork to be used. By default, `mainnet` and `istanbul` will be used. | ||
The `Transaction` constructor receives a parameter of an [`@ethereumjs/common`](https://github.com/ethereumjs/ethereumjs-vm/blob/master/packages/common) object that lets you specify the chain and hardfork to be used. The chain defaults to `mainnet`. | ||
### MuirGlacier Support | ||
The `MuirGlacier` hardfork is supported by the library since the `v2.1.2` release. | ||
Current default HF (determined by `Common`): `istanbul` | ||
### Istanbul Support | ||
### Supported Hardforks | ||
Support for reduced non-zero call data gas prices from the `Istanbul` hardfork | ||
([EIP-2028](https://eips.ethereum.org/EIPS/eip-2028)) has been added to the library | ||
along with the `v2.1.1` release. | ||
Hardfork | Introduced | Description | ||
--- | --- | --- | ||
`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`) | ||
## EIP-155 support | ||
`EIP-155` replay protection is activated since the `spuriousDragon` hardfork. To disable it, set the hardfork to one earlier than `spuriousDragon`. | ||
# API | ||
@@ -95,0 +181,0 @@ |
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
264822
28
48
3529
201
1
1
Updated@ethereumjs/common@^2.2.0
Updatedethereumjs-util@^7.0.9