Скомпилируйте контракты, которые вызывают друг друга

У меня два контракта, один админ, другой субъект. Для простоты я просто включаю функции, которые вызываются в контрактах, связанных друг с другом.

contract Subject {
  uint public count = 0;

  function increaseCount() returns newCount{
    count ++;
    newCount = count;
  }
}

Субъект контракта имеет счетчик, который можно увеличить с помощью прямого вызова из web3.jsили из Masterконтракта.

contract Master {
  bool public isActive=false;
  uint public num=0;

  function changeState() returns bool newState{
    isActive = !isActive;
    newState = isActive;
  }

  function increaseSubjectCount(subjectAddr) returns uint newCount{
    SubjectContract subjectContract = SubjectContract(subjectAddr);
    newCount = ubjectAddr.increaseCount();
  }
}

Таким образом, транзакция запускается для Masterзаключения контракта (конечно, после того, как она будет совершена) вместе с достаточным количеством газа. Затем эта функция использует газ для вызова increaseCount()функции в Subjectконтракте, который возвращает новый счетчик. Это, в свою очередь, возвращается по Masterконтракту через web3.js. Проблема, с которой я сталкиваюсь, заключается в том, что если я использую твердость браузера для компиляции Masterконтракта, он выдает ошибку о том, что параметр SubjectContract не определен. Если я добавлю оба контракта, а затем скомпилирую код, когда я использую

var myContract = web3.eth.contract(masterContract.abi);не вызовет ли это проблем, если код abi включает в себя код предмета и основного контракта вместе, но если я этого не сделаю, компилятор выдаст кучу ошибок.

Еще одна вещь, которую я рассматривал, — это использование операторов импорта перед компиляцией, но я не уверен, как это безопасно реализовать. Пожалуйста, помогите ребята!

@VarunКак вы получили SubjectAddr? У меня возникли проблемы с импортом контракта, SubjectContract subjectContract = SubjectContract(subjectAddr);потому что я хочу, чтобы он получил адрес сам по себе, например, с помощью Subject.deplyed().addressили что-то в этом роде.
При компиляции с использованием солидности браузера вам необходимо разместить оба контракта вместе. Браузер сгенерирует отдельный байт-код, поэтому вам не нужно об этом беспокоиться. Хотя я не совсем понял ваш вопрос. Что касается subjectAddr, это параметр, который вам нужно знать заранее и передавать как регулярное выражение.
@VarunЯ имел в виду это, потому что у меня есть оба контракта в одном файле, и я *.sol должен получить . Итак, есть ли команда, которую я могу использовать, чтобы мне не приходилось вставлять адрес контракта в трюфель или web3. что-то вродеsubjectAddrSubjectContract subjectContract = SubjectContract(subjectAddr);.address
Не то, что я знаю о. Вы видите, что в моем примере смысл SubjectContract subjectContract = SubjectContract(subjectAddr);заключался в том, чтобы сослаться на существующий контракт по известному адресу и проверить его значения. Итак, если развернуто 100 таких контрактов, я хочу иметь возможность вызывать каждый из них отдельно и проверять его значения из Masterконтракта. Если адрес контракта не будет вставлен, это противоречит цели моей функции. :)
Справедливо! Но я по-прежнему считаю, что если у меня есть один файл Solidity с несколькими контрактами, они должны иметь доступ к основной информации, такой как addressкакой-либо другой контракт в этом файле.
Нет, вы можете получить к нему доступ независимо от того, находится ли он в том же .solфайле или нет. На самом деле я думаю, что вы не сможете получить доступ к адресу другого контракта, если он находится в том же файле, что и основной контракт. Пожалуйста, проверьте это, используя браузер Solidity или тестовую сеть, потому что я уверен, что вы не сможете. Дайте мне знать, если вы можете, хотя.

Ответы (1)

Что вам нужно сделать, так это определить интерфейс SubjectContractконтракта, чтобы Masterконтракт можно было скомпилировать.

Вот ваш Masterконтракт с SubjectContractинтерфейсом вместе с небольшими изменениями:

pragma solidity ^0.4.2;

contract SubjectContract {
    function increaseCount() returns (uint newCount);
}

contract Master {
    bool public isActive=false;
    uint public num=0;

    function changeState() returns (bool newState) {
        isActive = !isActive;
        newState = isActive;
    }

    function increaseSubjectCount(address subjectAddr) returns (uint newCount) {
        SubjectContract subjectContract = SubjectContract(subjectAddr);
        newCount = subjectContract.increaseCount();
    }
}

Отдельно вам придется развернуть следующее SubjectContractс небольшими изменениями:

pragma solidity ^0.4.2;

contract SubjectContract {
    uint public count = 0;

    function increaseCount() returns (uint newCount) {
        count ++;
        newCount = count;
    }
}
Итак, чтобы составить генеральный контракт, я бы скопировал и вставил то, что вы написали в браузере, и скомпилировал его. Но теперь, когда я делаю let myContract = web3.eth.contract(MasterContract.abi)и выполняю это, в коде abi слово contractиспользуется дважды, так как же web3js узнает, что я хочу создать основной контракт, а предметный контракт — это просто интерфейс? Не будет ли путаницы по этому поводу?
Обратитесь к ethereum.stackexchange.com/questions/7488/… . Вы увидите, что существует отдельный abiDefinition для TokenCreator и OwnedToken. Точно так же у вас будут отдельные ABI для разных контрактов.
Да, когда я компилирую в solc, я получаю один abi. Но если у меня есть 3 контракта, которые взаимозависимы друг от друга, то должен ли я помещать все три вместе в browser-solidity и компилировать его три раза, чтобы получить три разных abi?