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

Using a struct in a public function with ABIEncoderV2 #3177

Closed
naddison36 opened this issue Nov 7, 2017 · 3 comments
Closed

Using a struct in a public function with ABIEncoderV2 #3177

naddison36 opened this issue Nov 7, 2017 · 3 comments

Comments

@naddison36
Copy link

The following code compiles using solidity version 0.4.18+commit.9cf6e910 on Mac OSX

pragma solidity ^0.4.18;
pragma experimental ABIEncoderV2;

contract TestContract
{
    struct TestStruct {
        uint256 id;
        string desc;
    }

    TestStruct[] tests;

    function addTestStruct(TestStruct testStruct) internal
    {
        tests.push(testStruct);
    }
}

If I change the addTestStruct function from internal to public, then I get the following error:
InternalCompilerError: Static memory load of more than 32 bytes requested.

I've tried numerous ways of declaring the struct as public.

Expected result is a struct can be passed into a public function when using ABIEncoderV2

@Tootoot222
Copy link

Tootoot222 commented Nov 15, 2017

I have the same bug, but it's even worse with libraries

pragma solidity ^0.4.18;
pragma experimental ABIEncoderV2;

library Arg {
    struct Struct {
        uint256 a;
        uint256 b;
    }
    
    function modifyStruct(Struct arg)
    //internal
    public
    pure returns (
        uint256,
        uint256
    ) {
        return (arg.a + 5, arg.b + 3);
    }
}

contract StructMemArg {

    function buildStruct(
        uint256 a,
        uint256 b
    ) public pure returns (
        uint256,
        uint256
    ) {
        return (Arg.modifyStruct(Arg.Struct({
            a: a,
            b: b
        })));
    }
}

Changing the function in the library from public to internal makes it work, but the internal keyword "inlines" the library code into the main contract, which bloats the main contract and defeats the purpose of separating the code out into a library. You don't even need to link the contract and the library when the library function (the only one in this simple example) is internal, which means that the code is included in the main contract.

This is a serious problem for me since the reason I started using libraries was because my contract was getting to be too big... and my structs are much more complex than in this example, which, combined with the 16 local variable limit, makes it impossible to easily pass data around between library functions and the contract that uses them, without approaching the block gas limit due to including all the library code in the main contract.

@chriseth
Copy link
Contributor

The decoder is not yet finished: #2863

@naddison36
Copy link
Author

I can confirm this problem has been fixed with Solidity 0.4.19. Thanks

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