Defines a new transaction type that has a field for a constraint on ancestor block hash. Transactions with this field are only valid on chain segments that include the defined ancestor.
We introduce a new EIP-2718 transaction type with the format
0x4 || rlp([chainId, ancestorHash, nonce, gasPrice, gasLimit, to, value, data, access_list, yParity, senderR, senderS]).
ancestorHash element adds a constraint on the validity of a transaction to a chain segment containing the cited ancestor in its graph.
Establish a protocol-based mechanism with which transactions are able to articulate a constraint on some chain state.
Generally, this constraint gives the consumer (the transactor) an ability to express requirements about the transaction’s relationship to blockchain data and its provenance.
- Restrict transaction applicability to a chain context that is currently available and reasoned about under some subjective view.
- Introduces a way for transactions to describe a dependency on their current view of a chain.
- Restrict transaction applicability to a chain context following some foregoing block (and its transactions).
- Introduces a way for transactions to describe ancestral dependencies at a “macro” (block) level. Indirectly, this offers a way for a transaction to depend on the presence of another, so long as the dependent transaction is in a different block.
0x4. See EIP-2718.
FORK_BLOCK_NUMBER, a new EIP-2718 transaction is introduced with
TransactionPayload for this transaction is
rlp([chainId, ancestorHash, nonce, gasPrice, gasLimit, to, value, data, access_list, yParity, senderR, senderS]).
ReceiptPayload for this transaction is
rlp([status, cumulativeGasUsed, logsBloom, logs]).
The values defined below act as a constraint on transaction validity. Transactions defining constraints which are not satisfied by their chain context should be rejected as invalid. Blocks containing invalid transactions should be rejected as invalid themselves, per the status quo.
bytes. A byte array 32 bytes in length.
ancestorHash is a reference to a specific block by hash.
If a transaction filling this field is included in block number
n, the annotated value must match some block numbered
<= n-1 and existing as a direct (canonical; non-ommer) ancestor of the transaction’s containing block.
A “direct ancestor” means that the hash of the block must exist in the
parentHash tree of the chain.
ancestorHash value should be RLP encoded as a byte array for hashing and transmission.
ancestorHash field allows the transactor to express and guarantee an assumption about some contemporary chain state for their pending transaction.
Reference to some assumed blockchain state for transaction composition is already the common case.
A transaction sender might reference their view of the chain to fill the transaction’s
nonce field, to check their balance, and even to determine the availability or pricing of some op code (via a hypothetical fork upgrade).
Currently, these references to a chain state during transaction composition are tacit and passive.
If the transactor’s assumption breaks, their transaction may yield an unintended or undesired outcome.
ancestorHash facilitates the declaration of these state assumptions, and demands their correctness in order for the transaction to be permitted.
Chain state on Ethereum only approaches finality, while its transactions are subject to somewhat arbitrary inclusion and ordering. This mechanism allows transactors to express demands about foregoing chain state for the eligibility of their transactions.
In this way,
ancestorHash values can operate as an observable heuristic for confidence (on behalf of transactors) about the finality of the chain state.
These measurements could be used to inform confirmation delay values of creditors.
Elon owns 1000000ETH.
Fred owns 100ETH.
Elon issues a transaction sending his balance to a known currency exchange, apparently selling this share in the currency.
This transaction is included at block number
1,000,000 with hash
Upon the publication of this block, Fred sees this transaction and thinks that he should follow in Elon’s footsteps to protect his capital from speculative devaluation. Fred constructs and publishes a similar transaction, which he expects to be included in some subsequent block.
By accident or design, block
0xb2957ab683ae69176b2eb7858f2baedb93752cb7cb45284529d543eebe20652e is orphaned, replaced with
This replacement block does NOT contain Elon’s transaction (or contains an alternative, replacement transaction from Elon), but it does contain Fred’s transaction.
Fred has been duped into a sale, while Elon hodls and profits.
If Fred can cite
0xb2957ab683ae69176b2eb7858f2baedb93752cb7cb45284529d543eebe20652e as an
ancestorHash dependency, his transaction will be inapplicable on the newly reorganized chain, and he won’t get duped.
Transactions citing ancestors on a public chain will not be valid on an attacker’s secret chain if the citations reference post-fork blocks.
Under the current protocol conditions, a double-spend attacker can choose to include none, some, or all-but-one of the public chain’s transaction on their attack chain.
We assume for the sake of this scenario’s argument that all transactors on the public chain use
ancestorHash values four blocks prior to their time of issuance.
Four blocks after the attacking fork, the attack chain will be entirely absent of those public transactions (thus approaching the ‘none’ option).
This scenario forces the hand of the attacker away from a targeted attack with a single victim toward an attack that jeapordizes the interests of all transactors during that time. Although risk is increased for the public users in this scenario, so too – and at a larger, aggregated, magnitude – is the risk for the attacker in the potential for a counterattack on behalf of the original public chain.
This pattern can be understood as a correlate of EIP-155’s
EIP155 defines the restriction of transactions between chains; limiting the applicability of any EIP-155 transaction to a chain with the annotated ChainID.
ancestorHash further restricts transaction application to some subsection (“segment”) of a chain defined under EIP-155.
From this constraint hierarchy, we note that an alternative implementation of
ancestorHash could make
chainId conceptually redundant.
So why keep
chainId is maintained as an invariant because:
- The use of the transaction type proposed by this EIP is optional, implying the continued necessity of
chainIdin the protocol infrastructure and tooling for legacy and other transaction types.
- The presence of
ancestorHashin the transaction type proposed by this EIP is optional. If the value is not filled by an RCC transaction, the demand for
chainIdvalue is not necessarily redundant to
ancestorHash, namely in cases where forks result in living chains. For example, an
ancestorHashreference to block
1_919_999would be ambiguous between Ethereum and Ethereum Classic.
- It would be possible to specify the omission of
chainIdin case of
ancestorHash’s use. This would add infrastructural complexity for the sake of removing the few bytes
chainIdtypically requires; we do not consider this trade-off worth making.
chainIdis used as the
v,r,s) in the transaction signing scheme; removing or modifying this incurs complexity at a level below encoded transaction fields, demanding additional infrastructural complexity for implementation.
The EIP-2930 Optional Access List Type Transaction is used as an assumed “base” transaction type for this proposal.
However, this is NOT a conceptual dependency; the included
accessList portion of this proposal (the only differential from post-EIP-155 legacy transaction fields) can readily be removed.
Standing on the shoulders of EIP-2930 is only intended to support and further the adoption of next-generation transactions.
The signature signs over the transaction type as well as the transaction data. This is done to ensure that the transaction cannot be “re-interpreted” as a transaction of a different type.
There are no known backward compatibility issues.
ancestorHash demands the assertion of a positive database hit by block hash.
This requires that the chain validator fills the role of a chain reader.
This necessary lookup can be cached (and maybe already is for some clients), but we must expect less than 100% hits on cached values, since the lookup value is arbitrary.
With that in mind, however, the value provided to a transaction using a deep
ancestorHash is increasingly marginal, so we should expect
most transactions using this field to use a relatively small set of common, shallow, cache-friendly values.
Transaction size increase
The proposed additional fields, if used, increase transaction size by 32 bytes.
Copyright and related rights waved via CC0.