Заводской шаблон работает нестабильно

3 дня уже бьюсь с этой проблемой. Итак, позвольте мне объяснить, и, надеюсь, один из вас столкнулся (и решил) с той же проблемой.

  1. Я использую локальную приватную цепочку блоков с версией geth 1.5.8-stable-f58fb322. Один узел майнинга и представления интерфейсов RPC следующим образом

geth --datadir "syndChain" --rpc --networkid 10001 --nodiscover --maxpeers 0 --rpcapi "debug,db,eth,net,web3,personal" --rpccorsdomain "*" --verbosity 6 --mine console

  1. У меня есть базовый заводской контракт
contract Factory {
    uint public counter;
    bytes32[] public Names;
    address[] public newContracts;

        function setCounter(uint v) {counter = v; }
    function createContract (bytes32 name) {
        counter++;
        address newContract = new Contract(name);
        newContracts.push(newContract);
    }

    function getName (uint i) {
        counter++;
        Contract con = Contract(newContracts[i]);
        Names[i] = con.Name();
    }
}

contract Contract {
    bytes32 public Name;

    function Contract (bytes32 name) {
        Name = name;
    }    
}
  1. Я развертываю его с помощью браузера Solidity или консоли Geth.
geth --solc '/usr/local/bin/solc' attach http://localhost:8545 console
  1. Я компилирую исходный код, используя импорт локального файла «sol».
var source= 'import "./sources/_deploy_.sol";' 
var compiled = eth.compile.solidity(source);

и скомпилированная переменная обеспечивает правильный результат при отображении.

  1. Я создаю экземпляр Factory обычным способом.
var defaultgas = eth.getBlock('latest').gasLimit;
var abi=[{"constant":false,"inputs":[{"name":"name","type":"bytes32"}],"name":"createContract","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"counter","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"i","type":"uint256"}],"name":"getName","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"v","type":"uint256"}],"name":"setCounter","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"newContracts","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"Names","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"}]
var code="0x6060604052341561000c57fe5b5b6105298061001c6000396000f30060606040523615610076576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633f811b801461007857806361bc221a1461009c5780636b8ff574146100c25780638bb5d9c3146100e2578063bd21ad1914610102578063f01a4e0e14610162575bfe5b341561008057fe5b61009a60048080356000191690602001909190505061019e565b005b34156100a457fe5b6100ac61024b565b6040518082815260200191505060405180910390f35b34156100ca57fe5b6100e06004808035906020019091905050610251565b005b34156100ea57fe5b6101006004808035906020019091905050610351565b005b341561010a57fe5b610120600480803590602001909190505061035c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561016a57fe5b610180600480803590602001909190505061039c565b60405180826000191660001916815260200191505060405180910390f35b6000600060008154809291906001019190505550816101bb6103c1565b808260001916600019168152602001915050604051809103906000f08015156101e057fe5b9050600280548060010182816101f691906103d0565b916000526020600020900160005b83909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505b5050565b60005481565b600060006000815480929190600101919050555060028281548110151561027457fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff16638052474d6000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401809050602060405180830381600087803b151561030f57fe5b60325a03f1151561031c57fe5b5050506040518051905060018381548110151561033557fe5b906000526020600020900160005b5081600019169055505b5050565b806000819055505b50565b60028181548110151561036b57fe5b906000526020600020900160005b915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6001818154811015156103ab57fe5b906000526020600020900160005b915090505481565b60405160dc8061042283390190565b8154818355818115116103f7578183600052602060002091820191016103f691906103fc565b5b505050565b61041e91905b8082111561041a576000816000905550600101610402565b5090565b9056006060604052341561000c57fe5b6040516020806100dc833981016040528080519060200190919050505b80600081600019169055505b505b6097806100456000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638052474d14603a575bfe5b3415604157fe5b60476065565b60405180826000191660001916815260200191505060405180910390f35b600054815600a165627a7a72305820a044c7782bc843f188703cdbb7a826b46130d87bd54980c54c008a215c2279c90029a165627a7a72305820e5fdae98aa6917cee58e86baf173680ffd7b690109704c8467f080ce548103ce0029"
var contract=eth.contract(abi)
var F=contract.new({from:eth.coinbase, code: code, gas: defaultgas})

Без параметров и обратного вызова для упрощения

  1. наблюдая за журналом консоли майнера, я вижу, когда контракт готов, и я проверяю вывод переменной F
> F
{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "createContract",
      outputs: [],
      payable: false,
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "counter",
      outputs: [{...}],
      payable: false,
      type: "function"
  }, {
      constant: false,
      inputs: [{...}],
      name: "getName",
      outputs: [],
      payable: false,
      type: "function"
  }, {
      constant: false,
      inputs: [{...}],
      name: "setCounter",
      outputs: [],
      payable: false,
      type: "function"
  }, {
      constant: true,
      inputs: [{...}],
      name: "newContracts",
      outputs: [{...}],
      payable: false,
      type: "function"
  }, {
      constant: true,
      inputs: [{...}],
      name: "Names",
      outputs: [{...}],
      payable: false,
      type: "function"
  }],
  address: "0x3c425e2f1d97139c0e23baddf3f77dbc0efc220f",
  transactionHash: "0x208fc2a4ffa8fd315a0f0db5a2087c67a4f9bb1b4ddfa4d56a40465d37e985c6",
  Names: function(),
  allEvents: function(),
  counter: function(),
  createContract: function(),
  getName: function(),
  newContracts: function(),
  setCounter: function()
}

Пока все хорошо.

  1. Я вызываю простую функцию контракта для проверки
> F.counter()
0
> F.setCounter(10)
"0xa304802c43b234b6f5a74d9db7a626633dfca716c9f517c5c9425a97a29931f5"
> F.counter()
10
  1. Я пытаюсь создать субконтракт, и тут все становится плохо.
> F.createContract("ABCD")
"0xc63c0dc0b2ed6ee8f22b2467331b3370b19648ef862610cf6e58d654f4859d98"

Проверяя журнал, я вижу отображаемую транзакцию.

I0211 23:07:55.914127 eth/downloader/downloader.go:1474] Quality of service: rtt 20s, conf 1.000, ttl 1m0s
I0211 23:07:58.780174 core/tx_pool.go:343] (t) 0xc43266ad => 3c425e2f (0x412df60)

270] C432666D7F60E313029EC3DE5BDC5E0C3682D945: #18 13535935700000000000000 (- 180000000000000000) I0211 23: 08: 03.606973 CORE/VM/VMGGO: 121] EVM RUNGE: 6FC. a851f2959a38baf9a01a9fb169259b129050c973 I0211 23:08:03.607159 core/vm/vm.go:121] evm работает: a205eaed I0211 23:08:03.607250 core/vm/vm.go:124] evmea сделано: a205ed. время: 82,753 мкс I0211 23:08:03.607298 core/vm/vm.go:124] выполнено evm: 6fcd7996. время: 319,118 мкс I0211 23:08:03.607310 core/state_transition.go:242] 82,753 мкс I0211 23:08:03.607298 core/vm/vm.go:124] выполнено evm: 6fcd7996. время: 319,118 мкс I0211 23:08:03.607310 core/state_transition.go:242] 82,753 мкс I0211 23:08:03.607298 core/vm/vm.go:124] выполнено evm: 6fcd7996. время: 319,118 мкс I0211 23:08:03.607310 core/state_transition.go:242]vm возвращается с ошибкой: <nil>GO: 257] C432666AD7F60E313029EC3DE5BDC5E0C3682D945: #19 13540937500000000000000 (+ 5000000000000000000) I0211 23: 08: 03.607791 Miner/Worker.go: 514] Come Commit New Block 2509. Заняло 1,666204 мс I0211 23:08:03.607844 miner/agent.go:111] (пере)запустил агент[0]. майнинг... I0211 23:08:06.160209 core/state/statedb.go:605] Статистика кеша Trie: 10131 промах, 3 выгрузки I0211 23:08:06.163689 core/database_util.go:385] общая сложность сохраненного блока [c362a0d1… ]: 638575412 I0211 23:08:06.163741 core/database_util.go:371] сохраненное тело блока [c362a0d1…] I0211 23:08:06.163809 core/database_util.go:352] сохраненный заголовок № 2509 [c362a0d1…] I0211 23:08 :06.164112 miner/unconfirmed.go:105] 🔗 добыт блок #2504 [34d145ea…] достиг канонической цепочки I0211 23:08:06.164124 miner/unconfirmed.go:83] 🔨 добыт потенциальный блок #2509 [c362a0d1…], 0x3f811b804142434400000000000000000000000000000000000000000000000000000000 V: 0x1b R: 0x84577996b6a8509a36d742dc349785f68d59d612a1a441f2d8559ead7d88e686 S: 0x99acc1ac7d9a19f60e333a3422b099982d334dae7c56d7d97a183fa05266181 Hex: f889128504a817c80083015f90943c425e2f1d97139c0e23baddf3f77dbc0efc220f80a43f811b8041424344000000000000000000000000000000000000000000000000000000001ba084577996b6a8509a36d742dc349785f68d59d612a1a441f2d8559ead7d88e686a0099acc1ac7d9a19f60e333a3422b099982d334dae7c56d7d97a183fa05266181 I0211 23:08:06.164449 core/state/state_object.go:257] c43266ad7f60e313029ec3de5bdc5e0c3682d945: #19 13545937500000000000000 (+ 5000000000000000000) I0211 23:08:06.164517 miner/worker.go: 514] зафиксируйте новую работу в блоке 2510 с 0 транзакциями и 0 дядями. Заняло 364,299 мкс 0x84577996b6a8509a36d742dc349785f68d59d612a1a441f2d8559ead7d88e686 S: 0x99acc1ac7d9a19f60e333a3422b099982d334dae7c56d7d97a183fa05266181 Hex: f889128504a817c80083015f90943c425e2f1d97139c0e23baddf3f77dbc0efc220f80a43f811b8041424344000000000000000000000000000000000000000000000000000000001ba084577996b6a8509a36d742dc349785f68d59d612a1a441f2d8559ead7d88e686a0099acc1ac7d9a19f60e333a3422b099982d334dae7c56d7d97a183fa05266181 I0211 23:08:06.164449 core/state/state_object.go:257] c43266ad7f60e313029ec3de5bdc5e0c3682d945: #19 13545937500000000000000 (+ 5000000000000000000) I0211 23:08:06.164517 miner/worker.go:514] commit new work on блок 2510 с 0 транзакциями и 0 дядями. Заняло 364,299 мкс 0x84577996b6a8509a36d742dc349785f68d59d612a1a441f2d8559ead7d88e686 S: 0x99acc1ac7d9a19f60e333a3422b099982d334dae7c56d7d97a183fa05266181 Hex: f889128504a817c80083015f90943c425e2f1d97139c0e23baddf3f77dbc0efc220f80a43f811b8041424344000000000000000000000000000000000000000000000000000000001ba084577996b6a8509a36d742dc349785f68d59d612a1a441f2d8559ead7d88e686a0099acc1ac7d9a19f60e333a3422b099982d334dae7c56d7d97a183fa05266181 I0211 23:08:06.164449 core/state/state_object.go:257] c43266ad7f60e313029ec3de5bdc5e0c3682d945: #19 13545937500000000000000 (+ 5000000000000000000) I0211 23:08:06.164517 miner/worker.go:514] commit new work on блок 2510 с 0 транзакциями и 0 дядями. Заняло 364,299 мкс f889128504a817c80083015f90943c425e2f1d97139c0e23baddf3f77dbc0efc220f80a43f811b8041424344000000000000000000000000000000000000000000000000000000001ba084577996b6a8509a36d742dc349785f68d59d612a1a441f2d8559ead7d88e686a0099acc1ac7d9a19f60e333a3422b099982d334dae7c56d7d97a183fa05266181 I0211 23:08:06.164449 core/state/state_object.go:257] c43266ad7f60e313029ec3de5bdc5e0c3682d945: #19 13545937500000000000000 (+ 5000000000000000000) I0211 23:08:06.164517 miner/worker.go:514] commit new work on block 2510 with 0 txs & 0 дяди. Заняло 364,299 мкс f889128504a817c80083015f90943c425e2f1d97139c0e23baddf3f77dbc0efc220f80a43f811b8041424344000000000000000000000000000000000000000000000000000000001ba084577996b6a8509a36d742dc349785f68d59d612a1a441f2d8559ead7d88e686a0099acc1ac7d9a19f60e333a3422b099982d334dae7c56d7d97a183fa05266181 I0211 23:08:06.164449 core/state/state_object.go:257] c43266ad7f60e313029ec3de5bdc5e0c3682d945: #19 13545937500000000000000 (+ 5000000000000000000) I0211 23:08:06.164517 miner/worker.go:514] commit new work on block 2510 with 0 txs & 0 дяди. Заняло 364,299 мкс 257] C43266AD7F60E313029EC3DE5BDC5E0C3682D945: #19 13545937500000000000000 (+ 5000000000000000000) I0211 23: 08: 06.164517 Miner/Worker.GE: 514] COMECT New Block Block 2510. Заняло 364,299 мкс 257] C43266AD7F60E313029EC3DE5BDC5E0C3682D945: #19 13545937500000000000000 (+ 5000000000000000000) I0211 23: 08: 06.164517 Miner/Worker.GE: 514] COMECT New Block Block 2510. Заняло 364,299 мкс

Это выглядит нормально, за исключением того, что виртуальная машина возвращается с ошибкой: когда я затем пытаюсь увидеть, увеличился ли счетчик, это не так. Но TransactionReceipt в порядке. Блок содержит транзакцию и т.д.

  1. Заключение Я провел много тестов и повторных тестов, и такое поведение, похоже, происходит только тогда, когда вызываемая функция в контракте Factory создает новый экземпляр субконтракта, независимо от того, назначаю ли я его переменной, помещаю в массив или нет.

Что очень странно, так это то, что иногда (но не всегда), когда я вызываю функцию createTranche из браузера Solidity, она работает на том же экземпляре Factory!!!

Я не думаю, что это проблема нехватки газа, поскольку я предоставляю максимально допустимое количество.

Так что, пожалуйста, может кто-нибудь попробовать повторить и посоветовать, как решить?

Благодарность

Предложение: попробуйте использовать getTransactionReceipt , например: eth.getTransactionReceipt("0xc63c0dc0b2ed6ee8f22b2467331b3370b19648ef862610cf6e58d654f4859d98")(Это хэш, который я вижу на шаге 7.) Он покажет вам, сколько газа он использовал, так что, по крайней мере, вы можете потенциально исключить ошибку OOG.

Ответы (1)

Мне жаль тратить столько времени на эту ситуацию. Я понял, что моя проблема возникла из-за отсутствия газа.

Чего я не знал, так это того, что газ, который должен был использоваться, по умолчанию не брался с газового месторождения конструктора. Теперь я понимаю, что функция JavaScript экземпляра должна передаваться {from: account, gas: <gas to use>}каждый раз.

Это раздражает, учитывая, что оставшийся газ будет возвращен звонящему по счету.

Есть ли способ установить по умолчанию газ, который будет отправлен так же, как у нас eth.defaultAccount?

Добро пожаловать в Эфириум! Если у вас есть другой вопрос, пожалуйста, задайте его, нажав кнопку « Задать вопрос» .