|
|
@ -3,7 +3,7 @@ const { hexListFromBNs, formatMemory } = util |
|
|
|
import { helpers } from '@remix-project/remix-lib' |
|
|
|
import { helpers } from '@remix-project/remix-lib' |
|
|
|
const { normalizeHexAddress } = helpers.ui |
|
|
|
const { normalizeHexAddress } = helpers.ui |
|
|
|
import { ConsoleLogs } from '@remix-project/remix-lib' |
|
|
|
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 Web3 from 'web3' |
|
|
|
import { ethers } from 'ethers' |
|
|
|
import { ethers } from 'ethers' |
|
|
|
import { VMContext } from './vm-context' |
|
|
|
import { VMContext } from './vm-context' |
|
|
@ -40,7 +40,6 @@ export class VmProxy { |
|
|
|
utils |
|
|
|
utils |
|
|
|
txsMapBlock |
|
|
|
txsMapBlock |
|
|
|
blocks |
|
|
|
blocks |
|
|
|
latestBlockNumber |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
constructor (vmContext: VMContext) { |
|
|
|
constructor (vmContext: VMContext) { |
|
|
|
this.vmContext = vmContext |
|
|
|
this.vmContext = vmContext |
|
|
@ -62,6 +61,7 @@ export class VmProxy { |
|
|
|
this.eth.getTransactionReceipt = (txHash, cb) => this.getTransactionReceipt(txHash, cb) |
|
|
|
this.eth.getTransactionReceipt = (txHash, cb) => this.getTransactionReceipt(txHash, cb) |
|
|
|
this.eth.getTransactionFromBlock = (blockNumber, txIndex, cb) => this.getTransactionFromBlock(blockNumber, txIndex, cb) |
|
|
|
this.eth.getTransactionFromBlock = (blockNumber, txIndex, cb) => this.getTransactionFromBlock(blockNumber, txIndex, cb) |
|
|
|
this.eth.getBlockNumber = (cb) => this.getBlockNumber(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.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.storageRangeAt = (blockNumber, txIndex, address, start, maxLength, cb) => this.storageRangeAt(blockNumber, txIndex, address, start, maxLength, cb) |
|
|
|
this.debug.preimage = (hashedKey, cb) => this.preimage(hashedKey, cb) |
|
|
|
this.debug.preimage = (hashedKey, cb) => this.preimage(hashedKey, cb) |
|
|
@ -83,7 +83,6 @@ export class VmProxy { |
|
|
|
this.utils = Web3.utils || [] |
|
|
|
this.utils = Web3.utils || [] |
|
|
|
this.txsMapBlock = {} |
|
|
|
this.txsMapBlock = {} |
|
|
|
this.blocks = {} |
|
|
|
this.blocks = {} |
|
|
|
this.latestBlockNumber = 0 |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
setVM (vm) { |
|
|
|
setVM (vm) { |
|
|
@ -132,6 +131,7 @@ export class VmProxy { |
|
|
|
this.txs[this.processingHash] = tx |
|
|
|
this.txs[this.processingHash] = tx |
|
|
|
this.txsReceipt[this.processingHash] = tx |
|
|
|
this.txsReceipt[this.processingHash] = tx |
|
|
|
this.storageCache[this.processingHash] = {} |
|
|
|
this.storageCache[this.processingHash] = {} |
|
|
|
|
|
|
|
this.storageCache['after_' + this.processingHash] = {} |
|
|
|
if (data.to) { |
|
|
|
if (data.to) { |
|
|
|
try { |
|
|
|
try { |
|
|
|
const storage = await this.vm.stateManager.dumpStorage(data.to) |
|
|
|
const storage = await this.vm.stateManager.dumpStorage(data.to) |
|
|
@ -175,6 +175,17 @@ export class VmProxy { |
|
|
|
const status = data.execResult.exceptionError ? 0 : 1 |
|
|
|
const status = data.execResult.exceptionError ? 0 : 1 |
|
|
|
this.txsReceipt[this.processingHash].status = `0x${status}` |
|
|
|
this.txsReceipt[this.processingHash].status = `0x${status}` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const to = this.txs[this.processingHash].to |
|
|
|
|
|
|
|
if (to) { |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
const account = Address.fromString(to) |
|
|
|
|
|
|
|
const storage = await this.vm.stateManager.dumpStorage(account) |
|
|
|
|
|
|
|
this.storageCache['after_' + this.processingHash][to] = storage |
|
|
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
|
|
console.log(e) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (data.createdAddress) { |
|
|
|
if (data.createdAddress) { |
|
|
|
const address = data.createdAddress.toString() |
|
|
|
const address = data.createdAddress.toString() |
|
|
|
this.vmTraces[this.processingHash].return = toChecksumAddress(address) |
|
|
|
this.vmTraces[this.processingHash].return = toChecksumAddress(address) |
|
|
@ -294,19 +305,31 @@ 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
|
|
|
|
// we don't use the range params here
|
|
|
|
address = toChecksumAddress(address) |
|
|
|
address = toChecksumAddress(address) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
blockNumber = blockNumber === 'latest' ? this.vmContext.latestBlockNumber : blockNumber |
|
|
|
|
|
|
|
|
|
|
|
let txHash |
|
|
|
const block = this.vmContext.blocks[blockNumber] |
|
|
|
if (txIndex === 'latest') { |
|
|
|
const txHash = '0x' + block.transactions[block.transactions.length - 1].hash().toString('hex') |
|
|
|
txHash = this.lastProcessedStorageTxHash[address] |
|
|
|
|
|
|
|
} else { |
|
|
|
if (this.storageCache['after_' + txHash] && this.storageCache['after_' + txHash][address]) { |
|
|
|
const block = this.vmContext.blocks[blockNumber] |
|
|
|
const slot = '0x' + keccak(toBuffer(ethers.utils.hexZeroPad(position, 32))).toString('hex') |
|
|
|
txHash = '0x' + block.transactions[txIndex].hash().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]) { |
|
|
|
if (this.storageCache[txHash] && this.storageCache[txHash][address]) { |
|
|
|
const storage = this.storageCache[txHash][address] |
|
|
|
const storage = this.storageCache[txHash][address] |
|
|
|