It is not possible to deploy a contract to an address of your choice
The address a contract is deployed to is generated deterministically using the address of the deployer and the deployer's total number of transactions (the nonce):
How is the address of an Ethereum contract computed?
This means you can work out the address of the contract before it is deployed:
var ethJsUtil = require('ethereumjs-util');
var futureAddress = ethJsUtil.bufferToHex(ethJsUtil.generateAddress(
yourAddress,
web3.eth.getTransactionCount(yourAddress)));
(from https://stackoverflow.com/a/42416934)
First things first, let's dive into the issue a bit more.
A linked library isn't just another contract deployed in the same ecosystem, it needs to be actively linked to the contract that uses it, as the link above (to the Truffle code for doing so) demonstrates.
Updated Answer
I'll keep the original answer for posterity (not sure why, just kind of feels like the right thing to do), Hardhat (formerly known as Buidler) at this point has an implementation for linking libraries on deploy (code snippet taken from their docs here). Note: This uses the ethers
Hardhat plugin (see link above):
const contractFactory = await this.env.ethers.getContractFactory("Example", {
libraries: {
ExampleLib: "0x...",
},
});
Old Answer
Buidler does not currently (mid-July 2020) have a native shortcut for doing this. An issue has been opened on GitHub, which also has the following workaround in it, also copied and pasted below.
The workaround is preceded by the devs saying that there should be a more direct and simple way to link contracts soon, so it may be worth verifying if they've implemented something for this before using the code below.
const { ethers, config } = require("@nomiclabs/buidler");
const { readArtifact } = require("@nomiclabs/buidler/plugins");
async function main() {
const Library = await ethers.getContractFactory("Library");
const library = await Library.deploy();
await library.deployed();
const cArtifact = await readArtifact(config.paths.artifacts, "Contract");
const linkedBytecode = linkBytecode(cArtifact, { Library: library.address });
const Contract = await ethers.getContractFactory(
cArtifact.abi,
linkedBytecode
);
const contract = await Contract.deploy();
await contract.deployed();
console.log("Contract address:", contract.address);
}
function linkBytecode(artifact, libraries) {
let bytecode = artifact.bytecode;
for (const [fileName, fileReferences] of Object.entries(
artifact.linkReferences
)) {
for (const [libName, fixups] of Object.entries(fileReferences)) {
const addr = libraries[libName];
if (addr === undefined) {
continue;
}
for (const fixup of fixups) {
bytecode =
bytecode.substr(0, 2 + fixup.start * 2) +
addr.substr(2) +
bytecode.substr(2 + (fixup.start + fixup.length) * 2);
}
}
}
return bytecode;
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
If my understanding of the code is correct, you would most likely use this inside /scripts/deploy.js
, which should contain the script for deploying the contracts in your project.
Best Answer
Depends on what is written/codded into the deployed contract.
If there are functions that only the contract owner should be able to call (Like minting or burning tokens, or changing some limits), then this is a serious problem that can't be solved (You might manage to transfer ownership to another address before the other party does it. That might somewhat salvage the situation) But nobody would feel confident using such a contract nor its functions.
If the contract in question only contains the functions that are public and everyone should have access to them anyhow, then there is no effect at all.