Я пытаюсь использовать библиотеку 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)
Это вообще разрешено? И если да, то как правильно связать и использовать его?
Я понял, что делаю не так. Это связано с порядком подключения/развертывания библиотек. Это правильный способ сделать это:
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);
};
На самом деле это имеет смысл.
Пол Разван Берг