Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

String memory variable cause function to return no value #3998

Closed
Pzixel opened this issue Apr 26, 2018 · 6 comments
Closed

String memory variable cause function to return no value #3998

Pzixel opened this issue Apr 26, 2018 · 6 comments

Comments

@Pzixel
Copy link

Pzixel commented Apr 26, 2018

I'm writing a simple smart contract which loops over internal array and checks if strings are equal. It compiles fine but when I run this smart contract I get no value at all. I started my investigation and here is what I have found.

Consider following smart contract:

pragma solidity ^0.4.23;

contract Season {
    address[] public requests;
    mapping(bytes32 => address) requestIdToAddress;
        
    function createRequest(string id) public {
        bytes32 hash = keccak256(id);
        require(requestIdToAddress[hash] == 0);

        Request request = new Request(id);
        requests.push(request);
        requestIdToAddress[hash] = request;
    }

    function getRequestsCount() public view returns(uint) {
        return requests.length;
    }

    function getRequestById(string id) public view returns(address) {
        return getRequestByHash(keccak256(id));
    }

    function getRequestByHash(bytes32 hash) public view returns(address) {
        return requestIdToAddress[hash];
    }

    function getRequestsByFilter(string id) public view returns(uint, uint, uint, bytes32[]) {
        bytes32[] memory filteredRequests = new bytes32[](getRequestsCount());
        uint j = 0;
        for (uint i = 0; i < filteredRequests.length; i++) {
            Request request = Request(requests[i]);
            //string memory requestId = request.id();
        }
        return (filteredRequests.length, getRequestsCount(), j, filteredRequests);
    }    
}

contract Request {
    string public id;

    constructor(string id_) public {
        id = id_;
    }
}

Deploy it and call createRequest(somevalue). Then call getRequestsByFilter(anyvalue) and you should see 1 1 1 0x00..00. Ok, it's good, it works fine.

However, try to uncomment //string memory requestId = request.id(); line and repeat steps above. In this case this contract is still compiling, however trying to call it always leads to 0 0 0 null. But this line shouldn't change observable behaviour?! Yes, it shouldn't, however, it does.

I consider it's either VM or compiler bug.

solc, the solidity compiler commandline interface
Version: 0.4.23+commit.124ca40d.Windows.msvc

@chriseth
Copy link
Contributor

Are you sure you are running this on a byzantium-compatible blockchain?

@Pzixel
Copy link
Author

Pzixel commented Apr 26, 2018

I run it on parity. However, it seems just an error because of trying to access other's contract dynamic string method. However, It doesn't work with sized types too:

pragma solidity ^0.4.23;

contract Season {
    address[] public requests;

    constructor() public {
        requests.push(new Request());
    }

    function getRequestsByFilter() public view returns(bool) {
        Request r = Request(requests[0]);
        bool ret = r.isMatch();
        return ret;
    }
}

contract Request {  
    function isMatch() public pure returns(bool) {
        return true;
    }    
}

Here expected value is true but it's actually false.

I'm not sure anymore if it's a compiler bug or just bad EVM, but I think we need at least some explanation here, like some warning or something.

@Pzixel
Copy link
Author

Pzixel commented Apr 27, 2018

I have found out that it's parity bug, others ethereum implementations works fine with this code.

@Pzixel Pzixel closed this as completed Apr 27, 2018
@axic
Copy link
Member

axic commented Apr 27, 2018

You can link to the Parity issue? It is useful for others finding this issue to be able to track what's going on.

@Pzixel
Copy link
Author

Pzixel commented Apr 27, 2018

Of course: openethereum/parity-ethereum#8503

It basically forbids any interacton between contracts, e.g. in provided example you cannot call id() function.

@axic
Copy link
Member

axic commented Jun 11, 2018

Related to #4259.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants