1

Deployed a local private Ethereum environment. While trying to invoke a constant method of a solidity contract getting inconsistent results.

Sometimes the result is returned and mostly not.

When I tried to fetch the data from geth command line was able to successfully list down the results every time.

In the Nodejs code below created a loop of 20 iterations to fetch the asset price. Sometimes 10-15 times the result is returned correctly and many a times in none of the iterations result is found rather it says 0.

Contract

pragma solidity ^0.4.9;

contract Asset {

    address public owner;
    struct Asset {
        string title;
        string description;
        uint  assetTime;
        uint price;
    }

    Asset[] public  assets;

    event LogAssetAdded(address indexed fromAddress, string description);

    // add asset
    function addAsset(string  description1, string title1, uint price1,uint assetTime1) 
      returns (uint, string, string, uint, uint) {
        uint assetID = assets.length++;
        Asset o = assets[assetID];

        o.description = description1;
        o.assetTime=assetTime1;
        o.title = title1;
        o.price = price1;

        LogAssetAdded(msg.sender, description1);

        return (assetID, assets[assetID].description, assets[assetID].title, assets[assetID].price, 
          assets[assetID].assetTime);
    }

    //return the  number of assets 
    function assetCount() public constant returns(uint) {
        uint assetCount =assets.length;
        return(assetCount);
    }

    function getAssetPrice(uint assetID) public constant returns(uint) {
        return assets[assetID].price;
    }

    function getDefAssetPrice() public constant returns(uint) {
        return assets[assets.length-1].price;
    }

    function getDefAssetTitle() public constant returns(string) {
        return assets[assets.length-1].title;
    }

    function getDefAssetTime() public constant returns(uint) {
        return assets[assets.length-1].assetTime;
    }
}

NodeJs Client Code

const rpcURL = 'http://localhost:9081'
var Web3 = require('web3');
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:9081"));

const fs = require("fs");

let abi ='<<Apply ABI>>';

let bytecode = '<<Apply Bytecode >>'
let gasEstimate = web3.eth.estimateGas({data: bytecode});

let assetContract = web3.eth.contract(JSON.parse(abi));
const account = '<<Provide from account>>';

var contractAddress = '<<Provide Contract Address>>';

var ctr1 = 0;
var contract = assetContract.at(contractAddress);

// Method to create asset
function addAsset(){
    contract.addAsset.sendTransaction("Asset Description", " Asset Title", 41202, 41203, {from: account, gas: 400000} 
    , function(err, result){
        if(err){
            console.log('Error '+ err);    
        }
        else{
            console.log('Transaction Hash: '+ result);
            getAssetPrice();
        }
    });
}

// Method to fetch asset price
function getAssetPrice(){  
    for(var i=0;i<20;i++){
      contract.getAssetPrice(0, (error, result) => {
        if (!error && result>0) {
            ctr1++;
            console.log(ctr1 +": getAssetPrice: "+ result);
        }
        if (!error){
             console.log("Error occurred: "+ error);
        }
    });
}

addAsset();
//getAssetPrice()

Dependencies

"web3": "^0.19",
"solc": "^0.4.9"

Geth Version

 v1.9.0 windows-amd64, go1.10.3

Geth Instance Command

geth --mine --minerthreads=1 --datadir D:/Ethereum/env-II/data/node1 --networkid 4224 --nodiscover --rpc --rpcport "9081" --port "30301" --rpccorsdomain "*" --nat "any" --rpcapi eth,web3,personal,net,miner --unlock 0 --password "D:/Ethereum/env-II/pwd.txt"  --rpcaddr 0.0.0.0 --verbosity 2 console

Geth command line result

> var assetContractRef = eth.contract('<<Contract abi>>');
> var assetContract = assetContractRef.at('<<Contract address>>')
> assetContract.getAssetPrice(1);
> 41202

Result on invoking with Call

Option 1: contract.getAssetPrice(0).call((error, result) => {                            

TypeError: contract.getCallPrice(...).call is not a function

Option 2: contract.getAssetPrice.call(0, (error, result) => {

Faced same result i.e. inconsistent output.

Note

I have tried this implementation, with Web3 1.0.0-beta.52 as well with a bit modified nodejs code i.e. specific to the web3 1.0.0 signatures, but have faced the same inconsistent results. If required could share that version of Nodejs code as well.

0

You might want to use .call() when invoking constant (view) methods. Check out this page of the Web3js docs to get familiar: https://web3js.readthedocs.io/en/1.0/web3-eth-contract.html#methods-mymethod-call

At a glance, I think all you would have to change is this line:

contract.getAssetPrice(0, (error, result) => {

To this:

contract.getAssetPrice(0).call((error, result) => {
  • Thomas, thanks for your reply. I have already tried the same and here is the error detail. contract.getAssetPrice(0).call((error, result) => { ^ TypeError: contract.getCallPrice(...).call is not a function – Geeky Researcher Apr 23 at 3:10
  • This type of call is supported by web3 version 1.0 on-wards. If you check above the one i am using is web3 0.19. – Geeky Researcher Apr 23 at 3:17
0

You are sending a request many times within a certain period of time. Your result might be due to the TCP connection. You are using http , try using websocket as a provider.

var web3 = new Web3(new Web3.providers.WebsocketProvider("http://localhost:9081"));
  • 1
    When i call it single time (i.e. without a loop) then it should always return the required result which anyway is not happening. – Geeky Researcher Apr 23 at 9:25
  • This may happen due to the TCP issue. Try once using WebSocket. And please share the result. – Gopal ojha Apr 23 at 11:30
  • It will be helpful if you could share the link or details about this TCP issue you mentioned above to have a better understanding. – Geeky Researcher Apr 24 at 8:42

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.