2

I have very simple contract as..

contract myContract {
    function foo() public returns(uint) {
        return 10;
    }

    function foo1() public view returns(uint) {
        return 10;
    }    
}

But when I test my contract with truffle test.js(as follows). Why the result is different with view and without view modifier?

here is parts of my test.js.

temp1 = await instant.foo1();
console.log("temp1 value : " + temp1);
assert.equal(temp1, 10, "should be 10 return");     
temp1 = await instant.foo();
console.log("temp1 value : " + temp1);
assert.equal(temp1, 10, "should be 10 return");

And it is my result.

enter image description here

2

A function without a pure modifier, a view modifier or a constant modifier (which is equivalent to a view modifier) is assumed to be changing the contents of the block-chain.

This "change" is refereed to as transaction, and the value returned to the off-chain caller (e.g., web3) is a hash which encrypts the transaction.

The actual value that you return from the function can be used only inside the block-chain (i.e., by any other function which calls your function).

If you want this value to be accessible on the off-chain side, then you need to generate an event (inside the Solidity function) which contains it.

Then, on the off-chain side, you will need to decode the returned value (i.e., the transaction hash) in order to retrieve that value.

On-Chain Example:

contract MyContract {
    event MyEvent(address indexed sender, uint256 amount);
    function myFunction(uint256 a, uint256 b, uint256 c) external returns (uint256) {
        uint256 x = a * b + c;
        MyEvent(msg.sender, x);
        return x;
    }
}

Off-Chain Example:

let PARAMS = [ // This should reflect MyEvent
    {name: "sender", size: 160, indexed: true },
    {name: "amount", size: 256, indexed: false},
];

function decode(data) {
    let transaction = {};
    let index = "0x".length;
    for (let i = 0; i < PARAMS.length; i++) {
        if (!PARAMS[i].indexed) {
            let name = PARAMS[i].name;
            let size = Math.floor(PARAMS[i].size / 4);
            transaction[name] = web3.toBigNumber("0x" + data.substr(index, size));
            index += size;
        }
    }
    return transaction;
}

async function myFunction(myContract) {
    let hash = await myContract.myFunction(5, 6, 7);
    let transaction = decode(hash.receipt.logs[0].data);
    return transaction.amount; // should be 5 * 6 + 7
}

Please note that by hash.receipt.logs[0], we are accessing the first event which occurred as a result of invoking myContract.myFunction. In other words, the index (in this case, 0) indicates the number of the desired event by chronological order.

4

Because without the view modifier, web3 (and thus Truffle JS tests, which uses web3) thinks it has to send a transaction. Sending transactions does not yield a return value from the smart contract.

Adding the view modifier tells web3 it can use call in order to get the function's return value. A call, however, cannot alter the contract's state. It cannot alter any storage variables.

If you want a function which alters the contract's state and does yield a value, you could create a function which emits an event. In that event, you could set the return value.

  • So, I can only check the value with an event function? Is there any way to get the correct value from even log? I mean, without view modifier, I want to make some test code using assert.equal. Thank you. – Kronos Apr 30 '18 at 8:26
  • i think, in wbe3 0.x you can always use the .call with any contract method, either it changes the state variables or not. – Kaki Master Of Time Apr 30 '18 at 9:10
  • If you use .call like that, web3 will simulate a transaction. The actual contract state will not be altered. – Henk Apr 30 '18 at 9:13
1

The view Modifier indicates, that you make no changes to the Blockchain and that the query of the uint wont require any gas cost.

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.