1

I am working with a simple contract where any user can pass a number to it and the response will be a number incremented by that number and a seed number. This contract does not serve any practical purpose and it is intended for experiments only.

addNum.sol

pragma solidity ^0.4.11;

contract NumberTracer {
    bytes32 tracer;
    uint256 seed = 1000;
    uint256 currentSum;

    function NumberTracer(bytes32 t) {
        tracer = t;
    }

    function addNumber(uint256 n) {
        currentSum = seed + n;
    }

    function getCurrentSum() returns (uint256) {
        return currentSum;
    }
}

I created two different web3.js based files to interact with the contract.

addNum-deploy.js

var Web3 = require('web3');
var fs = require('fs');
//
var ethHttpProvider = new Web3.providers.HttpProvider("http://localhost:8545");
var web3 = new Web3(ethHttpProvider);
var abiFile = fs.readFileSync('NumberTracer.abi').toString();
var abiDef = JSON.parse(abiFile);
var byteCode = fs.readFileSync('NumberTracer.bin').toString();
//
var contract = web3.eth.contract(abiDef);
var deployedContract = contract.new(['MyTrace0'],
    { data: byteCode, from: web3.eth.accounts[0], gas: 4700000 },
    (err, res) => {
        if (err) {
            console.log(err);
            return;
        } else {
            console.log("Transaction hash : " + res.transactionHash);
            console.log("Contract address : " + res.address);
        }
    }
);

Using the contract address from the deployment above, I run my test as follows.

addNum-test.js

var Web3 = require('web3');
var fs = require('fs');
//
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
var abiFile = fs.readFileSync('NumberTracer.abi').toString();
var abiDef = JSON.parse(abiFile);
var contract = web3.eth.contract(abiDef);
var contractInstance = contract.at('0x...');
//
contractInstance.addNumber.call([100],
    (err, res) => {
        if (err) {
            return
        } else {
            contractInstance.getCurrentSum.call([],
                (err, res) => {
                    if (err) {
                        console.log(err)
                    } else {
                        console.log(res)
                    }
                }
            )
        }
    }
)

And this is the output I see:

node addNum-test.js
{ [String: '0'] s: 1, e: 0, c: [ 0 ] }

Why is the update not visible?

The Solidity documentation mentions that state variables are persisted. So, why don't I updated value of currentSum?

  • What do you use as RPC provider? Testrpc? It should have console output that gives you a clue about what is going on. – comodoro Aug 26 '17 at 13:53
  • Yes. Testrpc. I just see a couple of eth_call. Just so that I am clear is the Solidity code ok? – cogitoergosum Aug 26 '17 at 13:55
  • 2
    Ah, it has just occurred to me that calls do not modify EVM state, you need sendTransaction. See ethereum.stackexchange.com/questions/765/… – comodoro Aug 26 '17 at 14:10
  • Thanks! I was able to get this syntax contractInstance.addNumber([500], { from: web3.eth.accounts[2] } working too. How is this different from sendTransaction? – cogitoergosum Aug 26 '17 at 16:37
  • 1
    " How is this different from sendTransaction? " Well, when you execute any function web3.js automatically decides to use .call or .sendTransaction based on the code of that function. When you execute contractInstance.addNumber() web3.js is actually doing a send transaction like this: contractInstance.addNumber.sendTransaction() – Merunas Grincalaitis Oct 21 '17 at 10:43

Your Answer

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

Browse other questions tagged or ask your own question.