Получение адреса контракта, развернутого другим контрактом

Я пытаюсь развернуть контракт из другого заводского контракта, а затем вернуть адрес только что созданного контракта. Однако адрес, который он возвращает, является хешем транзакции, а не адресом договора. Я считаю, что это потому, что контракт еще не заминирован, когда адрес возвращается. Когда я развертываю контракт с помощью развертывания 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 для создаваемого контракта или что он уже вызывает такое событие при создании.

Другие вопросы по тегам