2

How exactly are the contract addresses created that are returned by the DeployNewXYZ() method a bound contracts? Is it possible that, if the method is called rapidly consecutively, the same address is returned twice?

I am using this method of a bound contract to deploy a new one:

// DeployTemperatureMeasurementA deploys a new Ethereum contract, binding an instance of TemperatureMeasurementA to it.
func DeployTemperatureMeasurementA(auth *bind.TransactOpts, backend bind.ContractBackend, _temperatureWriter common.Address, _minTemperature int8, _maxTemperature int8, _maxFailureReports uint16, _storageLocation string) (common.Address, *types.Transaction, *TemperatureMeasurementA, error) {
    parsed, err := abi.JSON(strings.NewReader(TemperatureMeasurementAABI))
    if err != nil {
        return common.Address{}, nil, nil, err
    }
    address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(TemperatureMeasurementABin), backend, _temperatureWriter, _minTemperature, _maxTemperature, _maxFailureReports, _storageLocation)
    if err != nil {
        return common.Address{}, nil, nil, err
    }
    return address, tx, &TemperatureMeasurementA{TemperatureMeasurementACaller: TemperatureMeasurementACaller{contract: contract}, TemperatureMeasurementATransactor: TemperatureMeasurementATransactor{contract: contract}}, nil
}

This method is called like this:

address, _, _, err := contracts.DeployTemperatureMeasurementA(auth, backend, auth.From, minTemp, maxTemp, maxFailures, "")

I am only interested in storing the contract address. I am using this address to generate a binding to the contract at a later time.

Now, I call this method twice in a row in a for loop, I want to create two or more new instances of the bound contracts and store the addresses in a database.

When I do this, the Geth client produces two transactions but the contract address that results is the same (this is from the log of the geth client):

I0727 12:47:13.547767 eth/api.go:1203] Tx(b296bc8d329b2bb1002537040e997fd52a74fb6f0e4a749f685b3cfa968d42e0) created: cb744eb36354ada463dbe40fbf969c2d17f48e33
I0727 12:47:13.549639 eth/api.go:1203] Tx(ab1edcd1f39d64807921e92dea1680bc8224422738a5c45a0089aaac55a3594a) created: cb744eb36354ada463dbe40fbf969c2d17f48e33

I use a custom block chain to develop, the genesis file of my blockchain is this:

{
    "nonce": "0xdeadbeefdeadbeef",
    "timestamp": "0x0",
    "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "extraData": "0x0",
    "gasLimit": "0x8000000",
    "difficulty": "0x20000",
    "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "coinbase": "0x0133ee9831e6eee82731578e25ba8361837fa5a5",
    "alloc": {
        "0x0133ee9831e6eee82731578e25ba8361837fa5a5": {
            "balance": "1000"
        }
    }
}

I use geth Version: 1.5.0-unstable, installed with Homebrew on Mac OSX 10.11.6 (15G31)

MethDamon
  • 803
  • 1
  • 8
  • 9

1 Answers1

1

** It should not happen because of point two:** The address for an Ethereum contract is created deterministically with two components:

  1. the address of its owner account (sender)
  2. how many transactions the creator has sent (nonce).

The sender and nonce are RLP encoded and hashed with Keccak-256.

How is the address of an Ethereum contract computed?

Why it still happen I don't know, I tried with geth 1.4.10 and my addresses were different even if I did not mine until both contracts were broadcasted.

> var c = cContract.new(
...    {
......      from: web3.eth.accounts[0], 
...... {1610568565b5090565b5b5050509190906000526020600020900160005b73115744603fedb255e5ab4765cc1dc6c832639fd5909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff02191690830217905550505b5056', 
......      gas: 4700000
......    }, function (e, contract){
......     console.log(e, contract);
......     if (typeof contract.address !== 'undefined') {
.........          console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
.........     }
......  }) &&  cContract.new(
...    {
......      from: web3.eth.accounts[0], 
...... {1610568565b5090565b5b5050509190906000526020600020900160005b73115744603fedb255e5ab4765cc1dc6c832639fd5909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff02191690830217905550505b5056', 
......      gas: 4700000
......    }, function (e, contract){
......     console.log(e, contract);
......     if (typeof contract.address !== 'undefined') {
.........          console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
.........     }
......  })
I0727 14:30:29.037616 eth/api.go:1191] Tx(0x4c1efe8006a3dcbb0258854f95a8aff780e49299ca55eb4c9158e0edaf5e2c7f) created: 0x16e970af7fe214c46ad827222a06b6af35c8b0f3
null [object Object]
I0727 14:30:29.046066 eth/api.go:1191] Tx(0x93f3a27d1251727a199d79ee57feae4fb3cd408e7e8f5ff40390e4c5dbce4314) created: 0x9e431751f45d750199d491a435b3626c2c0fbbd7
null [object Object]
undefined
Roland Kofler
  • 11,638
  • 3
  • 44
  • 83