1 | # SYNOPSIS
|
2 |
|
3 | [![NPM Package](https://img.shields.io/npm/v/ethereumjs-vm.svg?style=flat-square)](https://www.npmjs.org/package/ethereumjs-vm)
|
4 | [![Actions Status](https://github.com/ethereumjs/ethereumjs-vm/workflows/vm-test/badge.svg)](https://github.com/ethereumjs/ethereumjs-vm/actions)
|
5 | [![Code Coverage](https://codecov.io/gh/ethereumjs/ethereumjs-vm/branch/master/graph/badge.svg)](https://codecov.io/gh/ethereumjs/ethereumjs-vm)
|
6 | [![Gitter](https://img.shields.io/gitter/room/ethereum/ethereumjs.svg?style=flat-square)](https://gitter.im/ethereum/ethereumjs)
|
7 |
|
8 | [![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard)
|
9 |
|
10 | Implements Ethereum's VM in Javascript.
|
11 |
|
12 | #### Fork Support
|
13 |
|
14 | The VM currently supports the following hardfork rules:
|
15 |
|
16 | - `Byzantium`
|
17 | - `Constantinople`
|
18 | - `Petersburg` (default)
|
19 | - `Istanbul`
|
20 | - `MuirGlacier` (only `mainnet` and `ropsten`)
|
21 |
|
22 | If you are still looking for a [Spurious Dragon](https://eips.ethereum.org/EIPS/eip-607) compatible version of this library install the latest of the `2.2.x` series (see [Changelog](./CHANGELOG.md)).
|
23 |
|
24 | ##### MuirGlacier Hardfork Support
|
25 |
|
26 | An Ethereum test suite compliant `MuirGlacier` HF implementation is available
|
27 | since the `v4.1.3` VM release. You can activate a `MuirGlacier` VM by using the
|
28 | `muirGlacier` `hardfork` option flag.
|
29 |
|
30 | **Note:** The original `v4.1.2` release contains a critical bug preventing the
|
31 | `MuirGlacier` VM to work properly and there is the need to update.
|
32 |
|
33 | ##### Istanbul Harfork Support
|
34 |
|
35 | An Ethereum test suite compliant `Istanbul` HF implementation is available
|
36 | since the `v4.1.1` VM release. You can activate an `Istanbul` VM by using the
|
37 | `istanbul` `hardfork` option flag.
|
38 |
|
39 | Supported `Istanbul` EIPs:
|
40 |
|
41 | - [EIP-152](https://eips.ethereum.org/EIPS/eip-152): Blake 2b `F` precompile,
|
42 | PR [#584](https://github.com/ethereumjs/ethereumjs-vm/pull/584)
|
43 | - [EIP-1108](https://eips.ethereum.org/EIPS/eip-1108): Reduce `alt_bn128`
|
44 | precompile gas costs,
|
45 | PR [#540](https://github.com/ethereumjs/ethereumjs-vm/pull/540)
|
46 | (already released in `v4.0.0`)
|
47 | - [EIP-1344](https://eips.ethereum.org/EIPS/eip-1344): Add ChainID Opcode,
|
48 | PR [#572](https://github.com/ethereumjs/ethereumjs-vm/pull/572)
|
49 | - [EIP-1884](https://eips.ethereum.org/EIPS/eip-1884): Trie-size-dependent
|
50 | Opcode Repricing,
|
51 | PR [#581](https://github.com/ethereumjs/ethereumjs-vm/pull/581)
|
52 | - [EIP-2200](https://eips.ethereum.org/EIPS/eip-2200): Rebalance net-metered
|
53 | SSTORE gas costs,
|
54 | PR [#590](https://github.com/ethereumjs/ethereumjs-vm/pull/590)
|
55 |
|
56 | # INSTALL
|
57 |
|
58 | `npm install ethereumjs-vm`
|
59 |
|
60 | # USAGE
|
61 |
|
62 | ```javascript
|
63 | const BN = require('bn.js')
|
64 | var VM = require('ethereumjs-vm').default
|
65 |
|
66 | // Create a new VM instance
|
67 | // For explicity setting the HF use e.g. `new VM({ hardfork: 'petersburg' })`
|
68 | const vm = new VM()
|
69 |
|
70 | const STOP = '00'
|
71 | const ADD = '01'
|
72 | const PUSH1 = '60'
|
73 |
|
74 | // Note that numbers added are hex values, so '20' would be '32' as decimal e.g.
|
75 | const code = [PUSH1, '03', PUSH1, '05', ADD, STOP]
|
76 |
|
77 | vm.on('step', function(data) {
|
78 | console.log(`Opcode: ${data.opcode.name}\tStack: ${data.stack}`)
|
79 | })
|
80 |
|
81 | vm.runCode({
|
82 | code: Buffer.from(code.join(''), 'hex'),
|
83 | gasLimit: new BN(0xffff),
|
84 | })
|
85 | .then(results => {
|
86 | console.log('Returned : ' + results.returnValue.toString('hex'))
|
87 | console.log('gasUsed : ' + results.gasUsed.toString())
|
88 | })
|
89 | .catch(err => console.log('Error : ' + err))
|
90 | ```
|
91 |
|
92 | ## Example
|
93 |
|
94 | This projects contain the following examples:
|
95 |
|
96 | 1. [./examples/run-blockchain](./examples/run-blockchain): Loads tests data, including accounts and blocks, and runs all of them in the VM.
|
97 | 1. [./examples/run-code-browser](./examples/run-code-browser): Show how to use this library in a browser.
|
98 | 1. [./examples/run-solidity-contract](./examples/run-solidity-contract): Compiles a Solidity contract, and calls constant and non-constant functions.
|
99 | 1. [./examples/run-transactions-complete](./examples/run-transactions-complete): Runs a contract-deployment transaction and then calls one of its functions.
|
100 | 1. [./examples/decode-opcodes](./examples/decode-opcodes): Decodes a binary EVM program into its opcodes.
|
101 |
|
102 | All of the examples have their own `README.md` explaining how to run them.
|
103 |
|
104 | # BROWSER
|
105 |
|
106 | To build the VM for standalone use in the browser, see: [Running the VM in a browser](https://github.com/ethereumjs/ethereumjs-vm/tree/master/examples/run-code-browser).
|
107 |
|
108 | # API
|
109 |
|
110 | ## VM
|
111 |
|
112 | For documentation on `VM` instantiation, exposed API and emitted `events` see generated [API docs](./docs/README.md).
|
113 |
|
114 | ## StateManger
|
115 |
|
116 | The API for the `StateManager` is currently in `Beta`, separate documentation can be found [here](./docs/classes/statemanager.md), see also [release notes](https://github.com/ethereumjs/ethereumjs-vm/releases/tag/v2.5.0) from the `v2.5.0` VM release for details on the `StateManager` rewrite.
|
117 |
|
118 | # Internal Structure
|
119 |
|
120 | The VM processes state changes at many levels.
|
121 |
|
122 | - **runBlockchain**
|
123 | - for every block, runBlock
|
124 | - **runBlock**
|
125 | - for every tx, runTx
|
126 | - pay miner and uncles
|
127 | - **runTx**
|
128 | - check sender balance
|
129 | - check sender nonce
|
130 | - runCall
|
131 | - transfer gas charges
|
132 | - **runCall**
|
133 | - checkpoint state
|
134 | - transfer value
|
135 | - load code
|
136 | - runCode
|
137 | - materialize created contracts
|
138 | - revert or commit checkpoint
|
139 | - **runCode**
|
140 | - iterate over code
|
141 | - run op codes
|
142 | - track gas usage
|
143 | - **OpFns**
|
144 | - run individual op code
|
145 | - modify stack
|
146 | - modify memory
|
147 | - calculate fee
|
148 |
|
149 | The opFns for `CREATE`, `CALL`, and `CALLCODE` call back up to `runCall`.
|
150 |
|
151 | ## VM's tracing events
|
152 |
|
153 | You can subscribe to the following events of the VM:
|
154 |
|
155 | - `beforeBlock`: Emits a `Block` right before running it.
|
156 | - `afterBlock`: Emits `RunBlockResult` right after running a block.
|
157 | - `beforeTx`: Emits a `Transaction` right before running it.
|
158 | - `afterTx`: Emits a `RunTxResult` right after running a transaction.
|
159 | - `beforeMessage`: Emits a `Message` right after running it.
|
160 | - `afterMessage`: Emits an `EVMResult` right after running a message.
|
161 | - `step`: Emits an `InterpreterStep` right before running an EVM step.
|
162 | - `newContract`: Emits a `NewContractEvent` right before creating a contract. This event contains the deployment code, not the deployed code, as the creation message may not return such a code.
|
163 |
|
164 | ### Asynchronous event handlers
|
165 |
|
166 | You can perform asynchronous operations from within an event handler
|
167 | and prevent the VM to keep running until they finish.
|
168 |
|
169 | In order to do that, your event handler has to accept two arguments.
|
170 | The first one will be the event object, and the second one a function.
|
171 | The VM won't continue until you call this function.
|
172 |
|
173 | If an exception is passed to that function, or thrown from within the
|
174 | handler or a function called by it, the exception will bubble into the
|
175 | VM and interrupt it, possibly corrupting its state. It's strongly
|
176 | recommended not to do that.
|
177 |
|
178 | ### Synchronous event handlers
|
179 |
|
180 | If you want to perform synchronous operations, you don't need
|
181 | to receive a function as the handler's second argument, nor call it.
|
182 |
|
183 | Note that if your event handler receives multiple arguments, the second
|
184 | one will be the continuation function, and it must be called.
|
185 |
|
186 | If an exception is thrown from withing the handler or a function called
|
187 | by it, the exception will bubble into the VM and interrupt it, possibly
|
188 | corrupting its state. It's strongly recommended not to throw from withing
|
189 | event handlers.
|
190 |
|
191 | # DEVELOPMENT
|
192 |
|
193 | Developer documentation - currently mainly with information on testing and debugging - can be found [here](./developer.md).
|
194 |
|
195 | # EthereumJS
|
196 |
|
197 | See our organizational [documentation](https://ethereumjs.readthedocs.io) for an introduction to `EthereumJS` as well as information on current standards and best practices.
|
198 |
|
199 | If you want to join for work or do improvements on the libraries have a look at our [contribution guidelines](https://ethereumjs.readthedocs.io/en/latest/contributing.html).
|
200 |
|
201 | # LICENSE
|
202 |
|
203 | [MPL-2.0](https://www.mozilla.org/MPL/2.0/)
|