Hi @bonedaddy,
I created an example to show linking with an upgradeable contract.
Can you try updating the way you are linking to this example?
Answer.sol
// contracts/Answer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
library Answer {
function getValue() public returns (uint256) {
return 42;
}
}
Box.sol
// contracts/Box.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "./Answer.sol";
contract Box {
uint256 private value;
// Emitted when the stored value changes
event ValueChanged(uint256 newValue);
// Stores a new value in the contract
function store(uint256 newValue) public {
value = newValue;
emit ValueChanged(newValue);
}
// Reads the last stored value
function retrieve() public view returns (uint256) {
return value;
}
// Stores the answer in the contract
function storeAnswer() public {
value = Answer.getValue();
emit ValueChanged(value);
}
}
Migrations
// migrations/2_deploy.js
const Answer = artifacts.require("Answer");
const Box = artifacts.require("Box");
const { deployProxy } = require('@openzeppelin/truffle-upgrades');
module.exports = async function (deployer) {
await deployer.deploy(Answer);
await deployer.link(Answer, Box);
await deployProxy(Box, [7], { deployer, initializer: 'store', unsafeAllowLinkedLibraries: true });
};
Box.test.js
Implementation unit test
// test/Box.test.js
// Load dependencies
const { expect } = require('chai');
// Load compiled artifacts
const Answer = artifacts.require('Answer');
const Box = artifacts.require('Box');
// Start test block
contract('Box', function () {
beforeEach(async function () {
// Deploy a new Box contract for each test
this.answer = await Answer.new();
await Box.link('Answer', this.answer.address);
this.box = await Box.new();
});
// Test case
it('retrieve returns a value previously stored', async function () {
// Store a value
await this.box.store(42);
// Test if the returned value is the same one
// Note that we need to use strings to compare the 256 bit integers
expect((await this.box.retrieve()).toString()).to.equal('42');
});
it('retrieve returns answer previously stored', async function () {
// Store a value
await this.box.storeAnswer();
// Test if the returned value is the same one
// Note that we need to use strings to compare the 256 bit integers
expect((await this.box.retrieve()).toString()).to.equal('42');
});
});
Box.proxy.test.js
// test/Box.proxy.test.js
// Load dependencies
const { expect } = require('chai');
const { deployProxy, silenceWarnings } = require('@openzeppelin/truffle-upgrades');
// Load compiled artifacts
const Answer = artifacts.require('Answer');
const Box = artifacts.require('Box');
// Start test block
contract('Box (proxy)', function () {
before(async function () {
await silenceWarnings();
});
beforeEach(async function () {
// Deploy a new Box contract for each test
this.answer = await Answer.new();
await Box.link('Answer', this.answer.address);
this.box = await deployProxy(Box, [7], {initializer: 'store', unsafeAllowLinkedLibraries: true});
});
// Test case
it('retrieve returns a value previously initialized', async function () {
// Test if the returned value is the same one
// Note that we need to use strings to compare the 256 bit integers
expect((await this.box.retrieve()).toString()).to.equal('7');
});
it('retrieve returns answer previously stored', async function () {
// Store a value
await this.box.storeAnswer();
// Test if the returned value is the same one
// Note that we need to use strings to compare the 256 bit integers
expect((await this.box.retrieve()).toString()).to.equal('42');
});
});
Tests
$ npx truffle test
Using network 'test'.
Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.
Warning: Potentially unsafe deployment of Box
You are using the `unsafeAllowLinkedLibraries` flag to include external libraries.
Make sure you have manually checked that the linked libraries are upgrade safe.
Contract: Box (proxy)
Warning: All subsequent Upgrades warnings will be silenced.
Make sure you have manually checked all uses of unsafe flags.
✓ retrieve returns a value previously initialized
✓ retrieve returns answer previously stored (70ms)
Contract: Box
✓ retrieve returns a value previously stored (61ms)
✓ retrieve returns answer previously stored (52ms)
4 passing (854ms)