Skip to main content
added 237 characters in body
Source Link
Sky
  • 2.4k
  • 2
  • 8
  • 26

Compiling the contract returns this error.

 TypeError: Function cannot be declared as view because this expression (potentially) modifies the state.
       --> contracts/certification/token/CleanEnergyCertificateToken.sol:104:9:
        |
    104 |         contractAddress.call(abi.encodeWithSignature("getTokenProperties(uint256 tokenId)", tokenID));
        |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The issue is that obvious: getTokenProperties() function's structure is unknown to the compiler in this case, because I am using call. So it doesn't know that getTokenProperties() is a view function that doesn't modify storage.

Here is getTokenProperties() code for reference:

function getTokenProperties(uint256 tokenId) public view returns (CleanEnergyCertificateTokenProperties memory)  {
    require(
        tokenId >= 0 && tokenIdToProperties[tokenId].timestamp > 0,
        "Token and it's properties for with respective tokenId must exist!"
    );
    return tokenIdToProperties[tokenId];
}

Therefor the only solution here seems to be to leave out the "view" modifier.

Question: Will getTokenProperties() spend gas if it has the functionality of a real "view" function, but it isn't declared as such.

EDIT: I just figured out I can use staticcall instead of call and that solves the issue.

But My question still remains. What if I forget to declare function and view ? Will it spend gas? I guess not, but I am not sure.

Compiling the contract returns this error.

 TypeError: Function cannot be declared as view because this expression (potentially) modifies the state.
       --> contracts/certification/token/CleanEnergyCertificateToken.sol:104:9:
        |
    104 |         contractAddress.call(abi.encodeWithSignature("getTokenProperties(uint256 tokenId)", tokenID));
        |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The issue is that obvious: getTokenProperties() function's structure is unknown to the compiler in this case, because I am using call. So it doesn't know that getTokenProperties() is a view function that doesn't modify storage.

Here is getTokenProperties() code for reference:

function getTokenProperties(uint256 tokenId) public view returns (CleanEnergyCertificateTokenProperties memory)  {
    require(
        tokenId >= 0 && tokenIdToProperties[tokenId].timestamp > 0,
        "Token and it's properties for with respective tokenId must exist!"
    );
    return tokenIdToProperties[tokenId];
}

Therefor the only solution here seems to be to leave out the "view" modifier.

Question: Will getTokenProperties() spend gas if it has the functionality of a real "view" function, but it isn't declared as such.

Compiling the contract returns this error.

 TypeError: Function cannot be declared as view because this expression (potentially) modifies the state.
       --> contracts/certification/token/CleanEnergyCertificateToken.sol:104:9:
        |
    104 |         contractAddress.call(abi.encodeWithSignature("getTokenProperties(uint256 tokenId)", tokenID));
        |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The issue is that obvious: getTokenProperties() function's structure is unknown to the compiler in this case, because I am using call. So it doesn't know that getTokenProperties() is a view function that doesn't modify storage.

Here is getTokenProperties() code for reference:

function getTokenProperties(uint256 tokenId) public view returns (CleanEnergyCertificateTokenProperties memory)  {
    require(
        tokenId >= 0 && tokenIdToProperties[tokenId].timestamp > 0,
        "Token and it's properties for with respective tokenId must exist!"
    );
    return tokenIdToProperties[tokenId];
}

Therefor the only solution here seems to be to leave out the "view" modifier.

Question: Will getTokenProperties() spend gas if it has the functionality of a real "view" function, but it isn't declared as such.

EDIT: I just figured out I can use staticcall instead of call and that solves the issue.

But My question still remains. What if I forget to declare function and view ? Will it spend gas? I guess not, but I am not sure.

Source Link
Sky
  • 2.4k
  • 2
  • 8
  • 26

Function cannot be declared as view because this expression (potentially) modifies the state

Compiling the contract returns this error.

 TypeError: Function cannot be declared as view because this expression (potentially) modifies the state.
       --> contracts/certification/token/CleanEnergyCertificateToken.sol:104:9:
        |
    104 |         contractAddress.call(abi.encodeWithSignature("getTokenProperties(uint256 tokenId)", tokenID));
        |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The issue is that obvious: getTokenProperties() function's structure is unknown to the compiler in this case, because I am using call. So it doesn't know that getTokenProperties() is a view function that doesn't modify storage.

Here is getTokenProperties() code for reference:

function getTokenProperties(uint256 tokenId) public view returns (CleanEnergyCertificateTokenProperties memory)  {
    require(
        tokenId >= 0 && tokenIdToProperties[tokenId].timestamp > 0,
        "Token and it's properties for with respective tokenId must exist!"
    );
    return tokenIdToProperties[tokenId];
}

Therefor the only solution here seems to be to leave out the "view" modifier.

Question: Will getTokenProperties() spend gas if it has the functionality of a real "view" function, but it isn't declared as such.