Die web3-API gibt keine Vertragsinstanz zurück, wenn sie mit eth-lightwallet und hookedweb3provider verwendet wird

Ich habe es geschafft, einen süchtigen Web3-Anbieter mit eth-lightwallet dazu zu bringen, einen Vertrag auf einem privaten Geth-Knoten zu erstellen. Ich sehe den TX in den Geth-Protokollen und sehe, dass er beim Mining zu einem Block hinzugefügt wird.

Allerdings bekomme ich die contract.address im Callback nicht zurück. Ich bekomme den Transaktionshash. Mein Bauchgefühl sagt mir, dass darunter zwei Schritte passieren: Der tx-Hash wird in der JSON-RPC-Antwort darunter bereitgestellt, aber ein entsprechender eth_getTransactionReceipt wird nicht ausgeführt oder verarbeitet, bevor er zum Callback zurückkehrt.

Hilfe geschätzt.

var ethClient = "http://localhost:1234";
var web3 = new Web3();
var global_keystore;

// setting up a web3 provider but using a keystore to get access to account information
function setWeb3Provider(keystore) {

    var web3Provider = new HookedWeb3Provider({
        host: ethClient,
        transaction_signer: keystore
    });

    web3.setProvider(web3Provider);

}

// .....

var password = prompt('Enter Password to encrypt your seed', 'Password');

var providedSeed = document.getElementById('seed').value;

lightwallet.keystore.deriveKeyFromPassword(password, function (err, pwDerivedKey) {

global_keystore = new lightwallet.keystore(
    providedSeed,
    pwDerivedKey);

global_keystore.generateNewAddress(pwDerivedKey, 2);

setWeb3Provider(global_keystore);


// .... important bit....

var contract = web3.eth.contract(_contractABI);
    var myContract = contract.new(
        {
            from: _ethWalletAddress,
            data: _contractCode,
            gas: 3000000,
            gasPrice: 18000000010
        }, function(e, contract){

            console.log("error object: " + e );
            console.log("contract object: " + contract);

            if (typeof contract != 'undefined') {
                console.log('address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);


                });

            }
        });

Beispiel für Protokolle aus einem privaten Geth-Netzwerk:

I0424 13:28:13.816421 eth/api.go:1177] Tx(3645d30afa7923cca42359dc2d1e46084f0da11f0b5476111a1e2ac7a82eb56f) created: 0746c6c2fde77b607e83e2bb6c25f919817e8459
I0424 13:28:23.028763 miner/miner.go:119] Starting mining operation (CPU=8 TOT=9)
I0424 13:28:23.036100 miner/worker.go:565] commit new work on block 4446 with 1 txs & 1 uncles. Took 7.286103ms

und das Ergebnis eines manuellen getTransactionReceipt mit JSON RPC:

curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0x3645d30afa7923cca42359dc2d1e46084f0da11f0b5476111a1e2ac7a82eb56f"],"id":1}'

{"jsonrpc":"2.0","id":1,"result":{"blockHash":"0x3a524c681be27a65d6058e54de35e5502d8353e85b7a5b013c86a6909eb63dd3","blockNumber":"0x115e","contractAddress":"0x0746c6c2fde77b607e83e2bb6c25f919817e8459","cumulativeGasUsed":"0x101716","from":"0xa57f54760210a39a376231bd20d5fcec4eaf75fa","gasUsed":"0x101716","logs":[],"root":"38789ca516316c1303eda94b690202875a77d66e3116f8733081197f7157f093","to":null,"transactionHash":"0x3645d30afa7923cca42359dc2d1e46084f0da11f0b5476111a1e2ac7a82eb56f","transactionIndex":"0x0"}}

p.s. Ich weiß nicht, was der Protokollbericht 1 Onkel. Andere Vertragserstellungsprotokolle haben keine Onkel gemeldet, aber alle weisen das gleiche Problem mit dem Rückruf auf.

Mein Gefühl ist, dass Sie mit dem Gaspreis vielleicht etwas geizig sind. Sind Sie sicher, dass die Transaktion in einem Block enthalten ist? Was sehen Sie, wenn Sie getTransactionReceipt manuell ausführen? Beachten Sie auch, dass web3 den Rückruf sofort abfeuert, bevor die Transaktion abgebaut wurde, und dann noch einmal, nachdem sie abgebaut wurde.
Privater Knoten protokolliert: I0424 09:47:32.895350 miner/worker.go:565] neue Arbeit an Block 4443 mit 0 txs & 0 Onkels festschreiben. Took 256.964974ms I0424 10:40:50.493671 eth/api.go:1177] Tx(59ac899e2e88f05ae2476a8988ad08531342fd3fc11012169b005ac1df57c3a0) created: 42b2c3b2fac0e4fc06aff755ecef9ee25d4ef740 I0424 10:41:33.602429 miner/miner.go:119] Starting mining operation (CPU=8 TOT=9) I0424 10:41:33.610067 miner/worker.go:565] neue Arbeit auf Block 4443 mit 1 txs & 0 Onkels festschreiben. Dauerte 7.551936ms I0424 10:41:35.881139 miner/worker.go:347] 🔨 Geminter Block (#4443 / d88f4f58). Warten Sie 5 Blöcke auf die Bestätigung
@Christian_Lundkvist - Ich habe getTransactionReceipt noch nicht manuell verwendet. Ich arbeite immer noch daran, wie und was es bedeutet, das zu tun.
ok, das Ergebnis von getTransactionReceipt wurde der Frage hinzugefügt. Alles scheint ok.
OK Cool. Sie sehen die Vertragsadresse in der Quittung? Führen Sie web3.eth.getCode('0x0746...') aus und prüfen Sie, ob es einen Code oder Null zurückgibt. Wenn es Null zurückgibt, bedeutet dies, dass die Vertragserstellung fehlgeschlagen ist. Ich denke jedoch, dass es auch ein Problem mit Ihren Rückrufen sein könnte. Ich persönlich verwende Pudding ( github.com/ConsenSys/ether-pudding ), das den Rückruf auslöst, sobald die Transaktion abgebaut ist. Web3 feuert zweimal, glaube ich.
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getCode","params":["0x0746c6c2fde77b607e83e2bb6c25f919817e8459", "latest"],"id":1}\' hat die zurückgegeben Vertragscode. Es muss also so sein, wie der Rückruf in web3 funktioniert.
@ChristianLundkvist danke. Pudding abstrahiert einfach noch mehr und ist für mich noch weniger klar. Ich habe es mit einem einfachen "Schneebesen" versucht und es ist fehlgeschlagen.

Antworten (1)

Das Code-Idiom funktioniert. Es muss meinerseits Verwirrung beim Lernen gewesen sein, denn plötzlich fing es an zu funktionieren.

Die neue Funktion für den Vertrag in der web3-API führt zwei Aufrufe des Rückrufs im obigen Code durch. Hier ist das Code-Snippet von web3.js.

if (callback) {

            // wait for the contract address adn check if the code was deployed
            this.eth.sendTransaction(options, function (err, hash) {
                if (err) {
                    callback(err);
                } else {
                    // add the transaction hash
                    contract.transactionHash = hash;

                    // call callback for the first time
                    callback(null, contract);

                    checkForContractAddress(contract, callback);
                }
            });
        } else {
            var hash = this.eth.sendTransaction(options);
            // add the transaction hash
            contract.transactionHash = hash;
            checkForContractAddress(contract);
        }

        return contract;

Dieser Code führt einen Rückruf durch, sobald er einen Transaktions-Hash aus dem ersten zugrunde liegenden JSON-RPC-Aufruf hat. Die checkForContractAddress ruft den Rückruf erneut auf, sobald der zweite zugrunde liegende JSON-RPC-Aufruf bestätigt, dass die Transaktion abgebaut wurde: ein bereitgestellter Vertrag.

Mir wäre das Problem vielleicht aufgefallen, wenn ich die beiden Callbacks mitbekommen und bei jedem etwas anderes protokolliert hätte.

Das web3-Dokumentationsbeispiel überprüft, ob die Vertragsadresse vor der Protokollierung definiert ist. Das hätte die Verwirrung verhindert. Ich habe es geändert, um "Vertrag" zu testen. Mein Fehler.

if (Vertragstyp.Adresse != 'undefiniert') {}