Skip to content

Commit 3c903dd

Browse files
authored
Merge pull request #5988 from ethereum/eip_7702
Eip 7702
2 parents f6dfdbb + 3f8bcad commit 3c903dd

File tree

48 files changed

+740
-309
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+740
-309
lines changed

apps/remix-dapp/src/locales/en/udapp.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"udapp.createSmartAccountDesc4":"Smart Account will by default have a PAYMASTER attached to it to execute GASLESS transactions, only for SEPOLIA testnet. ",
7070
"udapp.createSmartAccountDesc5":"Smart Account creation will require signing of an initial transaction at next step.",
7171
"udapp.continue": "Continue",
72+
"udapp.authorize": "Authorize",
7273
"udapp.createNewAccount": "Create a new account",
7374
"udapp.web3Title": "Creating an account is possible only in Personal mode. Please go to Settings to enable it.",
7475
"udapp.defaultTitle": "Unfortunately it's not possible to create an account using an external wallet ({selectExEnv}).",

apps/remix-ide-e2e/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"npm": "^6.14.15"
77
},
88
"dependencies": {
9-
"ethers": "^6.13.7",
9+
"ethers": "^6.14.0",
1010
"@openzeppelin/contracts": "^5.0.2",
1111
"@openzeppelin/contracts-upgradeable": "^5.0.2",
1212
"@openzeppelin/upgrades-core": "^1.30.0",
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
'use strict'
2+
3+
import { NightwatchBrowser } from 'nightwatch'
4+
import init from '../helpers/init'
5+
6+
module.exports = {
7+
'@disabled': true,
8+
before: function (browser: NightwatchBrowser, done: VoidFunction) {
9+
init(browser, done)
10+
},
11+
'Should activate delegation and make a transaction to the authority address #group1': function (browser: NightwatchBrowser) {
12+
let addressDelegate
13+
browser
14+
.clickLaunchIcon('udapp')
15+
.switchEnvironment('vm-pectra')
16+
.addFile('delegate.sol', { content: delegate })
17+
.clickLaunchIcon('solidity')
18+
.setSolidityCompilerVersion('soljson-v0.8.28+commit.7893614a.js')
19+
.clickLaunchIcon('solidity')
20+
.verifyContracts(['TestDelegate'])
21+
.clickLaunchIcon('udapp')
22+
.selectContract('Simple7702Account')
23+
.createContract('')
24+
.perform((done) => {
25+
browser.getAddressAtPosition(0, (address) => {
26+
addressDelegate = address
27+
done()
28+
})
29+
})
30+
.click('[data-id="deployAndRunClearInstances"]')
31+
.perform((done) => {
32+
browser
33+
.click('*[data-id="create-delegation-authorization"]')
34+
.waitForElementVisible('*[data-id="create-delegation-authorization-input"]')
35+
.execute(() => {
36+
(document.querySelector('*[data-id="create-delegation-authorization-input"]') as any).focus()
37+
}, [], () => {})
38+
.setValue('*[data-id="create-delegation-authorization-input"]', addressDelegate)
39+
.perform(() => done())
40+
})
41+
.modalFooterOKClick('udappNotify')
42+
.waitForElementContainsText('*[data-id="terminalJournal"]', 'This account will be running the code located at')
43+
.clickInstance(0)
44+
.clickFunction('entryPoint - call')
45+
.verifyCallReturnValue('0x5B38Da6a701c568545dCfcB03FcB875f56beddC4', ['0:address: 0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108'])
46+
},
47+
48+
'Should keep the delegation status after reloae & switching accounts #group1': function (browser: NightwatchBrowser) {
49+
browser
50+
.refresh()
51+
.clickLaunchIcon('udapp')
52+
.switchEnvironment('vm-pectra')
53+
.waitForElementVisible('*[data-id="delete-delegation"]')
54+
.selectAccount('0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2')
55+
.waitForElementNotPresent('*[data-id="delete-delegation"]')
56+
.selectAccount('0x5B38Da6a701c568545dCfcB03FcB875f56beddC4')
57+
.waitForElementVisible('*[data-id="delete-delegation"]')
58+
},
59+
60+
'Should remove the delegation #group1': function (browser: NightwatchBrowser) {
61+
browser
62+
.waitForElementVisible('*[data-id="delete-delegation"]')
63+
.click('*[data-id="delete-delegation"]')
64+
.modalFooterOKClick('udappNotify')
65+
.waitForElementNotPresent('*[data-id="delete-delegation"]')
66+
.waitForElementContainsText('*[data-id="terminalJournal"]', `Delegation for 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4 removed.`)
67+
.refresh()
68+
.clickLaunchIcon('udapp')
69+
.switchEnvironment('vm-pectra')
70+
.waitForElementNotPresent('*[data-id="delete-delegation"]')
71+
}
72+
}
73+
74+
const delegate = `import "https://github.com/eth-infinitism/account-abstraction/blob/v0.8.0/contracts/accounts/Simple7702Account.sol";`

apps/remix-ide/src/app.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import { StoragePlugin } from './app/plugins/storage'
3232
import { Layout } from './app/panels/layout'
3333
import { NotificationPlugin } from './app/plugins/notification'
3434
import { Blockchain } from './blockchain/blockchain'
35-
import { MergeVMProvider, LondonVMProvider, BerlinVMProvider, ShanghaiVMProvider, CancunVMProvider } from './app/providers/vm-provider'
35+
import { MergeVMProvider, LondonVMProvider, BerlinVMProvider, ShanghaiVMProvider, CancunVMProvider, PectraVMProvider } from './app/providers/vm-provider'
3636
import { MainnetForkVMProvider } from './app/providers/mainnet-vm-fork-provider'
3737
import { SepoliaForkVMProvider } from './app/providers/sepolia-vm-fork-provider'
3838
import { GoerliForkVMProvider } from './app/providers/goerli-vm-fork-provider'
@@ -341,6 +341,7 @@ class AppComponent {
341341
const vmProviderGoerliFork = new GoerliForkVMProvider(blockchain)
342342
const vmProviderShanghai = new ShanghaiVMProvider(blockchain)
343343
const vmProviderCancun = new CancunVMProvider(blockchain)
344+
const vmProviderPectra = new PectraVMProvider(blockchain)
344345
const vmProviderMerge = new MergeVMProvider(blockchain)
345346
const vmProviderBerlin = new BerlinVMProvider(blockchain)
346347
const vmProviderLondon = new LondonVMProvider(blockchain)
@@ -417,6 +418,7 @@ class AppComponent {
417418
storagePlugin,
418419
vmProviderShanghai,
419420
vmProviderCancun,
421+
vmProviderPectra,
420422
vmProviderMerge,
421423
vmProviderBerlin,
422424
vmProviderLondon,

apps/remix-ide/src/app/plugins/templates-selection/templates.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ export const templates = (intl, plugin) => {
44
name: "Generic",
55
items: [
66
{ value: "remixDefault", tagList: ["Solidity"], displayName: intl.formatMessage({ id: 'filePanel.basic' }), description: 'The default project' },
7-
{ value: "blank", displayName: intl.formatMessage({ id: 'filePanel.blank' }), IsArtefact: true, description: 'A blank project' }
7+
{ value: "blank", displayName: intl.formatMessage({ id: 'filePanel.blank' }), IsArtefact: true, description: 'A blank project' },
8+
{ value: "simpleEip7702", displayName: 'Simple EIP 7702', IsArtefact: true, description: 'Pectra upgrade allowing externally owner accounts (EOAs) to run contract code.' },
9+
{ value: "accountAbstraction", displayName: 'Account Abstraction Template', IsArtefact: true, description: 'Experiment with Account Abstraction contracts: (ERC-4337, EIP-7702)' }
810
]
911
},
1012
{

apps/remix-ide/src/app/providers/vm-provider.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,24 @@ export class CancunVMProvider extends BasicVMProvider {
132132
}
133133
}
134134

135+
export class PectraVMProvider extends BasicVMProvider {
136+
constructor(blockchain) {
137+
super(
138+
{
139+
name: 'vm-pectra',
140+
displayName: 'Remix VM (Pectra)',
141+
kind: 'provider',
142+
description: 'Remix VM (Pectra)',
143+
methods: ['sendAsync', 'init'],
144+
version: packageJson.version
145+
},
146+
blockchain
147+
)
148+
this.blockchain = blockchain
149+
this.fork = 'prague'
150+
}
151+
}
152+
135153
export class ForkedVMStateProvider extends BasicVMProvider {
136154
nodeUrl?: string
137155
blockNumber?: string

apps/remix-ide/src/app/tabs/locales/en/udapp.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"udapp.createSmartAccountDesc4":"Smart Account will by default have a PAYMASTER attached to it to execute GASLESS transactions, only for SEPOLIA testnet. ",
7070
"udapp.createSmartAccountDesc5":"Smart Account creation will require signing of an initial transaction at next step.",
7171
"udapp.continue": "Continue",
72+
"udapp.authorize": "Authorize",
7273
"udapp.createNewAccount": "Create new account",
7374
"udapp.web3Title": "Creating an account is possible only in Personal mode. Please go to Settings to enable it.",
7475
"udapp.defaultTitle": "Unfortunately it's not possible to create an account using an external wallet ({selectExEnv}).",
@@ -186,5 +187,10 @@
186187
"udapp.EIP712-3": "In Remix, signing typed data is possible by right clicking (right click / Sign Typed Data) on a JSON file whose content is EIP-712 compatible.",
187188
"udapp.EIP712-create-template": "Create a JSON compliant with EIP-712",
188189
"udapp.EIP712-close": "Close",
189-
"udapp.sign": "Sign"
190+
"udapp.sign": "Sign",
191+
192+
"udapp.createDelegationAuthorization": "Connect EOA to contract code (EIP 7702)",
193+
"udapp.createDelegationTitle": "Connect EOA to contract code (EIP 7702)",
194+
"udapp.removeDelegationTitle": "Remove contract delegation (EIP 7702)",
195+
"udapp.createDelegationDescription": "Authorize a delegation between the current EOA and the contract code at the provided address. The contract must be deployed in the current chain."
190196
}

apps/remix-ide/src/app/tabs/web3-provider.js

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -77,41 +77,7 @@ export class Web3ProviderModule extends Plugin {
7777
await this.call('compilerArtefacts', 'addResolvedContract', contractAddressStr, data)
7878
}
7979
}, 50)
80-
const provider = this.blockchain.executionContext.getProviderObject()
81-
82-
// a basic in-browser VM state.
83-
const isBasicVMState = provider.config.isVM && !provider.config.isVMStateForked && !provider.config.isRpcForkedState
84-
// a standard fork of an in-browser state.
85-
const isForkedVMState = provider.config.isVM && provider.config.isVMStateForked && !provider.config.isRpcForkedState
86-
// a fork of an in-browser state which derive from a live network.
87-
const isForkedRpcState = provider.config.isVM && provider.config.isVMStateForked && provider.config.isRpcForkedState
88-
89-
if (isBasicVMState || isForkedVMState || isForkedRpcState) {
90-
if (this.blockchain.config.get('settings/save-evm-state')) {
91-
try {
92-
let state = await this.blockchain.executionContext.getStateDetails()
93-
if (provider.config.statePath) {
94-
const stateFileExists = await this.call('fileManager', 'exists', provider.config.statePath)
95-
if (stateFileExists) {
96-
let stateDetails = await this.call('fileManager', 'readFile', provider.config.statePath)
97-
stateDetails = JSON.parse(stateDetails)
98-
state = JSON.parse(state)
99-
state['stateName'] = stateDetails.stateName
100-
state['forkName'] = stateDetails.forkName
101-
state['savingTimestamp'] = stateDetails.savingTimestamp
102-
state = JSON.stringify(state, null, 2)
103-
}
104-
this.call('fileManager', 'writeFile', provider.config.statePath, state)
105-
} else if (isBasicVMState && !isForkedRpcState && !isForkedRpcState) {
106-
// in that case, we store the state only if it is a basic VM.
107-
const provider = this.blockchain.executionContext.getProvider()
108-
this.call('fileManager', 'writeFile', `.states/${provider}/state.json`, state)
109-
}
110-
} catch (e) {
111-
console.error(e)
112-
}
113-
}
114-
}
80+
await this.call('blockchain', 'dumpState')
11581
}
11682
}
11783
resolve(message)

apps/remix-ide/src/app/udapp/run-tab.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ export class RunTab extends ViewPlugin {
148148
'vm-paris': 'Deploy to the in-browser virtual machine running the Paris fork.',
149149
'vm-london': 'Deploy to the in-browser virtual machine running the London fork.',
150150
'vm-berlin': 'Deploy to the in-browser virtual machine running the Berlin fork.',
151+
'vm-pectra': 'Deploy to the in-browser virtual machine running the Prague fork.',
151152
'vm-mainnet-fork': 'Deploy to a fork of the Ethereum mainnet latest block in the in-browser virtual machine.',
152153
'vm-sepolia-fork': 'Deploy to a fork of the Sepolia testnet latest block in the in-browser virtual machine.',
153154
'vm-custom-fork': 'Deploy to a fork of a custom network in the in-browser virtual machine.',
@@ -261,14 +262,15 @@ export class RunTab extends ViewPlugin {
261262

262263
// VM
263264
const titleVM = 'Execution environment is local to Remix. Data is only saved to browser memory and will vanish upon reload.'
264-
await addProvider(1, 'vm-cancun', 'Remix VM (Cancun)', { isInjected: false, isVM: true, isRpcForkedState: false, statePath: '.states/vm-cancun/state.json', fork: 'cancun' }, 'settingsVMCancunMode', titleVM)
265+
await addProvider(1, 'vm-pectra', 'Remix VM (Pectra)', { isInjected: false, isVM: true, isRpcForkedState: false, statePath: '.states/vm-pectra/state.json', fork: 'prague' }, 'settingsVMPectraMode', titleVM)
266+
await addProvider(2, 'vm-cancun', 'Remix VM (Cancun)', { isInjected: false, isVM: true, isRpcForkedState: false, statePath: '.states/vm-cancun/state.json', fork: 'cancun' }, 'settingsVMCancunMode', titleVM)
265267
await addProvider(50, 'vm-shanghai', 'Remix VM (Shanghai)', { isInjected: false, isVM: true, isRpcForkedState: false, statePath: '.states/vm-shanghai/state.json', fork: 'shanghai' }, 'settingsVMShanghaiMode', titleVM)
266268
await addProvider(51, 'vm-paris', 'Remix VM (Paris)', { isInjected: false, isVM: true, isRpcForkedState: false, statePath: '.states/vm-paris/state.json', fork: 'paris' }, 'settingsVMParisMode', titleVM)
267269
await addProvider(52, 'vm-london', 'Remix VM (London)', { isInjected: false, isVM: true, isRpcForkedState: false, statePath: '.states/vm-london/state.json', fork: 'london' }, 'settingsVMLondonMode', titleVM)
268270
await addProvider(53, 'vm-berlin', 'Remix VM (Berlin)', { isInjected: false, isVM: true, isRpcForkedState: false, statePath: '.states/vm-berlin/state.json', fork: 'berlin' }, 'settingsVMBerlinMode', titleVM)
269-
await addProvider(2, 'vm-mainnet-fork', 'Remix VM - Mainnet fork', { isInjected: false, isVM: true, isVMStateForked: true, isRpcForkedState: true, fork: 'cancun' }, 'settingsVMMainnetMode', titleVM)
270-
await addProvider(3, 'vm-sepolia-fork', 'Remix VM - Sepolia fork', { isInjected: false, isVM: true, isVMStateForked: true, isRpcForkedState: true, fork: 'cancun' }, 'settingsVMSepoliaMode', titleVM)
271-
await addProvider(4, 'vm-custom-fork', 'Remix VM - Custom fork', { isInjected: false, isVM: true, isVMStateForked: true, isRpcForkedState: true, fork: '' }, 'settingsVMCustomMode', titleVM)
271+
await addProvider(3, 'vm-mainnet-fork', 'Remix VM - Mainnet fork', { isInjected: false, isVM: true, isVMStateForked: true, isRpcForkedState: true, fork: 'cancun' }, 'settingsVMMainnetMode', titleVM)
272+
await addProvider(4, 'vm-sepolia-fork', 'Remix VM - Sepolia fork', { isInjected: false, isVM: true, isVMStateForked: true, isRpcForkedState: true, fork: 'cancun' }, 'settingsVMSepoliaMode', titleVM)
273+
await addProvider(5, 'vm-custom-fork', 'Remix VM - Custom fork', { isInjected: false, isVM: true, isVMStateForked: true, isRpcForkedState: true, fork: '' }, 'settingsVMCustomMode', titleVM)
272274

273275
// Forked VM States
274276
const addFVSProvider = async(stateFilePath, pos) => {

0 commit comments

Comments
 (0)