0

I am having an issue with ethereum based project.

I made web3 API to communicate to the blockchain. I did this two ways. both call the same function on same address:

METHOD 1 (Using Unlocked accounts provided by testrpc):

This is Js code which calls the contract:

lottery.generate = function (req, res) {
    var lotteryUsers = helper.getLotteryUsers();

    var biddingTime = req.body.bidding_time; //seconds
    var pricePerEntry = web3.utils.toWei(req.body.price_in_ether, 'ether'); //ether
    var minEntries = req.body.min_entries; //min entries per lottery
    var id = req.body.id; //id of lottery

    lotteryUsers
        .methods
        .createLottery(biddingTime, pricePerEntry, minEntries, id)
        .estimateGas()
        .then(function(gasAmount) {
            lotteryUsers
                .methods
                .createLottery(biddingTime, pricePerEntry, minEntries, id)
                .send({gas: gasAmount, from: config.account}) //config.account is test account
                .then(function(receipt) {
                    console.log("receipt", receipt);
                    res.send(receipt);
                })
                .catch(function(error) {
                    console.log("error", error);
                    res.status(500).send(error.toString());
                });
        })
        .catch(function(error) {
            res.send(error);
        });
};

It works perfectly. Creates an entry on blockchain. and returns me :

{
    "transactionHash": "0x79e459c35e6125b63a3c15bf18868bb79397fc2355ac08716fa5b5609a112579",
    "transactionIndex": 0,
    "blockHash": "0x0000ce5d0ca7699c6757678833b0d1fe0b506eb55a6a99fdffd4e188c7750a55",
    "blockNumber": 9,
    "gasUsed": 589396,
    "cumulativeGasUsed": 589396,
    "contractAddress": null,
    "status": true,
    "events": {
        "NewLottery": {
            "logIndex": 0,
            "transactionIndex": 0,
            "transactionHash": "0x79e459c35e6125b63a3c15bf18868bb79397fc2355ac08716fa5b5609a112579",
            "blockHash": "0x0000ce5d0ca7699c6757678833b0d1fe0b506eb55a6a99fdffd4e188c7750a55",
            "blockNumber": 9,
            "address": "0xEb6ca4A45F9F71ce55Eb8B821188ac27D1d92Fe7",
            "type": "mined",
            "id": "log_599f5c6f",
            "returnValues": {
                "0": "0x972877c35198A8dB560371cb558fE36aceBCF753",
                "1": "0xa2eF5c45f25b3b2E9559542f499402B535d89bc8",
                "2": "1524403958",
                "3": "1524404022",
                "4": "100000",
                "5": "9",
                "6": "25",
                "7": "10",
                "owner": "0x972877c35198A8dB560371cb558fE36aceBCF753",
                "usersContractAddress": "0xa2eF5c45f25b3b2E9559542f499402B535d89bc8",
                "entryTime": "1524403958",
                "lotteryEnd": "1524404022",
                "pricePerEntry": "100000",
                "startBlock": "9",
                "id": "25",
                "minEntries": "10"
            },
            "event": "NewLottery",
            "signature": "0x637e63e954826293e14c38de613bec8b58c00ec77125234b9aa753f78626732d",
            "raw": {
                "data": "0x000000000000000000000000972877c35198a8db560371cb558fe36acebcf753000000000000000000000000a2ef5c45f25b3b2e9559542f499402b535d89bc8000000000000000000000000000000000000000000000000000000005adc8ef6000000000000000000000000000000000000000000000000000000005adc8f3600000000000000000000000000000000000000000000000000000000000186a000000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000000a",
                "topics": [
                    "0x637e63e954826293e14c38de613bec8b58c00ec77125234b9aa753f78626732d"
                ]
            }
        }
    }
}

Notice the gas used : "gasUsed": 589396

METHOD 2 (Using users private key to manually sign the tx):

Js code which calls the same contract instance and function:

lottery.generate = function (req, res) {
    var lotteryUsers = helper.getLotteryUsers();

    var biddingTime = req.body.bidding_time; //seconds
    var pricePerEntry = web3.utils.toWei(req.body.price_in_ether, 'ether'); //ether
    var minEntries = req.body.min_entries; //min entries per lottery
    var id = req.body.id; //id of lottery
    var privateKey = req.body.private_key; //private key of the account
    var publicKey = req.body.public_key;

    var createLottery = lotteryUsers.methods.createLottery(biddingTime, pricePerEntry, minEntries, id);
    var encodedABI = createLottery.encodeABI();

    var tx = {
        gas: 4712388,
        gasPrice: 2,
        data: encodedABI
    }

    console.log("tx "+tx);
    console.log("privateKey "+privateKey);

     var successEvent = function (receipt) {
       res.status(200).send(receipt);
     }

    var failureEvent = function (error) {
       res.status(500).send({message: errorMessage});
    }

    web3.eth.accounts.signTransaction(tx, privateKey)
     .then(signed => {
      console.log("signed "+signed.toString());
      var tran = web3.eth.sendSignedTransaction(rawTx)

        tran.on('confirmation', (confirmationNumber, receipt) => {
          console.log('confirmation: ' + confirmationNumber);
        });

        tran.on('transactionHash', hash => {
          console.log('hash');
          console.log(hash);
        });

        tran.on('receipt', receipt => {
          console.log('reciept');
          console.log(receipt);
          successEvent(receipt);
        });

        tran.on('error', error => {
            console.log(error.toString());
            failureEvent(error);
        });
   });
};

Notice how I have created an ABI. then a tx object, with sufficient gas. Then used web3 apis to sign and broadcast the tx. Also getting events back.

Response of the api is:

{
    "transactionHash": "0x54569155c5af3744d17031787c6a5fee4c7ea468b947d76ddc7d525c5623ca2f",
    "transactionIndex": 0,
    "blockHash": "0xbaf67b7ff8449425d3ee175cb63eb078c18e4309ace58f558d7b45766d085cda",
    "blockNumber": 10,
    "gasUsed": 54171,
    "cumulativeGasUsed": 54171,
    "contractAddress": "0x6945a93653b36aCA660F230Fd2E84a0c7b394882",
    "logs": [],
    "status": true
}

The API does not error our, but somehow it executes partially on blockchain. I say partially, because of two reasons:

1) No entry is created like being created by Method 1 on the blockchain

2) Gas used in Method 2 is 1/10th of gas used in Method 1

I need your help to figure out what is the problem with method 2.

I have spent hours debugging and narrowed it down to this much , that problem is with the way i create tx object or broadcast the object. Any help would be really appreciated, thanks in advance.

0

I figured it out, Finally! :

the tx object in Method 2 does not have a "to" address.

I think without the to address, EVM was clueless where to send the tx. I had assumed lotteryUsers object would have taken care of this (since i made abi from it), but alas! i was wrong.

So remember to put in all transaction parameters in the object you plan to send with your transactions!

var tx = {
    to: config.lottery_user_address,
    gas: 4712388,
    gasPrice: 2,
    data: encodedABI
}

Note: i tried sending with and without from, both worked. I am assuming EVM figures out the "from" address from the private key. On this one i am sure.

0

This code in not providing "nonce" for the transaction. If you add code to generate valid nonce for this transaction, it should work.

Regarding your answer

the tx object in Method 2 does not have a "to" address.

 var lotteryUsers = helper.getLotteryUsers();

What is the code that supplies an instance of "lotteryUsers" ? If this Contract instance is initialized properly, "to" address would be lotteryUsers's address.

Example is available in this questions : Send signed transaction web3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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