testrpc, контракт на создание контракта не заминирован?

Я пытаюсь разработать контракт, который создает контракт (фабрика/рабочий, шаблон крана). Думаю, моя проблема может быть связана с инструментами, которые я использую:

  • testrpc (локальный блокчейн)
  • Remix Browser Solidity (подключен к testrpc)
  • MetaMask (для просмотра транзакций, балансов и т.д.)
  • трюфель (для развертывания/миграции)

Когда я развертываю свои контракты с помощью truffle, я сразу вижу транзакцию и адрес контракта в testrpc:

Transaction: 0x153a84e6478df590deb21a95cd9042dd5820e838ac14986fb47a8b13df34bd1b Contract created: 0x7a5812ba512df41432ed408ed0a1b266aa8a27dc Gas usage: 0x094d2a Block Number: 0x49 Block Time: Tue Mar 21 2017 19:30:56 GMT+0000 (GMT)

Однако, когда я получаю контракт Factory для создания контракта, я могу получить только транзакцию, но, используя Eventдля ведения журнала, я вижу адрес, но не могу с ним взаимодействовать. Также testrpcсообщает о транзакции, но без адреса контракта:

Transaction: 0x2984356f7ea77ac86f6dee92472736a682061fbeab7de335bc4a6aa7ed66462b Gas usage: 0x0532a9 Block Number: 0x4c Block Time: Tue Mar 21 2017 19:30:59 GMT+0000 (GMT)

Кажется, testrpcэто не майнинг, я пробовал добавить переключатель -b 1, но все тот же эффект. Также я попробовал демо-версию embark , когда я запускаю ее, фреймворк успешно развертывает контракты, как и в случае с трюфелем, но когда я пытаюсь, их транзакции dapp создаются, но никогда не добываются.

Заводской контракт

pragma solidity ^0.4.2;

import './Bar.sol';

contract Foo{

    function createBar(){

      Bar bar = new Bar();
    }
}

Рабочий / детский контракт

pragma solidity ^0.4.2;

contract Bar{

}

Проблема также сохраняется с embark framework , где фреймворк может создавать контракты, а я не могу. Вроде их не добывают?

Когда контракт создает контракт, отдельной транзакции нет — если вы получили событие с адресом, то дочерний контракт определенно был развернут. Это похоже на проблему с Solidity, а не с набором инструментов, но без более подробного кода я больше ничего не могу вам сказать.

Ответы (3)

Кто-то может улучшить этот ответ, но решение было простым...

testrpcне мое embarkне мое

geth делает мой, но я не смог заставить его работать, а именно ошибка с --fast. Паритет был решением.

Синхронизация с тестовой сетью (ropsten) с Parity, есть веб-интерфейс для проверки статуса. Тогда мой с Parity, это не займет много времени.

Затем добавьте сеть к трюфелю:

truffle.js ... "ropsten": { network_id: 3, host: "localhost", port: 8545, from: "$address_from_parity_wallet" }, ...

Теперь, пока работает четность, запустите truffle migrate --reset.

Кажется, что testrpc, remix и embark отлично подходят для общего построения, но для работы на более низком уровне. Паритет и тестовая сеть - это работа... на данный момент (я ожидаю, что инструменты улучшатся, и тестовая сеть будет больше промежуточной/предварительной).

Насколько я понимаю, проблема заключается в «вложенной» структуре контракта. Если вы создаете контракт с помощью new(), ситуация ясна — по адресу 0x0 выполняется одна транзакция, создающая ровно один контракт. Таким образом, EVM может установить поле «contractAddress» в квитанции о транзакции.

Но когда вы имеете дело с фабрикой, ситуация меняется. Транзакция, инициирующая создание контракта, отправляется не на 0x0, а на фабрику, поэтому для EVM это выглядит как обычная функция, поэтому поле contractAddress не задано.

Думая дальше, это становится еще более сложным. Что произойдет, если контракт Bar создаст другой контракт FooBar в своем конструкторе? Теперь вы получаете одну транзакцию на Фабрику, которая неявно создает 2 новых контракта. Поэтому невозможно установить допустимое поле contractAddress.

Из моего (ограниченного) опыта единственный способ добраться до адреса контракта, созданного фабрикой, — это заставить фабрику генерировать событие с адресом нового контракта и прослушивать это событие.

Я мог бы упустить некоторую информацию здесь, но если ваш контракт генерирует событие с допустимым адресом в нем (например, не 0x0000...0000), ваш контракт развернут.

У вас есть ABI для дочернего контракта? Когда у вас есть адрес, вам понадобится ABI, чтобы получить экземпляр контракта из web3. Это будет выглядеть примерно так:

var Bar = web3.eth.contract(abi).at(eventAddress);

Где abiнаходится ваш json ABI и eventAddressадрес, созданный событием, созданным вашим родительским контрактом.

Как правило, для контрактов не верхнего уровня вы не можете полагаться на фреймворки (например, embark/truffle) для автоматической настройки интерфейсов для них, поскольку они обычно не согласуются напрямую с этим вариантом использования. Скорее всего, вам придется вернуться к web3прямому использованию.