diff --git a/libs/remix-simulator/src/VmProxy.ts b/libs/remix-simulator/src/VmProxy.ts index a49043f295..dcc834b617 100644 --- a/libs/remix-simulator/src/VmProxy.ts +++ b/libs/remix-simulator/src/VmProxy.ts @@ -3,7 +3,7 @@ const { hexListFromBNs, formatMemory } = util import { helpers } from '@remix-project/remix-lib' const { normalizeHexAddress } = helpers.ui import { ConsoleLogs } from '@remix-project/remix-lib' -import { toChecksumAddress, BN, bufferToHex, Address } from 'ethereumjs-util' +import { toChecksumAddress, BN, keccak, bufferToHex, Address, toBuffer } from 'ethereumjs-util' import Web3 from 'web3' import { ethers } from 'ethers' import { VMContext } from './vm-context' @@ -40,7 +40,6 @@ export class VmProxy { utils txsMapBlock blocks - latestBlockNumber constructor (vmContext: VMContext) { this.vmContext = vmContext @@ -62,6 +61,7 @@ export class VmProxy { this.eth.getTransactionReceipt = (txHash, cb) => this.getTransactionReceipt(txHash, cb) this.eth.getTransactionFromBlock = (blockNumber, txIndex, cb) => this.getTransactionFromBlock(blockNumber, txIndex, cb) this.eth.getBlockNumber = (cb) => this.getBlockNumber(cb) + this.eth.getStorageAt = (address: string, position: string, blockNumber: string, cb) => this.getStorageAt(address, position, blockNumber, cb) this.debug.traceTransaction = (txHash, options, cb) => this.traceTransaction(txHash, options, cb) this.debug.storageRangeAt = (blockNumber, txIndex, address, start, maxLength, cb) => this.storageRangeAt(blockNumber, txIndex, address, start, maxLength, cb) this.debug.preimage = (hashedKey, cb) => this.preimage(hashedKey, cb) @@ -83,7 +83,6 @@ export class VmProxy { this.utils = Web3.utils || [] this.txsMapBlock = {} this.blocks = {} - this.latestBlockNumber = 0 } setVM (vm) { @@ -306,15 +305,34 @@ export class VmProxy { } } - storageRangeAt (blockNumber, txIndex, address, start, maxLength, cb) { + getStorageAt (address: string, position: string, blockNumber: string, cb) { // we don't use the range params here address = toChecksumAddress(address) + + blockNumber = blockNumber === 'latest' ? this.vmContext.latestBlockNumber : blockNumber const block = this.vmContext.blocks[blockNumber] - const txHash = '0x' + block.transactions[txIndex].hash().toString('hex') + const txHash = '0x' + block.transactions[block.transactions.length - 1].hash().toString('hex') if (this.storageCache['after_' + txHash] && this.storageCache['after_' + txHash][address]) { + const slot = '0x' + keccak(toBuffer(ethers.utils.hexZeroPad(position, 32))).toString('hex') const storage = this.storageCache['after_' + txHash][address] + return cb(null, storage[slot].value) + } + // Before https://github.com/ethereum/remix-project/pull/1703, it used to throw error as + // 'unable to retrieve storage ' + txIndex + ' ' + address + cb(null, { storage: {} }) + } + + storageRangeAt (blockNumber, txIndex, address, start, maxLength, cb) { + // we don't use the range params here + address = toChecksumAddress(address) + + const block = this.vmContext.blocks[blockNumber] + const txHash = '0x' + block.transactions[txIndex].hash().toString('hex') + + if (this.storageCache[txHash] && this.storageCache[txHash][address]) { + const storage = this.storageCache[txHash][address] return cb(null, { storage: JSON.parse(JSON.stringify(storage)), nextKey: null diff --git a/libs/remix-simulator/src/methods/blocks.ts b/libs/remix-simulator/src/methods/blocks.ts index cd0d220fc5..cc6f96f042 100644 --- a/libs/remix-simulator/src/methods/blocks.ts +++ b/libs/remix-simulator/src/methods/blocks.ts @@ -1,7 +1,7 @@ import Web3 from 'web3' - +import { VMContext } from '../vm-context' export class Blocks { - vmContext + vmContext: VMContext coinbase: string TX_INDEX = '0x0' // currently there's always only 1 tx per block, so the transaction index will always be 0x0 constructor (vmContext, _options) { @@ -73,7 +73,7 @@ export class Blocks { stateRoot: this.toHex(block.header.stateRoot), miner: this.coinbase, difficulty: this.toHex(block.header.difficulty), - totalDifficulty: this.toHex(block.header.totalDifficulty), + totalDifficulty: this.toHex((block.header as any).totalDifficulty), extraData: this.toHex(block.header.extraData), size: '0x027f07', // 163591 gasLimit: this.toHex(block.header.gasLimit), @@ -127,7 +127,7 @@ export class Blocks { stateRoot: this.toHex(block.header.stateRoot), miner: this.coinbase, difficulty: this.toHex(block.header.difficulty), - totalDifficulty: this.toHex(block.header.totalDifficulty), + totalDifficulty: this.toHex((block.header as any).totalDifficulty), extraData: this.toHex(block.header.extraData), size: '0x027f07', // 163591 gasLimit: this.toHex(block.header.gasLimit), @@ -173,15 +173,10 @@ export class Blocks { } eth_getStorageAt (payload, cb) { - const [ address, position, blockNumber ] = payload.params - - this.vmContext.web3().debug.storageRangeAt(blockNumber + 1, 0, address.toLowerCase(), position, 1, (err, result) => { - if (err || (result.storage && Object.values(result.storage).length === 0)) { - return cb(err, '') - } - - const value = Object.values(result.storage)[0]['value'] - cb(err, value) - }) + return this.vmContext.web3().eth.getStorageAt( + payload.params[0], + payload.params[1], + payload.params[2], + cb) } }