Контракт, создающий другой контракт с использованием ошибки Web3 для выхода из газа, несмотря на то, что стоимость газа велика (например, 50 000 000)

Я написал контракт A, который создает новый контракт B и возвращает адрес нового контракта B, который был создан. Когда я тестировал это в браузере Solidity, он работал хорошо, но когда я пытался запустить метод создания с помощью web3, я продолжал получать эту ошибку:

        throw errors.InvalidResponse(result);
    ^
Error: VM Exception while processing transaction: out of gas

Вот мой код контракта:

pragma solidity ^0.4.2; 
contract B { 
   int public id;
   function B(int _id) { 
     id = _id;
   }
} 

contract A { 
   address Baddress;
   function createB(int _id) returns (address) { 
     Baddress = new B(_id); 
     return Baddress;
   } 
}

Вот мой код Javascript, который пытается запустить метод createB A:

web3.eth.defaultAccount = web3.eth.coinbase;
var Acontract = web3.eth.contract([{"constant":false,"inputs":[],"name":"getdum","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"num","type":"int256"}],"name":"create","outputs":[],"payable":false,"type":"function"}]);

var A = Acontract.new({from: web3.eth.accounts[0], 
data: '{{compiled byte code}}', 
gas: '47000000'}, function (e, contract){
   console.log(e, contract);
   if (typeof contract.address !== 'undefined') {
     console.log('Contract mined! address: ' + contract.address);
     contract.createB(5000).then(console.log); // This line throws the error
   }
})

Я прочитал много других связанных сообщений и смог найти только ответы, которые предлагают использовать больше газа, но независимо от того, сколько газа я отправил с транзакцией, это выдавало ту же ошибку. Вы можете видеть, что я использую очень большое значение для газа в коде. Может ли кто-нибудь помочь мне определить, что я делаю неправильно? Я использую версию solc: 0.4.9+commit.364da425.Darwin.appleclang, EthereumJS TestRPC v3.0.3 и node v6.4.0.

Вы используете трюфель? Кроме того, я думаю, что у вас может быть опечатка в вашем коде .create(5000)..createB(5000)
Спасибо, что заметили опечатку. Я случайно удалил там букву B... Я пытался использовать трюфель, но когда я использовал эту команду: A.deployed().then(function(instance){return instance.createB(50)}).then(console.log), он вернул нулевой адрес контракта. Как мне получить адрес контракта только что созданного B..?
На самом деле я не использую трюфель, но обещанные методы не являются родными для web3 (пока!). .createB().then()не будет работать. Тем не менее, вы все равно можете использовать библиотеку, такую ​​​​как bluebird, для обещания web3.
Ага, понятно. Хотя, как вы думаете, я могу использовать createB()без обещания?
Вы можете, он просто вернет хэш транзакции, а не то, что можно. Стандартный способ — сделать это, а затем отфильтровать событие, созданное транзакцией.
Правильно, хотя в моем случае он возвращает только ошибку, независимо от того, сколько газа я использую. Это странно, потому что существует так много руководств по созданию контрактов, и ни в одном из них не было проблем с отсутствием газа.

Ответы (1)

После повторения этого я обнаружил проблему.

Вам нужно будет снова указать газ при отправке .createB()транзакции. То есть, если вы используете .createB(5000), он использует только лимит газа по умолчанию 90000 и терпит неудачу. Установка лимита газа на более высокий уровень .createB(5000, {gas: 200000})прошла успешно для меня. browser-solidity дает более точное значение 113598для стоимости транзакции.

Спасибо! Это действительно была подача газа, которую я пропустил. Тем не менее, я все еще не могу получить правильное значение идентификатора B из-за ошибки «недопустимый адрес» после вызова B с его контрактного адреса, возвращенного в A. Я следовал примеру на странице документации Web3, используя web3.eth.contract(abi).at(baddress).getB(), где он выдал эту ошибку . Хотя предыдущая ошибка была устранена, здесь у меня были проблемы раньше с трюфелем, а теперь с web3.
Нвм! Я исправил это после поиска eth.filter в вашем последнем комментарии. Еще раз спасибо за вашу помощь!!
ура за это! тратим наши на отладку.