7

I'm trying to call some of the new precompiled contract (ecmul) from a pure function but it fails with:

browser/ballot.sol:11:23: TypeError: Function declared as pure, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.
            if iszero(call(not(0), 0x07, 0, input, 0x60, p, 0x40)) {
                      ^--^

This is the sample contract (requires solc 0.4.19):

pragma solidity ^0.4.19;

contract Ballot {
    function ecmul(uint256 x, uint256 y, uint256 scalar) public pure returns (uint256[2] p) {
        // With a public key (x, y), this computes p = scalar * (x, y).
        uint256[3] memory input;
        input[0] = x;
        input[1] = y;
        input[2] = scalar;
        assembly {
            // call ecmul precompile
            if iszero(call(not(0), 0x07, 0, input, 0x60, p, 0x40)) {
                revert(0, 0)
            }
        }
    }
}

Taken from the article precompiles & solidity.

If I declare the function as view it will work but seems as unnecessary since it is a precompiled contract it should not modify the storage of any contract.

3
  • You say using view seems unnecessary, are there any other specific reasons you want to use pure instead of view?
    – willjgriff
    Jan 10, 2018 at 16:29
  • 1
    @willjgriff My main issue is that modifying it to view forces me to modify all functions that use ecmul to be declared as view, and this forces any function that calls one of those to also be declared as view.
    – Ismael
    Jan 10, 2018 at 19:40
  • Linking the OP's Reddit post as well: reddit.com/r/ethdev/comments/7p8b86/… Nov 19, 2020 at 16:20

1 Answer 1

3

Firstly note that the view modifier, as seen in the doc here doesn't allow modifying of the state, it only allows reading of the state and behaves the same as constant (the modifier used for these code snippets in the article you've linked to). The pure modifier, in the doc here prevents both modifying and reading of the state.

To answer your question, it seems like using call() with any arguments raises this error when the pure modifier, which prevents reading of the state, is used. Which makes sense as call() needs to read the state to get the contract code at the address specified so it can execute a function on it.

4
  • 1
    The thing is precompiled contracts do not read and do not modify their state. One can argue that they do not have state. As an example sha256() is a precompiled contract and you can call it from a pure function.
    – Ismael
    Jan 10, 2018 at 0:55
  • 1
    If they're not in the state and the EVM doesn't have to read from the state to get them then I guess the compiler just doesn't know what the precompiled code addresses are. For all other contract addresses view is required and it doesn't consider these addresses different.
    – willjgriff
    Jan 10, 2018 at 11:52
  • 1
    Perhaps functions will be added to Solidity to represent these precompiles in future like the sha256() and ecrecvoer() functions.
    – willjgriff
    Jan 10, 2018 at 12:05
  • 1
    Yes, I hope eventually all precompiled contracts will be added to solidity. I was hopping for a workaround.
    – Ismael
    Jan 10, 2018 at 16:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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