# How to calculate an Ethereum Contract's address during its creation using the Solidity language?

Now I know and have read the other thread saying that a contract's address is created deterministically via RLP encoding the creator's address and his nonce and then hashed with Keccak-256 but the problem is the solution is provided in Python.

I am currently coding in Solidity and although I have tried porting the solution over to Solidity, Solidity does not support multi-type arrays to my knowledge which is required by the rlp_encoder function. Any help or tips on how to achieve this in Solidity would be appreciated! (The nonce would be given as input during the contract creation)

• Haven't tried this but you shouldn't need nested arrays or anything since all you are encoding is 2 items of known length github.com/ethereum/wiki/wiki/RLP - something like 0x08 + address length + address as bytes +0x08 + nonce length + nonce as bytes? – Edmund Edgar Aug 13 '17 at 4:22
• I am also intrigued as to why you want to do this? – Thomas Clowes Aug 13 '17 at 11:22
• @EdmundEdgar Would you kindly post an example of how you would proceed with doing the addition you are referring to? Should overflow checking be done or is the addition bitwise or something? Thanks in advance. – Alex Papageorgiou Aug 14 '17 at 2:40

I happened implemented one.

My first version was by solidity but its cost more than 6000 gas to run so I spend sometime to build another version with purely assembly code. this one is much much more efficient.

• Hey, can you compare gas performance of your implementation with my answer? – k06a Oct 30 '18 at 6:23

The most optimized version:

``````function addressFrom(address _origin, uint _nonce) public pure returns (address) {
bytes memory data;
if(_nonce == 0x00)          data = abi.encodePacked(byte(0xd6), byte(0x94), _origin, byte(0x80));
else if(_nonce <= 0x7f)     data = abi.encodePacked(byte(0xd6), byte(0x94), _origin, byte(_nonce));
else if(_nonce <= 0xff)     data = abi.encodePacked(byte(0xd7), byte(0x94), _origin, byte(0x81), uint8(_nonce));
else if(_nonce <= 0xffff)   data = abi.encodePacked(byte(0xd8), byte(0x94), _origin, byte(0x82), uint16(_nonce));
else if(_nonce <= 0xffffff) data = abi.encodePacked(byte(0xd9), byte(0x94), _origin, byte(0x83), uint24(_nonce));
else                        data = abi.encodePacked(byte(0xda), byte(0x94), _origin, byte(0x84), uint32(_nonce));