From c987e8ebecfc38206dcb7babac84a8ac519db7eb Mon Sep 17 00:00:00 2001 From: Patricio Palladino Date: Mon, 24 Jun 2019 16:42:53 -0300 Subject: [PATCH 1/2] Upgrade ethereumjs-common --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ff1e70a..6aa6999 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "author": "mjbecze ", "license": "MPL-2.0", "dependencies": { - "ethereumjs-common": "^1.0.0", + "ethereumjs-common": "^1.3.0", "ethereumjs-util": "^6.0.0" }, "devDependencies": { From 4f3d3668125c0ede83f1f61537c78871d95aaf25 Mon Sep 17 00:00:00 2001 From: Patricio Palladino Date: Mon, 24 Jun 2019 17:03:56 -0300 Subject: [PATCH 2/2] Add examples and doc on how to customize the chain and hardfork --- README.md | 19 +++++++++----- examples/custom-chain-tx.ts | 50 +++++++++++++++++++++++++++++++++++++ examples/ropsten-tx.ts | 16 ++++++++++++ examples/transactions.ts | 3 ++- 4 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 examples/custom-chain-tx.ts create mode 100644 examples/ropsten-tx.ts diff --git a/README.md b/README.md index 254bc09..f442e4b 100644 --- a/README.md +++ b/README.md @@ -29,19 +29,26 @@ const txParams = { data: '0x7f7465737432000000000000000000000000000000000000000000000000000000600057', } -const tx = new EthereumTx(txParams) +// The second parameter is not necessary if these values are used +const tx = new EthereumTx(txParams, { chain: 'mainnet', hardfork: 'petersburg' }) tx.sign(privateKey) const serializedTx = tx.serialize() ``` # Chain and Hardfork Support -This library uses the [ethereumjs-common](https://github.com/ethereumjs/ethereumjs-common) -package to support different chain and hardfork options, see API documentation -for details. +The `Transaction` and `FakeTransaction` constructors receives a second parameter that lets you specify the chain and hardfork +to be used. By default, `mainnet` and `petersburg` will be used. -Currently all hardforks up to `petersburg` are supported, `EIP-155` replay protection -is activated since the `spuriousDragon` hardfork. +There are two ways of customizing these. The first one, as shown in the previous section, is by +using an object with `chain` and `hardfork` names. You can see en example of this in [./examples/ropsten-tx.ts](./examples/ropsten-tx.ts). + +The second option is by passing the option `common` set to an instance of [ethereumjs-common](https://github.com/ethereumjs/ethereumjs-common)' Common. This is specially useful for custom networks or chains/hardforks not yet supported by `ethereumjs-common`. You can see en example of this in [./examples/custom-chain-tx.ts](./examples/custom-chain-tx.ts). + +# EIP-155 support + +`EIP-155` replay protection is activated since the `spuriousDragon` hardfork. To disable it, set the +hardfork in the `Transaction`'s constructor. # API diff --git a/examples/custom-chain-tx.ts b/examples/custom-chain-tx.ts new file mode 100644 index 0000000..84fac7b --- /dev/null +++ b/examples/custom-chain-tx.ts @@ -0,0 +1,50 @@ +import { Transaction } from '../src' +import Common from 'ethereumjs-common' +import { bufferToHex, privateToAddress } from 'ethereumjs-util' + +// In this example we create a transaction for a custom network. +// +// All of these network's params are the same than mainnets', except for name, chainId, and +// networkId, so we use the Common.forCustomChain method. +const customCommon = Common.forCustomChain( + 'mainnet', + { + name: 'my-network', + networkId: 123, + chainId: 2134, + }, + 'petersburg', +) + +// We pass our custom Common object whenever we create a transaction + +const tx = new Transaction( + { + nonce: 0, + gasPrice: 100, + gasLimit: 1000000000, + value: 100000, + }, + { common: customCommon }, +) + +// Once we created the transaction using the custom Common object, we can use it as a normal tx. + +// Here we sign it and validate its signature +const privateKey = new Buffer( + 'e331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', + 'hex', +) + +tx.sign(privateKey) + +if ( + tx.validate() && + bufferToHex(tx.getSenderAddress()) === bufferToHex(privateToAddress(privateKey)) +) { + console.log('Valid signature') +} else { + console.log('Invalid signature') +} + +console.log("The transaction's chain id is", tx.getChainId()) diff --git a/examples/ropsten-tx.ts b/examples/ropsten-tx.ts new file mode 100644 index 0000000..c2d236e --- /dev/null +++ b/examples/ropsten-tx.ts @@ -0,0 +1,16 @@ +import { Transaction } from '../src' +import { bufferToHex } from 'ethereumjs-util' + +const tx = new Transaction( + '0xf9010b82930284d09dc30083419ce0942d18de92e0f9aee1a29770c3b15c6cf8ac5498e580b8a42f43f4fb0000000000000000000000000000000000000000000000000000016b78998da900000000000000000000000000000000000000000000000000000000000cb1b70000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000001363e4f00000000000000000000000000000000000000000000000000000000000186a029a0fac36e66d329af0e831b2e61179b3ec8d7c7a8a2179e303cfed3364aff2bc3e4a07cb73d56e561ccbd838818dd3dea5fa0b5158577ffc61c0e6ec1f0ed55716891', + { chain: 'ropsten', hardfork: 'petersburg' }, +) + +if ( + tx.validate() && + bufferToHex(tx.getSenderAddress()) === '0x9dfd2d2b2ed960923f7bf2e8883d73f213f3b24b' +) { + console.log('Correctly created the tx') +} else { + console.error('Invalid tx') +} diff --git a/examples/transactions.ts b/examples/transactions.ts index 327c24f..21df01b 100644 --- a/examples/transactions.ts +++ b/examples/transactions.ts @@ -5,6 +5,7 @@ import { Transaction } from '../src' // We create an unsigned transaction. // Notice we don't set the `to` field because we are creating a new contract. +// This transaction's chain is set to mainnet const tx = new Transaction({ nonce: 0, gasPrice: 100, @@ -49,7 +50,7 @@ const rawTx = [ '0x5bd428537f05f9830e93792f90ea6a3e2d1ee84952dd96edbae9f658f831ab13', ] -const tx2 = new Transaction(rawTx) +const tx2 = new Transaction(rawTx) // This is also a maninnet transaction // Note rlp.decode will actually produce an array of buffers `new Transaction` will // take either an array of buffers or an array of hex strings.