Merge pull request #1160 from ethereum/improve_remix_sim

add more methods to remix-sim; fix accounts
pull/7/head
Iuri Matias 6 years ago committed by GitHub
commit c7d84a0c41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 82
      remix-simulator/README.md
  2. 8
      remix-simulator/bin/ethsim
  3. 2
      remix-simulator/package.json
  4. 57
      remix-simulator/src/methods/accounts.js
  5. 49
      remix-simulator/src/methods/blocks.js
  6. 7
      remix-simulator/src/methods/misc.js
  7. 69
      remix-simulator/src/methods/transactions.js
  8. 4
      remix-simulator/src/provider.js
  9. 8
      remix-simulator/src/server.js
  10. 11
      remix-simulator/test/blocks.js
  11. 1
      remix-tests/tests/testRunner.ts

@ -1,2 +1,84 @@
# `remix-simulator`
Implemented:
* [X] web3_clientVersion
* [X] web3_sha3
* [X] net_version
* [X] net_listening
* [X] net_peerCount
* [X] eth_protocolVersion
* [X] eth_syncing
* [X] eth_coinbase
* [X] eth_mining
* [X] eth_hashrate
* [~] eth_gasPrice
* [~] eth_accounts
* [X] eth_blockNumber
* [X] eth_getBalance
* [_] eth_getStorageAt
* [~] eth_getTransactionCount
* [_] eth_getBlockTransactionCountByHash
* [_] eth_getBlockTransactionCountByNumber
* [_] eth_getUncleCountByBlockHash
* [_] eth_getUncleCountByBlockNumber
* [X] eth_getCode
* [~] eth_sign
* [X] eth_sendTransaction
* [_] eth_sendRawTransaction
* [X] eth_call
* [~] eth_estimateGas
* [~] eth_getBlockByHash
* [~] eth_getBlockByNumber
* [~] eth_getTransactionByHash
* [_] eth_getTransactionByBlockHashAndIndex
* [_] eth_getTransactionByBlockNumberAndIndex
* [~] eth_getTransactionReceipt
* [_] eth_getUncleByBlockHashAndIndex
* [_] eth_getUncleByBlockNumberAndIndex
* [X] eth_getCompilers (DEPRECATED)
* [_] eth_compileSolidity (DEPRECATED)
* [_] eth_compileLLL (DEPRECATED)
* [_] eth_compileSerpent (DEPRECATED)
* [_] eth_newFilter
* [_] eth_newBlockFilter
* [_] eth_newPendingTransactionFilter
* [_] eth_uninstallFilter
* [_] eth_getFilterChanges
* [_] eth_getFilterLogs
* [_] eth_getLogs
* [_] eth_getWork
* [_] eth_submitWork
* [_] eth_submitHashrate
* [_] eth_getProof
* [_] db_putString
* [_] db_getString
* [_] db_putHex
* [_] db_getHex
* [X] shh_version
* [_] shh_post
* [_] shh_newIdentity
* [_] shh_hasIdentity
* [_] shh_newGroup
* [_] shh_addToGroup
* [_] shh_newFilter
* [_] shh_uninstallFilter
* [_] shh_getFilterChanges
* [_] shh_getMessages
* [_] bzz_hive (stub)
* [_] bzz_info (stub)
* [_] debug_traceTransaction
* [_] eth_subscribe
* [_] eth_unsubscribe
* [_] miner_start
* [_] miner_stop
* [_] personal_listAccounts
* [_] personal_lockAccount
* [_] personal_newAccount
* [_] personal_importRawKey
* [_] personal_unlockAccount
* [_] personal_sendTransaction
* [_] rpc_modules
* [_] web3_clientVersion
* [_] web3_sha3

@ -21,9 +21,13 @@ program
program
.option('-p, --port [port]', 'specify port')
.option('-b, --ip [host]', 'specify host')
.option('-c, --coinbase [coinbase]', 'specify host')
.parse(process.argv)
const Server = require('../src/server')
const server = new Server()
server.start(program.port || 8545)
const server = new Server({
coinbase: program.coinbase || "0x0000000000000000000000000000000000000000"
})
server.start(program.host || '127.0.0.1', program.port || 8545)

@ -23,6 +23,8 @@
"fast-async": "^6.3.7",
"merge": "^1.2.0",
"remix-lib": "0.4.6",
"ethereumjs-vm": "3.0.0",
"ethereumjs-util": "^5.1.2",
"standard": "^10.0.3",
"time-stamp": "^2.0.0",
"web3": "1.0.0-beta.27"

@ -1,27 +1,66 @@
var RemixLib = require('remix-lib')
var executionContext = RemixLib.execution.executionContext
var ethJSUtil = require('ethereumjs-util')
var BN = ethJSUtil.BN
var Web3 = require('web3')
var Accounts = function () {
this.web3 = new Web3()
// TODO: make it random and/or use remix-libs
this.accounts = [this.web3.eth.accounts.create(['abcd']), this.web3.eth.accounts.create(['ef12']), this.web3.eth.accounts.create(['ef34'])]
this.accountsList = [this.web3.eth.accounts.create(['abcd']), this.web3.eth.accounts.create(['ef12']), this.web3.eth.accounts.create(['ef34'])]
this.accounts = {}
this.accountsKeys = {}
this.accounts[this.accounts[0].address.toLowerCase()] = this.accounts[0]
this.accounts[this.accounts[1].address.toLowerCase()] = this.accounts[1]
this.accounts[this.accounts[2].address.toLowerCase()] = this.accounts[2]
executionContext.init({get: () => { return true }})
this.accounts[this.accounts[0].address.toLowerCase()].privateKey = Buffer.from(this.accounts[this.accounts[0].address.toLowerCase()].privateKey.slice(2), 'hex')
this.accounts[this.accounts[1].address.toLowerCase()].privateKey = Buffer.from(this.accounts[this.accounts[1].address.toLowerCase()].privateKey.slice(2), 'hex')
this.accounts[this.accounts[2].address.toLowerCase()].privateKey = Buffer.from(this.accounts[this.accounts[2].address.toLowerCase()].privateKey.slice(2), 'hex')
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 }
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'
})
}
}
Accounts.prototype.methods = function () {
return {
eth_accounts: this.eth_accounts.bind(this)
eth_accounts: this.eth_accounts.bind(this),
eth_getBalance: this.eth_getBalance.bind(this),
eth_sign: this.eth_sign.bind(this)
}
}
Accounts.prototype.eth_accounts = function (payload, cb) {
return cb(null, this.accounts.map((x) => x.address))
return cb(null, this.accountsList.map((x) => x.address))
}
Accounts.prototype.eth_getBalance = function (payload, cb) {
let address = payload.params[0]
address = ethJSUtil.stripHexPrefix(address)
executionContext.vm().stateManager.getAccount(Buffer.from(address, 'hex'), (err, account) => {
if (err) {
return cb(err)
}
cb(null, new BN(account.balance).toString(10))
})
}
Accounts.prototype.eth_sign = function (payload, cb) {
let address = payload.params[0]
let message = payload.params[1]
let privateKey = this.accountsKeys[address]
let account = Web3.eth.accounts.privateKeyToAccount(privateKey)
let data = account.sign(message)
cb(null, data.signature)
}
module.exports = Accounts

@ -1,11 +1,18 @@
var Web3 = require('web3')
var Blocks = function () {
var Blocks = function (_options) {
const options = _options || {}
this.coinbase = options.coinbase || '0x0000000000000000000000000000000000000000'
this.blockNumber = 0
}
Blocks.prototype.methods = function () {
return {
eth_getBlockByNumber: this.eth_getBlockByNumber.bind(this),
eth_gasPrice: this.eth_gasPrice.bind(this)
eth_gasPrice: this.eth_gasPrice.bind(this),
eth_coinbase: this.eth_coinbase.bind(this),
eth_blockNumber: this.eth_blockNumber.bind(this),
eth_getBlockByHash: this.eth_getBlockByHash.bind(this)
}
}
@ -17,10 +24,36 @@ Blocks.prototype.eth_getBlockByNumber = function (payload, cb) {
'gasUsed': '0x0',
'hash': '0xdb731f3622ef37b4da8db36903de029220dba74c41185f8429f916058b86559f',
'logsBloom': '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
'miner': '0x3333333333333333333333333333333333333333',
'miner': this.coinbase,
'mixHash': '0x0000000000000000000000000000000000000000000000000000000000000000',
'nonce': '0x0000000000000042',
'number': '0x0',
'number': Web3.utils.toHex(this.blockNumber),
'parentHash': '0x0000000000000000000000000000000000000000000000000000000000000000',
'receiptsRoot': '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421',
'sha3Uncles': '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347',
'size': '0x1f8',
'stateRoot': '0xb7917653f92e62394d2207d0f39a1320ff1cb93d1cee80d3c492627e00b219ff',
'timestamp': '0x0',
'totalDifficulty': '0x0',
'transactions': [],
'transactionsRoot': '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421',
'uncles': []
}
cb(null, b)
}
Blocks.prototype.eth_getBlockByHash = function (payload, cb) {
let b = {
'difficulty': '0x0',
'extraData': '0x',
'gasLimit': '0x7a1200',
'gasUsed': '0x0',
'hash': '0xdb731f3622ef37b4da8db36903de029220dba74c41185f8429f916058b86559f',
'logsBloom': '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
'miner': this.coinbase,
'mixHash': '0x0000000000000000000000000000000000000000000000000000000000000000',
'nonce': '0x0000000000000042',
'number': Web3.utils.toHex(this.blockNumber),
'parentHash': '0x0000000000000000000000000000000000000000000000000000000000000000',
'receiptsRoot': '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421',
'sha3Uncles': '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347',
@ -39,4 +72,12 @@ Blocks.prototype.eth_gasPrice = function (payload, cb) {
cb(null, 1)
}
Blocks.prototype.eth_coinbase = function (payload, cb) {
cb(null, this.coinbase)
}
Blocks.prototype.eth_blockNumber = function (payload, cb) {
cb(null, this.blockNumber)
}
module.exports = Blocks

@ -11,7 +11,8 @@ Misc.prototype.methods = function () {
eth_syncing: this.eth_syncing.bind(this),
eth_mining: this.eth_mining.bind(this),
eth_hashrate: this.eth_hashrate.bind(this),
web3_sha3: this.web3_sha3.bind(this)
web3_sha3: this.web3_sha3.bind(this),
eth_getCompilers: this.eth_getCompilers.bind(this)
}
}
@ -41,4 +42,8 @@ Misc.prototype.web3_sha3 = function (payload, cb) {
cb(null, web3.utils.sha3(str))
}
Misc.prototype.eth_getCompilers = function (payload, cb) {
cb(null, [])
}
module.exports = Misc

@ -1,11 +1,24 @@
var RemixLib = require('remix-lib')
var executionContext = RemixLib.execution.executionContext
var ethJSUtil = require('ethereumjs-util')
var processTx = require('./txProcess.js')
var BN = ethJSUtil.BN
function hexConvert (ints) {
var ret = '0x'
for (var i = 0; i < ints.length; i++) {
var h = ints[i]
if (h) {
ret += (h <= 0xf ? '0' : '') + h.toString(16)
} else {
ret += '00'
}
}
return ret
}
var Transactions = function (accounts) {
this.accounts = accounts
// TODO: fix me; this is a temporary and very hackish thing just to get the getCode working for now
this.deployedContracts = {}
}
Transactions.prototype.methods = function () {
@ -14,7 +27,9 @@ Transactions.prototype.methods = function () {
eth_getTransactionReceipt: this.eth_getTransactionReceipt.bind(this),
eth_getCode: this.eth_getCode.bind(this),
eth_call: this.eth_call.bind(this),
eth_estimateGas: this.eth_estimateGas.bind(this)
eth_estimateGas: this.eth_estimateGas.bind(this),
eth_getTransactionCount: this.eth_getTransactionCount.bind(this),
eth_getTransactionByHash: this.eth_getTransactionByHash.bind(this)
}
}
@ -23,12 +38,10 @@ Transactions.prototype.eth_sendTransaction = function (payload, cb) {
}
Transactions.prototype.eth_getTransactionReceipt = function (payload, cb) {
const self = this
executionContext.web3().eth.getTransactionReceipt(payload.params[0], (error, receipt) => {
if (error) {
return cb(error)
}
self.deployedContracts[receipt.contractAddress] = receipt.data
var r = {
'transactionHash': receipt.hash,
@ -53,11 +66,55 @@ Transactions.prototype.eth_estimateGas = function (payload, cb) {
Transactions.prototype.eth_getCode = function (payload, cb) {
let address = payload.params[0]
cb(null, this.deployedContracts[address] || '0x')
const account = ethJSUtil.toBuffer(address)
executionContext.vm().stateManager.getContractCode(account, (error, result) => {
cb(error, hexConvert(result))
})
}
Transactions.prototype.eth_call = function (payload, cb) {
processTx(this.accounts, payload, true, cb)
}
Transactions.prototype.eth_getTransactionCount = function (payload, cb) {
let address = payload.params[0]
executionContext.vm().stateManager.getAccount(address, (err, account) => {
if (err) {
return cb(err)
}
let nonce = new BN(account.nonce).toString(10)
cb(null, nonce)
})
}
Transactions.prototype.eth_getTransactionByHash = function (payload, cb) {
const address = payload.params[0]
executionContext.web3().eth.getTransactionReceipt(address, (error, receipt) => {
if (error) {
return cb(error)
}
// executionContext.web3().eth.getBlock(receipt.hash).then((block) => {
const r = {
'hash': receipt.transactionHash,
// "nonce": 2,
'blockHash': receipt.hash,
// 'blockNumber': block.number,
// "transactionIndex": 0,
'from': receipt.from,
'to': receipt.to,
'value': receipt.value,
'gas': receipt.gas,
'gasPrice': '2000000000000',
'input': receipt.input
}
cb(null, r)
// })
})
}
module.exports = Transactions

@ -8,12 +8,12 @@ const Net = require('./methods/net.js')
const Transactions = require('./methods/transactions.js')
const Whisper = require('./methods/whisper.js')
var Provider = function () {
var Provider = function (options) {
this.Accounts = new Accounts()
this.methods = {}
this.methods = merge(this.methods, this.Accounts.methods())
this.methods = merge(this.methods, (new Blocks()).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())

@ -6,11 +6,11 @@ const Provider = require('./provider')
const log = require('./utils/logs.js')
class Server {
constructor () {
this.provider = new Provider()
constructor (options) {
this.provider = new Provider(options)
}
start (port) {
start (host, port) {
expressWs(app)
app.use(bodyParser.urlencoded({extended: true}))
@ -40,7 +40,7 @@ class Server {
})
})
app.listen(port, () => log('Remix Simulator listening on port ' + port))
app.listen(port, host, () => log('Remix Simulator listening on port ' + host + ':' + port))
}
}

@ -6,7 +6,9 @@ var assert = require('assert')
describe('blocks', function () {
before(function () {
let provider = new RemixSim.Provider()
let provider = new RemixSim.Provider({
coinbase: '0x0000000000000000000000000000000000000001'
})
web3.setProvider(provider)
})
@ -20,7 +22,7 @@ describe('blocks', function () {
gasUsed: 0,
hash: '0xdb731f3622ef37b4da8db36903de029220dba74c41185f8429f916058b86559f',
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
miner: '0x3333333333333333333333333333333333333333',
miner: '0x0000000000000000000000000000000000000001',
mixHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
nonce: '0x0000000000000042',
number: 0,
@ -43,4 +45,9 @@ describe('blocks', function () {
let gasPrice = await web3.eth.getGasPrice()
assert.equal(gasPrice, 1)
})
it('should get coinbase', async function () {
let coinbase = await web3.eth.getCoinbase()
assert.equal(coinbase, '0x0000000000000000000000000000000000000001')
})
})

@ -131,7 +131,6 @@ describe('testRunner', () => {
done()
}
runTest('StringTest', contracts.StringTest, compilationData[filename]['StringTest'], { accounts }, testCallback, resultsCallback)
runTest('StringTest2', contracts.StringTest2, compilationData[filename]['StringTest2'], { accounts }, testCallback, resultsCallback)
})
})

Loading…
Cancel
Save