Доступ к переменным состояния в другом контракте

Я пытался добавить методы в контракт, но он стал настолько большим, что я не мог развернуть его с помощью трюфеля. Теперь мне нужно создать другой контракт, который будет вызываться вместо исходного контракта для обработки данных, хранящихся в исходном контракте, в качестве переменной состояния.

Переменная, которую я собираюсь обработать, является отображением.

Я пытаюсь сделать что-то вроде этого:

contract Original {

mapping(bytes32 => Person) private Persons;

 /* many structs and methods here */
}

contract SecondContract {
   function processdata(){
     /* here i want to process the data stored in the mapping in the first contract */
   }
}

как мне получить связь между двумя контрактами и иметь возможность обрабатывать эти данные?

Ответы (2)

Если я правильно понимаю, вы просто хотите получить доступ к данным, хранящимся в Original. Если это так, вы можете сделать что-то вроде этого:

contract Original {
  mapping(bytes32 => Person) public persons;
}

contract SecondContract {
  Original original;

  function SecondContract(address ofOriginalContract) {
    original = Original(ofOriginalContract);
  }

  function processData(bytes32 someBytes) {
    Person entry = original.persons[someBytes];
    // do something with entry
  }
}

Обратите внимание, что я сделал personsсопоставление public, поэтому мы можем получить к нему доступ из другого контракта.

Это то, что я уже сделал, но проблема в том, что я не могу больше ничего добавить к своему контракту, потому что он не будет развернут на ganache-cli (из-за размера). поэтому добавление второго контракта рядом с исходным контрактом не будет отличаться от добавления processDataфункции к исходному контракту.

Усиление ответа @Travis.

Эта линия

Original original;

добавляет значительный размер, SecondContractпотому что он содержит файлы Original .

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

Есть некоторые сложные проблемы наследования и приведения типов, которые нужно распутать, чтобы SecondContractможно было наследовать наименьшее возможное представление Originalплощади поверхности (но не рабочий код), и оба контракта могут быть идеально синхронизированы в отношении макета Person. Решил для тебя поковыряться. Вы можете экстраполировать это на более сложную ситуацию.

SecondContractбудет намного меньше, потому что interfacesон наследует никогда не станет очень большим.

pragma solidity 0.8.1;

interface Types {
  struct Person {
    uint age;
    string name;
  }    
}

interface IOriginal is Types {
  function persons(bytes32) external view returns(uint, string memory);
}

contract Original is IOriginal {
  mapping(bytes32 => Person) public override persons;
}

contract SecondContract is Types {
  IOriginal original;

  constructor(address ofOriginalContract) {
    original = IOriginal(ofOriginalContract);
  }

  function processData(bytes32 someBytes) public {
    (uint age, string memory name) = original.persons(someBytes);
    // do something with entry
  }
}

Было бы более удовлетворительно, если бы function persons()он вернул a Personвместо членов, structно у меня не получилось. Возможно, добрая душа подскажет решение.

Надеюсь, поможет.