Можно ли использовать библиотеку Solidity внутри другой?

Я пытаюсь использовать библиотеку Solidity внутри другой. Минимальный код будет примерно таким:

Самая глубокая библиотека:SLib.sol

pragma solidity ^0.4.18;

library SLib {
  struct SCtx {
    uint a;
  }

  function init(SCtx storage self, uint _a) public
  {
    self.a = _a;
  }

  function getA(SCtx storage self) public view returns (uint)
  {
    return self.a;
  }
}

Затем TLib.solиспользует предыдущий:

pragma solidity ^0.4.18;

import "./SLib.sol";

library TLib {
  using SLib for SLib.SCtx;

  struct TCtx {
    SLib.SCtx s;
  }

  function init(TCtx storage self, uint _a) public
  {
    self.s.init(_a);
  }

  function getA(TCtx storage self) public view returns (uint) {
    return self.s.getA();
  }
}

Затем какой-то контракт на их использование TInterface.sol:

pragma solidity ^0.4.18;

import "./TLib.sol";

contract TInterface {
  using TLib for TLib.TCtx;
  TLib.TCtx t;

  function TInterface(uint _a) public {
    t.init(_a);
  }

  function getA() public view returns (uint) {
    return t.getA();
  }
}

В Truffle я даже не могу связать этих парней. В 2_deploy_libraries.js:

var TLib = artifacts.require("./TLib.sol");
var SLib = artifacts.require("./SLib.sol");
var TInterface = artifacts.require("./TInterface.sol");

module.exports = function(deployer) {
  deployer.deploy(SLib);
  deployer.deploy(TLib);
  deployer.link(SLib, TLib);
  deployer.link(TLib, TInterface);
};

Возвращает:

  Deploying SLib...
  ... 0xe0317d15a3eac...
  SLib: 0x8e4c131b37383e431b9cd0635d3cf9f3f628edae
  Deploying TLib...
  Linking SLib to TLib
Error encountered, bailing. Network state unknown. Review successful transactions manually.
Error: TLib contains unresolved libraries. You must deploy and link the following libraries before you can deploy a new version of TLib: SLib
    at /usr/l...:/~/truffle-contract/contract.js:371:1
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:228:7)

Это вообще разрешено? И если да, то как правильно связать и использовать его?

Ответы (1)

Я понял, что делаю не так. Это связано с порядком подключения/развертывания библиотек. Это правильный способ сделать это:

var TLib = artifacts.require("./TLib.sol");
var SLib = artifacts.require("./SLib.sol");
var TInterface = artifacts.require("./TInterface.sol");

module.exports = function(deployer) {
  deployer.deploy(SLib);
  deployer.link(SLib, TLib);
  deployer.deploy(TLib);
  deployer.link(TLib, TInterface);
};

На самом деле это имеет смысл.

Для ясности: да, вы можете использовать библиотеку Solidity внутри другой библиотеки Solidity.