Adding using MyLib for Data inside MyLib itself causes the contract to compile without error but then the linker will try to link the library to itself, which fails.
./contracts/MyLib.sol:
pragma solidity ^0.4.4;
library MyLib {
struct Data {
uint a;
}
using MyLib for Data;
function foo(Data storage self) returns (uint) {
self.bar();
}
function bar(Data storage self) returns (uint) {
self.a = 10;
return self.a;
}
}
contract MyContract {
using MyLib for MyLib.Data;
MyLib.Data data;
function a() returns (uint) {
return data.foo();
}
}
./migrations/2_libraries.js:
module.exports = function(deployer) {
deployer.deploy(MyLib);
deployer.deploy(MyContract);
};
Need to confirm, but I assume this is simply invalid code.
As rare as this is, maybe someone else will make the same mistake, and it would be nice to have an intelligent error message.
Running migration: 1_initial_migration.js
Deploying Migrations...
Migrations: 0x600bd8882fe9d3b6f2afbb6d1aa3e863fa8a9aaa
Saving successful migration to network...
Saving artifacts...
Running migration: 2_libraries.js
Error encountered, bailing. Network state unknown. Review successful transactions manually.
Error: Cannot link library: MyLib has no address. Has it been deployed?
at Object.module.exports.link (/Users/raine/projects/test-contracts/node_modules/truffle/lib/linker.js:16:13)
at /Users/raine/projects/test-contracts/node_modules/truffle/lib/linker.js:65:12
at Array.forEach (native)
at Object.module.exports.autolink (/Users/raine/projects/test-contracts/node_modules/truffle/lib/linker.js:58:24)
at /Users/raine/projects/test-contracts/node_modules/truffle/lib/deployer.js:12:14
at /Users/raine/projects/test-contracts/node_modules/truffle/lib/deferredchain.js:20:15
at run (/Users/raine/projects/test-contracts/node_modules/core-js/modules/es6.promise.js:87:22)
at /Users/raine/projects/test-contracts/node_modules/core-js/modules/es6.promise.js:100:28
at flush (/Users/raine/projects/test-contracts/node_modules/core-js/modules/_microtask.js:18:9)
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickDomainCallback (internal/process/next_tick.js:122:9)
Good catch, thanks @raineorshine
As late-introduced changes in the 3.x release, this should no longer be an issue since the autolink features have been removed. If you're still running into this issue, please reopen. Thanks @raineorshine!
Hi @raineorshine , did you solve your problem for library linking to itself?
I am using Truffle v4.1.13 (core: 4.1.13)/Solidity v0.4.24 (solc-js) and I get this error when try to deploy MyLib:
Error: MyLib contains unresolved libraries. You must deploy and link the following libraries before you can deploy a new version of MyLib: MyLib
at /usr/lib/node_modules/truffle/build/webpack:/packages/truffle-contract/contract.js:371:1
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
@sebasgoldberg I think I had to put the library in a separate file and import it.
@raineorshine, thanks for your response, but I am already have the library in a separate file.
I think it is not possible yet a 'use' statement inside a library that references to itself:
library MyLib{
...
use MyLib for MyType;
...
}
I tried to deploy your example in remix, and was not possible.
If I remove the 'use' statement inside the library, and pass 'self' as parameter (inside the library too), then the deploy is possible.
@sebasgoldberg That's too bad. It's a good syntax. You may have to use the normal syntax instead. :)