Skip to content
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

TRC: Create2 #26

Closed
ithinker1991 opened this issue Mar 8, 2019 · 8 comments
Closed

TRC: Create2 #26

ithinker1991 opened this issue Mar 8, 2019 · 8 comments

Comments

@ithinker1991
Copy link

ithinker1991 commented Mar 8, 2019

Simple Summary

A new contract creation function called CREATE2

Abstract

A new method of creating a contract is proposed where the resulting address can be determined by parties ahead of time.

Motivation

Allows interactions to (actually or counterfactually in channels) be made with addresses that do not exist yet on-chain but can be relied on to only possibly eventually contain code that has been created by a particular piece of init code. Important for state-channel use cases that involve counterfactual interactions with contracts.

Specification

Adds a new opcode at 0xf5, which takes 4 stack arguments: endowment, memory_start, memory_length, salt. Behaves identically to CREATE, except using addressPrefix ++ keccak256(address ++ salt ++ keccak256(init_code))[12:] to create a new contract address. addressPrefix is 0x41 forT

The CREATE2 has the same engery schema as CREATE, but also an extra hashcost of GSHA3WORD * ceil(len(init_code) / 32), to account for the hashing that must be performed. The hashcost is deducted at the same time as memory-expansion engery and Create is deducted: before evaluation of the resulting address and the execution of init_code.

  • address is always 21 bytes,
  • salt is always 32 bytes (a stack item).
  • keccak256(init_code) 32 bytes

The preimage for the final hashing round is thus always exactly 85 bytes long.

Rationale

Address formula

  • Because instruction CREATE mainly depends on trxHash, the CREATE2 addresses will not collide with CREATE addresses.
    • Deploy contract: addressPrefix ++ keccak256(trxHash ++ txOwnerAddress)[12:]
    • in internal transaction: addressPrefix ++ keccak256(trxHash ++ nonce)[12:]
  • Ensures that the hash preimage has a fixed size,

Engery cost

Since address calculation depends on hashing the init_code, it would leave clients open to DoS attacks if executions could repeatedly cause hashing of large pieces of init_code, since expansion of memory is paid for only once. This TIP uses the same cost-per-word as the SHA3 opcode.

@taihaofu
Copy link
Contributor

taihaofu commented Mar 8, 2019

@ithinker1991 , I notice etheream version has an extra 0xff to generate new contract address. Why we don't add that in our version?

@tzdybal
Copy link

tzdybal commented Mar 8, 2019

@taihaofu the formula in ETH is different and 0xFF is used to ensure no conflicts between CREATE and CREATE2 addresses. It's there because RLP encoding is used in ETH contract address calculation.

Excerpt from EIP-1014:

Ensures that addresses created with this scheme cannot collide with addresses created using the traditional keccak256(rlp([sender, nonce])) formula, as 0xff can only be a starting byte for RLP for data many petabytes long.

@tzdybal
Copy link

tzdybal commented Mar 8, 2019

@ithinker1991 IMHO it's not obvious why there is no conflict in generated address between CREATE and CREATE2 with your formula. Could you please elaborate more on this?

@ithinker1991
Copy link
Author

@taihaofu @tzdybal

CREATE formula:

  • Deploy contract: addressPrefix ++ keccak256(trxHash ++ txOwnerAddress)[12:]
  • In internal transaction: addressPrefix ++ keccak256(trxHash ++ nonce)[12:]

CREAT2 formula:

  • addressPrefix ++ keccak256(address ++ salt ++ keccak256(init_code))[12:]

address is always 21 bytes
trxHash is always 32 bytes

trxHash and sender address and different in length, so CREATE address and CREATE2 have different value spaces

@ithinker1991
Copy link
Author

pragma solidity >0.4.99 <0.6.0;

contract Factory {
  event Deployed(address addr, uint256 salt);

  function deploy(bytes memory code, uint256 salt) public {
    address addr;
    assembly {
      addr := create2(0, add(code, 0x20), mload(code), salt)
      if iszero(extcodesize(addr)) {
        revert(0, 0)
      }
    }

    emit Deployed(addr, salt);
  }
}

refer : https://github.com/miguelmota/solidity-create2-example

@ithinker1991
Copy link
Author

@tzdybal
Copy link

tzdybal commented Apr 5, 2019

Interesting reading: https://medium.com/coinmonks/why-create2-e99b6afcc28c

@saurik
Copy link

saurik commented Sep 20, 2020

By having arbitrarily dropped the 0xff from the prefix, you sadly broke Nick's method of being able to create singleton contracts across chains, including EIP-2470 singletons :(. https://eips.ethereum.org/EIPS/eip-2470

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants