HIP-329: Support CREATE2 opcode
Author | Michael Tinker |
---|---|
Discussions-To | https://github.com/hashgraph/hedera-improvement-proposal/discussions/328 |
Status | Final ⓘ |
Needs Council Approval | Yes ⓘ |
Review period ends ⓘ | Tue, 01 Feb 2022 07:00:00 +0000 |
Type | Standards Track ⓘ |
Category | Service ⓘ |
Created | 2022-01-14 |
Updated | 2022-04-26 |
Release | v0.23.0 |
Table of Contents
Abstract
EIP-1014 introduced the CREATE2
opcode to let a
contract be deployed to a predictable address on the Ethereum blockchain.
Because each Hedera entity must have a unique 0.0.X
id, and the Solidity address of a
Hedera contract is currently determined by its 0.0.X
id, there has not, historically,
been a natural way to implement CREATE2
on our ledger.
But after HIP-32, there is now a mechanism in the code
that provides a level of indirection between a ByteString
“alias” and a 0.0.X
id. We propose
in this HIP to implement CREATE2
by re-using the alias mechanism to link the deterministic
address specified in EIP-1014 to a new contract’s 0.0.X
id.
To externalize this 0.0.X
-to-address link to mirror nodes in the record stream, we propose to
re-use the “internal” transaction records introduced in HIP-206,
only adding a new bytes evm_address
field to the record. To simplify client calls to
contracts created via CREATE2
, we propose to extend the Hedera API (HAPI) protobufs so that
this evm_address
identifier can be used anywhere HAPI accepts a ContractID
.
Motivation
Standard implementations of a distributed exchange (DEX), for example, make heavy use of
the CREATE2
opcode. This opcode can also improve user onboarding flows in dApps. We want
to let such applications to be deployed on Hedera.
Rationale
The business value of this HIP is self-evident, so the only decision points are in the changes to Services code and protobuf messages. Our reasoning is that:
- Re-use of the alias mechanism reduces risk and complexity in the codebase.
- Externalizing created
0.0.X
-to-address links via a newevm_address
field in a child record follows the same pattern used in auto-account creation. - Although the
GetBySolidityIDQuery
could be re-enabled, and clients required to use it
to look up theContractID
of an EVM address, this poorly named query is not free—and some clients may want to pre-compute theCREATE2
address and use it directly.
User stories
- As a Hedera DEX operator, I want to re-use standard Solidity contracts that use the
CREATE2
opcode.
Specification
- Implement the
CREATE2
EVM opcode0xF5
in Services by linking the EIP-1014 address to the new contract’s underlying0.0.X
id as an alias, and updating the EVM address lookup to be alias-aware. - When the
ADDRESS
EVM opcode is executed in the context of a contract with an EIP-1014 address, preferentially return the EIP-1014 address instead of the “mirror”0x0000...<X>
address that derives from the contract’s0.0.X
id. - Externalize this
evm_address
-to-0.0.X
link via newContractCreate
child records which will now be created for every internal EVM creation (whether processed withCREATE
orCREATE2
). - (HAPI) Include a new
bytes evm_address
field in theTransactionRecord
message, to be populated in these child transaction records. - (HAPI) Deprecate the
createdContractIDs
field in theContractFunctionResult
message, since this information will now be duplicated by the new child transactions. - (HAPI) When the
0.0.<alias>
form of anAccountID
is used in aCryptoTransferTransactionBody
, respect use of anevm_address
for thealias
portion; thus allowing a HAPI client to do a native transfer of assets to a contract known only by itsCREATE2
address. - (HAPI) Extend the
ContractID
protobuf message as below, so that anevm_address
identifier can be used anywhere that HAPI accepts aContractID
. ``` message ContractID { /**- The shard number (nonnegative) */ int64 shardNum = 1;
/**
- The realm number (nonnegative) */ int64 realmNum = 2;
oneof contract { /**
* A nonnegative number unique within a given shard and realm */ int64 contractNum = 3;/** * The 20-byte EVM address of the contract to call. * * Every contract has an EVM address determined by its <tt>shard.realm.num</tt> id. * This address is as follows: * <ol> * <li>The first 4 bytes are the big-endian representation of the shard.</li> * <li>The next 8 bytes are the big-endian representation of the realm.</li> * <li>The final 8 bytes are the big-endian representation of the number.</li> * </ol> * * Contracts created via CREATE2 have an <b>additional, primary address</b> that is * derived from the <a href="https://eips.ethereum.org/EIPS/eip-1014">EIP-1014</a> * specification, and does not have a simple relation to a <tt>shard.realm.num</tt> id. * * (Please do note that CREATE2 contracts can also be referenced by the three-part * EVM address described above.) */ bytes evm_address = 4; } } ```
Backwards Compatibility
No existing contract should be affected by this HIP—unless it was failing due to use of
CREATE2
, in which case it should become functional.
Security Implications
The Ethereum community and others have now demonstrated patterns that allow safe use of CREATE2
.
As long as users follow the patterns in these contracts, there should not be security implications.
How to Teach This
“Implement EIP-1014 on Hedera to allow creating contracts at pre-determined addresses.”
Reference Implementation
The user-facing changes to HAPI have been discussed in this PR.
Rejected Ideas
In principle, it may be possible to make CREATE2
addresses globally unique across all shards.
But the extreme complexity of this task did not seem justified by the value provided.
Open Issues
No blocking issues are known at this time.
References
Copyright/license
This document is licensed under the Apache License, Version 2.0 – see LICENSE or (https://www.apache.org/licenses/LICENSE-2.0)
Citation
Please cite this document as: