6

"Contracts can be created by other contracts using the new keyword. Since 0.8.0, new keyword supports create2 feature by specifying salt options."

pragma solidity ^0.8.10;

contract Car {
address public owner;
string public model;
address public carAddr;

constructor(address _owner, string memory _model) payable {
    owner = _owner;
    model = _model;
    carAddr = address(this);
  }
}

contract CarFactory {
Car[] public cars;

function create(address _owner, string memory _model) public {
    Car car = new Car(_owner, _model);
    cars.push(car);
}

function createAndSendEther(address _owner, string memory _model) public payable {
    Car car = (new Car){value: msg.value}(_owner, _model);
    cars.push(car);
}

function create2(
    address _owner,
    string memory _model,
    bytes32 _salt
) public {
    Car car = (new Car){salt: _salt}(_owner, _model);
    cars.push(car);
}

function create2AndSendEther(
    address _owner,
    string memory _model,
    bytes32 _salt
) public payable {
    Car car = (new Car){value: msg.value, salt: _salt}(_owner, _model);
    cars.push(car);
}

function getCar(uint _index)
    public
    view
    returns (
        address owner,
        string memory model,
        address carAddr,
        uint balance
    )
{
    Car car = cars[_index];

    return (car.owner(), car.model(), car.carAddr(), address(car).balance);
    }
}

3 Answers 3

2

A salt (in cryptography) is a bit of randomness added to a transaction (usually inputs to a hashing function) in order to make discovering a secret (key) harder.

https://en.wikipedia.org/wiki/Salt_(cryptography)

5

According to the Solidity docs:

"When creating a contract, the address of the contract is computed from the address of the creating contract and a counter that is increased with each contract creation.

If you specify the option salt (a bytes32 value), then contract creation will use a different mechanism to come up with the address of the new contract: It will compute the address from the address of the creating contract, the given salt value, the (creation) bytecode of the created contract and the constructor arguments."

This allows you to predict the contract address before it is created, here is the example code that solidity provides:

    // SPDX-License-Identifier: GPL-3.0
    pragma solidity >=0.7.0 <0.9.0;
    contract D {
        uint public x;
        constructor(uint a) {
            x = a;
        }
    }
    
    contract C {
        function createDSalted(bytes32 salt, uint arg) public {
            // This complicated expression just tells you how the address
            // can be pre-computed. It is just there for illustration.
            // You actually only need ``new D{salt: salt}(arg)``.
            address predictedAddress = address(uint160(uint(keccak256(abi.encodePacked(
                bytes1(0xff),
                address(this),
                salt,
                keccak256(abi.encodePacked(
                    type(D).creationCode,
                    abi.encode(arg)
                ))
            )))));
    
            D d = new D{salt: salt}(arg);
            require(address(d) == predictedAddress);
        }
    }

I encourage you to go to the Solidity docs to read more about it including the main use case and a peculiar warning about using salt.

1

salt parameter is a value sender sends when deploying contract

Taken from: What is the benefit of using create2() to create a smart contract?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.