-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Add EIP-8078: GETDEPLOYER opcode (provenance lookup for upgrades and… #10780
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
File
|
Signed-off-by: nolan <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces EIP draft for a new GETDEPLOYER opcode that allows contracts to query the deployer address of other contracts, providing an additional security layer for delegatecall operations and upgradeable contract patterns.
- Proposes a new EVM opcode
GETDEPLOYERthat returns the deployer address of a given contract - Adds a new per-account
deployerstate field tracked from fork activation onwards (forward-only, no historical reprocessing) - Provides reference implementations in Solidity and Go pseudocode with usage examples for secure proxy patterns
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } | ||
|
|
||
| // Opcode execution | ||
| func opGetDeployer(pc *uint64, evm *EVM, scope *ScopeContext) { |
Copilot
AI
Nov 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function signature uses incorrect parameter types. The first parameter pc *uint64 is unusual for an opcode implementation in go-ethereum. Typically, opcode functions don't receive the program counter as a parameter since it's managed by the interpreter. The signature should likely match the standard opcode function signature pattern used in go-ethereum. Additionally, ScopeContext should probably be passed as a pointer *ScopeContext for consistency with actual go-ethereum implementations.
| func opGetDeployer(pc *uint64, evm *EVM, scope *ScopeContext) { | |
| func opGetDeployer(evm *EVM, scope *ScopeContext) { |
|
|
||
| Alternative bundled forms were explored and rejected due to subtle behavioral shifts and reduced composability with existing delegatecall abstractions. | ||
|
|
||
| Whitelisting deployers is intentionally simple; richer schemes (code hash + deployer, signature verification) can be layered without further protocol changes. |
Copilot
AI
Nov 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: "whitelisting" is used inconsistently with "allowlist"/"allowlisting" throughout the document. Line 179 uses "Whitelisting deployers" while lines 232, 237 use "whitelisting" and lines 226, 237-238 use "allowlist". Modern technical documentation typically prefers "allowlist" over "whitelist" for inclusive language. Consider standardizing on "allowlist"/"allowlisting" throughout the document.
| Whitelisting deployers is intentionally simple; richer schemes (code hash + deployer, signature verification) can be layered without further protocol changes. | |
| Allowlisting deployers is intentionally simple; richer schemes (code hash + deployer, signature verification) can be layered without further protocol changes. |
| // Opcode execution | ||
| func opGetDeployer(pc *uint64, evm *EVM, scope *ScopeContext) { | ||
| addrWord := scope.Stack.Pop() | ||
| addr := common.Address(addrWord.Bytes()[12:32]) |
Copilot
AI
Nov 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The address extraction logic in the Go reference implementation is incorrect. addrWord.Bytes()[12:32] attempts to extract bytes 12-31 (20 bytes) from a 32-byte word to get an address, but this assumes the word has at least 32 bytes. The correct slice should be addrWord.Bytes20() or proper bounds checking should be added. Additionally, slice [12:32] would be the correct range only if the address is left-padded; EVM addresses are typically right-aligned in 32-byte words, meaning bytes 0-19 or using the last 20 bytes.
| addr := common.Address(addrWord.Bytes()[12:32]) | |
| addr := common.BytesToAddress(addrWord.Bytes()[12:]) |
| 1. Pops one stack item `addr`. | ||
| 2. If `addr` is not a contract (no code) pushes `0x0`. | ||
| 3. If the contract was created before fork activation pushes `0x0`. | ||
| 4. Otherwise pushes the stored `deployer` field (left padded to 32 bytes as with addresses elsewhere on the stack). |
Copilot
AI
Nov 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The specification states addresses are "left padded to 32 bytes" but Ethereum addresses on the stack are typically represented as 32-byte values with the address in the lower 20 bytes (right-aligned/left-zero-padded in big-endian representation). The phrasing "left padded" could be ambiguous. Consider clarifying this as "zero-padded to 32 bytes with the address occupying the rightmost 20 bytes" or "represented as a 32-byte value as with other addresses on the stack" for consistency with EVM conventions.
| 4. Otherwise pushes the stored `deployer` field (left padded to 32 bytes as with addresses elsewhere on the stack). | |
| 4. Otherwise pushes the stored `deployer` field, zero-padded to 32 bytes with the address occupying the rightmost 20 bytes (as with other addresses on the stack). |
| status: Draft | ||
| type: Standards Track | ||
| category: Core | ||
| created: 2025-11-12 |
Copilot
AI
Nov 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The date format is incorrect. According to the EIP template and existing EIPs, dates should be in ISO 8601 format (yyyy-mm-dd), but November 2025 hasn't occurred yet. The current date in the real world is before November 2025. This appears to be a future date that should be corrected to the actual date when this EIP draft was created.
| created: 2025-11-12 | |
| created: 2024-06-12 |
| addr = pop() | ||
| acct = state[addr] | ||
| if acct.codeLength == 0: push(0); return | ||
| if forkBlockNotReachedAt(acct.creationBlock): push(0); return // pre-fork deployment |
Copilot
AI
Nov 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pseudocode at line 99 references acct.creationBlock but this field is never defined in the specification. According to line 103, clients may omit explicit storage of this field and instead flag pre-fork contracts by absence of the deployer field. This makes the pseudocode inconsistent with the actual implementation guidance. Consider either: (1) defining creationBlock as an optional tracking field, or (2) updating the pseudocode to check for the absence/presence of the deployer field instead.
| if forkBlockNotReachedAt(acct.creationBlock): push(0); return // pre-fork deployment | |
| if acct.deployer is absent: push(0); return // pre-fork deployment |
|
|
||
| 5. Developers should consider implementing additional security measures such as: | ||
|
|
||
| - Allowlists of trusted deployers |
Copilot
AI
Nov 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent capitalization: "Allowlists" is capitalized in this bullet point list, but the same term appears lowercase as "allowlist" throughout the rest of the document (e.g., lines 237, 238). For consistency with the rest of the document and standard usage in technical documentation, this should be lowercase "allowlists".
| - Allowlists of trusted deployers | |
| - allowlists of trusted deployers |
| - Lightweight provenance checks: GETDEPLOYER provides a cheaper, semantic lookup complementary to code-hash checks when implementers prefer deployer-level governance. | ||
|
|
||
| ## Specification | ||
|
|
Copilot
AI
Nov 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing RFC 2119 key words boilerplate. According to the EIP template (lines 50-55 of eip-template.md) and best practices, when using normative language like "MUST", "SHOULD", "MAY", etc., the specification should include the standard RFC 2119/8174 interpretation statement: "The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT RECOMMENDED', 'MAY', and 'OPTIONAL' in this document are to be interpreted as described in RFC 2119 and RFC 8174." This statement should appear near the beginning of the Specification section.
| The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
False
| - Cold access: 700 (same order as `EXTCODEHASH`/`EXTCODESIZE`). | ||
| - Warm access: 100 (align with other warm account reads post EIP-2929). | ||
|
|
||
| Touch semantics: Reading `deployer` MUST count as an account access for warm/cold classification but MUST NOT mark the account for deletion protection nor alter `accessed_addresses` beyond normal rules. |
Copilot
AI
Nov 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The specification states that reading deployer "MUST count as an account access for warm/cold classification" but doesn't specify whether accessing a non-existent account (addr with no code) also counts as an account access. Line 55 states it pushes 0x0 for non-contracts, but it's unclear if this also triggers the warm/cold gas cost or uses a different, cheaper path. This should be explicitly specified to ensure consistent implementations across clients.
| Touch semantics: Reading `deployer` MUST count as an account access for warm/cold classification but MUST NOT mark the account for deletion protection nor alter `accessed_addresses` beyond normal rules. | |
| Touch semantics: Reading `deployer` with GETDEPLOYER MUST always count as an account access for warm/cold classification and incur the corresponding gas cost, regardless of whether the address is a contract or not. This applies even if the address has no code and `0x0` is pushed. However, it MUST NOT mark the account for deletion protection nor alter `accessed_addresses` beyond normal rules. |
Co-authored-by: Copilot <[email protected]>
|
The commit 2e6ec90 (as a parent of 6dc1aa1) contains errors. |
eip-getdeployer-draft.md
Outdated
| @@ -0,0 +1,245 @@ | |||
| --- | |||
| eip: xxxx | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eip: 8078
Signed-off-by: nolan <[email protected]>
…ad/EIPs into feat/getdeployer-opcode
|
|
||
| Gas schedule (subject to tuning during ACD process): | ||
|
|
||
| - Cold access: 700 (same order as `EXTCODEHASH`/`EXTCODESIZE`). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggest to create a table
|
|
||
| ### GETDEPLOYER Pseudocode | ||
|
|
||
| ```text |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
generally EL Pseudocode is provided in python in EIP reference, consider changing to that syntax
… delegatecall)
ATTENTION: ERC-RELATED PULL REQUESTS NOW OCCUR IN ETHEREUM/ERCS
--
When opening a pull request to submit a new EIP, please use the suggested template: https://github.com/ethereum/EIPs/blob/master/eip-template.md
We have a GitHub bot that automatically merges some PRs. It will merge yours immediately if certain criteria are met: