Description
tip: 7702
title: Set EOA account code
description: Add a new tx type that permanently sets the code for an EOA
authors: ---
status: ---
type: Standards Track
category: Core
created: 2025-02-18
Summary
This tip is aiming to introduce EIP-7702 into Tron to enhance the functionality of EOAs. It elucidates the primary characteristics of EIP-7702 and compares some differences in implementing this feature between Ethereum and Tron.
Abstract
Introduce a novel transaction type that incorporates a series of authorization tuples, each consisting of [chain_id, address, nonce, r, s, v]
. For each of these tuples, a delegation designator (0xef0100 + address) is written into the code of the signing account. All subsequent code executions must load and execute the code referenced by this designator.
Motivation
There is a lot of interest in adding short-term functionality improvements to EOAs, increasing the usability of applications and in some cases allowing improved security. Three particular applications include:
- Batching: allowing multiple operations from the same user in one atomic transaction. One common example is an TRC-20 approval followed by spending that approval, a common workflow in DEXes that requires two transactions today. Advanced use cases of batching occasionally involve dependencies: the output of the first operation is part of the input to the second operation.
- Sponsorship: account X pays for a transaction on behalf of account Y. Account X could be paid in some other TRC-20 for this service, or it could be an application operator including the transactions of its users for free.
- Privilege de-escalation: users can sign sub-keys and give them specific permissions that are much weaker than global access to the account. For example, you could imagine a permission to spend TRC-20 tokens but not TRX, or to spend up to 1% of the total balance per day, or to interact only with a specific application.
Specification
Set Code Transaction
A new transaction type "set code transaction" is introduced. The transaction contains a authrization_list
, which is a list of tuples that store the address to code which the signer desires to execute in the context of their EOA. The transaction is considered invalid if the length of authorization_list
is zero. Each tuple consists of [chain_id, address, nonce, r, s, v]
.
The transaction is also considered invalid when any field in an authorization
tuple cannot fit within the following bounds:
assert auth.chain_id < 2**256
assert auth.nonce < 2**64
assert auth.v < 2**8
assert auth.r < 2**256
assert auth.s < 2**256
Behavior
For each [chain_id, address, nonce, r, s, v]
tuple do the following:
- Verify the chain id is either 0 or the chain's current ID.
- Verify the
nonce
is less than2**64 - 1
. authority = ecrecover(keccak(rlp([chain_id, address, nonce])), r, s, v)
s
value must be less than or equal tosecp256k1n/2
, as specified in EIP-2.
- Verify the code of
authority
is either empty or already delegated. - Verify the nonce of
authority
is equal tononce
. In caseauthority
does not exist in the repository, verify thatnonce
is equal to0
. - Set the code of
authority
to be0xef0100 || address
. This is a delegation designation.- As a special case, if
address
is0x0000000000000000000000000000000000000000
do not write the designation. Clear the account's code and reset the account's code hash to empty.
- As a special case, if
- Increase the nonce of
authority
by one.
If any of the above steps fail, immediately stop processing that tuple and continue to the next tuple in the list. It will in the case of multiple tuples for the same authority, set the code using the address in the last valid occurrence.
Note that the signer of an authorization tuple may be different than tx.origin
of the transaction.
If transaction execution results in failure (any exceptional condition or code reverting), setting delegation designations is not rolled back.
Delegation Designation
This designator requires all code executing operations to follow the address pointer to get the account's executable code, and requires all other code reading operations to act only on the delegation designator (0xef0100 || address
). The following reading instructions are impacted: EXTCODESIZE
, EXTCODECOPY
, EXTCODEHASH
, and the following executing instructions are impacted: CALL
, CALLCODE
, STATICCALL
, DELEGATECALL
, as well as transactions with destination
targeting the code with delegation designation.
For example, EXTCODESIZE
would return 23
(the size of 0xef0100 || address
), EXTCODEHASH
would return keccak256(0xef0100 || address)
, and CALL
would load the code from address
and execute it in the context of authority
.
CODESIZE
and CODECOPY
instructions operate on executable code, as before. Note that in a delegated execution CODESIZE
and CODECOPY
produce different result comparing to EXTCODESIZE
and EXTCODECOPY
of execution target.
In case a delegation designator points to a precompile address, retrieved code is considered empty and CALL
, CALLCODE
, STATICCALL
, DELEGATECALL
instructions targeting this account will execute empty code, i.e. succeed with no execution given enough gas.
In case a delegation designator points to another designator, creating a potential chain or loop of designators, clients must retrieve only the first code and then stop following the designator chain.
The delegation designation can be revoked at any time by signing and sending an TIP-7702 authorization to a new target. Without such action, a delegation will remain valid in perpetuity.
Difference
Transaction
Ethereum introduce a new transaction type according to EIP-2718 standard. Tron hasn't implement this eip. We need to consider how to add the new transaction type that is compatible with Tron. Following is a feasible way:
Introduce a new contract type, SetCodeContract
.
enum ContractType {
...
SetCodeContract = 60;
}
And the data structure of SetCodeContract
is:
message SetCodeContract {
message Authority {
bytes chainId = 1;
bytes address = 2;
int64 nonce = 3;
bytes r = 4;
bytes s = 5;
byte v = 6;
}
repeated Authority authorityList = 1
}
Nonce
There is a nonce field in Ethereum accounts to prevent repay attacks on transactions. The authorization in EIP-7702 also use nonce for repay protection. Each authorization will increase the signer's nonce by 1. Tron account does not contain nonce, so it is necessary to consider how to prevent authorization replay attacks on Tron.
EIPs
Some eips have not been implemented on Tron, which will have an impact on EIP-7702.
EIP-2
s
value must be less than or equal to secp256k1n/2
, as specified in EIP-2, which is not implemented on tron.
Allowing transactions with any s value with 0 < s < secp256k1n
, as is currently the case, opens a transaction malleability concern, as one can take any transaction, flip the s value from s
to secp256k1n - s
, flip the v value (27 -> 28
, 28 -> 27
), and the resulting signature would still be valid.
EIP-3541
The delegation designation uses the banned opcode 0xef
from EIP-3541 to designate the code has a special purpose. EIP-3541 disallow new code starting with the 0xef
byte to be deployed. Although codes starting with 0xef
is rejected for execution on Tron , users can still deploy such codes, which may have an impact on our implementation of 7702. For example, if a user directly deploys a contract with 0xef0100+address
, we cannot determine whether the code is deployed according to the 7702 standard, nor can we specify whether it should be executed according to the 7702 scheme or rejected.
Key Features
- After setting the account's code, it will be effective permanently until the next code setting or setting the code to empty.
- In case a delegation designator points to another designator, creating a potential chain or loop of designators, clients must retrieve only the first code and then stop following the designator chain.
- After setting up the delegation designator, the
calldata
contained in the 7702-transaction will continue to be executed.
Security Considerations
-
Ensuring the security of proxy contracts. Must be careful when setting up delegate contratct.
-
Once code exists in the EOA, it's possible for self-sponsored EIP-7702 transactions to have
msg.sender == tx.origin
anytime the code in the EOA dispatches a call. Without EIP-7702, this situation can only ever arise in the topmost execution layer of a transaction. Therefore, this EIP breaks that invariant and so it affects smart contracts containingrequire(msg.sender == tx.origin)
checks. This check is used for at least three purposes:- Ensuring that
msg.sender
is an EOA (given thattx.origin
always has to be an EOA). This invariant does not depend on the execution layer depth and, therefore, is not affected. - Protecting against atomic sandwich attacks like flash loans, which rely on the ability to modify state before and after the execution of the target contract as part of the same atomic transaction. This protection would be broken by this EIP. However, relying on
tx.origin
in this way is considered bad practice. - Reentrancy verification.
- Ensuring that
-
When a sponsor sends a transaction on behalf of an authority, there may be losses due to malicious users. For example, all assets could be withdrawn, or the nonce could be incremented, causing the transaction to fail. The sponsor then loses the gas fee and does not receive the authority's fee. Attention should be paid to this during design to avoid losses.
-
Managing storage with caution to ensure that setting new code does not conflict with the original storage.
Sub-issues
Metadata
Metadata
Assignees
Labels
Type
Projects
Status