0

I want to use some variables in multiple functions in my library contract. Is there any way to do that? I got following error code for my library code.

library myArithmetic {
    bytes1[10] mData;

    function doSomeMath(bytes1[10] _input) public returns (bytes1[10]) {
        for(uint8 i=0 ; i<10 ; i++){
            mData[i] = _input[i];
        }
        //do some my math..here..
    }
}

I have error, like TypeError: Library cannot have non-constant state variables I do not want to make each of my functions with several parameter input and return, and to another functions..so on. Is it possible to do that??

I know in the normal contract, the mData will be storage variables. But library does not allow to have state variables. So I cannot define such this way?

  • Think of a physical library, you can check in and check out books, but you can’t edit books. Same applies for most programmatic implementations of a “Library”. – ReyHaynes Apr 25 '18 at 13:04
0

An approach to solve this is to define a struct inside your library and pass that struct as the first parameter. The functions in your library will be able to modify the struct.

pragma solidity ^0.4.0;

library Arithmetic {
    struct Data {
        bytes1[10] mData;
    }

    function doSomeMath(Data s, bytes1 _input, uint8 _idx) internal pure returns (bytes1) {
        s.mData[_idx] = _input;
        return _input;
    }
}

In your contract you create an instance of that struct and pass it to the library functions. You can use the "using" syntax sugar to have a better looking code.

contract Ballot {
    // Reserver storage for library data
    Arithmetic.Data d;

    // When referencing Data allow shortcut to Arithmetic functions
    using Arithmetic for Arithmetic.Data;

    function bar(bytes1 a) public view returns (uint8) {
        // The following is equivalente to 
        // bytes1 b = Arithmetic.doSomeMath(d, a, 3);
        bytes1 b = d.doSomeMath(a, 3);
        return uint8(b);
    }
}
2

Libraries don't have storage. Their methods are invoked with the delegatecall opcode, which means that they are run in the context of the caller. In a library, this points to the calling contract.

If you want to work around this, create a storage contract with the globals and pass it to every library method you want to use the globals in.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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