# 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? Commented Aug 13, 2017 at 4:22
• I am also intrigued as to why you want to do this? Commented Aug 13, 2017 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. Commented Aug 14, 2017 at 2:40

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));
}
``````

Update for Solidity 0.6.x:

``````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, uint8(_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));
}
``````

Update for Solidity 0.8.x:

``````function addressFrom(address _origin, uint _nonce) public pure returns (address) {
bytes memory data;
if (_nonce == 0x00)          data = abi.encodePacked(bytes1(0xd6), bytes1(0x94), _origin, bytes1(0x80));
else if (_nonce <= 0x7f)     data = abi.encodePacked(bytes1(0xd6), bytes1(0x94), _origin, uint8(_nonce));
else if (_nonce <= 0xff)     data = abi.encodePacked(bytes1(0xd7), bytes1(0x94), _origin, bytes1(0x81), uint8(_nonce));
else if (_nonce <= 0xffff)   data = abi.encodePacked(bytes1(0xd8), bytes1(0x94), _origin, bytes1(0x82), uint16(_nonce));
else if (_nonce <= 0xffffff) data = abi.encodePacked(bytes1(0xd9), bytes1(0x94), _origin, bytes1(0x83), uint24(_nonce));
else                         data = abi.encodePacked(bytes1(0xda), bytes1(0x94), _origin, bytes1(0x84), uint32(_nonce));
}
``````
• Which version of Solidity does this code compile with? When I try to compile this with Solidity ^0.6.0, I get `TypeError: Explicit type conversion not allowed from "uint256" to "bytes1".` Commented Apr 24, 2020 at 14:18
• @erwaman see my answer for a fix. Commented Sep 28, 2020 at 6:51

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
Commented Oct 30, 2018 at 6:23

actually there's no need to waste gas on this. `address` is available and can be used in constructor using `address(this)`

Updated version of @k06a's answer for Solidity version 0.6:

``````    function addressFrom(address _origin, uint _nonce) public pure returns (address _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, uint8(_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));
bytes32 hash = keccak256(data);
assembly {
mstore(0, hash)
}
}
``````

And for version 0.8 and above:

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