Как развернуть сложное приложение Ethereum, разделенное на несколько контрактов

Если вы разрабатываете сложное dApp и должны разделить его на отдельные отдельные контракты из-за лимита газа развертывания, каков чистый процесс/шаблон для развертывания и связывания отдельных контрактов вместе?

Что я делаю, так это создаю один контракт как «ретранслятор» для других. Там вы сохраняете все адреса других контрактов, и когда вы развертываете новый/измененный контракт, вы просто меняете его адрес в реле. Затем оттуда вы вызываете функции для связанных контрактов, чтобы установить новый адрес.
Разверните их по одному. Если для контракта X требуется адрес контракта Y при построении, то сначала разверните контракт Y и используйте его адрес при развертывании контракта X.
Проблема в том, что другим становится сложнее/обременительнее проверять, соответствует ли определенный исходный код конкретному dApp. Кроме того, как можно красиво автоматизировать этот процесс? Трюфельные миграции?

Ответы (2)

Итак, вот как я это делаю.

Relay.sol:

contract Relay {

    IOtherContract private otherContractInterface;

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

    function initialize(address _otherContractAddress) external onlyOwner {

        otherContractInterface = IOtherContract(_otherContractAddress);
    }
}

OtherContract.sol:

contract OtherContract {


  address relay;

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

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

И затем вы звоните OtherContract.setRelay(relayAddress)из своей учетной записи владельца или оборачиваете ее в initializeфункцию и звоните setRelayсразу после установки адреса newContract.
РЕДАКТИРОВАТЬ : также используйте интерфейсы/абстрактные классы при доступе к контракту из другого контракта, это сэкономит вам газ и позволит поместить больше кода в один контракт.

Если вы импортируете один контракт в другой, байт-код просто прикрепляется в конце. Это приводит к очень большим файлам/байт-кодам, если вы импортируете несколько контрактов. Что я делаю, так это реализую интерфейс для каждого контракта, а затем просто импортирую его. Затем я жестко прописываю адреса соответствующих контрактов в контракт, который их реализует. Это гарантирует, что нет возможности вмешаться в дизайн.

например: (псевдокод)

mycontract1.sol
implements Imycontract2.sol
{

  Imycontract(address).callFunction()
}

где Imycontract2.sol — просто пустышка с пустыми реализациями функций mycontract2.sol