0

Is there a way for a Solidity contract to programmatically find out another solidity Contract's address?

Right now I'm letting Contract A know about Contract B by hard-coding the address of B into the constructor of A, like so:

BContract = MyNFT721(0xA8978c16E9640508947A93B4Df5b49c8740B752D);

But every time I make edits/updates to B I have to redeploy it, which means it gets a new address - and then A can no longer find it.

It'd be great if A could programmatically find the newly updated address of B, cause right now I have to deploy them separately, deploying B first, then getting its new Address, then hard-coding this new address into A, and then redeploying A.

Its kinda crazy.

(same thing for the ABI's by the way: every time I do an update, I have to copy-paste the new ABI into the calling contract's code...)

=======================

UPDATE:

I resorted to using the Migrations approach - but from past experience I wouldn't recommend it for deploying to the mainnet. I just remember it kept error'ing out. I think it had to do with how long it was taking for Blocks to be approved/mined.

Remember that Contract 1 has to be deployed first, at which point its address becomes known and available - and can then be passed into Contract 2, which is the next contract in the Migration files cue to be deployed.

So they're basically chained to one another.

But if the first deployment times out - or anything else goes wrong or "too long" with it, the 2nd. deployment will suffer/fail.

So while this solution works well for development - meaning deploying contracts locally to Ganache, it has NOT worked for me on live MainNet deployment.

But I supposed that when you get to that last "MainNet" stage (or even Ropsten or Rinkeby) - after thoroughly testing everything out locally, you can then just do your deployment manually, one contract at a time - and be good to go.

1

Yes and no.

It's not going to be able to discover it without help. Probably the most common approach is to pass this information into the constructor, like this:

contract MyNFT721 { 
  ...
}

contract BContract {
  MyNFT721 myNft;

  constructor(address nft) public {
    myNFT721 = MyNFT721(nft);
  }
}

You can also set up periodic changes to linked contracts:

In MyNFT721:

BContract bContract;

function changeBContract(address newB) public onlyOwner {
  bContract = BContract(newB);

You can also coordinate the deployment with truffle migration scripts such that the deployed address MyNFT721 is passed into the deploy transaction when BContract gets created.

Roughly ...

...
deployer.deploy(MyNFT721)
.then(function() {
 deployer.deploy(BContract, MyNFT721.deployed().address);
 ...

If MyNFT721 needs to know where the new BContract is from time to time, then the script can carry on:

var myNft;
MyNFT721.deployed().then(function(instance) { 
  myNFT = instance;
  myNFT.changeBContract(BContract.deployed()); // you have to add this function
  ...

I like to check that there was no obvious oversight by having the client confirm that the address is indeed the expected type of contract. Here's a crude check:

In MyNFT721:

function isMyNFT721() public pure returns(bool isIndeed) {return true;}

In BContract:

constructor(address nft) public {
  myNFT721 = MyNFT721(nft);
  require(myNFT721.isMyNFT721());
}

It's not impossible for an imposter to mimic that we should be the only ones doing the deploying. This is sufficient to catch cases where we missed it (address(0)) or cases where we provided an address but it's not the contract it's supposed to be.

Hope it helps.

  • Thank you. Didn't realize there were so many options - I'll see which - if any - actually work. I also hinted at creating a contract using the ABI created in the .json file - but that's a separate question. Would love your thoughts on it as well - I posted it here: ethereum.stackexchange.com/questions/67876/… – Stanster Mar 4 at 0:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.