Копировать состояние из одного контракта в другой

Я экспериментирую с обновляемыми контрактами zeppelin os, но для моего контракта мне нужно только сохранить один конкретный массив состояний при развертывании на другой адрес. Избегайте проблем с прокси, обновляйте фреймворки и тому подобное, есть ли способ сделать это вручную?

Ответы (1)

Это всего лишь грубый набросок, чтобы дать вам некоторые идеи о разделении проблем в простой обновляемой структуре.

  • Во-первых, очень простой Ownedконтракт на передаваемое управление доступом.
  • Затем Keeperконтракт, предназначенный для хранения массива во время обновлений.
  • Эта версия Replaceableразвертывает свои собственные, Keeperчтобы начать работу. Тем самым Keeperпризнается, что Replaceableявляется владельцем, а не разработчиком.
  • Чтобы фактически заменить Replaceable, вы должны сначала развернуть его новую версию. В случае замены конструктор не будет создавать новый Keeper. Вместо этого вы должны передать адрес существующего Keeper и использовать keeper = Keeper(keeperAddress);Конечно, Keeperсначала будет игнорироваться новый контракт, поскольку он не «владеет» хранилищем данных. Вы говорите старому Replaceable, чтобы оно спустило курок и передало право собственности от себя.

-

pragma solidity 0.4.24;

contract Owned {

    address public owner;

    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }

    constructor() public {
        owner = msg.sender;
    }

    function changeOwner(address newOwner) public onlyOwner returns(bool success) {
        owner = newOwner;
        return true;
    }
}

contract Keeper is Owned {

    bytes32[] public array;

    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }

    constructor() public {
        owner = msg.sender;
    }

    function appendArray(bytes32 value) public onlyOwner returns(uint arrayLength) {
        uint length = array.push(value);
        return length;
    }
}

contract Replacable is Owned {

    Keeper keeper;

    constructor() public {
        keeper = new Keeper();
    }

    function getKeeperAddress() public view returns(address keeperAddress) {
        return address(keeper);
    }

    function appendInKeeper(bytes32 value) public onlyOwner returns(uint arrayLength) {
        return keeper.appendArray(value);
    }

    function inspectInKeeper(uint row) public view returns(bytes32 value) {
        return keeper.array(row);
    }

    function appointNewReplacable(address newContract) public onlyOwner returns(bool success) {
        return keeper.changeOwner(newContract);
    }

}

Я опустил довольно много деталей, чтобы пример был точным.

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

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