If you develop a complex dApp and have to split it into separate individual contracts because of the deployment gas limit, What's a clean process/pattern for deploying and linking the individual contracts together?

  • What i do is to create one contract as "relay" to others. There you keep all addresses to other contracts and when you deploy new/changed contract you just change address of it in relay. Then from there you call functions to related contracts to set new address. – Maxpeinas Aug 23 '18 at 9:14
  • Deploy them one by one. If contract X requires the address of contract Y at construction, then deploy contract Y first, and use its address when deploying contract X. – goodvibration Aug 23 '18 at 9:15
  • The problem of that is that it makes it more difficult/cumbersome for others to verify that a certain source-code matches a particular dApp. Also, how would one nicely automate this process? Truffle Migrations? – matthias_buehlmann Aug 23 '18 at 9:18

Ok so here is how i do it.


contract Relay {

    IOtherContract private otherContractInterface;

    modifier onlyOwner() {
      require(msg.sender == owner, "Sender is not owner");

    function initialize(address _otherContractAddress) external onlyOwner {

        otherContractInterface = IOtherContract(_otherContractAddress);


contract OtherContract {

  address relay;

  modifier onlyRelay() {
      require(msg.sender == relay, "Sender is not relay.");

  function setRelay(address _relay) external onlyOwner {
      relay = _relay;

And then you call OtherContract.setRelay(relayAddress) from your owner account or wrap it in initialize function and call setRelay right after newContract address is set.
EDIT: also use interfaces/abstract classes when accessing contract from other contract, it will save you gas and allow more code to be put into single contract.


If you import one contract into another, the bytecode is just attached at the end. This leads to very big files/bytecodes if you import multiple contracts. What I do is to implement an interface for each contract and then just import this. Then I hardcode the address of the corresponding contracts into the contract that implements them. This ensures there is no way to tamper with the design.

e.g.: (pseudocode)

implements Imycontract2.sol


where Imycontract2.sol is just a dummy with empty implementations of the functions of mycontract2.sol

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.