5

I have managed to get a hooked web3 provider with eth-lightwallet creating a contract on a private geth node. I see the tx on the geth logs and see it get added to a block when mined.

However I am not getting the contract.address returned in the callback. I get the transaction hash. My gut feeling tells me there are two steps happening underneath: the tx hash is provided in the JSON RPC response underneath but a corresponding eth_getTransactionReceipt is not being done or processes before comingback to the callback.

Help appreciated.

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);


                });

            }
        });

Example of logs from a private geth network:

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

and the result of a manual getTransactionReceipt with 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"}}

ps. I don't know what the log report 1 uncle. Other contract creation logs didn't report any uncles but all exhibit the same issue with the callback.

7
  • My feeling is that you might be a bit stingy with the gasPrice. Are you sure you're seeing the transaction included in a block? If you do getTransactionReceipt manually, what do you see? Also note that web3 will immediately fire off the callback before the transaction has been mined, and then again after it has been mined.
    – user375
    Commented Apr 24, 2016 at 12:14
  • Private node logged:I0424 09:47:32.895350 miner/worker.go:565] commit new work on block 4443 with 0 txs & 0 uncles. 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] commit new work on block 4443 with 1 txs & 0 uncles. Took 7.551936ms I0424 10:41:35.881139 miner/worker.go:347] 🔨 Mined block (#4443 / d88f4f58). Wait 5 blocks for confirmation
    – Interition
    Commented Apr 24, 2016 at 12:30
  • @Christian_Lundkvist - I have not used getTransactionReceipt manually yet. Still working out how and what it means to do that.
    – Interition
    Commented Apr 24, 2016 at 12:37
  • ok, added the result of the getTransactionReceipt to the question. All seems ok.
    – Interition
    Commented Apr 24, 2016 at 12:57
  • Ok, cool. You see the contractAddress in the receipt? Do web3.eth.getCode('0x0746...') and see if it returns some code or zero. If it returns zero it means that the contract creation has failed. However I think that it might also be a problem with your callbacks. I personally use Pudding(github.com/ConsenSys/ether-pudding) which fires the callback once the transaction is mined. Web3 fires twice I think.
    – user375
    Commented Apr 24, 2016 at 20:53

1 Answer 1

3

The code idiom does work. It must have been confusion on my part when learning because suddenly it started to work.

The new function on the contract in the web3 API does make two call to the callback in the code above. Here is the code snippet from 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;

This code does do a callback as soon as it has a transaction hash from the first underlying JSON RPC call. The checkForContractAddress will call the callback again once the second underlying JSON RPC call confirms that the transaction was mined: a contract deployed.

I might have noticed the problem if I had been aware of the two calls to the callback and logged something different for each.

The web3 documentation example DOES check the contract address is defined before logging. That would have prevented the confusion. I changed it to test "contract". My fault.

if (typeof contract.address != 'undefined') {}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.