I am trying to deploy a contract from another factory contract and then return the address of the newly created contract. The address it returns however is the transaction hash
Consider the below example. There are a number of ways you can get the address of the contract:
contract Object {
string name;
function Object(String _name) {
name = _name
}
}
contract ObjectFactory {
function createObject(string name) returns (address objectAddress) {
return address(new Object(name));
}
}
Store the address in the contract as an attribute and retrieve it using a normal getter method.
contract ObjectFactory {
Object public theObj;
function createObject(string name) returns (address objectAddress) {
theObj = address(new Object(name));
return theObj;
}
}
Call
Before You Make A TransactionYou can make a call
before you make a transaction:
var address = web3.eth.contract(objectFactoryAbi)
.at(contractFactoryAddress)
.createObject.call("object");
Once you have the address perform the transaction:
var txHash = web3.eth.contract(objectFactoryAbi)
.at(contractFactoryAddress)
.createObject("object", { gas: price, from: accountAddress });
Otherwise, you can calculate the address of the future contract like so:
var ethJsUtil = require('ethereumjs-util');
var futureAddress = ethJsUtil.bufferToHex(ethJsUtil.generateAddress(
contractFactoryAddress,
await web3.eth.getTransactionCount(contractFactoryAddress)));
We ran across this problem today, and we're solving it as follows:
In the creation of the new contract raise an event.
Then once the block has been mined use the transaction hash and call web3.eth.getTransaction
:
http://web3js.readthedocs.io/en/1.0/web3-eth.html#gettransaction
Then look at the logs
object and you should find the event called by your newly created contract with its address.
Note: this assumes you're able to update the Solidity code for the contract being created, or that it already calls such an event upon creation.