Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ethereumjs-vm

Package Overview
Dependencies
Maintainers
1
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ethereumjs-vm - npm Package Compare versions

Comparing version 1.4.1 to 2.0.0

circle.yml

70

lib/hooked.js

@@ -31,5 +31,3 @@ const inherits = require('util').inherits

function createHookedVm(opts, hooks){
function createHookedVm (opts, hooks) {
var codeStore = new FallbackAsyncStore(hooks.fetchAccountCode.bind(hooks))

@@ -45,9 +43,8 @@

function createAccountStorageTrie(address, cb){
function createAccountStorageTrie (address, cb) {
var addressHex = ethUtil.addHexPrefix(address.toString('hex'))
var storageTrie = new FallbackStorageTrie({
fetchStorage: function(key, cb){
fetchStorage: function (key, cb) {
hooks.fetchAccountStorage(addressHex, key, cb)
},
}
})

@@ -57,15 +54,15 @@ cb(null, storageTrie)

function loadAccount(address, cb){
function loadAccount (address, cb) {
var addressHex = ethUtil.addHexPrefix(address.toString('hex'))
async.parallel({
nonce: hooks.fetchAccountNonce.bind(hooks, addressHex),
balance: hooks.fetchAccountBalance.bind(hooks, addressHex),
}, function(err, results){
balance: hooks.fetchAccountBalance.bind(hooks, addressHex)
}, function (err, results) {
if (err) return cb(err)
results._exists = results.nonce !== '0x0' || results.balance != '0x0' || results._code != '0x'
// console.log('fetch account results:', results)
results._exists = results.nonce !== '0x0' || results.balance !== '0x0' || results._code !== '0x'
// console.log('fetch account results:', results)
var account = new Account(results)
// not used but needs to be anything but the default (ethUtil.SHA3_NULL)
// code lookups are handled by `codeStore`
// not used but needs to be anything but the default (ethUtil.SHA3_NULL)
// code lookups are handled by `codeStore`
account.codeHash = ZERO_BUFFER.slice()

@@ -75,3 +72,2 @@ cb(null, account)

}
}

@@ -86,12 +82,12 @@

function fromWeb3Provider(provider, blockNumber, opts){
function fromWeb3Provider (provider, blockNumber, opts) {
return createHookedVm(opts, {
fetchAccountBalance: createRpcFunction(provider, 'eth_getBalance', blockNumber),
fetchAccountNonce: createRpcFunction(provider, 'eth_getTransactionCount', blockNumber),
fetchAccountCode: createRpcFunction(provider, 'eth_getCode', blockNumber),
fetchAccountStorage: createRpcFunction(provider, 'eth_getStorageAt', blockNumber),
fetchAccountNonce: createRpcFunction(provider, 'eth_getTransactionCount', blockNumber),
fetchAccountCode: createRpcFunction(provider, 'eth_getCode', blockNumber),
fetchAccountStorage: createRpcFunction(provider, 'eth_getStorageAt', blockNumber)
})
function createRpcFunction(provider, method, blockNumber){
return function sendRpcRequest(){
function createRpcFunction (provider, method, blockNumber) {
return function sendRpcRequest () {
// prepare arguments

@@ -101,8 +97,8 @@ var args = [].slice.call(arguments)

args.push(blockNumber)
// send rpc payload
// send rpc payload
provider.sendAsync({
id: 1,
method: method,
params: args,
}, function(err, res){
params: args
}, function (err, res) {
if (err) return cb(err)

@@ -125,3 +121,3 @@ cb(null, res.result)

function FallbackStorageTrie(opts) {
function FallbackStorageTrie (opts) {
const self = this

@@ -132,12 +128,12 @@ FakeMerklePatriciaTree.call(self)

FallbackStorageTrie.prototype.get = function(key, cb){
FallbackStorageTrie.prototype.get = function (key, cb) {
const self = this
var _super = FakeMerklePatriciaTree.prototype.get.bind(self)
_super(key, function(err, value){
_super(key, function (err, value) {
if (err) return cb(err)
if (value) return cb(null, value)
// if value not in tree, try network
// if value not in tree, try network
var keyHex = key.toString('hex')
self._fetchStorage(keyHex, function(err, rawValue){
self._fetchStorage(keyHex, function (err, rawValue) {
if (err) return cb(err)

@@ -159,3 +155,3 @@ var value = ethUtil.toBuffer(rawValue)

function FallbackAsyncStore(fetchFn){
function FallbackAsyncStore (fetchFn) {
// console.log('FallbackAsyncStore - new')

@@ -167,6 +163,6 @@ const self = this

FallbackAsyncStore.prototype.get = function(address, cb){
FallbackAsyncStore.prototype.get = function (address, cb) {
// console.log('FallbackAsyncStore - get', arguments)
const self = this
var addressHex = '0x'+address.toString('hex')
var addressHex = '0x' + address.toString('hex')
var code = self.cache[addressHex]

@@ -177,6 +173,6 @@ if (code !== undefined) {

// console.log('FallbackAsyncStore - fetch init')
self.fetch(addressHex, function(err, value){
self.fetch(addressHex, function (err, value) {
// console.log('FallbackAsyncStore - fetch return', arguments)
if (err) return cb(err)
value = ethUtil.toBuffer(value);
value = ethUtil.toBuffer(value)
self.cache[addressHex] = value

@@ -188,8 +184,8 @@ cb(null, value)

FallbackAsyncStore.prototype.set = function(address, code, cb){
FallbackAsyncStore.prototype.set = function (address, code, cb) {
// console.log('FallbackAsyncStore - set', arguments)
const self = this
var addressHex = '0x'+address.toString('hex')
var addressHex = '0x' + address.toString('hex')
self.cache[addressHex] = code
cb()
}
}

@@ -23,12 +23,12 @@ const util = require('util')

* @constructor
* @param {Trie} [trie] A merkle-patricia-tree instance for the state tree
* @param {Blockchain} [blockchain] A blockchain object for storing/retrieving blocks
* @param {Object} [opts]
* @param {Trie} [opts.state] A merkle-patricia-tree instance for the state tree
* @param {Blockchain} [opts.blockchain] A blockchain object for storing/retrieving blocks
* @param {Boolean} [opts.activatePrecompiles] Create entries in the state tree for the precompiled contracts
* @param {Boolean} [opts.enableHomestead] Force enable Homestead irrelevant to block number
*/
function VM (trie, blockchain, opts) {
function VM (opts = {}) {
this.stateManager = new StateManager({
trie: trie,
blockchain: blockchain
trie: opts.state,
blockchain: opts.blockchain
})

@@ -51,3 +51,3 @@

for (var i = 1; i <= 4; i++) {
this.trie.put(new Buffer('000000000000000000000000000000000000000' + i, 'hex'), new Account().serialize());
this.trie.put(new Buffer('000000000000000000000000000000000000000' + i, 'hex'), new Account().serialize())
}

@@ -54,0 +54,0 @@ }

@@ -432,3 +432,3 @@ const async = require('async')

if (!jumpIsValid(runState, dest)) {
trap(ERROR.INVALID_JUMP)
trap(ERROR.INVALID_JUMP + ' at ' + describeLocation(runState))
}

@@ -445,3 +445,3 @@

if (i && !jumpIsValid(runState, dest)) {
trap(ERROR.INVALID_JUMP)
trap(ERROR.INVALID_JUMP + ' at ' + describeLocation(runState))
}

@@ -462,4 +462,4 @@

PUSH: function (runState) {
var numToPush = runState.opCode - 0x5f
var loaded = utils.unpad(runState.code.slice(runState.programCounter, runState.programCounter + numToPush))
const numToPush = runState.opCode - 0x5f
const loaded = utils.unpad(runState.code.slice(runState.programCounter, runState.programCounter + numToPush))
runState.programCounter += numToPush

@@ -470,7 +470,5 @@ return loaded

const stackPos = runState.opCode - 0x7f
if (stackPos > runState.stack.length) {
trap(ERROR.STACK_UNDERFLOW)
}
// dupilcated stack items point to the same Buffer

@@ -707,2 +705,9 @@ return runState.stack[runState.stack.length - stackPos]

function describeLocation (runState) {
var hash = utils.sha3(runState.code).toString('hex')
var address = runState.address.toString('hex')
var pc = runState.programCounter - 1
return hash + '/' + address + ':' + pc
}
function subGas (runState, amount) {

@@ -740,9 +745,13 @@ runState.gasLeft.isub(amount)

var newMemoryWordCount = Math.ceil((offset + length) / 32)
runState.memoryWordCount = Math.max(newMemoryWordCount, runState.memoryWordCount)
var words = new BN(newMemoryWordCount)
var fee = new BN(fees.memoryGas.v)
var quadCoeff = new BN(fees.quadCoeffDiv.v)
var cost = words.mul(fee).add(words.mul(words).div(quadCoeff))
const newMemoryWordCount = Math.ceil((offset + length) / 32)
if (newMemoryWordCount <= runState.memoryWordCount) return
runState.memoryWordCount = newMemoryWordCount
const words = new BN(newMemoryWordCount)
const fee = new BN(fees.memoryGas.v)
const quadCoeff = new BN(fees.quadCoeffDiv.v)
// words * 3 + words ^2 / 512
const cost = words.mul(fee).add(words.mul(words).div(quadCoeff))
if (cost.cmp(runState.highestMemCost) === 1) {

@@ -749,0 +758,0 @@ subGas(runState, cost.sub(runState.highestMemCost))

{
"name": "ethereumjs-vm",
"version": "1.4.1",
"version": "2.0.0",
"description": "an ethereum VM implementation",

@@ -22,4 +22,4 @@ "main": "index.js",

"level": "^1.4.0",
"leveldown": "^1.4.2",
"levelup": "^1.3.0",
"leveldown": "^1.4.6",
"levelup": "^1.3.2",
"memdown": "^1.1.0",

@@ -26,0 +26,0 @@ "minimist": "^1.1.1",

# SYNOPSIS
[![NPM Package](https://img.shields.io/npm/v/ethereumjs-vm.svg?style=flat-square)](https://www.npmjs.org/package/ethereumjs-vm)

@@ -38,3 +39,3 @@ [![Build Status](https://img.shields.io/travis/ethereumjs/ethereumjs-vm.svg?branch=master&style=flat-square)](https://travis-ci.org/ethereumjs/ethereumjs-vm)

# API
- [`new VM([StateTrie], [blockchain], [opts])`](#new-vmstatetrie-blockchain)
- [`new VM([opts])`](#new-vmstatetrie-blockchain)
- [`VM` methods](#vm-methods)

@@ -55,2 +56,4 @@ - [`vm.runBlockchain([blockchain], [cb])`](#vmrunblockchainblockchain-cb)

- `opts`
- `state` - the state trie
- `blockchain` - an instance of ethereumjs-blockchain
- `enableHomestead` - a boolean that overrides the homestead settings based on blocknumber

@@ -57,0 +60,0 @@ - `activatePrecompiles` - create entries in the state tree for the precompiled contracts

@@ -19,3 +19,6 @@ const async = require('async')

blockchain.ethash.cacheDB = cacheDB
var vm = new VM(state, blockchain)
var vm = new VM({
state: state,
blockchain: blockchain
})
var genesisBlock = new Block()

@@ -22,0 +25,0 @@

const tape = require('tape')
const createHookedVm = require('../lib/hooked')
tape('hooked-vm', function(test){
tape('hooked-vm', function (test) {
var contractAddressHex = '0x1234000000000000000000000000000000001234'

@@ -11,15 +10,15 @@ var contractAddress = new Buffer(contractAddressHex.slice(2), 'hex')

var contractCode = new Buffer([
0x30, // ADDRESS of contract being run
0x31, // BALANCE of address on stack
0x30, // ADDRESS of contract being run
0x31, // BALANCE of address on stack
// return the last thing on the stack
0x60, //PUSH1
0x60, //(data1) <-- MSTORE offset top| [prev]
0x90, //SWAP1 top| [prev, data1]
0x81, //DUP2 top| [data1, prev, data1]
0x52, //MSTORE (offset:data1, word:prev) top| [data1] -> offset:data1, word:prev
0x60, //PUSH1
0x20, //(data2) <-- RETURN length top| [data2, data1]
0x90, //SWAP1 top| [data1, data2]
0xf3, //RETURN (offset:data1, length:data2) top| [] -> offset:data1, length:data2
0x60, // PUSH1
0x60, // (data1) <-- MSTORE offset top| [prev]
0x90, // SWAP1 top| [prev, data1]
0x81, // DUP2 top| [data1, prev, data1]
0x52, // MSTORE (offset:data1, word:prev) top| [data1] -> offset:data1, word:prev
0x60, // PUSH
0x20, // (data2) <-- RETURN length top| [data2, data1]
0x90, // SWAP1 top| [data1, data2]
0xf3 // RETURN (offset:data1, length:data2) top| [] -> offset:data1, length:data2
])

@@ -31,4 +30,4 @@

nonce: '0x00',
code: '0x'+contractCode.toString('hex'),
storage: {},
code: '0x' + contractCode.toString('hex'),
storage: {}
}

@@ -38,3 +37,3 @@ }

var vm = createHookedVm({
enableHomestead: true,
enableHomestead: true
}, hooksForBlockchainState(blockchainState))

@@ -47,45 +46,42 @@

// })
vm.runCode({
code: contractCode,
address: contractAddress,
gasLimit: new Buffer('ffffffffff'),
}, function(err, results){
gasLimit: new Buffer('ffffffffff')
}, function (err, results) {
// console.log(arguments)
test.ifError(err, 'Should run code without error')
test.ifError(results.exceptionError, 'Should run code without vm error')
test.equal('0x'+results.return.toString('hex'), contractBalanceHex, 'Should return correct balance of contract')
test.equal('0x' + results.return.toString('hex'), contractBalanceHex, 'Should return correct balance of contract')
test.end()
})
})
function hooksForBlockchainState(blockchainState){
function hooksForBlockchainState (blockchainState) {
return {
fetchAccountBalance: function(addressHex, cb){
fetchAccountBalance: function (addressHex, cb) {
var value = blockchainState[addressHex].balance
// console.log('fetchAccountBalance', addressHex, '->', value)
// console.log('fetchAccountBalance', addressHex, '->', value)
cb(null, value)
},
fetchAccountNonce: function(addressHex, cb){
fetchAccountNonce: function (addressHex, cb) {
var value = blockchainState[addressHex].nonce
// console.log('fetchAccountNonce', addressHex, '->', value)
// console.log('fetchAccountNonce', addressHex, '->', value)
cb(null, value)
},
fetchAccountCode: function(addressHex, cb){
fetchAccountCode: function (addressHex, cb) {
var value = blockchainState[addressHex].code
// console.log('fetchAccountCode', addressHex, '->', value)
// console.log('fetchAccountCode', addressHex, '->', value)
cb(null, value)
},
fetchAccountStorage: function(addressHex, keyHex, cb){
var value = blockchainState[addressHex].storage[key]
// console.log('fetchAccountStorage', addressHex, keyHex, '->', value)
fetchAccountStorage: function (addressHex, keyHex, cb) {
var value = blockchainState[addressHex].storage[keyHex]
// console.log('fetchAccountStorage', addressHex, keyHex, '->', value)
cb(null, value)
},
}
}
}
}

@@ -8,9 +8,8 @@ const async = require('async')

module.exports = function runStateTest (options, testData, t, cb) {
var state = new Trie()
var block, vm, result
const state = new Trie()
let block, vm, result
async.series([
function (done) {
vm = new VM(state)
vm = new VM({state: state})
testUtil.setupPreConditions(state, testData, done)

@@ -17,0 +16,0 @@ },

@@ -10,10 +10,9 @@ const async = require('async')

module.exports = function runStateTest (options, testData, t, cb) {
var sstream = false
var state = new Trie()
var results
var account
let state = new Trie()
let results
let account
async.series([
function (done) {
var acctData = testData.pre[testData.exec.address]
let acctData = testData.pre[testData.exec.address]
account = new Account()

@@ -26,3 +25,3 @@ account.nonce = testUtil.format(acctData.nonce)

state.get(new Buffer(testData.exec.address, 'hex'), function (err, data) {
var a = new Account(data)
let a = new Account(data)
account.stateRoot = a.stateRoot

@@ -34,8 +33,13 @@ // console.log(account.toJSON(true))

function (done) {
var block = testUtil.makeBlockFromEnv(testData.env)
var vm = new VM(state)
var runCodeData = testUtil.makeRunCodeData(testData.exec, account, block)
let block = testUtil.makeBlockFromEnv(testData.env)
let vm = new VM({state: state})
let runCodeData = testUtil.makeRunCodeData(testData.exec, account, block)
if (options.vmtrace) {
sstream = testUtil.enableVMtracing(vm, options.vmtrace)
vm.on('step', (op) => {
const string = `${op.opcode.name} ${op.gasLeft.toString()}`
console.log(string)
op.stack.forEach((item) => {
console.log(item.toString('hex'))
})
})
}

@@ -51,4 +55,4 @@

function (done) {
if (sstream) {
sstream.push(null)
if (options.vmtrace) {
console.log(results.runState.gasLeft.toString())
}

@@ -55,0 +59,0 @@

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
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc