1

I'm trying to learn about using libraries in solidity. In the following test contract, swapNumberLib does not successfully set value1 = value2. I thought libraries could act on the storage of a contract if the variables were passed into the function - does it not work in this case?

pragma solidity ^0.4.24;

library TestLibrary {
    function swapNumber(uint value1, uint value2) internal {
        value1 = value2;
    }
}

contract Test {
    uint public value1;
    uint public value2;

    constructor() public {
        value1 = 1;
        value2 = 2;
    }

    function swapNumberLib() public {
        TestLibrary.swapNumber(value1, value2);
    }

    function swapNumber() public {
        value1 = value2;
    }
}
1

Based on my understanding, the libraries can access to the contract storage, but the point is that the uint is a value type, not a reference type. So you can't specify the storage location to explicitly point to the contract's storage.

This means that if library functions are called, their code is executed in the context of the calling contract, i.e. this points to the calling contract, and especially the storage from the calling contract can be accessed.
As a library is an isolated piece of source code, it can only access state variables of the calling contract if they are explicitly supplied (it would have no way to name them, otherwise)

from the doc

array and structs behave differently, since you can point to their storage into the calling contract:

pragma solidity ^0.4.24;

library TestLibrary {
    function setMyArray(uint[] storage value1) internal {
        value1[0] = 100;
    }
}

contract Test {
    uint[] public arr;

    constructor() public {
        arr = [1];
    }

    function setMe() public {
        TestLibrary.setMyArray(arr);
    }
}

if you remove storage from setMyArray this example it won't work anymore. Or, similar:

library TestLibrary {
    function setMyArray(uint[] storage value1, uint[] storage value2) internal {
        value1[0] = value2[0];
    }
}

contract Test {
    uint[] public arr;
    uint[] public arr1;

    constructor() public {
        arr = [1];
        arr1 = [2];
    }

    function setMe() public {
        TestLibrary.setMyArray(arr, arr1);
    }
}
  • Thanks for the information! In your final example, if I change value1[0] = value2[0] to value1 = value2, it no longer works. Any idea why? – Jordan Jun 5 '18 at 14:50
  • No, not sure if its a bug or not... – mirg Jun 5 '18 at 14:57

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.