mardi 27 juillet 2021

Design implementation: Using Structs inside Libraries with interface and dynamic lib address

Base on some articles on using library with struct in it.

  1. sample article
  2. eth doc for library shows the design pattern of using struct in library

Below are sample codes from sample article.

Count.sol

pragma solidity ^0.6.4;

library Count{
    struct hold{
        uint a;
        mapping( uint => bool ) isGood;
    }
    
    function subUint(hold storage s, uint b) external view returns(uint){
        
        require(s.a >= b); // Make sure it doesn't return a negative value.
        return s.a - b;
        
    }

}

Math.sol

pragma solidity ^0.6.4;


import { Count } from  './Count.sol';

contract Math {
    
    using Count for Count.hold;
    
    Count.hold  h;
    address h1;
    
    constructor() public {
        h.a = 123;
        h.isGood[1] = true;
    }
    
    function subHold(uint a) public view  returns(uint){
        return h.subUint(a);
    }
    
    function show(uint a) public view returns ( bool){
        return h.isGood[a];
    }
}

Problem:

I try to add an interface to my library and because I would like to upgrade my library in the future, so I try to store it as address so that I can access it with new address h.

But I'm confused how I should write it as there is no article about it to do anymore research on this.

Count.sol

pragma solidity ^0.6.4;

library Count{
    struct hold{
        uint a;
        mapping( uint => bool ) isGood;
    }
    
    function subUint(hold storage s, uint b) external view returns (uint){
        require(s.a >= b); // Make sure it doesn't return a negative value.
        return s.a - b;
        
    }
    
    function setA(hold storage s, uint _a) external returns (bool){
        s.a = _a;
    }
    
    function setGood(hold storage s, uint _a, bool _good) external returns (bool){
        s.isGood[_a] = _good;
        
        return true; // successful
    }
    
    function showGood(hold storage s, uint _a) external view returns (bool) {
        return s.isGood[_a];
    }

}

Math.sol

pragma solidity ^0.6.4;


import { ICount } from  './ICount.sol';
import { Count } from  './Count.sol';

contract Math {
    
    using Count for ICount;
    
    address h;
    
    constructor() public {
        ICount(h).setA(123);
        ICount(h).setGood(1, true);
    }
    
    function subHold(uint a) public view  returns(uint){
        return ICount(h).subUint(a);
    }
    
    function show(uint a) public view returns ( bool){
        return ICount(h).showGood(a);
    }
}

ICount.sol

pragma solidity ^0.6.4;

import { Count } from  './Count.sol';  // this makes my code not dynamic, but I need the type declaration for functions below

interface ICount {
    function subUint(Count.hold calldata s, uint b) external view returns(uint);
    function setA(Count.hold calldata s, uint _a) external returns (bool);
    function setGood(Count.hold calldata s, uint _a, bool _good) external returns (bool);
    function showGood(Count.hold calldata s, uint _a) external view returns (bool);
}

There are several problems in the above codes and I'm stuck.

Firstly ,I have to increase the number of function in the Count.sol since struct is not easily accessible directly. Which is ok, if it is what it takes.

Secondly, I tried to use address of library and store it at h and convert it to with ICount(h).function and use it as function. but There are many problem.

Thirdly, as shown at ICount.sol, I do not want to import Count.sol, but I need the type Count for function parameter type declaration.


Purposes of doing all above and what I try to achieve.

  1. Interface is to set a standard for future and backward compatibility.
  2. Interface is used to convert address to Count so function can be called.
  3. Count.sol is used because my Math.sol is getting too big for compilation. I need to move related code with the same purpose to Count.sol

Please advise and sorry the amended code doesn't compile because I'm stuck entirely.

Aucun commentaire:

Enregistrer un commentaire