Получение адреса контракта, развернутого другим контрактом
Я пытаюсь развернуть контракт из другого заводского контракта, а затем вернуть адрес только что созданного контракта. Однако адрес, который он возвращает, является хешем транзакции, а не адресом договора. Я считаю, что это потому, что контракт еще не заминирован, когда адрес возвращается. Когда я развертываю контракт с помощью развертывания web3, кажется, что он ждет, пока контракт не будет развернут, прежде чем выводить адрес.
Заводской контракт:
contract Factory {
mapping(uint256 => Contract) deployedContracts;
uint256 numContracts;
function Factory(){
numContracts = 0;
}
function createContract (uint32 name) returns (address){
deployedContracts[numContracts] = new Contract(name);
numContracts++;
return deployedContracts[numContracts];
}}
Вот как я вызываю функцию createContract.
factory.createContract(2,function(err, res){
if (err){
console.log(err)
}else{
console.log(res)
}
});
2 ответа
Рассмотрим приведенный ниже пример. Есть несколько способов получить адрес договора:
contract Object {
string name;
function Object(String _name) {
name = _name
}
}
contract ObjectFactory {
function createObject(string name) returns (address objectAddress) {
return address(new Object(name));
}
}
1 Сохраните адрес и верните его:
Сохраните адрес в контракте в качестве атрибута и получите его, используя обычный метод получения.
contract ObjectFactory {
Object public theObj;
function createObject(string name) returns (address objectAddress) {
theObj = address(new Object(name));
return theObj;
}
}
2 Call
Прежде чем сделать транзакцию
Вы можете сделать call
прежде чем совершить транзакцию:
var address = web3.eth.contract(objectFactoryAbi)
.at(contractFactoryAddress)
.createObject.call("object");
Когда у вас есть адрес, выполните транзакцию:
var txHash = web3.eth.contract(objectFactoryAbi)
.at(contractFactoryAddress)
.createObject("object", { gas: price, from: accountAddress });
3 Рассчитать будущий адрес
В противном случае вы можете рассчитать адрес будущего договора следующим образом:
var ethJsUtil = require('ethereumjs-util');
var futureAddress = ethJsUtil.bufferToHex(ethJsUtil.generateAddress(
contractFactoryAddress,
await web3.eth.getTransactionCount(contractFactoryAddress)));
Мы столкнулись с этой проблемой сегодня, и мы решаем ее следующим образом:
При создании нового контракта поднимают событие.
Затем, как только блок был добыт, используйте хэш транзакции и вызовите web3.eth.getTransaction
: http://web3js.readthedocs.io/en/1.0/web3-eth.html
Тогда посмотрите на logs
объект, и вы должны найти событие, вызванное вашим вновь созданным договором с его адресом.
Примечание: предполагается, что вы можете обновить код Solidity для создаваемого контракта или что он уже вызывает такое событие при создании.