0

I am still a solidity noob, so I apologize if the question is too basic.

I am trying to write a contract which saves the hash of a (potentially) large bunch of data on chain.

For this reason, I would like to write a function which performs the hash externally (i.e. on the caller machine, something like a view function), and then it saves back the result on the chain. Is it possible? A code example here:

contract Test {
  bytes32[] hashes;

  function extCall(bytes _data) external view {
    bytes32 hash = keccak256(_data);
    _intCall(hash);
  }

  function _intCall(bytes32 _hash) private {
    hashes.push(_hash)
  }
}

The intention here was to exclude the possibility to save the hash on the chain without having the original data. For this reason, the only way to call the function _intCall would be by means of calling it through extCall. But, it seems that by doing this trick, also extCall is called on chain and consumes gas. In particular, i get this warning while testing on truffle:

Warning: Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.

P.s. there is a (BIG) chance that I totally misunderstood the topic, so every help is really accepted!

1

Anything you do as part of a transaction happens on chain. Anything that modifies a contract's state needs to be done as part of a transaction.

It's fine to call a view function as a helper; that code will only run on a single node (the one you're talking to) and can return a value. So this would not incur a cost for all the data you're hashing:

contract Test {
    bytes32[] hashes;

    function hash(bytes data) public pure {
        return keccak256(data);
    }

    function store(bytes32 hash) public {
        hashes.push(hash);
    }
}

This would be used something like this (web3.py-ish pseudocode):

hash = contract.call().hash("my document here")  # not a transaction
contract.transact().store(hash)  # a transaction

But then you may as well just do the hashing outside of the contract altogether (e.g. hash = keccak256("my document here")).

There's no way to prove to anyone that you have a document matching the hash unless you send the entire document as part of a transaction.

  • Ok thanks, just one more question: it is just a solidity feature or is it inherent in ethereum? I mean, to your knowledge, there will be a way to implement a sort of "mixed external/internal call" directly in an assembly call? – Gnaaaa Mar 28 '18 at 8:23
  • It's inherent to Ethereum. – smarx Mar 28 '18 at 10:14
0

pure -> To operate with data (literal) examples:

function helloo() public/external pure {

a) return 4 + 5;

b) uint number = 6;
   return number;

c) string memory hello = "hi"; // 'memory' -> refers to the temporary memory of the virtual machine of ethereum.
   return hello;

}

view -> to read contract data

examples:

string hello = "hi"; -> GLOBAL IN THE CONTRACT (BLOCKCHAIN) if it has been declared outside the function.

function helloo() public/external view {

a) return hello; 

b) string storage str = hello; -> Refers to the state variable 
(pointer).   
return str;

}

*None of these modifiers consumes gas because these function not write or save data in the blockchain.

  • Thanks, what happens if I call a pure/view public function A in a non pure/view function B? Does A will consume gas because it is called in B "scope"? Because if I call the function B inside A, A starts to consume gas itself even if it is marked as pure/view. – Gnaaaa Mar 28 '18 at 8:20
  • In that case 'B' consumes gas, if you call to 'A', you are going to consume gas. It's no matter the modifier 'puer / view' of 'A'.As a general rule, whenever you call a function other than 'view / puere' it will cost you gas. – AlbertoLasa Mar 28 '18 at 9:09

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.