Ein Vertrag, der einen anderen Vertrag aufruft, kann nicht bereitgestellt werden

Wenn ich den folgenden Code ausführe, wenn ich mit verbunden bin geth --dev --mine, lautet die Ausgabe:

A transmitted, waiting for mining...
aAddress: 0xbaxxxxx4ae42d
B transmitted, waiting for mining...
bAddress: 0x47xxxxxfe8aa
53

Wenn ich es im Live-Netzwerk ausführe, wenn es über verbunden gethist, lautet die Ausgabe:

A transmitted, waiting for mining...
aAddress: 0x04xxx76
B transmitted, waiting for mining...
[Error: The contract code couldn't be stored, please check your gas amount.]

Wenn ich das a.a()durch 7in der b()Funktion ersetze, ist die Ausgabe:

A transmitted, waiting for mining...
aAddress: 0xbaxxxxxae42d
B transmitted, waiting for mining...
bAddress: 0x472xxxfe8aa
53

Ich führe den folgenden Code mit aus node:

var Web3 = require('web3');
var web3 = new Web3();

web3.setProvider(new web3.providers.HttpProvider('http://0.0.0.0:8545'));
web3.eth.defaultAccount = web3.eth.coinbase;

var aSource = 'contract A { function a() constant returns (uint) { return 7; } }';
var aCompiled = web3.eth.compile.solidity(aSource);
var aCode = aCompiled.A.code;
var aAbi = aCompiled.A.info.abiDefinition;

web3.eth.contract(aAbi).new({data: aCode}, function (err, contract) {
    if (err) {
        console.error(err);
        return;
    } else if(contract.address){
        var aAddress = contract.address;
        console.log('aAddress: ' + aAddress);
        deployB(aAddress);
    } else {
        console.log("A transmitted, waiting for mining...");
    }
});

function deployB(aAddress) {
    var bSource = 'contract A { function a() constant returns (uint); }'+
    'contract B { A a; function B(A _a) { a = _a; } function b() returns (uint) { uint c = 46 + a.a(); return c; } }';
    var bCompiled = web3.eth.compile.solidity(bSource);
    var bCode = bCompiled.B.code;
    var bAbi = bCompiled.B.info.abiDefinition;
    var bContract = web3.eth.contract(bAbi);

    bContract.new(aAddress,{data: bCode}, function (err, contract) {
        if (err) {
            console.error(err);
            return;

        } else if(contract.address) {
            var bAddress = contract.address
            console.log('bAddress: ' + bAddress);
            var res = bContract.at(bAddress).b.call();
            console.log(res.toString());
        } else {
            console.log("B transmitted, waiting for mining...");
        }
    });
}
Wenn der Wert von anicht korrekt ist, a.a()wäre dies eine Ausnahme. Ist es wirklich aAddress: 0x04xxx76? Aber ich würde versuchen, Gas wie hinzuzufügen{data: bCode, gas:2000000}
Ich verschleiere die Adresse. Danke, ich werde versuchen, mehr Gas hinzuzufügen.
Eigentlich, bevor ich es noch einmal versuche, empfehlen Sie mir, 2.000.000 Benzin auszugeben? Sind das nicht über 4,50 USD?
Es tut uns leid, dass Sie es im Live-Netzwerk versuchen. Ich denke, die Probleme können zuerst im Testnet gedebuggt werden geth --testnet, und es gibt Faucets, um den Äther zu bekommen.
@redsquirrel überschüssiges Benzin wird übrigens erstattet.
Außerdem sind 2 Millionen Gas derzeit etwa 0,04 Ether – ~0,30 $
@NickJohnson Ja, ich habe mir schlechte Wechselkursdaten angesehen. :\
Lass mich raten, ether.fund? Dieser Ort ist eine Bedrohung.
@NickJohnson Ja, es war ether.fund. Google-Suchanfragen lieben sie, aber ihre Daten scheinen sehr veraltet zu sein. :(

Antworten (1)

Dank einiger Hinweise von @eth (siehe Kommentare) und wie die Fehlermeldung vermuten lässt, besteht die Lösung darin, einfach mehr Gas zu senden. Aus irgendeinem Grund waren die Kosten für die Bereitstellung des Vertrags mit dem Code a.a()etwa 30.000 höher als die Kosten für den Vertrag mit einer fest codierten 7. Lektion gelernt!

Ich habe den folgenden Code hinzugefügt, um die Gaskosten intelligenter zu handhaben:

var contractData = web3.eth.contract(bAbi).new.getData({data: bCode});
console.log("estimating gas price of creating B...");
var gasEstimate = web3.eth.estimateGas({data: contractData});
console.log(gasEstimate);

bContract.new(aAddress,{data: bCode, gas:gasEstimate+30000}, function (err, contract) {