According to the official doc, a contract can create a new contract using the new keyword. But it does not work when I test the code from this post. My dev environment is truffle 2.1.1 and testrpc (or geth).
pragma solidity ^0.4.2;
contract MyContract {
bytes32 public Name;
function MyContract (bytes32 name) {
Name = name;
}
}
contract Factory {
bytes32[] public Names;
address[] public newContracts;
function createContract(bytes32 name) returns(address) {
address newContract = new MyContract(name);
newContracts.push(newContract);
return newContract;
}
function getName(uint i) {
MyContract con = MyContract(newContracts[i]);
Names[i] = con.Name();
}
}
When calling Factory.createContract, it sends a new transaction and returns the tx hash instead of contract address.
Factory.deployed().createContract("1234")
// or
Factory.deployed().createContract("1234", {from:web3.eth.accounts[0], gas:200000})
Transaction: 0x7f92f8bfa88c5707879ca0b8a93e53dbb7919c55fc90d352fb00269d70fd0fdb
Gas usage: 0x5418
Block Number: 0x0a
Block Time: Fri Jan 20 2017 15:16:25 GMT+0800 (CST)
But calling Contract.New gets a new transaction with contract address.
Contract.new("12345")
Transaction: 0x7275b47ac3712fd26c46b41b1e3f5f2ccbbb638a736e759a48103e08dfccda2a
Contract created: 0x1787b9e9e99802c2c1a580ae7e2bcef045e5b7e7
Gas usage: 0x019d5f
Block Number: 0x09
Block Time: Fri Jan 20 2017 15:14:43 GMT+0800 (CST)
What's the correct way to make Factory.createContract work? Any help will be welcomed.
Even tried compiling the contracts in browser-solidity and loading in geth console. But got the same result, a transaction with contractAddress=null.
factory.createContract("1234", {from:eth.accounts[0], gas:200000})
> eth.getTransactionReceipt("0x31cc7dc3b36fa9c4c524fa672f4537d19b5ac8459cc9f8232a073b9607f6d54e")
{
blockHash: "0x026ecdfec95100d0322bff322c16a3f9df35fac9b6e21106dba1cd6d8c6c7ff5",
blockNumber: 3029,
contractAddress: null,
cumulativeGasUsed: 144490,
from: "0x5fae6ee92e44ddbf09bc5a9602c14decad10f235",
gasUsed: 144490,
logs: [],
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
root: "0x5481a645efdb0c07d4be3c137e9ef053b3fdb7695a96ce5b6ad92fca1b2edc0e",
to: "0x2c978a345ed2fe0fc8ecf10b5e00737973f9a07a",
transactionHash: "0x31cc7dc3b36fa9c4c524fa672f4537d19b5ac8459cc9f8232a073b9607f6d54e",
transactionIndex: 0
}
Thank @Rob Hitchens for the code. Though the contractAddress is null, but getContractAddressAtIndex returns a valid contract address.
> factory.createContract("hello1", {from:eth.accounts[0], gas:200000})
"0x8e3d1b7d743f935bf4f88fa567292247f583ff22dea4e07ab21806e5546aeacb"
> xx = factory.getContractAddressAtIndex(0)
"0x93936cdf4fcc383679cf0305fb314e18fef620d0"
> eth.getTransactionReceipt("0x8e3d1b7d743f935bf4f88fa567292247f583ff22dea4e07ab21806e5546aeacb")
{
blockHash: "0x951a2081ba61618820b5def8bec249eb52f829d9932d68555d03a5d4f70b4d42",
blockNumber: 5,
contractAddress: null,
cumulativeGasUsed: 129810,
gasUsed: 129810,
logs: [],
transactionHash: "0x8e3d1b7d743f935bf4f88fa567292247f583ff22dea4e07ab21806e5546aeacb",
transactionIndex: 0
}
Another issue is it doesn't work in truffle console.
truffle(default)> f = Factory.at(Factory.address)
truffle(default)> f.createContract("hello", {from:web3.eth.accounts[0], gas:200000})
'0xe505daa028d408a800681fba1733777b8ea788cd47f45d28f36a0ff589e12356'
truffle(default)> f.getContractAddressAtIndex(0)
'0x'