diff --git a/apps/remix-ide-e2e/src/tests/debugger.test.ts b/apps/remix-ide-e2e/src/tests/debugger.test.ts index 5fa826e502..f97f871386 100644 --- a/apps/remix-ide-e2e/src/tests/debugger.test.ts +++ b/apps/remix-ide-e2e/src/tests/debugger.test.ts @@ -206,16 +206,40 @@ module.exports = { }, // depends on Should debug using generated sources 'Should call the debugger api: getTrace #group4': function (browser: NightwatchBrowser) { + let txhash browser - .addFile('test_jsGetTrace.js', { content: jsGetTrace }) + .clickLaunchIcon('udapp') + .perform((done) => { + browser.getLastTransactionHash((hash) => { + txhash = hash + done() + }) + }) + .perform((done) => { + browser.addFile('test_jsGetTrace.js', { content: jsGetTrace.replace('', txhash) }).perform(() => { + done() + }) + }) .executeScriptInTerminal('remix.exeCurrent()') .pause(3000) .waitForElementContainsText('*[data-id="terminalJournal"]', '{"gas":"0x5752","return":"0x0000000000000000000000000000000000000000000000000000000000000000","structLogs":', 60000) }, // depends on Should debug using generated sources 'Should call the debugger api: debug #group4': function (browser: NightwatchBrowser) { + let txhash browser - .addFile('test_jsDebug.js', { content: jsDebug }) + .clickLaunchIcon('udapp') + .perform((done) => { + browser.getLastTransactionHash((hash) => { + txhash = hash + done() + }) + }) + .perform((done) => { + browser.addFile('test_jsDebug.js', { content: jsDebug.replace('', txhash) }).perform(() => { + done() + }) + }) .executeScriptInTerminal('remix.exeCurrent()') .pause(3000) .clickLaunchIcon('debugger') @@ -495,7 +519,7 @@ const localVariable_step717_ABIEncoder = { // eslint-disable-line const jsGetTrace = `(async () => { try { - const result = await remix.call('debugger', 'getTrace', '0x00a9f5b1ac2c9cb93e5890ea86c81efbd36b619ef2378136ef74d8c6171ddda6') + const result = await remix.call('debugger', 'getTrace', '') console.log('result ', result) } catch (e) { console.log(e.message) @@ -504,7 +528,7 @@ const jsGetTrace = `(async () => { const jsDebug = `(async () => { try { - const result = await remix.call('debugger', 'debug', '0x00a9f5b1ac2c9cb93e5890ea86c81efbd36b619ef2378136ef74d8c6171ddda6') + const result = await remix.call('debugger', 'debug', '') console.log('result ', result) } catch (e) { console.log(e.message) diff --git a/apps/remix-ide-e2e/src/tests/eip1153.test.ts b/apps/remix-ide-e2e/src/tests/eip1153.test.ts new file mode 100644 index 0000000000..1f8598c49c --- /dev/null +++ b/apps/remix-ide-e2e/src/tests/eip1153.test.ts @@ -0,0 +1,51 @@ +'use strict' + +import { NightwatchBrowser } from 'nightwatch' +import init from '../helpers/init' + +module.exports = { + '@disabled': true, + before: function (browser: NightwatchBrowser, done: VoidFunction) { + init(browser, done) + }, + 'Should execute a contract that uses transient storage #group1': function (browser: NightwatchBrowser) { + browser + .clickLaunchIcon('udapp') + .switchEnvironment('vm-cancun') // switch to a vm that know this eip. + .addFile('transient_storage.sol', { content: contractTransientStorage }) + .clickLaunchIcon('solidity') + .setSolidityCompilerVersion('soljson-v0.8.24+commit.e11b9ed9.js') + .click('*[data-id="scConfigExpander"]') + .setValue('#evmVersionSelector', 'cancun') // set target compilation to cancun + .clickLaunchIcon('solidity') + .verifyContracts(['TestTransientStorage']) + .clickLaunchIcon('udapp') + .createContract('') + .clickInstance(0) + .clickFunction('useTransientStorage - transact (not payable)') + .testFunction('last', + { + status: '0x1 Transaction mined and execution succeed', + 'decoded output': { + 0: 'uint256: out1 14', + 1: 'uint256: out2 15' + } + }) + .end() + } +} + +const contractTransientStorage = `// SPDX-License-Identifier: GPL-3.0 + +pragma solidity >=0.8.2 <0.9.0; + +contract TestTransientStorage { + function useTransientStorage() public returns (uint out1, uint out2) { + assembly { + tstore(0, 14) + tstore(1, 15) + out1 := tload(0) + out2 := tload(1) + } + } +}` diff --git a/apps/remix-ide-e2e/src/tests/proxy_oz_v5_non_shanghai_runtime.test.ts b/apps/remix-ide-e2e/src/tests/proxy_oz_v5_non_shanghai_runtime.test.ts index a93c9afc51..fa2545c4e0 100644 --- a/apps/remix-ide-e2e/src/tests/proxy_oz_v5_non_shanghai_runtime.test.ts +++ b/apps/remix-ide-e2e/src/tests/proxy_oz_v5_non_shanghai_runtime.test.ts @@ -20,7 +20,7 @@ module.exports = { 'Should show deploy proxy option for UUPS upgradeable contract #group1': function (browser: NightwatchBrowser) { browser .clickLaunchIcon('udapp') - .switchEnvironment('vm-merge') // this runtime doesn't have the PUSH0 opcode. + .switchEnvironment('vm-paris') // this runtime doesn't have the PUSH0 opcode. .clickLaunchIcon('solidity') .click('.remixui_compilerConfigSection') .setValue('#evmVersionSelector', 'paris') // set an evm version which doesn't have PUSH0 opcode. diff --git a/apps/remix-ide-e2e/src/tests/runAndDeploy.test.ts b/apps/remix-ide-e2e/src/tests/runAndDeploy.test.ts index 943292cc82..d8e6a14506 100644 --- a/apps/remix-ide-e2e/src/tests/runAndDeploy.test.ts +++ b/apps/remix-ide-e2e/src/tests/runAndDeploy.test.ts @@ -33,7 +33,7 @@ module.exports = { 'Should sign message using account key #group2': function (browser: NightwatchBrowser) { browser.waitForElementVisible('*[data-id="settingsRemixRunSignMsg"]') - .switchEnvironment('vm-merge') + .switchEnvironment('vm-paris') .pause(2000) .click('*[data-id="settingsRemixRunSignMsg"]') .pause(2000) @@ -266,7 +266,7 @@ module.exports = { .openFile('.states/vm-shanghai/state.json') .getEditorValue((content) => { browser - .assert.ok(content.includes('"latestBlockNumber": "0x02"'), 'State is saved') + .assert.ok(content.includes('"latestBlockNumber": "0x2"'), 'State is saved') }) }, @@ -303,7 +303,7 @@ module.exports = { .pause(100000) .getEditorValue((content) => { browser - .assert.ok(content.includes('"latestBlockNumber": "0x01"'), 'State is saved') + .assert.ok(content.includes('"latestBlockNumber": "0x1"'), 'State is saved') }) }, @@ -324,7 +324,7 @@ module.exports = { .openFile('.states/vm-shanghai/state.json') .getEditorValue((content) => { browser - .assert.ok(content.includes('"latestBlockNumber": "0x02"'), 'State is unchanged') + .assert.ok(content.includes('"latestBlockNumber": "0x2"'), 'State is unchanged') }) .end() } diff --git a/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts b/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts index 4aecf74ff3..dfe567603e 100644 --- a/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts +++ b/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts @@ -339,6 +339,8 @@ module.exports = { 'Basic Solidity Unit tests with local compiler #group6': function (browser: NightwatchBrowser) { browser + .clickLaunchIcon('udapp') + .switchEnvironment('vm-cancun') .clickLaunchIcon('solidity') .setSolidityCompilerVersion('builtin') .click('.remixui_compilerConfigSection') diff --git a/apps/remix-ide-e2e/src/tests/terminal.test.ts b/apps/remix-ide-e2e/src/tests/terminal.test.ts index 0127b830ef..eb5074e3ca 100644 --- a/apps/remix-ide-e2e/src/tests/terminal.test.ts +++ b/apps/remix-ide-e2e/src/tests/terminal.test.ts @@ -319,7 +319,7 @@ module.exports = { .execute(() => { (document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkEvmType"]') as any).focus() }, [], () => { }) - .click('*[data-id="CustomForkEvmType"] [value="merge"]') + .click('*[data-id="CustomForkEvmType"] [value="cancun"]') .pause(5000) .modalFooterOKClick('vm-custom-fork') .waitForElementPresent({ diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index 6f01181fa5..d78768c6a2 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -28,7 +28,7 @@ import {StoragePlugin} from './app/plugins/storage' import {Layout} from './app/panels/layout' import {NotificationPlugin} from './app/plugins/notification' import {Blockchain} from './blockchain/blockchain' -import {MergeVMProvider, LondonVMProvider, BerlinVMProvider, ShanghaiVMProvider} from './app/providers/vm-provider' +import {MergeVMProvider, LondonVMProvider, BerlinVMProvider, ShanghaiVMProvider, CancunVMProvider} from './app/providers/vm-provider' import {MainnetForkVMProvider} from './app/providers/mainnet-vm-fork-provider' import {SepoliaForkVMProvider} from './app/providers/sepolia-vm-fork-provider' import {GoerliForkVMProvider} from './app/providers/goerli-vm-fork-provider' @@ -260,6 +260,7 @@ class AppComponent { const vmProviderSepoliaFork = new SepoliaForkVMProvider(blockchain) const vmProviderGoerliFork = new GoerliForkVMProvider(blockchain) const vmProviderShanghai = new ShanghaiVMProvider(blockchain) + const vmProviderCancun = new CancunVMProvider(blockchain) const vmProviderMerge = new MergeVMProvider(blockchain) const vmProviderBerlin = new BerlinVMProvider(blockchain) const vmProviderLondon = new LondonVMProvider(blockchain) @@ -334,6 +335,7 @@ class AppComponent { dGitProvider, storagePlugin, vmProviderShanghai, + vmProviderCancun, vmProviderMerge, vmProviderBerlin, vmProviderLondon, diff --git a/apps/remix-ide/src/app/providers/abstract-provider.tsx b/apps/remix-ide/src/app/providers/abstract-provider.tsx index ea4cc5e281..e169e048d6 100644 --- a/apps/remix-ide/src/app/providers/abstract-provider.tsx +++ b/apps/remix-ide/src/app/providers/abstract-provider.tsx @@ -119,7 +119,7 @@ export abstract class AbstractProvider extends Plugin implements IProvider { } this.call('notification', 'alert', modalContent) } - await this.call('udapp', 'setEnvironmentMode', {context: 'vm-merge'}) + await this.call('udapp', 'setEnvironmentMode', {context: 'vm-paris'}) return } diff --git a/apps/remix-ide/src/app/providers/vm-provider.tsx b/apps/remix-ide/src/app/providers/vm-provider.tsx index aa1583f596..94c25ffdfc 100644 --- a/apps/remix-ide/src/app/providers/vm-provider.tsx +++ b/apps/remix-ide/src/app/providers/vm-provider.tsx @@ -46,17 +46,17 @@ export class MergeVMProvider extends BasicVMProvider { constructor(blockchain) { super( { - name: 'vm-merge', - displayName: 'Remix VM (Merge)', + name: 'vm-paris', + displayName: 'Remix VM (Paris)', kind: 'provider', - description: 'Remix VM (Merge)', + description: 'Remix VM (Paris)', methods: ['sendAsync', 'init'], version: packageJson.version }, blockchain ) this.blockchain = blockchain - this.fork = 'merge' + this.fork = 'paris' } } @@ -113,3 +113,21 @@ export class ShanghaiVMProvider extends BasicVMProvider { this.fork = 'shanghai' } } + +export class CancunVMProvider extends BasicVMProvider { + constructor(blockchain) { + super( + { + name: 'vm-cancun', + displayName: 'Remix VM (Cancun)', + kind: 'provider', + description: 'Remix VM (Cancun)', + methods: ['sendAsync', 'init'], + version: packageJson.version + }, + blockchain + ) + this.blockchain = blockchain + this.fork = 'cancun' + } +} diff --git a/apps/remix-ide/src/app/tabs/runTab/model/recorder.js b/apps/remix-ide/src/app/tabs/runTab/model/recorder.js index e27edcd3d9..23b9abf4be 100644 --- a/apps/remix-ide/src/app/tabs/runTab/model/recorder.js +++ b/apps/remix-ide/src/app/tabs/runTab/model/recorder.js @@ -1,6 +1,6 @@ var async = require('async') var remixLib = require('@remix-project/remix-lib') -import { bufferToHex } from '@ethereumjs/util' +import { bytesToHex } from '@ethereumjs/util' import { hash } from '@remix-project/remix-lib' import { Plugin } from '@remixproject/engine' import * as packageJson from '../../../../.././../../package.json' @@ -43,7 +43,7 @@ class Recorder extends Plugin { } if (!to) { var abi = payLoad.contractABI - var keccak = bufferToHex(hash.keccakFromString(JSON.stringify(abi))) + var keccak = bytesToHex(hash.keccakFromString(JSON.stringify(abi))) record.abi = keccak record.contractName = payLoad.contractName record.bytecode = payLoad.contractBytecode @@ -208,7 +208,7 @@ class Recorder extends Plugin { // resolve the bytecode and ABI using the contract name, this ensure getting the last compiled one. const data = await this.call('compilerArtefacts', 'getArtefactsByContractName', tx.record.contractName) tx.record.bytecode = data.artefact.evm.bytecode.object - const updatedABIKeccak = bufferToHex(hash.keccakFromString(JSON.stringify(data.artefact.abi))) + const updatedABIKeccak = bytesToHex(hash.keccakFromString(JSON.stringify(data.artefact.abi))) abis[updatedABIKeccak] = data.artefact.abi tx.record.abi = updatedABIKeccak } diff --git a/apps/remix-ide/src/app/udapp/run-tab.js b/apps/remix-ide/src/app/udapp/run-tab.js index 166ac7a42b..9d80081f0d 100644 --- a/apps/remix-ide/src/app/udapp/run-tab.js +++ b/apps/remix-ide/src/app/udapp/run-tab.js @@ -177,8 +177,9 @@ export class RunTab extends ViewPlugin { // VM const titleVM = 'Execution environment is local to Remix. Data is only saved to browser memory and will vanish upon reload.' + await addProvider('vm-cancun', 'Remix VM (Cancun)', false, true, 'cancun', 'settingsVMCancunMode', titleVM) await addProvider('vm-shanghai', 'Remix VM (Shanghai)', false, true, 'shanghai', 'settingsVMShanghaiMode', titleVM) - await addProvider('vm-merge', 'Remix VM (Merge)', false, true, 'merge', 'settingsVMMergeMode', titleVM) + await addProvider('vm-paris', 'Remix VM (Paris)', false, true, 'paris', 'settingsVMParisMode', titleVM) await addProvider('vm-london', 'Remix VM (London)', false, true, 'london', 'settingsVMLondonMode', titleVM) await addProvider('vm-berlin', 'Remix VM (Berlin)', false, true, 'berlin', 'settingsVMBerlinMode', titleVM) await addProvider('vm-mainnet-fork', 'Remix VM - Mainnet fork', false, true, 'merge', 'settingsVMMainnetMode', titleVM) diff --git a/apps/remix-ide/src/assets/list.json b/apps/remix-ide/src/assets/list.json index b22d882d4b..04a4929e01 100644 --- a/apps/remix-ide/src/assets/list.json +++ b/apps/remix-ide/src/assets/list.json @@ -1091,9 +1091,22 @@ "bzzr://c604bdd6384bf73594cd0e5cfbe979048191549ebc88e70996346f3b744c0680", "dweb:/ipfs/QmW2SQbEhiz3n2qV5iL8WBgzapv6cXjkLStvTMpCZhvr2x" ] + }, + { + "path": "soljson-v0.8.25+commit.b61c2a91.js", + "version": "0.8.25", + "build": "commit.b61c2a91", + "longVersion": "0.8.25+commit.b61c2a91", + "keccak256": "0x4639103a26b2f669bd3ecc22b1a1665819f2a2956f917ab91380bd9565dbcd01", + "sha256": "0xf8c9554471ff2db3843167dffb7a503293b5dc728c8305b044ef9fd37d626ca7", + "urls": [ + "bzzr://d201e60bd46193b11382988a854132b9e7fb0e1574cc766cb7f9efe8e44a680c", + "dweb:/ipfs/QmdduJxmPXungjJk2FBDw1bdDQ6ucHxYGLXRMBJqMFW7h9" + ] } ], "releases": { + "0.8.25": "soljson-v0.8.25+commit.b61c2a91.js", "0.8.24": "soljson-v0.8.24+commit.e11b9ed9.js", "0.8.23": "soljson-v0.8.23+commit.f704f362.js", "0.8.22": "soljson-v0.8.22+commit.4fc1097e.js", @@ -1186,5 +1199,5 @@ "0.4.0": "soljson-v0.4.0+commit.acd334c9.js", "0.3.6": "soljson-v0.3.6+commit.3fc68da5.js" }, - "latestRelease": "0.8.24" + "latestRelease": "0.8.25" } \ No newline at end of file diff --git a/apps/remix-ide/src/blockchain/blockchain.tsx b/apps/remix-ide/src/blockchain/blockchain.tsx index d0eba12fc7..fa57a1d58b 100644 --- a/apps/remix-ide/src/blockchain/blockchain.tsx +++ b/apps/remix-ide/src/blockchain/blockchain.tsx @@ -1,7 +1,7 @@ import React from 'react' // eslint-disable-line import {fromWei, toBigInt, toWei} from 'web3-utils' import {Plugin} from '@remixproject/engine' -import {toBuffer, addHexPrefix} from '@ethereumjs/util' +import {toBytes, addHexPrefix} from '@ethereumjs/util' import {EventEmitter} from 'events' import {format} from 'util' import {ExecutionContext} from './execution-context' @@ -906,9 +906,12 @@ export class Blockchain extends Plugin { let returnValue = null if (isVM) { if (!tx.useCall && this.config.get('settings/save-evm-state')) { - await this.executionContext.getStateDetails().then((state) => { + try { + const state = await this.executionContext.getStateDetails() this.call('fileManager', 'writeFile', `.states/${this.executionContext.getProvider()}/state.json`, state) - }) + } catch (e) { + console.error(e) + } } const hhlogs = await this.web3().remix.getHHLogsForTx(txResult.transactionHash) @@ -941,8 +944,8 @@ export class Blockchain extends Plugin { if (execResult) { // if it's not the VM, we don't have return value. We only have the transaction, and it does not contain the return value. returnValue = execResult - ? toBuffer(execResult.returnValue) - : toBuffer(addHexPrefix(txResult.result) || '0x0000000000000000000000000000000000000000000000000000000000000000') + ? toBytes(execResult.returnValue) + : toBytes(addHexPrefix(txResult.result) || '0x0000000000000000000000000000000000000000000000000000000000000000') const compiledContracts = await this.call('compilerArtefacts', 'getAllContractDatas') const vmError = txExecution.checkError({ errorMessage: execResult.exceptionError ? execResult.exceptionError.error : '', errorData: execResult.returnValue }, compiledContracts) if (vmError.error) { @@ -951,7 +954,7 @@ export class Blockchain extends Plugin { } } if (!isVM && tx && tx.useCall) { - returnValue = toBuffer(addHexPrefix(txResult.result)) + returnValue = toBytes(addHexPrefix(txResult.result)) } let address = null diff --git a/apps/remix-ide/src/blockchain/execution-context.js b/apps/remix-ide/src/blockchain/execution-context.js index 89ad383c7c..fe20b2dd04 100644 --- a/apps/remix-ide/src/blockchain/execution-context.js +++ b/apps/remix-ide/src/blockchain/execution-context.js @@ -3,7 +3,7 @@ import Web3 from 'web3' import { execution } from '@remix-project/remix-lib' import EventManager from '../lib/events' -import {bufferToHex} from '@ethereumjs/util' +import { bytesToHex } from '@ethereumjs/util' const _paq = window._paq = window._paq || [] let web3 @@ -114,7 +114,7 @@ export class ExecutionContext { removeProvider (name) { if (name && this.customNetWorks[name]) { - if (this.executionContext === name) this.setContext('vm-merge', null, null, null) + if (this.executionContext === name) this.setContext('vm-shanghai', null, null, null) delete this.customNetWorks[name] this.event.trigger('removeProvider', [name]) } @@ -207,10 +207,10 @@ export class ExecutionContext { } async getStateDetails() { - const db = await this.web3().remix.getStateDb() + const stateDb = await this.web3().remix.getStateDb() const blocksData = await this.web3().remix.getBlocksData() const state = { - db: Object.fromEntries(db._database), + db: Object.fromEntries(stateDb.db._database), blocks: blocksData.blocks, latestBlockNumber: blocksData.latestBlockNumber } @@ -218,11 +218,17 @@ export class ExecutionContext { if (key === 'db') { return value } else if (key === 'blocks') { - return value.map(block => bufferToHex(block)) - }else if (key === '') { - return value + return value.map(block => bytesToHex(block)) + } else if (key === '') { + return value } - return bufferToHex(value) + if (typeof value === 'string') { + return value.startsWith('0x') ? value : '0x' + value + } else if (typeof value === 'number') { + return '0x' + value.toString(16) + } else { + return bytesToHex(value) + } }, '\t') return stringifyed diff --git a/apps/remix-ide/src/blockchain/providers/injected.ts b/apps/remix-ide/src/blockchain/providers/injected.ts index 32b4938f70..905e77559a 100644 --- a/apps/remix-ide/src/blockchain/providers/injected.ts +++ b/apps/remix-ide/src/blockchain/providers/injected.ts @@ -1,5 +1,5 @@ import Web3 from 'web3' -import { hashPersonalMessage, isHexString } from '@ethereumjs/util' +import { hashPersonalMessage, isHexString, bytesToHex } from '@ethereumjs/util' import { ExecutionContext } from '../execution-context' export class InjectedProvider { @@ -42,7 +42,7 @@ export class InjectedProvider { try { message = isHexString(message) ? message : Web3.utils.utf8ToHex(message) this.executionContext.web3().eth.personal.sign(message, account).then((error, signedData) => { - cb(error, '0x' + messageHash.toString('hex'), signedData) + cb(error, bytesToHex(messageHash), signedData) }).catch((error => cb(error))) } catch (e) { cb(e.message) diff --git a/apps/remix-ide/src/blockchain/providers/node.ts b/apps/remix-ide/src/blockchain/providers/node.ts index c77421e045..fec159f11f 100644 --- a/apps/remix-ide/src/blockchain/providers/node.ts +++ b/apps/remix-ide/src/blockchain/providers/node.ts @@ -1,5 +1,5 @@ import Web3 from 'web3' -import { hashPersonalMessage, isHexString } from '@ethereumjs/util' +import { hashPersonalMessage, isHexString, bytesToHex } from '@ethereumjs/util' import { Personal } from 'web3-eth-personal' import { ExecutionContext } from '../execution-context' import Config from '../../config' @@ -49,8 +49,8 @@ export class NodeProvider { const personal = new Personal(this.executionContext.web3().currentProvider) message = isHexString(message) ? message : Web3.utils.utf8ToHex(message) personal.sign(message, account, passphrase) - .then(signedData => cb(undefined, '0x' + messageHash.toString('hex'), signedData)) - .catch(error => cb(error, '0x' + messageHash.toString('hex'), undefined)) + .then(signedData => cb(undefined, bytesToHex(messageHash), signedData)) + .catch(error => cb(error, bytesToHex(messageHash), undefined)) } catch (e) { cb(e.message) } diff --git a/apps/remix-ide/src/blockchain/providers/vm.ts b/apps/remix-ide/src/blockchain/providers/vm.ts index 5156206c1c..e44b67946a 100644 --- a/apps/remix-ide/src/blockchain/providers/vm.ts +++ b/apps/remix-ide/src/blockchain/providers/vm.ts @@ -1,8 +1,7 @@ import Web3, { FMT_BYTES, FMT_NUMBER, LegacySendAsyncProvider } from 'web3' import { fromWei, toBigInt } from 'web3-utils' -import { privateToAddress, hashPersonalMessage, isHexString } from '@ethereumjs/util' +import { privateToAddress, hashPersonalMessage, isHexString, bytesToHex } from '@ethereumjs/util' import { extend, JSONRPCRequestPayload, JSONRPCResponseCallback } from '@remix-project/remix-simulator' -import {toBuffer} from '@ethereumjs/util' import { ExecutionContext } from '../execution-context' export class VMProvider { @@ -110,7 +109,7 @@ export class VMProvider { const { privateKey, balance } = newAccount this.worker.postMessage({ cmd: 'addAccount', privateKey: privateKey, balance }) const privKey = Buffer.from(privateKey, 'hex') - return '0x' + privateToAddress(privKey).toString('hex') + return bytesToHex(privateToAddress(privKey)) } newAccount (_passwordPromptCb, cb) { @@ -133,7 +132,7 @@ export class VMProvider { const messageHash = hashPersonalMessage(Buffer.from(message)) message = isHexString(message) ? message : Web3.utils.utf8ToHex(message) this.web3.eth.sign(message, account) - .then(signedData => cb(null, '0x' + messageHash.toString('hex'), signedData)) + .then(signedData => cb(null, bytesToHex(messageHash), signedData)) .catch(error => cb(error)) } diff --git a/apps/remix-ide/src/lib/helper.js b/apps/remix-ide/src/lib/helper.js index d332c7e937..cb0a421fca 100644 --- a/apps/remix-ide/src/lib/helper.js +++ b/apps/remix-ide/src/lib/helper.js @@ -1,5 +1,5 @@ var async = require('async') -import { toChecksumAddress } from '@ethereumjs/util' +import { toChecksumAddress, bytesToHex } from '@ethereumjs/util' export default { shortenAddress: function (address, etherBalance) { @@ -9,7 +9,7 @@ export default { addressToString: function (address) { if (!address) return null if (typeof address !== 'string') { - address = address.toString('hex') + address = bytesToHex(address) } if (address.indexOf('0x') === -1) { address = '0x' + address diff --git a/apps/remix-ide/src/polyfills.ts b/apps/remix-ide/src/polyfills.ts index 53c485753e..ea29e0f516 100644 --- a/apps/remix-ide/src/polyfills.ts +++ b/apps/remix-ide/src/polyfills.ts @@ -5,3 +5,4 @@ */ import 'core-js/stable' import 'regenerator-runtime/runtime' +// import 'text-encoding' diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index 7234c60d59..9eaca5b06d 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -62,7 +62,7 @@ let requiredModules = [ // services + layout views + system views 'vm-goerli-fork', 'vm-mainnet-fork', 'vm-sepolia-fork', - 'vm-merge', + 'vm-paris', 'vm-london', 'vm-berlin', 'vm-shanghai', diff --git a/apps/remix-ide/webpack.config.js b/apps/remix-ide/webpack.config.js index 48d2c4eda1..5b3d7d56c1 100644 --- a/apps/remix-ide/webpack.config.js +++ b/apps/remix-ide/webpack.config.js @@ -6,7 +6,7 @@ const version = require('../../package.json').version const fs = require('fs') const TerserPlugin = require('terser-webpack-plugin') const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') -const axios = require('axios') +const rustbnWasm = require('rustbn-wasm') const versionData = { version: version, @@ -68,13 +68,15 @@ module.exports = composePlugins(withNx(), withReact(), (config) => { readline: false, child_process: false, buffer: require.resolve('buffer/'), - vm: require.resolve('vm-browserify') + vm: require.resolve('vm-browserify'), + 'rustbn-wasm': require.resolve('rustbn-wasm') } // add externals config.externals = { ...config.externals, - solc: 'solc' + solc: 'solc', + 'rustbn-wasm': rustbnWasm } // uncomment this to enable react profiling @@ -113,6 +115,7 @@ module.exports = composePlugins(withNx(), withReact(), (config) => { Buffer: ['buffer', 'Buffer'], url: ['url', 'URL'], process: 'process/browser', + 'rustbn-wasm': 'rustbn-wasm' }) ) diff --git a/libs/remix-analyzer/package.json b/libs/remix-analyzer/package.json index 701ae7116d..ca1fe428ce 100644 --- a/libs/remix-analyzer/package.json +++ b/libs/remix-analyzer/package.json @@ -21,10 +21,10 @@ } ], "dependencies": { - "@ethereumjs/block": "^4.2.0", - "@ethereumjs/tx": "^4.1.1", - "@ethereumjs/util": "^8.0.5", - "@ethereumjs/vm": "^6.4.1", + "@ethereumjs/block": "5.0.1", + "@ethereumjs/tx": "5.1.0", + "@ethereumjs/util": "9.0.1", + "@ethereumjs/vm": "7.1.0", "@remix-project/remix-astwalker": "^0.0.74", "@remix-project/remix-lib": "^0.5.51", "async": "^2.6.2", diff --git a/libs/remix-astwalker/package.json b/libs/remix-astwalker/package.json index 0aa4033927..38b5f214f1 100644 --- a/libs/remix-astwalker/package.json +++ b/libs/remix-astwalker/package.json @@ -33,10 +33,10 @@ ] }, "dependencies": { - "@ethereumjs/block": "^4.2.0", - "@ethereumjs/tx": "^4.1.1", - "@ethereumjs/util": "^8.0.5", - "@ethereumjs/vm": "^6.4.1", + "@ethereumjs/block": "5.0.1", + "@ethereumjs/tx": "5.1.0", + "@ethereumjs/util": "9.0.1", + "@ethereumjs/vm": "7.1.0", "@remix-project/remix-lib": "^0.5.51", "@types/tape": "^4.2.33", "async": "^2.6.2", diff --git a/libs/remix-debug/package.json b/libs/remix-debug/package.json index 2da1be4944..f03a6f68db 100644 --- a/libs/remix-debug/package.json +++ b/libs/remix-debug/package.json @@ -21,11 +21,11 @@ "test": "./../../node_modules/.bin/ts-node --project ../../tsconfig.base.json --require tsconfig-paths/register ./../../node_modules/.bin/tape ./test/tests.ts" }, "dependencies": { - "@ethereumjs/block": "^4.2.0", - "@ethereumjs/common": "^3.1.1", - "@ethereumjs/tx": "^4.1.1", - "@ethereumjs/util": "^8.0.5", - "@ethereumjs/vm": "^6.4.1", + "@ethereumjs/block": "5.0.1", + "@ethereumjs/common": "4.1.0", + "@ethereumjs/tx": "5.1.0", + "@ethereumjs/util": "9.0.1", + "@ethereumjs/vm": "7.1.0", "@remix-project/remix-astwalker": "^0.0.74", "@remix-project/remix-lib": "^0.5.51", "@remix-project/remix-simulator": "^0.2.44", diff --git a/libs/remix-debug/src/code/codeUtils.ts b/libs/remix-debug/src/code/codeUtils.ts index f9784bb135..b73956d1f4 100644 --- a/libs/remix-debug/src/code/codeUtils.ts +++ b/libs/remix-debug/src/code/codeUtils.ts @@ -1,6 +1,8 @@ 'use strict' +import { bytesToHex } from '@ethereumjs/util' import { Common } from '@ethereumjs/common' -import { getOpcodesForHF, OpcodeList } from '@ethereumjs/evm/dist/opcodes/codes' +// TODO fix the import when getOpcodesForHF is exported +import { getOpcodesForHF } from '../../../../node_modules/@ethereumjs/evm/dist/esm/opcodes/codes' import getOpcodes from './opcodes' export function nameOpCodes (raw, hardfork) { @@ -27,7 +29,8 @@ export function nameOpCodes (raw, hardfork) { i += jumpNum } - const data = (pushData as any).toString('hex') !== '' ? ' ' + (pushData as any).toString('hex') : '' + const hexCode = bytesToHex((pushData as any)) + const data = hexCode !== '' ? ' ' + hexCode : '' code.push(pad(pc, roundLog(raw.length, 10)) + ' ' + curOpCode + data) pushData = '' @@ -47,7 +50,7 @@ type Opcode = { */ export function parseCode (raw) { const common = new Common({ chain: 'mainnet', hardfork: 'merge' }) - const opcodes = getOpcodesForHF(common).opcodes + const opcodes = null // getOpcodesForHF(common).opcodes const code = [] for (let i = 0; i < raw.length; i++) { diff --git a/libs/remix-debug/src/code/disassembler.ts b/libs/remix-debug/src/code/disassembler.ts index b828fe7e5d..8087f44380 100644 --- a/libs/remix-debug/src/code/disassembler.ts +++ b/libs/remix-debug/src/code/disassembler.ts @@ -2,7 +2,7 @@ import { parseCode } from './codeUtils' import { util } from '@remix-project/remix-lib' -import { bufferToHex } from '@ethereumjs/util' +import { bytesToHex } from '@ethereumjs/util' function createExpressions (instructions) { const expressions = [] @@ -37,7 +37,7 @@ function createExpressions (instructions) { function toString (expr) { if (expr.name.slice(0, 4) === 'PUSH') { - return bufferToHex(expr.pushData) + return bytesToHex(expr.pushData) } else if (expr.name === 'JUMPDEST') { return expr.label + ':' } else if (expr.args) { diff --git a/libs/remix-debug/src/solidity-decoder/types/Mapping.ts b/libs/remix-debug/src/solidity-decoder/types/Mapping.ts index 2968ac1ba9..2810a9e6fb 100644 --- a/libs/remix-debug/src/solidity-decoder/types/Mapping.ts +++ b/libs/remix-debug/src/solidity-decoder/types/Mapping.ts @@ -2,7 +2,7 @@ import { hash } from '@remix-project/remix-lib' import { RefType } from './RefType' import { normalizeHex } from './util' -import { toBuffer, setLengthLeft, bufferToHex, addHexPrefix } from '@ethereumjs/util' +import { toBytes, setLengthLeft, bytesToHex, addHexPrefix } from '@ethereumjs/util' import BN from 'bn.js' export class Mapping extends RefType { @@ -44,7 +44,7 @@ export class Mapping extends RefType { } async decodeMappingsLocation (preimages, location, storageResolver) { - const mapSlot = normalizeHex(bufferToHex(location.slot)) + const mapSlot = normalizeHex('0x' + location.slot.toString(16)) if (!preimages[mapSlot]) { return {} } @@ -66,11 +66,11 @@ function getMappingLocation (key, position) { // > the value corresponding to a mapping key k is located at keccak256(k . p) where . is concatenation. // key should be a hex string, and position an int - const mappingK = toBuffer(addHexPrefix(key)) - let mappingP = toBuffer(addHexPrefix(position)) + const mappingK = toBytes(addHexPrefix(key)) + let mappingP = toBytes(addHexPrefix(position)) mappingP = setLengthLeft(mappingP, 32) const mappingKeyBuf = concatTypedArrays(mappingK, mappingP) - const mappingStorageLocation: Buffer = hash.keccak(mappingKeyBuf) + const mappingStorageLocation: Uint8Array = hash.keccak(mappingKeyBuf) const mappingStorageLocationinBn: BN = new BN(mappingStorageLocation, 16) return mappingStorageLocationinBn } diff --git a/libs/remix-debug/src/solidity-decoder/types/util.ts b/libs/remix-debug/src/solidity-decoder/types/util.ts index bd6a7f4bd1..a8d78b3acd 100644 --- a/libs/remix-debug/src/solidity-decoder/types/util.ts +++ b/libs/remix-debug/src/solidity-decoder/types/util.ts @@ -1,5 +1,5 @@ 'use strict' -import { bufferToHex, unpadHexString } from '@ethereumjs/util' +import { unpadHex } from '@ethereumjs/util' import BN from 'bn.js' export function decodeIntFromHex (value, byteLength, signed) { @@ -11,7 +11,7 @@ export function decodeIntFromHex (value, byteLength, signed) { } export function readFromStorage (slot, storageResolver): Promise { - const hexSlot = '0x' + normalizeHex(bufferToHex(slot)) + const hexSlot = '0x' + normalizeHex(slot.toString(16)) return new Promise((resolve, reject) => { storageResolver.storageSlot(hexSlot, (error, slot) => { if (error) { @@ -58,7 +58,7 @@ export function toBN (value) { if (value instanceof BN) { return value } else if (value.match && value.match(/^(0x)?([a-f0-9]*)$/)) { - value = unpadHexString(value) + value = unpadHex(value) value = value.replace('0x', '') value = new BN(value === '' ? '0' : value, 16) } else if (!isNaN(value)) { diff --git a/libs/remix-debug/src/trace/traceHelper.ts b/libs/remix-debug/src/trace/traceHelper.ts index 0f49bde110..1ab108b83d 100644 --- a/libs/remix-debug/src/trace/traceHelper.ts +++ b/libs/remix-debug/src/trace/traceHelper.ts @@ -44,7 +44,7 @@ export function isSSTOREInstruction (step) { } export function isSHA3Instruction (step) { - return step.op === 'SHA3' + return step.op === 'SHA3' || step.op === 'KECCAK256' } export function newContextStorage (step) { diff --git a/libs/remix-debug/test/decoder/stateTests/mapping.ts b/libs/remix-debug/test/decoder/stateTests/mapping.ts index 09056d3693..d13f4c36f5 100644 --- a/libs/remix-debug/test/decoder/stateTests/mapping.ts +++ b/libs/remix-debug/test/decoder/stateTests/mapping.ts @@ -10,7 +10,7 @@ import { InternalCallTree } from '../../../src/solidity-decoder/internalCallTree import * as vmCall from '../../vmCall' import { StorageResolver } from '../../../src/storage/storageResolver' import { StorageViewer } from '../../../src/storage/storageViewer' -import { Address, bufferToHex } from '@ethereumjs/util' +import { Address, bytesToHex } from '@ethereumjs/util' module.exports = async function testMappingStorage (st, cb) { const mappingStorage = require('../contracts/mappingStorage') diff --git a/libs/remix-lib/package.json b/libs/remix-lib/package.json index 1a0d3f574d..4d5e51dc63 100644 --- a/libs/remix-lib/package.json +++ b/libs/remix-lib/package.json @@ -17,7 +17,7 @@ "test": "./../../node_modules/.bin/ts-node --require tsconfig-paths/register ./../../node_modules/.bin/tape ./test/tests.ts" }, "dependencies": { - "@ethereumjs/util": "^8.0.5", + "@ethereumjs/util": "9.0.1", "async": "^2.1.2", "create-hash": "^1.2.0", "ethers": "^5.7.2", diff --git a/libs/remix-lib/src/execution/logsManager.ts b/libs/remix-lib/src/execution/logsManager.ts index fbb0d1cf8c..c81bea4b6c 100644 --- a/libs/remix-lib/src/execution/logsManager.ts +++ b/libs/remix-lib/src/execution/logsManager.ts @@ -1,6 +1,6 @@ import { eachOf } from 'async' import { randomBytes } from 'crypto' -import { toChecksumAddress } from '@ethereumjs/util' +import { toChecksumAddress, bytesToHex } from '@ethereumjs/util' export class LogsManager { notificationCallbacks @@ -19,7 +19,7 @@ export class LogsManager { checkBlock (blockNumber, block, web3) { eachOf(block.transactions, (tx: any, i, next) => { - const txHash = '0x' + tx.hash().toString('hex') + const txHash = bytesToHex(tx.hash()) web3.eth.getTransactionReceipt(txHash, (_error, receipt) => { if (!receipt) return next() for (const log of receipt.logs) { @@ -29,8 +29,8 @@ export class LogsManager { const result = { logIndex: '0x1', // 1 blockNumber: blockNumber, - blockHash: ('0x' + block.hash().toString('hex')), - transactionHash: ('0x' + tx.hash().toString('hex')), + blockHash: bytesToHex(block.hash()), + transactionHash: bytesToHex(tx.hash()), transactionIndex: '0x' + i.toString(16), // TODO: if it's a contract deploy, it should be that address instead address: log.address, @@ -140,7 +140,7 @@ export class LogsManager { if (filterType === 'block') { const blocks = this.oldLogs.filter(x => x.type === 'block').filter(x => tracking.block === undefined || x.blockNumber >= tracking.block) tracking.block = blocks[blocks.length - 1] - return blocks.map(block => ('0x' + block.hash().toString('hex'))) + return blocks.map(block => bytesToHex(block.hash())) } if (filterType === 'pendingTransactions') { return [] @@ -148,13 +148,13 @@ export class LogsManager { } getLogsByTxHash (hash) { - return this.oldLogs.filter((log) => '0x' + log.tx.hash().toString('hex') === hash) + return this.oldLogs.filter((log) => bytesToHex(log.tx.hash()) === hash) .map((log) => { return { logIndex: '0x1', // 1 blockNumber: log.blockNumber, - blockHash: ('0x' + log.block.hash().toString('hex')), - transactionHash: ('0x' + log.tx.hash().toString('hex')), + blockHash: bytesToHex(log.block.hash()), + transactionHash: bytesToHex(log.tx.hash()), transactionIndex: '0x' + log.txNumber.toString(16), // TODO: if it's a contract deploy, it should be that address instead address: log.log.address, @@ -171,8 +171,8 @@ export class LogsManager { results.push({ logIndex: '0x1', // 1 blockNumber: log.blockNumber, - blockHash: ('0x' + log.block.hash().toString('hex')), - transactionHash: ('0x' + log.tx.hash().toString('hex')), + blockHash: bytesToHex(log.block.hash()), + transactionHash: bytesToHex(log.tx.hash()), transactionIndex: '0x' + log.txNumber.toString(16), // TODO: if it's a contract deploy, it should be that address instead address: log.log.address, diff --git a/libs/remix-lib/src/execution/txListener.ts b/libs/remix-lib/src/execution/txListener.ts index 32f5427ebe..efa5449c62 100644 --- a/libs/remix-lib/src/execution/txListener.ts +++ b/libs/remix-lib/src/execution/txListener.ts @@ -1,6 +1,6 @@ 'use strict' import { ethers } from 'ethers' -import { toBuffer, addHexPrefix } from '@ethereumjs/util' +import { toBytes, addHexPrefix } from '@ethereumjs/util' import { EventManager } from '../eventManager' import { compareByteCode, getinputParameters } from '../util' import { decodeResponse } from './txFormat' @@ -64,9 +64,9 @@ export class TxListener { let execResult if (this.executionContext.isVM()) { execResult = await this.executionContext.web3().remix.getExecutionResultFromSimulator(txResult.transactionHash) - returnValue = toBuffer(execResult.returnValue) + returnValue = toBytes(execResult.returnValue) } else { - returnValue = toBuffer(addHexPrefix(txResult.result)) + returnValue = toBytes(addHexPrefix(txResult.result)) } const call = { from: from, @@ -374,8 +374,8 @@ export class TxListener { } _decodeInputParams (data, abi) { - data = toBuffer(addHexPrefix(data)) - if (!data.length) data = new Uint8Array(32 * abi.inputs.length) // ensuring the data is at least filled by 0 cause `AbiCoder` throws if there's not enough data + data = toBytes(addHexPrefix(data)) + if (!data.length) data = new Uint8Array(32 * abi.inputs.length) // ensuring the data is at least filled by 0 cause `AbiCoder` throws if there's not engouh data const inputTypes = [] for (let i = 0; i < abi.inputs.length; i++) { diff --git a/libs/remix-lib/src/execution/txRunnerVM.ts b/libs/remix-lib/src/execution/txRunnerVM.ts index 74e42feb51..c3b6efd690 100644 --- a/libs/remix-lib/src/execution/txRunnerVM.ts +++ b/libs/remix-lib/src/execution/txRunnerVM.ts @@ -1,9 +1,10 @@ 'use strict' import { RunBlockResult, RunTxResult } from '@ethereumjs/vm' import { ConsensusType } from '@ethereumjs/common' -import { Transaction, FeeMarketEIP1559Transaction } from '@ethereumjs/tx' +import { LegacyTransaction, FeeMarketEIP1559Transaction } from '@ethereumjs/tx' import { Block } from '@ethereumjs/block' -import { bufferToHex, Address } from '@ethereumjs/util' +import { bytesToHex, Address, hexToBytes } from '@ethereumjs/util' +import { EVM } from '@ethereumjs/evm' import type { Account } from '@ethereumjs/util' import { EventManager } from '../eventManager' import { LogsManager } from './logsManager' @@ -13,7 +14,7 @@ export type VMexecutionResult = { result: RunTxResult, transactionHash: string block: Block, - tx: Transaction + tx: LegacyTransaction } export type VMExecutionCallBack = (error: string | Error, result?: VMexecutionResult) => void @@ -24,20 +25,20 @@ export class TxRunnerVM { pendingTxs vmaccounts queusTxs - blocks: Buffer[] + blocks: Uint8Array[] logsManager commonContext blockParentHash nextNonceForCall: number + standaloneTx: boolean getVMObject: () => any - constructor (vmaccounts, api, getVMObject, blocks: Buffer[] = []) { + constructor (vmaccounts, api, getVMObject, blocks: Uint8Array[] = []) { this.event = new EventManager() this.logsManager = new LogsManager() // has a default for now for backwards compatibility this.getVMObject = getVMObject - this.commonContext = this.getVMObject().common - this.blockNumber = Array.isArray(blocks) ? blocks.length : 0 // TODO: this should be set to the fetched block number count + this.commonContext = this.getVMObject().common this.pendingTxs = {} this.vmaccounts = vmaccounts this.queusTxs = [] @@ -74,7 +75,7 @@ export class TxRunnerVM { } } - runInVm (from: string, to: string, data: string, value: string, gasLimit: number, useCall: boolean, callback: VMExecutionCallBack) { + async runInVm (from: string, to: string, data: string, value: string, gasLimit: number, useCall: boolean, callback: VMExecutionCallBack) { let account if (!from && useCall && Object.keys(this.vmaccounts).length) { from = Object.keys(this.vmaccounts)[0] @@ -85,52 +86,51 @@ export class TxRunnerVM { return callback('Invalid account selected') } - this.getVMObject().stateManager.getAccount(Address.fromString(from)).then((res: Account) => { + try { + const res = await this.getVMObject().stateManager.getAccount(Address.fromString(from)) const EIP1559 = this.commonContext.hardfork() !== 'berlin' // berlin is the only pre eip1559 fork that we handle. let tx if (!EIP1559) { - tx = Transaction.fromTxData({ + tx = LegacyTransaction.fromTxData({ nonce: useCall ? this.nextNonceForCall : res.nonce, gasPrice: '0x1', gasLimit: gasLimit, to: to, value: value, - data: Buffer.from(data.slice(2), 'hex') + data: hexToBytes(data) }, { common: this.commonContext }).sign(account.privateKey) } else { tx = FeeMarketEIP1559Transaction.fromTxData({ nonce: useCall ? this.nextNonceForCall : res.nonce, maxPriorityFeePerGas: '0x01', - maxFeePerGas: '0x1', + maxFeePerGas: '0x7', gasLimit: gasLimit, to: to, value: value, - data: Buffer.from(data.slice(2), 'hex') + data: hexToBytes(data) }).sign(account.privateKey) } if (useCall) this.nextNonceForCall++ const coinbases = ['0x0e9281e9c6a0808672eaba6bd1220e144c9bb07a', '0x8945a1288dc78a6d8952a92c77aee6730b414778', '0x94d76e24f818426ae84aa404140e8d5f60e10e7e'] const difficulties = [69762765929000, 70762765929000, 71762765929000] - const difficulty = this.commonContext.consensusType() === ConsensusType.ProofOfStake ? 0 : difficulties[this.blockNumber % difficulties.length] - const blocknumber = this.blocks.length + const difficulty = this.commonContext.consensusType() === ConsensusType.ProofOfStake ? 0 : difficulties[this.blocks.length % difficulties.length] const block = Block.fromBlockData({ header: { timestamp: new Date().getTime() / 1000 | 0, - number: blocknumber, - coinbase: coinbases[blocknumber % coinbases.length], + number: this.blocks.length, + coinbase: coinbases[this.blocks.length % coinbases.length], difficulty, gasLimit, baseFeePerGas: EIP1559 ? '0x1' : undefined, parentHash: this.blockParentHash }, transactions: [tx] - }, { common: this.commonContext, hardforkByBlockNumber: false, hardforkByTTD: undefined }) + }, { common: this.commonContext }) - if (!useCall) { - this.blockNumber = blocknumber + if (!this.standaloneTx) { this.blockParentHash = block.hash() - this.runBlockInVm(tx, block, (err, result) => { + this.runBlockInVm(tx, block, async (err, result) => { if (!err) { this.getVMObject().vm.blockchain.putBlock(block) this.blocks.push(block.serialize()) @@ -138,25 +138,36 @@ export class TxRunnerVM { callback(err, result) }) } else { - this.getVMObject().stateManager.checkpoint().then(() => { - this.runBlockInVm(tx, block, (err, result) => { - this.getVMObject().stateManager.revert().then(() => { - callback(err, result) - }) - }) + await this.getVMObject().vm.evm.journal.checkpoint() + this.runTxInVm(tx, block, async (err, result) => { + await this.getVMObject().vm.evm.journal.revert() + callback(err, result) }) } - }).catch((e) => { + } catch (e) { callback(e) + } + } + + runTxInVm (tx, block, callback) { + this.getVMObject().vm.runTx({ tx, skipNonce: true, skipBlockValidation: true, skipBalance: false }).then((result: RunTxResult) => { + callback(null, { + result, + transactionHash: bytesToHex(Buffer.from(tx.hash())), + block, + tx + }) + }).catch(function (err) { + callback(err) }) } runBlockInVm (tx, block, callback) { - this.getVMObject().vm.runBlock({ block: block, generate: true, skipBlockValidation: true, skipBalance: false, skipNonce: true }).then((results: RunBlockResult) => { + this.getVMObject().vm.runBlock({ block: block, generate: true, skipNonce: true, skipBlockValidation: true, skipBalance: false }).then((results: RunBlockResult) => { const result: RunTxResult = results.results[0] callback(null, { result, - transactionHash: bufferToHex(Buffer.from(tx.hash())), + transactionHash: bytesToHex(Buffer.from(tx.hash())), block, tx }) diff --git a/libs/remix-lib/src/execution/typeConversion.ts b/libs/remix-lib/src/execution/typeConversion.ts index c05e9873ec..b960cae173 100644 --- a/libs/remix-lib/src/execution/typeConversion.ts +++ b/libs/remix-lib/src/execution/typeConversion.ts @@ -1,6 +1,6 @@ 'use strict' import { BN } from 'bn.js' -import { bufferToHex } from '@ethereumjs/util' +import { bytesToHex } from '@ethereumjs/util' import { isBigInt } from 'web3-validator' export function toInt (h) { @@ -27,7 +27,7 @@ function convertToString (v) { } else if (v._isBigNumber) { return toInt(v._hex) } else if (v._isBuffer) { - return bufferToHex(v) + return bytesToHex(v) } else if (typeof v === 'object') { const retObject = {} for (const i in v) { diff --git a/libs/remix-lib/src/hash.ts b/libs/remix-lib/src/hash.ts index a12cc75d88..4d543f0e52 100644 --- a/libs/remix-lib/src/hash.ts +++ b/libs/remix-lib/src/hash.ts @@ -1,27 +1,26 @@ import { keccak224, keccak384, keccak256 as k256, keccak512 } from 'ethereum-cryptography/keccak' const createHash = require('create-hash') import { encode, Input } from 'rlp' -import { toBuffer, setLengthLeft, isHexString } from '@ethereumjs/util' +import { toBytes, setLengthLeft, isHexString } from '@ethereumjs/util' /** - * Creates Keccak hash of a Buffer input - * @param a The input data (Buffer) + * Creates Keccak hash of a Uint8Array input + * @param a The input data (Uint8Array) * @param bits (number = 256) The Keccak width */ -export const keccak = function(a: Buffer, bits: number = 256): Buffer { - assertIsBuffer(a) +export const keccak = function(a: Uint8Array, bits: number = 256): Uint8Array { switch (bits) { case 224: { - return toBuffer(keccak224(a)) + return toBytes(keccak224(Buffer.from(a))) } case 256: { - return toBuffer(k256(a)) + return toBytes(k256(Buffer.from(a))) } case 384: { - return toBuffer(keccak384(a)) + return toBytes(keccak384(Buffer.from(a))) } case 512: { - return toBuffer(keccak512(a)) + return toBytes(keccak512(Buffer.from(a))) } default: { throw new Error(`Invalid algorithm: keccak${bits}`) @@ -33,7 +32,7 @@ export const keccak = function(a: Buffer, bits: number = 256): Buffer { * Creates Keccak-256 hash of the input, alias for keccak(a, 256). * @param a The input data (Buffer) */ -export const keccak256 = function(a: Buffer): Buffer { +export const keccak256 = function(a: Buffer): Uint8Array { return keccak(a) } @@ -55,7 +54,7 @@ export const keccakFromString = function(a: string, bits: number = 256) { */ export const keccakFromHexString = function(a: string, bits: number = 256) { assertIsHexString(a) - return keccak(toBuffer(a), bits) + return keccak(Buffer.from(toBytes(a)), bits) } /** @@ -65,7 +64,7 @@ export const keccakFromHexString = function(a: string, bits: number = 256) { */ export const keccakFromArray = function(a: number[], bits: number = 256) { assertIsArray(a) - return keccak(toBuffer(a), bits) + return keccak(Buffer.from(toBytes(a)), bits) } /** @@ -73,7 +72,7 @@ export const keccakFromArray = function(a: number[], bits: number = 256) { * @param a The input data (Buffer|Array|String) */ const _sha256 = function(a: any): Buffer { - a = toBuffer(a) + a = toBytes(a) return createHash('sha256') .update(a) .digest() @@ -112,12 +111,12 @@ export const sha256FromArray = function(a: number[]): Buffer { * @param padded Whether it should be padded to 256 bits or not */ const _ripemd160 = function(a: any, padded: boolean): Buffer { - a = toBuffer(a) + a = toBytes(a) const hash = createHash('rmd160') .update(a) .digest() if (padded === true) { - return setLengthLeft(hash, 32) + return Buffer.from(setLengthLeft(hash, 32)) } else { return hash } @@ -158,7 +157,7 @@ export const ripemd160FromArray = function(a: number[], padded: boolean): Buffer * @param a The input data */ export const rlphash = function(a: Input): Buffer { - return keccak(Buffer.from(encode(a))) + return Buffer.from(keccak(Buffer.from(encode(a)))) } /** diff --git a/libs/remix-lib/src/helpers/txResultHelper.ts b/libs/remix-lib/src/helpers/txResultHelper.ts index a7a89163c6..c406fd2701 100644 --- a/libs/remix-lib/src/helpers/txResultHelper.ts +++ b/libs/remix-lib/src/helpers/txResultHelper.ts @@ -1,12 +1,12 @@ 'use strict' -import { bufferToHex } from '@ethereumjs/util' +import { bytesToHex } from '@ethereumjs/util' import { isHexString } from 'ethjs-util' function convertToPrefixedHex (input) { if (input === undefined || input === null || isHexString(input)) { return input } else if (Buffer.isBuffer(input)) { - return bufferToHex(input) + return bytesToHex(input) } return '0x' + input.toString(16) } diff --git a/libs/remix-lib/src/util.ts b/libs/remix-lib/src/util.ts index 3cefab792e..7cb42f1470 100644 --- a/libs/remix-lib/src/util.ts +++ b/libs/remix-lib/src/util.ts @@ -1,6 +1,6 @@ 'use strict' import { hash } from '@remix-project/remix-lib' -import { bufferToHex, setLengthLeft, toBuffer, addHexPrefix } from '@ethereumjs/util' +import { bytesToHex, setLengthLeft, toBytes, addHexPrefix } from '@ethereumjs/util' import stringSimilarity from 'string-similarity' /* @@ -58,7 +58,7 @@ export function toHexPaddedString(v: bigint | string): string { ints: ints: IntArray */ export function formatMemory (mem) { - const hexMem = bufferToHex(mem).substr(2) + const hexMem = bytesToHex(mem).substr(2) const ret = [] for (let k = 0; k < hexMem.length; k += 32) { const row = hexMem.substr(k, 32) @@ -152,9 +152,9 @@ export function buildCallPath (index, rootCall) { */ // eslint-disable-next-line camelcase export function sha3_256 (value) { - value = toBuffer(addHexPrefix(value)) - const retInBuffer: Buffer = hash.keccak(setLengthLeft(value, 32)) - return bufferToHex(retInBuffer) + value = toBytes(addHexPrefix(value)) + const retInBuffer: Uint8Array = hash.keccak(Buffer.from(setLengthLeft(value, 32))) + return bytesToHex(retInBuffer) } /** diff --git a/libs/remix-simulator/package.json b/libs/remix-simulator/package.json index 3b77d65bb3..9ecd366a78 100644 --- a/libs/remix-simulator/package.json +++ b/libs/remix-simulator/package.json @@ -17,11 +17,11 @@ "test": "./../../node_modules/.bin/ts-node --project ../../tsconfig.base.json --require tsconfig-paths/register ./../../node_modules/.bin/mocha test/*.ts" }, "dependencies": { - "@ethereumjs/block": "^4.2.0", - "@ethereumjs/common": "^3.1.1", - "@ethereumjs/tx": "^4.1.1", - "@ethereumjs/util": "^8.0.5", - "@ethereumjs/vm": "^6.4.1", + "@ethereumjs/block": "5.0.1", + "@ethereumjs/common": "4.1.0", + "@ethereumjs/tx": "5.1.0", + "@ethereumjs/util": "9.0.1", + "@ethereumjs/vm": "7.1.0", "@remix-project/remix-lib": "^0.5.51", "ansi-gray": "^0.1.1", "async": "^3.1.0", diff --git a/libs/remix-simulator/src/VmProxy.ts b/libs/remix-simulator/src/VmProxy.ts index d0a5e634e2..3d6353faa7 100644 --- a/libs/remix-simulator/src/VmProxy.ts +++ b/libs/remix-simulator/src/VmProxy.ts @@ -3,13 +3,13 @@ const { toHexPaddedString, formatMemory } = util import { helpers } from '@remix-project/remix-lib' const { normalizeHexAddress } = helpers.ui import { ConsoleLogs, hash } from '@remix-project/remix-lib' -import { toChecksumAddress, bufferToHex, Address, toBuffer } from '@ethereumjs/util' +import { toChecksumAddress, bytesToHex, Address, toBytes, bigIntToHex} from '@ethereumjs/util' import utils, {toBigInt} from 'web3-utils' import {isBigInt} from 'web3-validator' import { ethers } from 'ethers' import { VMContext } from './vm-context' -import type { StateManager } from '@ethereumjs/statemanager' -import type { InterpreterStep } from '@ethereumjs/evm/dist/interpreter' +import type { EVMStateManagerInterface } from '@ethereumjs/common' +import type { EVMResult, InterpreterStep, Message } from '@ethereumjs/evm' import type { AfterTxEvent, VM } from '@ethereumjs/vm' import type { TypedTransaction } from '@ethereumjs/tx' @@ -43,9 +43,12 @@ export class VmProxy { utils txsMapBlock blocks - stateCopy: StateManager - flagDoNotRecordEVMSteps: boolean + stateCopy: EVMStateManagerInterface + flagrecordVMSteps: boolean lastMemoryUpdate: Array + randomCallHash: bigint + callIncrement: bigint + txRunning: boolean constructor (vmContext: VMContext) { this.vmContext = vmContext @@ -89,20 +92,41 @@ export class VmProxy { this.txsMapBlock = {} this.blocks = {} this.lastMemoryUpdate = [] + this.flagrecordVMSteps = true + this.randomCallHash = BigInt('0x34c5f87d9ac75c4b2a3ba8fba43c30456a346c6a9e250bf48f29167fc6798826') + this.callIncrement = BigInt(1) + this.txRunning = false } setVM (vm) { if (this.vm === vm) return this.vm = vm - this.vm.evm.events.on('step', async (data: InterpreterStep) => { + /*this.vm.evm.events.on('beforeMessage', async (data: Message, resolve: (result?: any) => void) => { + if (!this.txRunning) { + await this.messageWillProcess(data) + } + resolve() + }) + this.vm.evm.events.on('afterMessage', async (data: EVMResult, resolve: (result?: any) => void) => { + if (!this.txRunning) { + await this.messageProcessed(data) + } + resolve() + })*/ + this.vm.evm.events.on('step', async (data: InterpreterStep, resolve: (result?: any) => void) => { await this.pushTrace(data) + resolve() }) this.vm.events.on('afterTx', async (data: AfterTxEvent, resolve: (result?: any) => void) => { + console.log('afterTx') await this.txProcessed(data) + this.txRunning = false resolve() }) this.vm.events.on('beforeTx', async (data: TypedTransaction, resolve: (result?: any) => void) => { - await this.txWillProcess(data) + console.log('beforeTx') + this.txRunning = true + await this.txWillProcess(data) resolve() }) } @@ -113,16 +137,16 @@ export class VmProxy { return ret } - flagNextAsDoNotRecordEvmSteps () { - this.flagDoNotRecordEVMSteps = true + recordVMSteps (record) { + this.flagrecordVMSteps = record } - + async txWillProcess (data: TypedTransaction) { - if (this.flagDoNotRecordEVMSteps) return + if (!this.flagrecordVMSteps) return this.lastMemoryUpdate = [] - this.stateCopy = await this.vm.stateManager.copy() + this.stateCopy = await this.vm.stateManager.shallowCopy() this.incr++ - this.processingHash = bufferToHex(data.hash()) + this.processingHash = bytesToHex(data.hash()) this.vmTraces[this.processingHash] = { gas: '0x0', return: '0x0', @@ -135,7 +159,7 @@ export class VmProxy { tx['to'] = toChecksumAddress(data.to.toString()) } this.processingAddress = tx['to'] - tx['input'] = bufferToHex(data.data) + tx['input'] = bytesToHex(data.data) tx['gas'] = data.gasLimit.toString(10) if (data.value) { tx['value'] = data.value.toString(10) @@ -158,10 +182,7 @@ export class VmProxy { } async txProcessed (data: AfterTxEvent) { - if (this.flagDoNotRecordEVMSteps) { - this.flagDoNotRecordEVMSteps = false - return - } + if (!this.flagrecordVMSteps) return const lastOp = this.vmTraces[this.processingHash].structLogs[this.processingIndex - 1] if (lastOp) { lastOp.error = lastOp.op !== 'RETURN' && lastOp.op !== 'STOP' && lastOp.op !== 'DESTRUCT' @@ -176,14 +197,14 @@ export class VmProxy { if (log[1].length > 0) { for (const k in log[1]) { // @ts-ignore - topics.push('0x' + log[1][k].toString('hex')) + topics.push(bytesToHex(log[1][k])) } } else { topics.push('0x') } logs.push({ - address: toChecksumAddress('0x' + log[0].toString('hex')), - data: '0x' + log[2].toString('hex'), + address: toChecksumAddress(bytesToHex(log[0])), + data: bytesToHex(log[2]), topics: topics, rawVMResponse: log }) @@ -216,18 +237,20 @@ export class VmProxy { this.vmTraces[this.processingHash].return = checksumedAddress this.txsReceipt[this.processingHash].contractAddress = checksumedAddress } else if (data.execResult.returnValue) { - this.vmTraces[this.processingHash].return = '0x' + data.execResult.returnValue.toString('hex') + this.vmTraces[this.processingHash].return = bytesToHex(data.execResult.returnValue) } else { this.vmTraces[this.processingHash].return = '0x' } this.processingIndex = null this.processingAddress = null + this.processingHash = null this.previousDepth = 0 this.stateCopy = null } async pushTrace (data: InterpreterStep) { - if (this.flagDoNotRecordEVMSteps) return + if (!this.flagrecordVMSteps) return + try { const depth = data.depth + 1 // geth starts the depth from 1 if (!this.processingHash) { @@ -308,7 +331,7 @@ export class VmProxy { } } } - if (previousOpcode && previousOpcode.op === 'SHA3') { + if (previousOpcode && (previousOpcode.op === 'SHA3' || previousOpcode.op === 'KECCAK256')) { const preimage = this.getSha3Input(previousOpcode.stack, formatMemory(this.lastMemoryUpdate)) const imageHash = toHexPaddedString(step.stack[step.stack.length - 1]).replace('0x', '') this.sha3Preimages[imageHash] = { @@ -325,7 +348,7 @@ export class VmProxy { getCode (address, cb) { address = toChecksumAddress(address) this.vm.stateManager.getContractCode(Address.fromString(address)).then((result) => { - cb(null, bufferToHex(result)) + cb(null, bytesToHex(result)) }).catch((error) => { cb(error) }) @@ -352,10 +375,10 @@ export class VmProxy { blockNumber = blockNumber === 'latest' ? this.vmContext.latestBlockNumber : blockNumber const block = this.vmContext.blocks[blockNumber] - const txHash = '0x' + block.transactions[block.transactions.length - 1].hash().toString('hex') + const txHash = bytesToHex(block.transactions[block.transactions.length - 1].hash()) if (this.storageCache['after_' + txHash] && this.storageCache['after_' + txHash][address]) { - const slot = '0x' + hash.keccak(toBuffer(ethers.utils.hexZeroPad(position, 32))).toString('hex') + const slot = bytesToHex(hash.keccak(toBytes(ethers.utils.hexZeroPad(position, 32)))) const storage = this.storageCache['after_' + txHash][address] return cb(null, storage[slot].value) } @@ -369,7 +392,7 @@ export class VmProxy { address = toChecksumAddress(address) const block = this.vmContext.blocks[blockNumber] - const txHash = '0x' + block.transactions[txIndex].hash().toString('hex') + const txHash = bytesToHex(block.transactions[txIndex].hash()) if (this.storageCache[txHash] && this.storageCache[txHash][address]) { const storage = this.storageCache[txHash][address] diff --git a/libs/remix-simulator/src/methods/accounts.ts b/libs/remix-simulator/src/methods/accounts.ts index 62a8411a0d..5ac0116555 100644 --- a/libs/remix-simulator/src/methods/accounts.ts +++ b/libs/remix-simulator/src/methods/accounts.ts @@ -1,4 +1,4 @@ -import { privateToAddress, toChecksumAddress, isValidPrivate, Address } from '@ethereumjs/util' +import { privateToAddress, toChecksumAddress, isValidPrivate, Address, toBytes, bytesToHex, Account } from '@ethereumjs/util' import { privateKeyToAccount } from 'web3-eth-accounts' import { toBigInt } from 'web3-utils' import * as crypto from 'crypto' @@ -36,26 +36,27 @@ export class Web3Accounts { await this._addAccount('71975fbf7fe448e004ac7ae54cad0a383c3906055a65468714156a07385e96ce', '0x56BC75E2D63100000') } - _addAccount (privateKey, balance) { - return new Promise((resolve, reject) => { - privateKey = Buffer.from(privateKey, 'hex') - const address: Buffer = privateToAddress(privateKey) - const addressStr = toChecksumAddress('0x' + address.toString('hex')) + async _addAccount (privateKey, balance) { + try { + privateKey = toBytes('0x' + privateKey) + const address: Uint8Array = privateToAddress(privateKey) + const addressStr = toChecksumAddress(bytesToHex(address)) this.accounts[addressStr] = { privateKey, nonce: 0 } - this.accountsKeys[addressStr] = '0x' + privateKey.toString('hex') + this.accountsKeys[addressStr] = bytesToHex(privateKey) const stateManager = this.vmContext.vm().stateManager - stateManager.getAccount(Address.fromString(addressStr)).then((account) => { + const account = await stateManager.getAccount(Address.fromString(addressStr)) + if (!account) { + const account = new Account(BigInt(0), toBigInt(balance || '0xf00000000000000001')) + await stateManager.putAccount(Address.fromString(addressStr), account) + } else { account.balance = toBigInt(balance || '0xf00000000000000001') - stateManager.putAccount(Address.fromString(addressStr), account).catch((error) => { - reject(error) - }).then(() => { - resolve({}) - }) - }).catch((error) => { - reject(error) - }) - }) + await stateManager.putAccount(Address.fromString(addressStr), account) + } + } catch (e) { + console.error(e) + } + } newAccount (cb) { @@ -64,7 +65,7 @@ export class Web3Accounts { privateKey = crypto.randomBytes(32) } while (!isValidPrivate(privateKey)) this._addAccount(privateKey, '0x56BC75E2D63100000') - return cb(null, '0x' + privateToAddress(privateKey).toString('hex')) + return cb(null, bytesToHex(privateToAddress(privateKey))) } methods (): Record { @@ -82,7 +83,6 @@ export class Web3Accounts { eth_getBalance (payload, cb) { const address = payload.params[0] - this.vmContext.vm().stateManager.getAccount(Address.fromString(address)).then((account) => { cb(null, toBigInt(account.balance).toString(10)) }).catch((error) => { diff --git a/libs/remix-simulator/src/methods/blocks.ts b/libs/remix-simulator/src/methods/blocks.ts index 60b47bab25..885ec47d0e 100644 --- a/libs/remix-simulator/src/methods/blocks.ts +++ b/libs/remix-simulator/src/methods/blocks.ts @@ -1,6 +1,6 @@ import { toHex } from 'web3-utils' import { VMContext } from '../vm-context' -import { bigIntToHex } from '@ethereumjs/util' +import { bigIntToHex, bytesToHex } from '@ethereumjs/util' export class Blocks { vmContext: VMContext @@ -43,12 +43,12 @@ export class Blocks { } const transactions = block.transactions.map((t) => { - const hash = '0x' + t.hash().toString('hex') + const hash = bytesToHex(t.hash()) const tx = this.vmContext.txByHash[hash] const receipt = this.vmContext.currentVm.web3vm.txsReceipt[hash] if (receipt) { return { - blockHash: '0x' + block.hash().toString('hex'), + blockHash: bytesToHex(block.hash()), blockNumber: bigIntToHex(block.header.number), from: receipt.from, gas: bigIntToHex(receipt.gas), @@ -89,7 +89,7 @@ export class Blocks { toHex (value) { if (!value) return '0x0' - const v = value.toString('hex') + const v = bytesToHex(value) return ((v === '0x' || v === '') ? '0x0' : ('0x' + v)) } @@ -97,12 +97,12 @@ export class Blocks { const block = this.vmContext.blocks[payload.params[0]] const transactions = block.transactions.map((t) => { - const hash = '0x' + t.hash().toString('hex') + const hash = bytesToHex(t.hash()) const tx = this.vmContext.txByHash[hash] const receipt = this.vmContext.currentVm.web3vm.txsReceipt[hash] if (receipt) { return { - blockHash: '0x' + block.hash().toString('hex'), + blockHash: bytesToHex(block.hash()), blockNumber: bigIntToHex(block.header.number), from: receipt.from, gas: toHex(receipt.gas), diff --git a/libs/remix-simulator/src/methods/transactions.ts b/libs/remix-simulator/src/methods/transactions.ts index 41e502fe06..9e46cc3d5f 100644 --- a/libs/remix-simulator/src/methods/transactions.ts +++ b/libs/remix-simulator/src/methods/transactions.ts @@ -1,5 +1,5 @@ import { toHex, toNumber, toBigInt } from 'web3-utils' -import { toChecksumAddress, Address, bigIntToHex } from '@ethereumjs/util' +import { toChecksumAddress, Address, bigIntToHex, bytesToHex} from '@ethereumjs/util' import { processTx } from './txProcess' import { execution } from '@remix-project/remix-lib' import { ethers } from 'ethers' @@ -88,9 +88,9 @@ export class Transactions { processTx(this.txRunnerInstance, payload, false, (error, result: VMexecutionResult) => { if (!error && result) { this.vmContext.addBlock(result.block) - const hash = '0x' + result.tx.hash().toString('hex') + const hash = bytesToHex(result.tx.hash()) this.vmContext.trackTx(hash, result.block, result.tx) - const returnValue = `0x${result.result.execResult.returnValue.toString('hex') || '0'}` + const returnValue = `${bytesToHex(result.result.execResult.returnValue) || '0x0'}` const execResult: VMExecResult = { exceptionError: result.result.execResult.exceptionError, executionGasUsed: result.result.execResult.executionGasUsed, @@ -129,7 +129,7 @@ export class Transactions { const r: Record = { transactionHash: receipt.hash, transactionIndex: this.TX_INDEX, - blockHash: '0x' + txBlock.hash().toString('hex'), + blockHash: bytesToHex(txBlock.hash()), blockNumber: bigIntToHex(txBlock.header.number), gasUsed: receipt.gasUsed, cumulativeGasUsed: receipt.gasUsed, // only 1 tx per block @@ -148,6 +148,7 @@ export class Transactions { } eth_estimateGas (payload, cb) { + // return cb(null, 3000000) // from might be lowercased address (web3) if (payload.params && payload.params.length > 0 && payload.params[0].from) { payload.params[0].from = toChecksumAddress(payload.params[0].from) @@ -157,13 +158,16 @@ export class Transactions { } payload.params[0].gas = 10000000 * 10 - this.vmContext.web3().flagNextAsDoNotRecordEvmSteps() + this.vmContext.web3().recordVMSteps(false) + this.txRunnerInstance.internalRunner.standaloneTx = true processTx(this.txRunnerInstance, payload, true, (error, value: VMexecutionResult) => { + this.txRunnerInstance.internalRunner.standaloneTx = false + this.vmContext.web3().recordVMSteps(true) if (error) return cb(error) const result: any = value.result if ((result as any).receipt?.status === '0x0' || (result as any).receipt?.status === 0) { try { - const msg = `0x${result.execResult.returnValue.toString('hex') || '0'}` + const msg = `${bytesToHex(result.execResult.returnValue) || '0x00'}` const abiCoder = new ethers.utils.AbiCoder() const reason = abiCoder.decode(['string'], '0x' + msg.slice(10))[0] return cb('revert ' + reason) @@ -201,13 +205,19 @@ export class Transactions { } eth_getStateDb (_, cb) { - cb(null, this.vmContext.currentVm.stateManager.getDb()) + const run = async () => { + if ((this.vmContext.currentVm.stateManager as any)._getCodeDB) { + return cb(null, await (this.vmContext.currentVm.stateManager as any)._getCodeDB()) + } + throw new Error('current state does not support "getStateDetails"') + } + run() } eth_getBlocksData (_, cb) { cb(null, { blocks: this.txRunnerVMInstance.blocks, - latestBlockNumber: this.txRunnerVMInstance.blockNumber + latestBlockNumber: this.txRunnerVMInstance.blocks.length - 1 }) } @@ -225,9 +235,9 @@ export class Transactions { processTx(this.txRunnerInstance, payload, true, (error, result: VMexecutionResult) => { if (!error && result) { this.vmContext.addBlock(result.block, null, true) - const hash = '0x' + result.tx.hash().toString('hex') + const hash = bytesToHex(result.tx.hash()) this.vmContext.trackTx(hash, result.block, result.tx) - const returnValue = `0x${result.result.execResult.returnValue.toString('hex') || '0'}` + const returnValue = `${bytesToHex(result.result.execResult.returnValue) || '0x0'}` const execResult: VMExecResult = { exceptionError: result.result.execResult.exceptionError, executionGasUsed: result.result.execResult.executionGasUsed, @@ -278,7 +288,7 @@ export class Transactions { // TODO: params to add later const r: Record = { - blockHash: '0x' + txBlock.hash().toString('hex'), + blockHash: bytesToHex(txBlock.hash()), blockNumber: bigIntToHex(txBlock.header.number), from: receipt.from, gas: toHex(BigInt(receipt.gas)), @@ -316,7 +326,7 @@ export class Transactions { const txIndex = payload.params[1] const txBlock = this.vmContext.blocks[payload.params[0]] - const txHash = '0x' + txBlock.transactions[toNumber(txIndex) as number].hash().toString('hex') + const txHash = bytesToHex(txBlock.transactions[toNumber(txIndex) as number].hash()) this.vmContext.web3().eth.getTransactionReceipt(txHash, (error, receipt) => { if (error) { @@ -327,7 +337,7 @@ export class Transactions { // TODO: params to add later const r: Record = { - blockHash: '0x' + txBlock.hash().toString('hex'), + blockHash: bytesToHex(txBlock.hash()), blockNumber: bigIntToHex(txBlock.header.number), from: receipt.from, gas: toHex(BigInt(receipt.gas)), @@ -361,7 +371,7 @@ export class Transactions { const txIndex = payload.params[1] const txBlock = this.vmContext.blocks[payload.params[0]] - const txHash = '0x' + txBlock.transactions[toNumber(txIndex) as number].hash().toString('hex') + const txHash = bytesToHex(txBlock.transactions[toNumber(txIndex) as number].hash()) this.vmContext.web3().eth.getTransactionReceipt(txHash, (error, receipt) => { if (error) { @@ -372,7 +382,7 @@ export class Transactions { // TODO: params to add later const r: Record = { - blockHash: '0x' + txBlock.hash().toString('hex'), + blockHash: bytesToHex(txBlock.hash()), blockNumber: bigIntToHex(txBlock.header.number), from: receipt.from, gas: toHex(BigInt(receipt.gas)), diff --git a/libs/remix-simulator/src/vm-context.ts b/libs/remix-simulator/src/vm-context.ts index 9acf1128c1..589b08df90 100644 --- a/libs/remix-simulator/src/vm-context.ts +++ b/libs/remix-simulator/src/vm-context.ts @@ -1,27 +1,25 @@ /* global ethereum */ 'use strict' -import { Cache } from '@ethereumjs/statemanager/dist/cache' import { hash } from '@remix-project/remix-lib' -import { bufferToHex, Account, toBuffer, bufferToBigInt, bigIntToHex } from '@ethereumjs/util' +import { bytesToHex, Account, bigIntToHex, MapDB, toBytes, bytesToBigInt } from '@ethereumjs/util' import { keccak256 } from 'ethereum-cryptography/keccak' -import type { Address } from '@ethereumjs/util' +import { Address } from '@ethereumjs/util' import { decode } from 'rlp' import { ethers } from 'ethers' import { execution } from '@remix-project/remix-lib' const { LogsManager } = execution import { VmProxy } from './VmProxy' import { VM } from '@ethereumjs/vm' -import type { BigIntLike } from '@ethereumjs/util' import { Common, ConsensusType } from '@ethereumjs/common' -import { Trie, MapDB } from '@ethereumjs/trie' -import { DefaultStateManager, StateManager, EthersStateManager, EthersStateManagerOpts } from '@ethereumjs/statemanager' -import { StorageDump } from '@ethereumjs/statemanager/dist/interface' +import { Trie } from '@ethereumjs/trie' +import { DefaultStateManager } from '@ethereumjs/statemanager' +import { EVMStateManagerInterface, StorageDump } from '@ethereumjs/common' import { EVM } from '@ethereumjs/evm' -import { EEI } from '@ethereumjs/vm' import { Blockchain } from '@ethereumjs/blockchain' import { Block } from '@ethereumjs/block' -import { Transaction } from '@ethereumjs/tx' +import { TypedTransaction } from '@ethereumjs/tx' import { State } from './provider' +import { hexToBytes } from 'web3-utils' /** * Options for constructing a {@link StateManager}. @@ -56,39 +54,46 @@ class StateManagerCommonStorageDump extends DefaultStateManager { } putContractStorage (address, key, value) { - this.keyHashes[hash.keccak(key).toString('hex')] = bufferToHex(key) + this.keyHashes[bytesToHex(hash.keccak(key))] = bytesToHex(key) return super.putContractStorage(address, key, value) } - copy(): StateManagerCommonStorageDump { + shallowCopy(): StateManagerCommonStorageDump { const copyState = new StateManagerCommonStorageDump({ - trie: this._trie.copy(false), + trie: this._trie.shallowCopy(false), }) copyState.keyHashes = this.keyHashes return copyState } async dumpStorage (address): Promise { + await this.flush() + const account = await this.getAccount(address) + if (!account) { + throw new Error(`dumpStorage f() can only be called for an existing account`) + } return new Promise((resolve, reject) => { - this._getStorageTrie(address) - .then((trie) => { - const storage = {} - const stream = trie.createReadStream() - - stream.on('data', (val) => { - const value: any = decode(val.value) - storage['0x' + val.key.toString('hex')] = { - key: this.keyHashes[val.key.toString('hex')], - value: '0x' + value.toString('hex') - } - }) - stream.on('end', () => { - resolve(storage) - }) + try { + const trie = this._getStorageTrie(address, account) + const storage = {} + const stream = trie.createReadStream() + + stream.on('data', (val) => { + const value: any = decode(val.value) + storage[bytesToHex(val.key)] = { + key: this.keyHashes[bytesToHex(val.key)], + value: bytesToHex(value) + } + }) + stream.on('end', () => { + resolve(storage) }) - .catch((e) => { + stream.on('error', (e) => { reject(e) }) + } catch (e) { + reject(e) + } }) } } @@ -105,6 +110,7 @@ export interface CustomEthersStateManagerOpts { class CustomEthersStateManager extends StateManagerCommonStorageDump { private provider: ethers.providers.StaticJsonRpcProvider | ethers.providers.JsonRpcProvider private blockTag: string + constructor(opts: CustomEthersStateManagerOpts) { super(opts) if (typeof opts.provider === 'string') { @@ -116,32 +122,6 @@ class CustomEthersStateManager extends StateManagerCommonStorageDump { } this.blockTag = opts.blockTag - - /* - * For a custom StateManager implementation adopt these - * callbacks passed to the `Cache` instantiated to perform - * the `get`, `put` and `delete` operations with the - * desired backend. - */ - const getCb = async (address) => { - const rlp = await this._trie.get(address.buf) - if (rlp) { - const ac = Account.fromRlpSerializedAccount(rlp) - return ac - } else { - const ac = await this.getAccountFromProvider(address) - return ac - } - } - const putCb = async (keyBuf, accountRlp) => { - const trie = this._trie - await trie.put(keyBuf, accountRlp) - } - const deleteCb = async (keyBuf: Buffer) => { - const trie = this._trie - await trie.del(keyBuf) - } - this._cache = new Cache({ getCb, putCb, deleteCb }) } /** @@ -153,11 +133,11 @@ class CustomEthersStateManager extends StateManagerCommonStorageDump { this.blockTag = blockTag === 'earliest' ? blockTag : bigIntToHex(blockTag) } - copy(): CustomEthersStateManager { + shallowCopy(): CustomEthersStateManager { const newState = new CustomEthersStateManager({ provider: this.provider, blockTag: this.blockTag, - trie: this._trie.copy(false), + trie: this._trie.shallowCopy(false), }) return newState } @@ -168,11 +148,11 @@ class CustomEthersStateManager extends StateManagerCommonStorageDump { * @returns {Promise} - Resolves with the code corresponding to the provided address. * Returns an empty `Buffer` if the account has no associated code. */ - async getContractCode(address: Address): Promise { + async getContractCode(address: Address): Promise { const code = await super.getContractCode(address) if (code && code.length > 0) return code else { - const code = toBuffer(await this.provider.getCode(address.toString(), this.blockTag)) + const code = toBytes(await this.provider.getCode(address.toString(), this.blockTag)) await super.putContractCode(address, code) return code } @@ -187,13 +167,13 @@ class CustomEthersStateManager extends StateManagerCommonStorageDump { * corresponding to the provided address at the provided key. * If this does not exist an empty `Buffer` is returned. */ - async getContractStorage(address: Address, key: Buffer): Promise { + async getContractStorage(address: Address, key: Buffer): Promise { let storage = await super.getContractStorage(address, key) if (storage && storage.length > 0) return storage else { - storage = toBuffer(await this.provider.getStorageAt( + storage = toBytes(await this.provider.getStorageAt( address.toString(), - bufferToBigInt(key), + bytesToBigInt(key), this.blockTag) ) await super.putContractStorage(address, key, storage) @@ -206,19 +186,30 @@ class CustomEthersStateManager extends StateManagerCommonStorageDump { * @param address - Address of the `account` to check */ async accountExists(address: Address): Promise { - const localAccount = this._cache.get(address) - if (!localAccount.isEmpty()) return true + const account = await super.getAccount(address) + if (!account.isEmpty()) return true + // Get merkle proof for `address` from provider const proof = await this.provider.send('eth_getProof', [address.toString(), [], this.blockTag]) - const proofBuf = proof.accountProof.map((proofNode: string) => toBuffer(proofNode)) + const proofBuf = proof.accountProof.map((proofNode: string) => toBytes(proofNode)) const trie = new Trie({ useKeyHashing: true }) const verified = await trie.verifyProof( Buffer.from(keccak256(proofBuf[0])), - address.buf, + address.bytes, proofBuf ) + if (verified) { + const codeHash = proof.codeHash === '0x0000000000000000000000000000000000000000000000000000000000000000' ? '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' : proof.codeHash + const account = Account.fromAccountData({ + balance: BigInt(proof.balance), + nonce: BigInt(proof.nonce), + codeHash: hexToBytes(codeHash) + // storageRoot: toBuffer([]), // we have to remove this in order to force the creation of the Trie in the local state. + }) + super.putAccount(address, account) + } // if not verified (i.e. verifyProof returns null), account does not exist return verified === null ? false : true } @@ -244,14 +235,14 @@ class CustomEthersStateManager extends StateManagerCommonStorageDump { account = Account.fromAccountData({ balance: BigInt(0), nonce: BigInt(0), - codeHash: toBuffer('0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470') + codeHash: hexToBytes('0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470') }) } else { const codeHash = accountData.codeHash === '0x0000000000000000000000000000000000000000000000000000000000000000' ? '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' : accountData.codeHash account = Account.fromAccountData({ balance: BigInt(accountData.balance), nonce: BigInt(accountData.nonce), - codeHash: toBuffer(codeHash) + codeHash: hexToBytes(codeHash) // storageRoot: toBuffer([]), // we have to remove this in order to force the creation of the Trie in the local state. }) } @@ -259,29 +250,21 @@ class CustomEthersStateManager extends StateManagerCommonStorageDump { } } + export type CurrentVm = { vm: VM, web3vm: VmProxy, - stateManager: StateManagerCommonStorageDump, + stateManager: EVMStateManagerInterface, common: Common } export class VMCommon extends Common { /** - * Override "setHardforkByBlockNumber" to disable updating the original fork state - * - * @param blockNumber - * @param td - * @param timestamp - * @returns The name of the HF set - */ - setHardforkByBlockNumber( - blockNumber: BigIntLike, - td?: BigIntLike, - timestamp?: BigIntLike - ): string { - return this.hardfork() + * Always return the fork set at initialization + */ + setHardforkBy() { + return this._hardfork; } } @@ -295,16 +278,16 @@ export class VMContext { blocks: Record latestBlockNumber: string blockByTxHash: Record - txByHash: Record + txByHash: Record currentVm: CurrentVm web3vm: VmProxy logsManager: any // LogsManager - exeResults: Record + exeResults: Record nodeUrl: string blockNumber: number | 'latest' stateDb: State rawBlocks: string[] - serializedBlocks: Buffer[] + serializedBlocks: Uint8Array[] constructor (fork?: string, nodeUrl?: string, blockNumber?: number | 'latest', stateDb?: State, blocksData?: string[]) { this.blockGasLimitDefault = 4300000 @@ -328,7 +311,7 @@ export class VMContext { } async createVm (hardfork) { - let stateManager: StateManagerCommonStorageDump + let stateManager: EVMStateManagerInterface if (this.nodeUrl) { let block = this.blockNumber if (this.blockNumber === 'latest') { @@ -342,11 +325,11 @@ export class VMContext { } else { stateManager = new CustomEthersStateManager({ provider: this.nodeUrl, - blockTag: '0x' + this.blockNumber.toString(16) + blockTag: '0x' + block.toString(16) }) } - } else{ - const db = this.stateDb ? new Map(Object.entries(this.stateDb).map(([k, v]) => [k, toBuffer(v)])) : new Map() + } else { + const db = this.stateDb ? new Map(Object.entries(this.stateDb).map(([k, v]) => [k, hexToBytes(v)])) : new Map() const mapDb = new MapDB(db) const trie = await Trie.create({ useKeyHashing: true, db: mapDb, useRootPersistence: true }) @@ -358,8 +341,7 @@ export class VMContext { const common = new VMCommon({ chain: 'mainnet', hardfork }) const blocks = (this.rawBlocks || []).map(block => { - const serializedBlock = toBuffer(block) - + const serializedBlock = hexToBytes(block) this.serializedBlocks.push(serializedBlock) return Block.fromRLPSerializedBlock(serializedBlock, { common }) }) @@ -371,15 +353,14 @@ export class VMContext { difficulty, gasLimit: 8000000 } - }, { common, hardforkByBlockNumber: false, hardforkByTTD: undefined }) + }, { common }) + const blockchain = await Blockchain.create({ common, validateBlocks: false, validateConsensus: false, genesisBlock }) - const eei = new EEI(stateManager, common, blockchain) - const evm = new EVM({ common, eei, allowUnlimitedContractSize: true }) + const evm = new EVM({ common, allowUnlimitedContractSize: true, stateManager, blockchain }) const vm = await VM.create({ common, activatePrecompiles: true, - hardforkByBlockNumber: false, stateManager, blockchain, evm @@ -419,7 +400,7 @@ export class VMContext { blockNumber = '0x0' } - this.blocks['0x' + block.hash().toString('hex')] = block + this.blocks[bytesToHex(block.hash())] = block this.blocks[blockNumber] = block this.latestBlockNumber = blockNumber diff --git a/libs/remix-solidity/package.json b/libs/remix-solidity/package.json index d37f06a745..c6d91e1d7f 100644 --- a/libs/remix-solidity/package.json +++ b/libs/remix-solidity/package.json @@ -15,10 +15,10 @@ } ], "dependencies": { - "@ethereumjs/block": "^4.2.0", - "@ethereumjs/tx": "^4.1.1", - "@ethereumjs/util": "^8.0.5", - "@ethereumjs/vm": "^6.4.1", + "@ethereumjs/block": "5.0.1", + "@ethereumjs/tx": "5.1.0", + "@ethereumjs/util": "9.0.1", + "@ethereumjs/vm": "7.1.0", "@remix-project/remix-lib": "^0.5.51", "async": "^2.6.2", "eslint-scope": "^5.0.0", diff --git a/libs/remix-tests/package.json b/libs/remix-tests/package.json index 4357920375..fb3fa69732 100644 --- a/libs/remix-tests/package.json +++ b/libs/remix-tests/package.json @@ -36,11 +36,11 @@ "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-tests#readme", "dependencies": { "@erebos/bzz-node": "^0.13.0", - "@ethereumjs/block": "^4.2.0", - "@ethereumjs/common": "^3.1.1", - "@ethereumjs/tx": "^4.1.1", - "@ethereumjs/util": "^8.0.5", - "@ethereumjs/vm": "^6.4.1", + "@ethereumjs/block": "5.0.1", + "@ethereumjs/common": "4.1.0", + "@ethereumjs/tx": "5.1.0", + "@ethereumjs/util": "9.0.1", + "@ethereumjs/vm": "7.1.0", "@remix-project/remix-lib": "^0.5.51", "@remix-project/remix-simulator": "^0.2.44", "@remix-project/remix-solidity": "^0.5.30", diff --git a/libs/remix-ui/helper/src/lib/remix-ui-helper.ts b/libs/remix-ui/helper/src/lib/remix-ui-helper.ts index cac2138f6b..68ea85b72d 100644 --- a/libs/remix-ui/helper/src/lib/remix-ui-helper.ts +++ b/libs/remix-ui/helper/src/lib/remix-ui-helper.ts @@ -1,4 +1,4 @@ -import * as ethJSUtil from '@ethereumjs/util' +import { bytesToHex, toChecksumAddress } from '@ethereumjs/util' export const extractNameFromKey = (key: string): string => { if (!key) return @@ -97,12 +97,12 @@ export const shortenAddress = (address, etherBalance?) => { export const addressToString = (address) => { if (!address) return null if (typeof address !== 'string') { - address = address.toString('hex') + address = bytesToHex(address) } if (address.indexOf('0x') === -1) { address = '0x' + address } - return ethJSUtil.toChecksumAddress(address) + return toChecksumAddress(address) } export const is0XPrefixed = (value) => { diff --git a/libs/remix-ui/run-tab/src/lib/components/account.tsx b/libs/remix-ui/run-tab/src/lib/components/account.tsx index 1ea87b2d12..d1ab6b5552 100644 --- a/libs/remix-ui/run-tab/src/lib/components/account.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/account.tsx @@ -34,7 +34,7 @@ export function AccountUI(props: AccountProps) { }) break - case 'vm-merge': + case 'vm-paris': setPlusOpt({ classList: '', title: intl.formatMessage({id: 'udapp.createNewAccount'}) diff --git a/libs/remix-ui/run-tab/src/lib/reducers/runTab.ts b/libs/remix-ui/run-tab/src/lib/reducers/runTab.ts index 2e8fbbe807..d35175882b 100644 --- a/libs/remix-ui/run-tab/src/lib/reducers/runTab.ts +++ b/libs/remix-ui/run-tab/src/lib/reducers/runTab.ts @@ -19,7 +19,7 @@ export const runTabInitialState: RunTabState = { sendValue: '0', sendUnit: 'wei', gasLimit: 3000000, - selectExEnv: 'vm-merge', + selectExEnv: 'vm-paris', personalMode: false, networkName: 'VM', providers: { @@ -173,7 +173,7 @@ export const runTabReducer = (state: RunTabState = runTabInitialState, action: A return { ...state, selectExEnv: payload, - networkName: state.selectExEnv === 'vm-merge' ? 'VM' : state.networkName, + networkName: state.selectExEnv === 'vm-paris' ? 'VM' : state.networkName, accounts: { ...state.accounts, selectedAccount: '', diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index 047975301d..9376ab30b6 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -1,5 +1,5 @@ import React from 'react' -import { bufferToHex } from '@ethereumjs/util' +import { bytesToHex } from '@ethereumjs/util' import { hash } from '@remix-project/remix-lib' import { TEMPLATE_METADATA, TEMPLATE_NAMES } from '../utils/constants' import { TemplateType } from '../types' @@ -253,7 +253,7 @@ export const loadWorkspacePreset = async (template: WorkspaceTemplate = 'remixDe let content if (params.code) { - const hashed = bufferToHex(hash.keccakFromString(params.code)) + const hashed = bytesToHex(hash.keccakFromString(params.code)) path = 'contract-' + hashed.replace('0x', '').substring(0, 10) + (params.language && params.language.toLowerCase() === 'yul' ? '.yul' : '.sol') content = atob(decodeURIComponent(params.code)) @@ -272,7 +272,7 @@ export const loadWorkspacePreset = async (template: WorkspaceTemplate = 'remixDe // authorization: auth } }) - const hashed = bufferToHex(hash.keccakFromString(params.shareCode)) + const hashed = bytesToHex(hash.keccakFromString(params.shareCode)) path = 'contract-' + hashed.replace('0x', '').substring(0, 10) + (params.language && params.language.toLowerCase() === 'yul' ? '.yul' : '.sol') const fileData = ipfs.get(params.shareCode) diff --git a/package.json b/package.json index c9a5f0d7bb..13ac059327 100644 --- a/package.json +++ b/package.json @@ -130,13 +130,13 @@ "@babel/plugin-proposal-class-properties": "^7.16.0", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@erebos/bzz-node": "^0.13.0", - "@ethereumjs/block": "^4.2.0", - "@ethereumjs/common": "^3.1.1", - "@ethereumjs/evm": "^1.3.1", - "@ethereumjs/statemanager": "^1.0.4", - "@ethereumjs/tx": "^4.1.1", - "@ethereumjs/util": "^8.0.5", - "@ethereumjs/vm": "^6.4.1", + "@ethereumjs/block": "5.0.1", + "@ethereumjs/common": "4.1.0", + "@ethereumjs/evm": "2.1.0", + "@ethereumjs/statemanager": "2.1.0", + "@ethereumjs/tx": "5.1.0", + "@ethereumjs/util": "9.0.1", + "@ethereumjs/vm": "7.1.0", "@ethersphere/bee-js": "^3.2.0", "@isomorphic-git/lightning-fs": "^4.4.1", "@microlink/react-json-view": "^1.23.0", @@ -230,11 +230,13 @@ "remark-gfm": "^3.0.1", "rlp": "^3.0.0", "rss-parser": "^3.12.0", + "rustbn-wasm": "^0.2.0", "signale": "^1.4.0", "snarkjs": "^0.7.0", "sol2uml": "^2.4.3", "string-similarity": "^4.0.4", "svg2pdf.js": "^2.2.1", + "text-encoding": "^0.7.0", "time-stamp": "^2.2.0", "toml": "^3.0.0", "tree-kill": "^1.2.2", @@ -402,6 +404,15 @@ "webpack-cli": "^4.10.0" }, "resolutions": { - "@types/react": "^18.2.0" + "@types/react": "^18.2.0", + "@ethereumjs/blockchain": "7.0.1", + "@ethereumjs/block": "5.0.1", + "@ethereumjs/common": "4.1.0", + "@ethereumjs/evm": "2.1.0", + "@ethereumjs/statemanager": "2.1.0", + "@ethereumjs/tx": "5.1.0", + "@ethereumjs/util": "9.0.1", + "@ethereumjs/vm": "7.1.0", + "@ethereumjs/trie": "6.0.1" } } diff --git a/yarn.lock b/yarn.lock index dc5cdcb7e8..6963ef8949 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,6 +7,11 @@ resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== +"@adraffy/ens-normalize@1.10.1": + version "1.10.1" + resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069" + integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw== + "@adraffy/ens-normalize@^1.8.8": version "1.9.4" resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.9.4.tgz#aae21cb858bbb0411949d5b7b3051f4209043f62" @@ -1819,11 +1824,6 @@ resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz#3639df0e1435cab03f4d9870cc3ac079e57a6fc9" integrity sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg== -"@chainsafe/as-sha256@^0.4.1": - version "0.4.1" - resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.4.1.tgz#cfc0737e25f8c206767bdb6703e7943e5d44513e" - integrity sha512-IqeeGwQihK6Y2EYLFofqs2eY2ep1I2MvQXHzOAI+5iQN51OZlUkrLgyAugu2x86xZewDk5xas7lNczkzFzF62w== - "@chainsafe/persistent-merkle-tree@^0.4.2": version "0.4.2" resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.4.2.tgz#4c9ee80cc57cd3be7208d98c40014ad38f36f7ff" @@ -1838,14 +1838,6 @@ dependencies: "@chainsafe/as-sha256" "^0.3.1" -"@chainsafe/persistent-merkle-tree@^0.6.1": - version "0.6.1" - resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.6.1.tgz#37bde25cf6cbe1660ad84311aa73157dc86ec7f2" - integrity sha512-gcENLemRR13+1MED2NeZBMA7FRS0xQPM7L2vhMqvKkjqtFT4YfjSVADq5U0iLuQLhFUJEMVuA8fbv5v+TN6O9A== - dependencies: - "@chainsafe/as-sha256" "^0.4.1" - "@noble/hashes" "^1.3.0" - "@chainsafe/ssz@^0.10.0": version "0.10.2" resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.10.2.tgz#c782929e1bb25fec66ba72e75934b31fd087579e" @@ -1854,14 +1846,6 @@ "@chainsafe/as-sha256" "^0.3.1" "@chainsafe/persistent-merkle-tree" "^0.5.0" -"@chainsafe/ssz@^0.11.1": - version "0.11.1" - resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.11.1.tgz#d4aec883af2ec5196ae67b96242c467da20b2476" - integrity sha512-cB8dBkgGN6ZoeOKuk+rIRHKN0L5i9JLGeC0Lui71QX0TuLcQKwgbfkUexpyJxnGFatWf8yeJxlOjozMn/OTP0g== - dependencies: - "@chainsafe/as-sha256" "^0.4.1" - "@chainsafe/persistent-merkle-tree" "^0.6.1" - "@chainsafe/ssz@^0.9.2": version "0.9.4" resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.9.4.tgz#696a8db46d6975b600f8309ad3a12f7c0e310497" @@ -2284,165 +2268,138 @@ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.44.0.tgz#961a5903c74139390478bdc808bcde3fc45ab7af" integrity sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw== -"@ethereumjs/block@^4.2.0", "@ethereumjs/block@^4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@ethereumjs/block/-/block-4.2.2.tgz#fddecd34ed559f84ab8eb13098a6dee51a1360ae" - integrity sha512-kMxjeUwJSuLMwnavok5W17ayMNXXsu3hWsllK33XtZgoqt4ywvGo6ABh+xVEqwq/nn/iKuryCpDYYKEyXeFOlA== +"@ethereumjs/block@5.0.1", "@ethereumjs/block@^5.0.1", "@ethereumjs/block@^5.1.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@ethereumjs/block/-/block-5.0.1.tgz#573f62a9fc9604ad30f57edb7fb852540c9d3829" + integrity sha512-DoQ/lVEO3NGl5sfxoWjl1zjPnQqAaFqlqq7aOmzB4qMe89nXm0mYTate2xDUruS7it8R8FHzXga16soV7qQykA== dependencies: - "@ethereumjs/common" "^3.1.2" - "@ethereumjs/rlp" "^4.0.1" - "@ethereumjs/trie" "^5.0.5" - "@ethereumjs/tx" "^4.1.2" - "@ethereumjs/util" "^8.0.6" - ethereum-cryptography "^2.0.0" + "@ethereumjs/common" "^4.1.0" + "@ethereumjs/rlp" "^5.0.1" + "@ethereumjs/trie" "^6.0.1" + "@ethereumjs/tx" "^5.1.0" + "@ethereumjs/util" "^9.0.1" + ethereum-cryptography "^2.1.2" -"@ethereumjs/blockchain@^6.2.2": - version "6.2.2" - resolved "https://registry.yarnpkg.com/@ethereumjs/blockchain/-/blockchain-6.2.2.tgz#68897a802839b217967083958022601a12afa0ed" - integrity sha512-w1Zjskk35hr0qe0Zfwb88qrEFQJNMo73YrsqtJuBap+WamibEsw0rVuN4Ch+o8Dc66An+8rpk5SxEIK7PHF7KQ== - dependencies: - "@ethereumjs/block" "^4.2.2" - "@ethereumjs/common" "^3.1.2" - "@ethereumjs/ethash" "^2.0.5" - "@ethereumjs/rlp" "^4.0.1" - "@ethereumjs/trie" "^5.0.5" - "@ethereumjs/tx" "^4.1.2" - "@ethereumjs/util" "^8.0.6" - abstract-level "^1.0.3" +"@ethereumjs/blockchain@7.0.1", "@ethereumjs/blockchain@^7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@ethereumjs/blockchain/-/blockchain-7.0.1.tgz#0540b2dc06b9dd6b1b1a6a5d84f08a32c56f487b" + integrity sha512-JQoRpMHxAyMnlHSNe7H3EnM3mMZOHaBGkBmwLQ02Jv9zg9rnJ/g9r9LvW6yhjs7ifrKCn94j54yMv4i+W99XwA== + dependencies: + "@ethereumjs/block" "^5.0.1" + "@ethereumjs/common" "^4.1.0" + "@ethereumjs/ethash" "^3.0.1" + "@ethereumjs/rlp" "^5.0.1" + "@ethereumjs/trie" "^6.0.1" + "@ethereumjs/tx" "^5.1.0" + "@ethereumjs/util" "^9.0.1" debug "^4.3.3" - ethereum-cryptography "^2.0.0" - level "^8.0.0" - lru-cache "^5.1.1" - memory-level "^1.0.0" - -"@ethereumjs/common@^3.1.1", "@ethereumjs/common@^3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-3.1.2.tgz#c810301b78bcb7526bd690c6d7eb3f4a3c70839d" - integrity sha512-YV+bZfRlFhAXg+FfwC5r4UQKVj4OG7vDP5/JvvNXLLbYpNplH5Vca9jD0L+ab8y0YlTYJMQM1ALyHFu3AE3eBA== - dependencies: - "@ethereumjs/util" "^8.0.6" - crc-32 "^1.2.0" + ethereum-cryptography "^2.1.2" + lru-cache "^10.0.0" -"@ethereumjs/common@^3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-3.2.0.tgz#b71df25845caf5456449163012074a55f048e0a0" - integrity sha512-pksvzI0VyLgmuEF2FA/JR/4/y6hcPq8OUail3/AvycBaW1d5VSauOZzqGvJ3RTmR4MU35lWE8KseKOsEhrFRBA== +"@ethereumjs/common@4.1.0", "@ethereumjs/common@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-4.1.0.tgz#0a959320a69bd2e3b194144b29c61b63bd6e2f6a" + integrity sha512-XWdQvUjlQHVwh4uGEPFKHpsic69GOsMXEhlHrggS5ju/+2zAmmlz6B25TkCCymeElC9DUp13tH5Tc25Iuvtlcg== dependencies: - "@ethereumjs/util" "^8.1.0" - crc-32 "^1.2.0" + "@ethereumjs/util" "^9.0.1" + crc "^4.3.2" -"@ethereumjs/ethash@^2.0.5": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@ethereumjs/ethash/-/ethash-2.0.5.tgz#577b9d470eea6b61f77d624b58ac90929d6e857d" - integrity sha512-JIPr39Zd9lULLftyzPGHUQmdziElqNWk0EkO1BAw3yns4TVx+BxCYZOkRQ55fuIFeKcXBupAI9V+7xdvIT2CPw== +"@ethereumjs/ethash@^3.0.1": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@ethereumjs/ethash/-/ethash-3.0.2.tgz#2828ec7959a0b64e474c7d7c325e7074a85ae3a2" + integrity sha512-iJEH63xudwzSYxYb81RX2Mf2+Wkuu6P7ism29wpM7fxQE+pcI9S6V65CaITprH98SAZjuMrZU6ZGHDGbqolSkg== dependencies: - "@ethereumjs/block" "^4.2.2" - "@ethereumjs/rlp" "^4.0.1" - "@ethereumjs/util" "^8.0.6" - abstract-level "^1.0.3" + "@ethereumjs/block" "^5.1.1" + "@ethereumjs/rlp" "^5.0.2" + "@ethereumjs/util" "^9.0.2" bigint-crypto-utils "^3.2.2" - ethereum-cryptography "^2.0.0" + ethereum-cryptography "^2.1.3" -"@ethereumjs/evm@^1.3.1", "@ethereumjs/evm@^1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@ethereumjs/evm/-/evm-1.3.2.tgz#3123190b0d021122b183534d7b040a3b241905b8" - integrity sha512-9PzshkvwO8YBkSD9+vyhJuzM6hxfZlljGnuUbXQlTSGEod7we8BRyzJW53W7nw/WRw5U6wf9Q2fpWypfZFkrbw== - dependencies: - "@ethereumjs/common" "^3.1.2" - "@ethereumjs/tx" "^4.1.2" - "@ethereumjs/util" "^8.0.6" - "@ethersproject/providers" "^5.7.1" +"@ethereumjs/evm@2.1.0", "@ethereumjs/evm@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/evm/-/evm-2.1.0.tgz#1b58be5eee0d217b26488194347dbeda22f44a5a" + integrity sha512-+4X9fw9X3pRnvbtJn02TDbwoTICc+W6ccNLgNx2IXiJkIArtUTK8xJ764MgmUvNIb14PuXAAUMEZ0l6UrZQcDw== + dependencies: + "@ethereumjs/common" "^4.1.0" + "@ethereumjs/statemanager" "^2.1.0" + "@ethereumjs/tx" "^5.1.0" + "@ethereumjs/util" "^9.0.1" + "@types/debug" "^4.1.9" debug "^4.3.3" - ethereum-cryptography "^2.0.0" - mcl-wasm "^0.7.1" - rustbn.js "~0.2.0" + ethereum-cryptography "^2.1.2" + rustbn-wasm "^0.2.0" "@ethereumjs/rlp@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-4.0.1.tgz#626fabfd9081baab3d0a3074b0c7ecaf674aaa41" integrity sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw== -"@ethereumjs/statemanager@^1.0.4", "@ethereumjs/statemanager@^1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@ethereumjs/statemanager/-/statemanager-1.0.5.tgz#4496a315d27e60d9a3a036dbe82899f6f20dd2df" - integrity sha512-TVkx9Kgc2NtObCzUTTqrpUggNLnftdmxZybzKPd565Bh98FJJB30FrVkWdPwaIV8oB1d9ADtthttfx5Y/kY9gw== +"@ethereumjs/rlp@^5.0.1", "@ethereumjs/rlp@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-5.0.2.tgz#c89bd82f2f3bec248ab2d517ae25f5bbc4aac842" + integrity sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA== + +"@ethereumjs/statemanager@2.1.0", "@ethereumjs/statemanager@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/statemanager/-/statemanager-2.1.0.tgz#2c5f045539c26ac49c5b457d4f80debc492f6c60" + integrity sha512-1wcaZJZq/TqnWWkdwNHOMt27M7SJQKa6J2XZ2hf8ivyPg+3kuf2FoZHCTha1JKPCGJtAttBLgklFnQ/S4sAgPg== dependencies: - "@ethereumjs/common" "^3.1.2" - "@ethereumjs/rlp" "^4.0.1" + "@ethereumjs/common" "^4.1.0" + "@ethereumjs/rlp" "^5.0.1" + "@ethereumjs/trie" "^6.0.1" + "@ethereumjs/util" "^9.0.1" debug "^4.3.3" - ethereum-cryptography "^2.0.0" - ethers "^5.7.1" + ethereum-cryptography "^2.1.2" + ethers "^6.4.0" js-sdsl "^4.1.4" + lru-cache "^10.0.0" -"@ethereumjs/trie@^5.0.5": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethereumjs/trie/-/trie-5.0.5.tgz#c232a4913871ffc45bf52cccd214fe5aa24cb3e2" - integrity sha512-H3gHtYxJVGfkT4H05LTJfD1W6h9WZYNkfhTUyAYruNZKFitkSHUM/bEFWH/GIhxt5SAkf283F5uJOx7X2Fr6pQ== +"@ethereumjs/trie@6.0.1", "@ethereumjs/trie@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@ethereumjs/trie/-/trie-6.0.1.tgz#f57382aecbbb10ae0900d8c0ba8368f3c6db4547" + integrity sha512-fPdiTaT2aZ2b3LUdBAZVLKnlHz9CV3dR8zdBEX7eDWLOuQ2E9rM2smk2sGdyzXPr9Sf2gmeE1od+CjY0ea8ICg== dependencies: - "@ethereumjs/rlp" "^4.0.1" - "@ethereumjs/util" "^8.0.6" + "@ethereumjs/rlp" "^5.0.1" + "@ethereumjs/util" "^9.0.1" "@types/readable-stream" "^2.3.13" - ethereum-cryptography "^2.0.0" + ethereum-cryptography "^2.1.2" + lru-cache "^10.0.0" readable-stream "^3.6.0" -"@ethereumjs/tx@^4.1.1", "@ethereumjs/tx@^4.1.2": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-4.1.2.tgz#10bc6741b74d2404331b82b87f9b2c26177b6f90" - integrity sha512-PWWyO9lAFOiLwk7nB9OQisoJUsuvMz2PN2v4/ILbBpzamC5Ug79OddVq9r4rKvIDLPY+bn4NFerxBJg29+sjaA== - dependencies: - "@chainsafe/ssz" "^0.11.1" - "@ethereumjs/common" "^3.1.2" - "@ethereumjs/rlp" "^4.0.1" - "@ethereumjs/util" "^8.0.6" - ethereum-cryptography "^2.0.0" - -"@ethereumjs/tx@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-4.2.0.tgz#5988ae15daf5a3b3c815493bc6b495e76009e853" - integrity sha512-1nc6VO4jtFd172BbSnTnDQVr9IYBFl1y4xPzZdtkrkKIncBCkdbgfdRV+MiTkJYAtTxvV12GRZLqBFT1PNK6Yw== - dependencies: - "@ethereumjs/common" "^3.2.0" - "@ethereumjs/rlp" "^4.0.1" - "@ethereumjs/util" "^8.1.0" - ethereum-cryptography "^2.0.0" - -"@ethereumjs/util@^8.0.5", "@ethereumjs/util@^8.0.6": - version "8.0.6" - resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-8.0.6.tgz#f9716ed34235ea05eff8353bc5d483e5a6455989" - integrity sha512-zFLG/gXtF3QUC7iKFn4PT6HCr+DEnlCbwUGKGtXoqjA+64T+e0FuqMjlo4bQIY2ngRzk3EtudKdGYC4g31ehhg== +"@ethereumjs/tx@5.1.0", "@ethereumjs/tx@^4.1.2", "@ethereumjs/tx@^4.2.0", "@ethereumjs/tx@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-5.1.0.tgz#c61a9048ec09fff360b18188224aae90c370e57f" + integrity sha512-VUhw2+4yXArJZRWhPjmZFrN4WUjUo0qUZUszVpW2KzsGlqCFf67kwJcH9Rca5eS0CRHjr2qHJLpvYOjNuaXVdA== dependencies: - "@chainsafe/ssz" "^0.11.1" - "@ethereumjs/rlp" "^4.0.1" - ethereum-cryptography "^2.0.0" - micro-ftch "^0.3.1" + "@ethereumjs/common" "^4.1.0" + "@ethereumjs/rlp" "^5.0.1" + "@ethereumjs/util" "^9.0.1" + ethereum-cryptography "^2.1.2" -"@ethereumjs/util@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-8.1.0.tgz#299df97fb6b034e0577ce9f94c7d9d1004409ed4" - integrity sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA== +"@ethereumjs/util@9.0.1", "@ethereumjs/util@^9.0.1", "@ethereumjs/util@^9.0.2": + version "9.0.1" + resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-9.0.1.tgz#cbe0380981263451e3080ddcd74accf4b10f8723" + integrity sha512-NdFFEzCc3H1sYkNnnySwLg6owdQMhjUc2jfuDyx8Xv162WSluCnnSKouKOSG3njGNEyy2I9NmF8zTRDwuqpZWA== dependencies: - "@ethereumjs/rlp" "^4.0.1" - ethereum-cryptography "^2.0.0" - micro-ftch "^0.3.1" + "@ethereumjs/rlp" "^5.0.1" + ethereum-cryptography "^2.1.2" -"@ethereumjs/vm@^6.4.1": - version "6.4.2" - resolved "https://registry.yarnpkg.com/@ethereumjs/vm/-/vm-6.4.2.tgz#9898105a96f0975d561db69319331944db4bfafc" - integrity sha512-kTzOvJfNpUQHi2a0SbglYNWHIEOg5j3NlN80KU0IrdagWAeaEqz6Jj5XVN5lBs4VAfwXNdf+56xYtMg8Nate7Q== - dependencies: - "@ethereumjs/block" "^4.2.2" - "@ethereumjs/blockchain" "^6.2.2" - "@ethereumjs/common" "^3.1.2" - "@ethereumjs/evm" "^1.3.2" - "@ethereumjs/rlp" "^4.0.1" - "@ethereumjs/statemanager" "^1.0.5" - "@ethereumjs/trie" "^5.0.5" - "@ethereumjs/tx" "^4.1.2" - "@ethereumjs/util" "^8.0.6" +"@ethereumjs/vm@7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/vm/-/vm-7.1.0.tgz#e4594fc5e05857fd6da7a8daf38e24c54a205df3" + integrity sha512-AWLsz6GFWR8aRDHFjrLXsBVJ6qjP6jVJiuQeGY8JYbzwGIrKjgN/xxFtZwzyIpXgAXsX+WZYp8omRmkBlPA3zg== + dependencies: + "@ethereumjs/block" "^5.0.1" + "@ethereumjs/blockchain" "^7.0.1" + "@ethereumjs/common" "^4.1.0" + "@ethereumjs/evm" "^2.1.0" + "@ethereumjs/rlp" "^5.0.1" + "@ethereumjs/statemanager" "^2.1.0" + "@ethereumjs/trie" "^6.0.1" + "@ethereumjs/tx" "^5.1.0" + "@ethereumjs/util" "^9.0.1" debug "^4.3.3" - ethereum-cryptography "^2.0.0" - mcl-wasm "^0.7.1" - rustbn.js "~0.2.0" + ethereum-cryptography "^2.1.2" "@ethersphere/bee-js@^3.2.0": version "3.2.0" @@ -4220,17 +4177,36 @@ dependencies: "@noble/hashes" "1.3.0" +"@noble/curves@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35" + integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw== + dependencies: + "@noble/hashes" "1.3.2" + +"@noble/curves@1.3.0", "@noble/curves@~1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.3.0.tgz#01be46da4fd195822dab821e72f71bf4aeec635e" + integrity sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA== + dependencies: + "@noble/hashes" "1.3.3" + "@noble/hashes@1.2.0", "@noble/hashes@~1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== -"@noble/hashes@1.3.0", "@noble/hashes@^1.3.0", "@noble/hashes@~1.3.0": +"@noble/hashes@1.3.0", "@noble/hashes@~1.3.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1" integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg== -"@noble/hashes@^1.3.1": +"@noble/hashes@1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" + integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== + +"@noble/hashes@1.3.3", "@noble/hashes@^1.3.1", "@noble/hashes@~1.3.2": version "1.3.3" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== @@ -5564,7 +5540,7 @@ estree-walker "^2.0.1" picomatch "^2.2.2" -"@scure/base@^1.1.3": +"@scure/base@^1.1.1", "@scure/base@^1.1.3", "@scure/base@~1.1.4": version "1.1.5" resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.5.tgz#1d85d17269fe97694b9c592552dd9e5e33552157" integrity sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ== @@ -5592,6 +5568,15 @@ "@noble/hashes" "~1.3.0" "@scure/base" "~1.1.0" +"@scure/bip32@1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.3.tgz#a9624991dc8767087c57999a5d79488f48eae6c8" + integrity sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ== + dependencies: + "@noble/curves" "~1.3.0" + "@noble/hashes" "~1.3.2" + "@scure/base" "~1.1.4" + "@scure/bip39@1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.1.tgz#b54557b2e86214319405db819c4b6a370cf340c5" @@ -5608,6 +5593,14 @@ "@noble/hashes" "~1.3.0" "@scure/base" "~1.1.0" +"@scure/bip39@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.2.tgz#f3426813f4ced11a47489cbcf7294aa963966527" + integrity sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA== + dependencies: + "@noble/hashes" "~1.3.2" + "@scure/base" "~1.1.4" + "@sentry/core@5.30.0": version "5.30.0" resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" @@ -6184,7 +6177,7 @@ dependencies: "@types/ms" "*" -"@types/debug@^4.1.7": +"@types/debug@^4.1.7", "@types/debug@^4.1.9": version "4.1.12" resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917" integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ== @@ -6437,6 +6430,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.1.tgz#5db121e9c5352925bb1f1b892c4ae620e3526799" integrity sha512-DZxSZWXxFfOlx7k7Rv4LAyiMroaxa3Ly/7OOzZO8cBNho0YzAi4qlbrx8W27JGqG57IgR/6J7r+nOJWw6kcvZA== +"@types/node@18.15.13": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== + "@types/node@>= 8": version "8.9.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.9.5.tgz#162b864bc70be077e6db212b322754917929e976" @@ -7674,6 +7672,11 @@ aes-js@3.0.0: resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== +aes-js@4.0.0-beta.5: + version "4.0.0-beta.5" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873" + integrity sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q== + agent-base@4, agent-base@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" @@ -11557,6 +11560,11 @@ crc-32@^1.2.0, crc-32@^1.2.2: resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== +crc@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/crc/-/crc-4.3.2.tgz#49b7821cbf2cf61dfd079ed93863bbebd5469b9a" + integrity sha512-uGDHf4KLLh2zsHa8D8hIQ1H/HtFQhyHrc0uhHBcoKGol/Xnb+MPYfUMw7cvON6ze/GUESTudKayDcJC5HnJv1A== + create-ecdh@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" @@ -13800,6 +13808,16 @@ ethereum-cryptography@^2.0.0: "@scure/bip32" "1.3.0" "@scure/bip39" "1.2.0" +ethereum-cryptography@^2.1.2, ethereum-cryptography@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.1.3.tgz#1352270ed3b339fe25af5ceeadcf1b9c8e30768a" + integrity sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA== + dependencies: + "@noble/curves" "1.3.0" + "@noble/hashes" "1.3.3" + "@scure/bip32" "1.3.3" + "@scure/bip39" "1.2.2" + ethereumjs-abi@^0.6.8: version "0.6.8" resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" @@ -13868,6 +13886,19 @@ ethers@^5, ethers@^5.7.1, ethers@^5.7.2: "@ethersproject/web" "5.7.1" "@ethersproject/wordlists" "5.7.0" +ethers@^6.4.0: + version "6.11.1" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.11.1.tgz#96aae00b627c2e35f9b0a4d65c7ab658259ee6af" + integrity sha512-mxTAE6wqJQAbp5QAe/+o+rXOID7Nw91OZXvgpjDa1r4fAbq2Nu314oEZSbjoRLacuCzs7kUC3clEvkCQowffGg== + dependencies: + "@adraffy/ens-normalize" "1.10.1" + "@noble/curves" "1.2.0" + "@noble/hashes" "1.3.2" + "@types/node" "18.15.13" + aes-js "4.0.0-beta.5" + tslib "2.4.0" + ws "8.5.0" + ethjs-util@0.1.6, ethjs-util@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" @@ -20371,11 +20402,6 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -micro-ftch@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/micro-ftch/-/micro-ftch-0.3.1.tgz#6cb83388de4c1f279a034fb0cf96dfc050853c5f" - integrity sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg== - micromark-core-commonmark@^1.0.0, micromark-core-commonmark@^1.0.1: version "1.0.6" resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-1.0.6.tgz#edff4c72e5993d93724a3c206970f5a15b0585ad" @@ -25954,6 +25980,13 @@ run@^1.4.0: dependencies: minimatch "*" +rustbn-wasm@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/rustbn-wasm/-/rustbn-wasm-0.2.0.tgz#0407521fb55ae69eeb4968d01885d63efd1c4ff9" + integrity sha512-FThvYFNTqrEKGqXuseeg0zR7yROh/6U1617mCHF68OVqrN1tNKRN7Tdwy4WayPVsCmmK+eMxtIZX1qL6JxTkMg== + dependencies: + "@scure/base" "^1.1.1" + rustbn.js@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" @@ -27951,6 +27984,11 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" +text-encoding@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.7.0.tgz#f895e836e45990624086601798ea98e8f36ee643" + integrity sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA== + text-extensions@^1.0.0: version "1.9.0" resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26"