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

Use returndatacopy for cross-contract calls #3270

Closed
axic opened this issue Dec 1, 2017 · 10 comments
Closed

Use returndatacopy for cross-contract calls #3270

axic opened this issue Dec 1, 2017 · 10 comments

Comments

@axic
Copy link
Member

axic commented Dec 1, 2017

This will enable passing dynamic (bytes, string, variable length arrays, structs, etc.) data between calls.

For passing structs the new ABI encoder/decoder must be enabled - preferably by the time returndatacopy is enabled, the ABI rewrite will be mature enough to be on by default.

A related issue is #434 which introduces a new low-level call method which returns the raw bytes using returndatacopy.

The main risk here is that it makes contracts incompatible with pre-Byzantium EVMs.

@axic
Copy link
Member Author

axic commented Dec 1, 2017

As a short term solution there could be annotation for functions to mark they are using the new ABI encoder. In that case the compiler could use returndatacopy.

@axic
Copy link
Member Author

axic commented Dec 2, 2017

Proposal in #1117 would allow these features to be turned on/off.

@fulldecent
Copy link
Contributor

Can you please provide us more details here.

  • Is this issue "accepted"?
  • It is committed that a change will be made?
  • Is there a target version?

I am working on ERC-721 (ethereum/EIPs#841 (comment)). Could you please take a quick look at ERC721Enumerable. Am I doing it right? Should we delay this standard to wait for this issue?

@chriseth
Copy link
Contributor

We are currently working on this. The main problem is that the old ABI decoder does not perform bounds checking and thus it would be possible for a malicious called contract to return data that can interfere with existing data in memory (read-only).

Since we are not yet 100% confident with the new ABI decoder (which does bounds checking), it might take a while until this is enabled by default.

@chriseth
Copy link
Contributor

Actually thinking about this a little more, the old ABI decoder does not support multi-dimensional arrays or structs anyway, so the bounds checking would be a lot simpler.

@fulldecent
Copy link
Contributor

Thank you for clarifying.

@fulldecent
Copy link
Contributor

Adding notes here for people designing interfaces (originally discussed in solidity-dev).

Test case

pragma solidity ^0.4.20;

contract Items {
    uint256[] public oddNumbers;
    
    function Items() public {
        oddNumbers.push(1);
    }
    
    function extendSequence() external {
        uint256 next = oddNumbers[oddNumbers.length-1] + 2;
        require(next >= oddNumbers[oddNumbers.length-1]);
        oddNumbers.push(next);
    }
    
    function oddNumbersLength() external view returns (uint256) {
        return oddNumbers.length;
    }
    
    function oddNumbersAll() external view returns (uint256[]) {
        return oddNumbers;
    }
}

This exposes two interfaces for interrogating oddNumbers:

Piecemeal

function oddNumbers(uint256 index) external view returns (uint256); // Implicitly defined;
function oddNumbersLength() external view returns (uint256);

All-at-once

function oddNumbersAll() external view returns (uint256[]);

Discussion

The piecemeal approach is guaranteed to always work. But the all-at-once approach will fail for on-blockchain calls after the array reaches a certain length. This is because memory is copied, it is not mmaped.

If we live in a world where we see:

uint a;
uint b;
uint total = a + b;
require(total > a);

then I think it is important to make the above stipulation.

attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Feb 21, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Feb 21, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Feb 28, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Feb 28, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 1, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 1, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 1, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 1, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 1, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 2, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 2, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 3, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 3, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 3, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 4, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 4, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 4, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 4, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 4, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 5, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 5, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 5, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 5, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 6, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 6, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 6, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 6, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 7, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Mar 7, 2018
@beether
Copy link

beether commented Mar 22, 2018

I was looking for this exact feature and found it implemented 8 hours ago. Awesome work. Looking forward to the nightly build!

@fulldecent Spot on with the Piecemeal approach. Not exposing an indexed getter() could be a security risk. Is it possible to have an compiler warning for views returning dynamic arrays-of-arrays that the response is not always guaranteed to work?

@fulldecent
Copy link
Contributor

@beether The compiler will not check for that because it is too difficult and requires conventions.

A new new SALOAD instruction (storage load from arbitrary account) would solve this. Then you could do:

pragma solidity ^0.4.21;

contract Array {
    uint[] public a;
}

contract Inspector {
    function getLength(Array _addr) external view returns (uint){
        return _addr.a.length;
    }

    function getIndex(Array _addr, uint _index) external view returns (uint){
        return _addr.a(_index);
    }
}

My idea here does not have consensus. And it is a breaking change to a fundamental concept (the implicit functions) -- it would not be accepted.

@beether
Copy link

beether commented Mar 22, 2018

@fulldecent Couldn't the compiler warn anytime a view returns arrays-of-arrays? It's similar to an infinite gas warning.

attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Apr 23, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Apr 24, 2018
attente added a commit to horizon-games/eth-state-channels-research that referenced this issue Apr 24, 2018
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

4 participants