diff --git a/package.json b/package.json index 2b4ea90861..ae49df4a19 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "0.1.16", + "version": "0.1.19", "devDependencies": { "gulp": "^3.9.1", "lerna": "^2.10.2" diff --git a/remix-analyzer/package.json b/remix-analyzer/package.json index 431db4409e..4657b1c5d2 100644 --- a/remix-analyzer/package.json +++ b/remix-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "remix-analyzer", - "version": "0.3.10", + "version": "0.3.13", "description": "Remix Analyzer", "main": "./index.js", "contributors": [ @@ -18,7 +18,7 @@ } ], "dependencies": { - "remix-lib": "0.4.9" + "remix-lib": "0.4.12" }, "scripts": { "lint": "standard", diff --git a/remix-astwalker/package.json b/remix-astwalker/package.json index db2441b605..6c70ffadbe 100644 --- a/remix-astwalker/package.json +++ b/remix-astwalker/package.json @@ -1,6 +1,6 @@ { "name": "remix-astwalker", - "version": "0.0.6", + "version": "0.0.9", "description": "Remix sub-module for walking through AST", "main": "dist/index.js", "scripts": { @@ -34,7 +34,7 @@ "dependencies": { "@types/tape": "^4.2.33", "nyc": "^13.3.0", - "remix-lib": "0.4.9", + "remix-lib": "0.4.12", "tape": "^4.10.1", "ts-node": "^8.0.3", "typescript": "^3.4.3" diff --git a/remix-debug/package.json b/remix-debug/package.json index f4218ed566..d7bb1b7a8a 100644 --- a/remix-debug/package.json +++ b/remix-debug/package.json @@ -1,6 +1,6 @@ { "name": "remix-debug", - "version": "0.3.11", + "version": "0.3.14", "description": "Ethereum IDE and tools for the web", "contributors": [ { @@ -22,7 +22,7 @@ "ethereumjs-util": "^4.5.0", "ethereumjs-vm": "3.0.0", "fast-async": "^6.1.2", - "remix-lib": "0.4.9", + "remix-lib": "0.4.12", "web3": "0.20.6" }, "devDependencies": { diff --git a/remix-lib/package.json b/remix-lib/package.json index 4760a943ac..b8cc484c58 100644 --- a/remix-lib/package.json +++ b/remix-lib/package.json @@ -1,6 +1,6 @@ { "name": "remix-lib", - "version": "0.4.9", + "version": "0.4.12", "description": "Ethereum IDE and tools for the web", "contributors": [ { diff --git a/remix-lib/src/execution/execution-context.js b/remix-lib/src/execution/execution-context.js index 3985978c35..ce6beeb89d 100644 --- a/remix-lib/src/execution/execution-context.js +++ b/remix-lib/src/execution/execution-context.js @@ -56,6 +56,24 @@ class StateManagerCommonStorageDump extends StateManager { }) }) } + + getStateRoot (cb) { + let checkpoint = this._checkpointCount + this._checkpointCount = 0 + super.getStateRoot((err, stateRoot) => { + this._checkpointCount = checkpoint + cb(err, stateRoot) + }) + } + + setStateRoot (stateRoot, cb) { + let checkpoint = this._checkpointCount + this._checkpointCount = 0 + super.setStateRoot(stateRoot, (err) => { + this._checkpointCount = checkpoint + cb(err) + }) + } } function createVm (hardfork) { @@ -220,20 +238,6 @@ function ExecutionContext () { } } - this.checkpointAndCommit = function (cb, checkpointCount) { - // due to issue https://github.com/ethereumjs/ethereumjs-vm/issues/567 - if (this.vm().stateManager._checkpointCount > (checkpointCount || 0)) { - return this.vm().stateManager.commit(() => { - cb() - }) - } - this.vm().stateManager.checkpoint(() => { - this.vm().stateManager.commit(() => { - cb() - }) - }) - } - this.currentblockGasLimit = function () { return this.blockGasLimit } diff --git a/remix-lib/src/execution/txRunner.js b/remix-lib/src/execution/txRunner.js index a8911981b8..6816c60db4 100644 --- a/remix-lib/src/execution/txRunner.js +++ b/remix-lib/src/execution/txRunner.js @@ -101,59 +101,70 @@ class TxRunner { return callback('Invalid account selected') } - var tx = new EthJSTX({ - timestamp: timestamp, - nonce: new BN(account.nonce++), - gasPrice: new BN(1), - gasLimit: gasLimit, - to: to, - value: new BN(value, 10), - data: Buffer.from(data.slice(2), 'hex') - }) - tx.sign(account.privateKey) + executionContext.vm().stateManager.getAccount(Buffer.from(from.replace('0x', ''), 'hex'), (err, res) => { + if (err) { + callback('Account not found') + } else { + var tx = new EthJSTX({ + timestamp: timestamp, + nonce: new BN(res.nonce), + gasPrice: new BN(1), + gasLimit: gasLimit, + to: to, + value: new BN(value, 10), + data: Buffer.from(data.slice(2), 'hex') + }) + tx.sign(account.privateKey) - const coinbases = ['0x0e9281e9c6a0808672eaba6bd1220e144c9bb07a', '0x8945a1288dc78a6d8952a92c77aee6730b414778', '0x94d76e24f818426ae84aa404140e8d5f60e10e7e'] - const difficulties = [new BN('69762765929000', 10), new BN('70762765929000', 10), new BN('71762765929000', 10)] - var block = new EthJSBlock({ - header: { - timestamp: timestamp || (new Date().getTime() / 1000 | 0), - number: self.blockNumber, - coinbase: coinbases[self.blockNumber % coinbases.length], - difficulty: difficulties[self.blockNumber % difficulties.length], - gasLimit: new BN(gasLimit, 10).imuln(2) - }, - transactions: [tx], - uncleHeaders: [] + const coinbases = ['0x0e9281e9c6a0808672eaba6bd1220e144c9bb07a', '0x8945a1288dc78a6d8952a92c77aee6730b414778', '0x94d76e24f818426ae84aa404140e8d5f60e10e7e'] + const difficulties = [new BN('69762765929000', 10), new BN('70762765929000', 10), new BN('71762765929000', 10)] + var block = new EthJSBlock({ + header: { + timestamp: timestamp || (new Date().getTime() / 1000 | 0), + number: self.blockNumber, + coinbase: coinbases[self.blockNumber % coinbases.length], + difficulty: difficulties[self.blockNumber % difficulties.length], + gasLimit: new BN(gasLimit, 10).imuln(2) + }, + transactions: [tx], + uncleHeaders: [] + }) + if (!useCall) { + ++self.blockNumber + this.runBlockInVm(tx, block, callback) + } else { + executionContext.vm().stateManager.checkpoint(() => { + this.runBlockInVm(tx, block, (err, result) => { + executionContext.vm().stateManager.revert(() => { + callback(err, result) + }) + }) + }) + } + } }) - if (!useCall) { - ++self.blockNumber - } else { - executionContext.vm().stateManager.checkpoint(() => { }) - } + } - executionContext.checkpointAndCommit(() => { - executionContext.vm().runBlock({ block: block, generate: true, skipBlockValidation: true, skipBalance: false }, function (err, results) { - err = err ? err.message : err - if (err) { - return callback(err) - } - let result = results.results[0] - if (useCall) { - executionContext.vm().stateManager.revert(function () { }) - } - if (result) { - result.status = '0x' + result.vm.exception.toString(16) - } + runBlockInVm (tx, block, callback) { + executionContext.vm().runBlock({ block: block, generate: true, skipBlockValidation: true, skipBalance: false }, function (err, results) { + err = err ? err.message : err + if (err) { + return callback(err) + } + let result = results.results[0] - executionContext.addBlock(block) - executionContext.trackTx('0x' + tx.hash().toString('hex'), block) + if (result) { + result.status = '0x' + result.vm.exception.toString(16) + } - callback(err, { - result: result, - transactionHash: ethJSUtil.bufferToHex(Buffer.from(tx.hash())) - }) + executionContext.addBlock(block) + executionContext.trackTx('0x' + tx.hash().toString('hex'), block) + + callback(err, { + result: result, + transactionHash: ethJSUtil.bufferToHex(Buffer.from(tx.hash())) }) - }, 1) + }) } runInNode (from, to, data, value, gasLimit, useCall, confirmCb, gasEstimationForceSend, promptCb, callback) { diff --git a/remix-lib/src/universalDapp.js b/remix-lib/src/universalDapp.js index db8c6d00df..03960f430c 100644 --- a/remix-lib/src/universalDapp.js +++ b/remix-lib/src/universalDapp.js @@ -1,5 +1,5 @@ const async = require('async') -const { BN, privateToAddress, isValidPrivate, stripHexPrefix } = require('ethereumjs-util') +const { BN, privateToAddress, isValidPrivate, stripHexPrefix, toChecksumAddress } = require('ethereumjs-util') const crypto = require('crypto') const { EventEmitter } = require('events') @@ -121,7 +121,7 @@ module.exports = class UniversalDApp { }) }) - this.accounts['0x' + address.toString('hex')] = { privateKey, nonce: 0 } + this.accounts[toChecksumAddress('0x' + address.toString('hex'))] = { privateKey, nonce: 0 } } } diff --git a/remix-lib/src/util.js b/remix-lib/src/util.js index d0b5ee86ef..04899c29c2 100644 --- a/remix-lib/src/util.js +++ b/remix-lib/src/util.js @@ -180,13 +180,23 @@ module.exports = { * * @return {RegEx} */ - swarmHashExtractionPOC3: function () { + swarmHashExtractionPOC31: function () { return /a265627a7a72315820([0-9a-f]{64})64736f6c6343([0-9a-f]{6})0032$/ }, + /** + * return a regex which extract the swarmhash from the bytecode, from POC 0.3 + * + * @return {RegEx} + */ + swarmHashExtractionPOC32: function () { + return /a265627a7a72305820([0-9a-f]{64})64736f6c6343([0-9a-f]{6})0032$/ + }, + extractSwarmHash: function (value) { value = value.replace(this.swarmHashExtraction(), '') - value = value.replace(this.swarmHashExtractionPOC3(), '') + value = value.replace(this.swarmHashExtractionPOC31(), '') + value = value.replace(this.swarmHashExtractionPOC32(), '') return value }, diff --git a/remix-simulator/package.json b/remix-simulator/package.json index dbad6850c9..dff56aef6c 100644 --- a/remix-simulator/package.json +++ b/remix-simulator/package.json @@ -1,6 +1,6 @@ { "name": "remix-simulator", - "version": "0.1.9-alpha.2", + "version": "0.1.9-alpha.5", "description": "Ethereum IDE and tools for the web", "contributors": [ { @@ -18,13 +18,14 @@ "body-parser": "^1.18.2", "color-support": "^1.1.3", "commander": "^2.19.0", + "cors": "^2.8.5", "ethereumjs-util": "^5.1.2", "ethereumjs-vm": "3.0.0", "express": "^4.16.3", "express-ws": "^4.0.0", "fast-async": "^6.3.7", "merge": "^1.2.0", - "remix-lib": "0.4.9", + "remix-lib": "0.4.12", "standard": "^10.0.3", "time-stamp": "^2.0.0", "web3": "1.0.0-beta.27" diff --git a/remix-simulator/src/genesis.js b/remix-simulator/src/genesis.js index 295cb935f4..2d4d7e74ee 100644 --- a/remix-simulator/src/genesis.js +++ b/remix-simulator/src/genesis.js @@ -17,10 +17,8 @@ function generateBlock () { uncleHeaders: [] }) - executionContext.checkpointAndCommit(() => { - executionContext.vm().runBlock({ block: block, generate: true, skipBlockValidation: true, skipBalance: false }, function () { - executionContext.addBlock(block) - }) + executionContext.vm().runBlock({ block: block, generate: true, skipBlockValidation: true, skipBalance: false }, function () { + executionContext.addBlock(block) }) } diff --git a/remix-simulator/src/methods/accounts.js b/remix-simulator/src/methods/accounts.js index a32ab96f53..176cd129c4 100644 --- a/remix-simulator/src/methods/accounts.js +++ b/remix-simulator/src/methods/accounts.js @@ -12,19 +12,28 @@ var Accounts = function () { this.accountsKeys = {} executionContext.init({get: () => { return true }}) +} - for (let _account of this.accountsList) { - this.accountsKeys[_account.address.toLowerCase()] = _account.privateKey - this.accounts[_account.address.toLowerCase()] = { privateKey: Buffer.from(_account.privateKey.replace('0x', ''), 'hex'), nonce: 0 } +Accounts.prototype.init = async function () { + let setBalance = (account) => { + return new Promise((resolve, reject) => { + this.accountsKeys[ethJSUtil.toChecksumAddress(account.address)] = account.privateKey + this.accounts[ethJSUtil.toChecksumAddress(account.address)] = { privateKey: Buffer.from(account.privateKey.replace('0x', ''), 'hex'), nonce: 0 } - executionContext.vm().stateManager.getAccount(Buffer.from(_account.address.toLowerCase().replace('0x', ''), 'hex'), (err, account) => { - if (err) { - throw new Error(err) - } - var balance = '0x56BC75E2D63100000' - account.balance = balance || '0xf00000000000000001' + executionContext.vm().stateManager.getAccount(Buffer.from(account.address.toLowerCase().replace('0x', ''), 'hex'), (err, account) => { + if (err) { + throw new Error(err) + } + var balance = '0x56BC75E2D63100000' + account.balance = balance || '0xf00000000000000001' + resolve() + }) }) } + + for (let _account of this.accountsList) { + await setBalance(_account) + } } Accounts.prototype.methods = function () { @@ -36,7 +45,7 @@ Accounts.prototype.methods = function () { } Accounts.prototype.eth_accounts = function (payload, cb) { - return cb(null, this.accountsList.map((x) => x.address)) + return cb(null, this.accountsList.map((x) => ethJSUtil.toChecksumAddress(x.address))) } Accounts.prototype.eth_getBalance = function (payload, cb) { diff --git a/remix-simulator/src/methods/transactions.js b/remix-simulator/src/methods/transactions.js index 754b191604..b861fc4b3d 100644 --- a/remix-simulator/src/methods/transactions.js +++ b/remix-simulator/src/methods/transactions.js @@ -5,7 +5,9 @@ var ethJSUtil = require('ethereumjs-util') var processTx = require('./txProcess.js') var BN = ethJSUtil.BN -var Transactions = function (accounts) { +var Transactions = function () {} + +Transactions.prototype.init = function (accounts) { this.accounts = accounts } @@ -24,6 +26,10 @@ Transactions.prototype.methods = function () { } Transactions.prototype.eth_sendTransaction = function (payload, cb) { + // from might be lowercased address (web3) + if (payload.params && payload.params.length > 0 && payload.params[0].from) { + payload.params[0].from = ethJSUtil.toChecksumAddress(payload.params[0].from) + } processTx(this.accounts, payload, false, cb) } @@ -68,6 +74,10 @@ Transactions.prototype.eth_getCode = function (payload, cb) { } Transactions.prototype.eth_call = function (payload, cb) { + // from might be lowercased address (web3) + if (payload.params && payload.params.length > 0 && payload.params[0].from) { + payload.params[0].from = ethJSUtil.toChecksumAddress(payload.params[0].from) + } processTx(this.accounts, payload, true, cb) } diff --git a/remix-simulator/src/provider.js b/remix-simulator/src/provider.js index 3778b58876..4c1f9e706a 100644 --- a/remix-simulator/src/provider.js +++ b/remix-simulator/src/provider.js @@ -12,18 +12,24 @@ const generateBlock = require('./genesis.js') var Provider = function (options) { this.Accounts = new Accounts() + this.Transactions = new Transactions() this.methods = {} this.methods = merge(this.methods, this.Accounts.methods()) this.methods = merge(this.methods, (new Blocks(options)).methods()) this.methods = merge(this.methods, (new Misc()).methods()) this.methods = merge(this.methods, (new Net()).methods()) - this.methods = merge(this.methods, (new Transactions(this.Accounts.accounts)).methods()) + this.methods = merge(this.methods, (this.Transactions.methods())) this.methods = merge(this.methods, (new Whisper()).methods()) generateBlock() } +Provider.prototype.init = async function () { + await this.Accounts.init() + this.Transactions.init(this.Accounts.accounts) +} + Provider.prototype.sendAsync = function (payload, callback) { log.info('payload method is ', payload.method) diff --git a/remix-simulator/src/server.js b/remix-simulator/src/server.js index a8d33023c8..92bb43aad9 100644 --- a/remix-simulator/src/server.js +++ b/remix-simulator/src/server.js @@ -1,4 +1,5 @@ const express = require('express') +const cors = require('cors') const bodyParser = require('body-parser') const app = express() const expressWs = require('express-ws') @@ -8,11 +9,17 @@ const log = require('./utils/logs.js') class Server { constructor (options) { this.provider = new Provider(options) + this.provider.init().then(() => { + log('Provider initiated') + }).catch((error) => { + log(error) + }) } start (host, port) { expressWs(app) + app.use(cors()) app.use(bodyParser.urlencoded({extended: true})) app.use(bodyParser.json()) diff --git a/remix-solidity/package.json b/remix-solidity/package.json index bf5f0ef6c5..10b2075836 100644 --- a/remix-solidity/package.json +++ b/remix-solidity/package.json @@ -1,6 +1,6 @@ { "name": "remix-solidity", - "version": "0.3.12", + "version": "0.3.15", "description": "Ethereum IDE and tools for the web", "contributors": [ { @@ -17,7 +17,7 @@ "ethereumjs-util": "^4.5.0", "ethereumjs-vm": "3.0.0", "fast-async": "^6.1.2", - "remix-lib": "0.4.9", + "remix-lib": "0.4.12", "solc": "^0.5.0", "webworkify": "^1.2.1" }, diff --git a/remix-tests/package.json b/remix-tests/package.json index a0af850c43..3035827d08 100644 --- a/remix-tests/package.json +++ b/remix-tests/package.json @@ -1,6 +1,6 @@ { "name": "remix-tests", - "version": "0.1.15", + "version": "0.1.18", "description": "Tests for the Ethereum tool suite Remix", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -42,9 +42,9 @@ "change-case": "^3.0.1", "colors": "^1.1.2", "commander": "^2.13.0", - "remix-lib": "0.4.9", - "remix-simulator": "0.1.9-alpha.2", - "remix-solidity": "0.3.12", + "remix-lib": "0.4.12", + "remix-simulator": "0.1.9-alpha.5", + "remix-solidity": "0.3.15", "web3": "1.0.0-beta.36", "winston": "^3.0.0" }, diff --git a/remix-tests/src/runTestSources.ts b/remix-tests/src/runTestSources.ts index 4e765434fd..eefa1be9ba 100644 --- a/remix-tests/src/runTestSources.ts +++ b/remix-tests/src/runTestSources.ts @@ -10,15 +10,17 @@ import Web3 = require('web3') import { Provider } from 'remix-simulator' import { FinalResult } from './types' -const createWeb3Provider = function () { +const createWeb3Provider = async function () { let web3 = new Web3() - web3.setProvider(new Provider()) + let provider = new Provider() + await provider.init() + web3.setProvider(provider) return web3 } -export function runTestSources(contractSources, testCallback, resultCallback, finalCallback, importFileCb, opts) { +export async function runTestSources(contractSources, testCallback, resultCallback, finalCallback, importFileCb, opts) { opts = opts || {} - let web3 = opts.web3 || createWeb3Provider() + let web3 = opts.web3 || await createWeb3Provider() let accounts = opts.accounts || null async.waterfall([ function getAccountList (next) { diff --git a/remix-tests/tests/testRunner.ts b/remix-tests/tests/testRunner.ts index 89fc55a408..2bcf256363 100644 --- a/remix-tests/tests/testRunner.ts +++ b/remix-tests/tests/testRunner.ts @@ -44,8 +44,9 @@ function deepEqualExcluding(a: any, b: any, excludedKeys: string[]) { let accounts: string[] let provider = new Provider() -function compileAndDeploy(filename: string, callback: Function) { +async function compileAndDeploy(filename: string, callback: Function) { let web3: Web3 = new Web3() + await provider.init() web3.setProvider(provider) let compilationData: object async.waterfall([