-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Deployed Contracts have no Network when using async/await #713
Comments
I have the same issue.
then it updates only contract1 json file. However, if you rewrite it with Promise chain
then all 3 JSON files are updated with valid addresses I am using |
Ahh, I recently migrated to use ES7 in my truffle scripts, so it sounds like that's the root cause? EDIT: Thanks @olekon, that fixed it. Closing. |
Had the same issue with code
when refactored to
works fine, thanks a lot @olekon |
Is there a reason for this? Is it a bug or intended behavior? I'm experiencing this issue, except that I deploy my contracts across multiple migration scripts; the workaround effectively makes me put everything in one migration script. I'm running Truffle v4.0.5. EDIT: |
Me too. I would swear that this was working in Truffle v4.0.4. |
Had the same issue. Rewriting migrations with Promises fixed my problem. |
This issue needs to be reopened, as the behavior of smart contracts deployment is different when using ES7 async/await syntax, which is totally unexpected. The latest version of Truffle still has this issue. |
Still an issue! |
@cgewecke should we open a new issue for this case? I will consider it pretty critical but possibly not as simple to fix. Thank you!
|
@ZitRos Agree - we're actively working on this for the next release. In my view the issue here is semantic confusion caused by changes in JS norms around async. (Migrations was written before I'd rather not re-open just because it's not a 'bug' per se - it's super counter-intuitive behavior relative to |
@cgewecke, I appreciate your work, thank you for sharing notes on this. I've checked the truffle code, the issue seems to be very trivial. Looks like we just need to await on the [possible] promise returned from fn, because finish() runs synchronously afterwards. If you would like I can make a PR fixing this. |
@ZitRos [EDIT - I just realized - even testing this is going to be an issue because of 6.9.1. I think we'd have to target a higher node version in CI or start using babel - that's something that we've been discussing for the next release.] You're more than welcome to work on a PR - thank you! There's a guide to setting up truffle for development here you might find useful. |
@cgewecke, of course NodeJS 6.9.1 doesn't supports let result = fn(deployer, options.network, accounts);
if (result && typeof result.then === "function") {
result.then(() => finish()).catch(() => "...");
} else {
finish();
} ...instead of calling |
@ZitRos Right, ok excellent. |
@cgewecke, another thing I wanted to catch here right away is that any exceptions thrown in |
@ZitRos I'm not certain about this, apologies. I need to look at the code a bit. . . . |
I had removed all references to What fixed it for me was removing all references to |
Just ran into this same issue, and agree this should be reopened until proper |
Re-opening. |
This is occurring when running truffle test. I believe it is because of the testing "clean-room" environment. const Contract1 = artifacts.require("./Contract1.sol");
const Token = artifacts.require('./Token.sol');
module.exports = function(deployer) {
deployer.deploy(Token).then(() => {
Token.deployed().then((instance) => {
return instance;
}).then((token) => {
deployer.deploy(Contract1, token.address);
});
})
}; The above works fine when deploying to a chain, but I can run tests successfully by giving the test the deployed address. // Instead of
Contract1.deployed()
// say
Contract1.at("0x36a8054476cef7d35251fae816f87e09a49e7e43")
.then((instance) => console.log); The above will display the contract and tests will pass, but the clean-room environment is thus rendered unused. |
@ahester57, I guess it may happen because you missed |
@ZitRos, Now that is something which simply ruins a night. I had to add returns before Token.deployed() and the second deployer.deploy() for tests to work. My question: Why? Why does the migration work fine but the test suite not pick these up? |
@ahester57, I guess that internally, in Truffle, Thus, by returning I guess that the reason of why your code may work during the deployment to the real network is simply because of the delays during deployment (like saving successful migration to the network). Before terminating the process (which in tests happens immediately after promise resolves) transaction gets successfully published to the network. |
- added WRIOOS.sol smart contract - setup webpack with truffle-contract loading JSON(abi) contract - check MetaMask existing - add links to MetaMask download - extend profile dropdown menu with download MetaMask Current problem: empty field "networks" at WRIOOS.json (builded smart contract) [trufflesuite/truffle#713]
We were hit by some the same issue, where strangely enough all our contracts deploy correctly, all of them have a completed network section in the json file, except the Migrations.json. We make heavy use of async/await so I happened on this issue and tried to figure out what was wrong. I started with a clean var Migrations = artifacts.require('./Migrations.sol');
module.exports = function(deployer) {
deployer.deploy(Migrations);
}; Now for the async version, we like to use: var Migrations = artifacts.require('Migrations');
async function performMigration(deployer, network, accounts) {
await deployer.deploy(Migrations);
}
module.exports = function(deployer, network, accounts) {
deployer
.then(() => performMigration(deployer, network, accounts))
.catch(error => {
console.log(error);
process.exit(1);
});
}; This one does not work, nothing in the networks section. ... 🤦♂️ here goes an hour or two of trying things 🤦♂️ ... What I noticed is that it has nothing to do with the async awaits, but with the artifacts.require. var Migrations = artifacts.require('Migrations');
module.exports = function(deployer) {
deployer.deploy(Migrations);
}; This does not work, and this does work: var Migrations = artifacts.require('./Migrations.sol');
async function performMigration(deployer, network, accounts) {
await deployer.deploy(Migrations);
}
module.exports = function(deployer, network, accounts) {
deployer
.then(() => performMigration(deployer, network, accounts))
.catch(error => {
console.log(error);
process.exit(1);
});
}; So, now I only have to figure out why this does work for my other contracts, and not for the Migrations contract. |
Hi @roderik, thanks for this report! Will investigate - at a minimum it looks like Truffle is hard-coding the Migrations.sol path internally here. @gnidan actually just picked this out as potentially problematic in a code review of a Migrations re-write referenced in the link above, although I'm not sure I understand why the resolver isn't handling this correctly. I will add a regression test for this and make sure it's fixed in the new version. |
Hello guys, I deploy ContractA via truffle and as a result, the contracts artifact contains its address. However, I've got a 2nd contract which is not deployed by truffle but within the ContracA's constructor: // ContractA
constructor() public {
contractB = new ContractB();
} I prefer this method over single truffle deployments because it's about 1,000,000 gas cheaper (with Ganache - idk why). And as a side effect A owns B which is what I want. However, as a result, the ContracB's artifact DOES NOT contain it's address. module.exports = function(deployer, network, accounts) {
return deployer.deploy(ContractA).then(() => {
return ContractA.deployed();
}).then(async (contractAInstance) => {
const contractB = await contractAInstance.contractB();
// How to tell truffle about contractB?
});
}; EDIT: solved var ContractA = artifacts.require("ContractA");
var ContractB = artifacts.require("ContractB");
module.exports = function(deployer, network, accounts) {
return deployer.deploy(ContractA).then(() => {
return ContractA.deployed();
}).then(async (contractAInstance) => {
const contractB = await contractAInstance.contractB();
// Update artifact manually
ContractB.address = contractB;
ContractB.transactionHash = ContractA.transactionHash;
});
}; |
So this works: module.exports = function(deployer) {
// You have to use the `then` of the first deployer instance. Do not try to wrap this in async / await
deployer.then(async () => {
console.log('Deploying token')
const token = await deployer.deploy(Token)
console.log('Deploying crowdsale')
const crowdsale = await deployer.deploy(
Crowdsale,
RATE,
TREASURY,
CAP,
token.address
)
console.log('Make crowdsale owner of token')
return token.transferOwnership(crowdsale.address)
})
} So you have to start with one The problem is obviously also that the exported function is not expected to return a promise. You can see this because the following actually works: var Migrations = artifacts.require('Migrations');
module.exports = function(deployer) {
deployer.deploy(Migrations);
}; While I actually would expect only this to work: var Migrations = artifacts.require('Migrations');
module.exports = function(deployer) {
return deployer.deploy(Migrations);
}; So instead of attaching some weird own |
@levino Agree, this has been the source of confusion for a while. truffle@beta includes a fix for it. The migrations can now be written using const One = artifacts.require("One");
const Two = artifacts.require("Two");
module.exports = async function(deployer) {
await deployer.deploy(One);
const one = await One.deployed();
const value = await one.value();
await deployer.deploy(Two, value);
}; |
Looks like this is fixed and released with the rest of v5. Closing this for issue maintenance, but please feel free to let us know and we will re-open. Thank you! |
Issue
When my contracts are deployed using the
truffle migrate --reset
command, none of them have a network in the contract JSON even though the contracts are deployed. This causes the unit tests to fail saying the contract hasn't been deployed to the network.This only happens with the contracts I'm working on as it works fine with different solidity projects.
I've tested the contracts in question on Remix and they deploy fine.
Steps to Reproduce
truffle migrate --reset
truffle test
Expected Behavior
Actual Results
Environment
ℹ️ I can provide access to the repo where the contracts are stored. I'm reluctant to publicly post the source of them until they're ready.
The text was updated successfully, but these errors were encountered: