Реализация проекта: Использование структур внутри библиотек с интерфейсом и динамическим адресом библиотеки

#design-patterns #interface #solidity #smartcontracts

Вопрос:

Основывайтесь на некоторых статьях об использовании библиотеки со структурой в ней.

  1. образец статьи
  2. документ eth для библиотеки показывает шаблон проектирования использования структуры в библиотеке

Ниже приведены примеры кодов из образца статьи.

Считай.сол

 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;
        
    }

}
 

Математика.соль

 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];
    }
}
 

Проблема:

Я пытаюсь добавить интерфейс в свою библиотеку, и потому что я хотел бы обновить свою библиотеку в будущем, поэтому я пытаюсь сохранить ее как адрес, чтобы я мог получить к ней доступ с новым адресом h .

Но я в замешательстве от того, как я должен это писать, так как больше нет статьи об этом, чтобы проводить исследования по этому вопросу.

Считай.сол

 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.

UPDATE:
This article gives some hints of what possibly should be done in order to have a replaceable library address. But since it is kind of risky so I don’t think it is suitable to use it in real production case.