Возможно ли иметь несколько отображений в одной структуре в Solidity? - PullRequest
0 голосов
/ 08 марта 2019

Я пытаюсь добиться того, чтобы два сопоставления типа структурных значений указывали на одну и ту же ссылку на структуру, поэтому я могу искать и редактировать конкретный экземпляр структуры двумя способами. Однако обновление структуры в одном отображении, по-видимому, не приводит к обновлению структуры в другом. Вот мой упрощенный контракт, чтобы проиллюстрировать идею:

contract Example {
    mapping(uint => Pool) public poolsByDay;
    mapping(uint => Pool) public poolsById;

    constructor(uint day) public {
        for (uint i = 1; i <= day; i++) {
            Pool memory pool = Pool({
                id: i,
                amount: 0
            });

            poolsByDay[i] = pool;
            poolsById[i] = pool; 
        }
    }

    function deposit(uint day, uint amount) external {
        Pool storage pool = poolsByDay[day];
        pool.amount += amount; 
    }
}

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

Вот мой тест:

const example = await Example.new(7)
const day = 1
const amount = 100e18

await example.deposit(day, amount.toString())
const pool = await example.poolsByDay(term)
const anotherPool = await example.poolsById(pool.id)

assert.equal(pool.amount, amount) // succeeded
assert.equal(anotherPool.amount, amount) // failed

Из того, что я понимаю, структура Solidity - это ссылочный тип. Поэтому я ожидаю, что модификация одного пула будет отражена в обоих сопоставлениях poolsByDay и poolsById, но это не так. Неужели я не смог правильно инициализировать два сопоставления?

1 Ответ

1 голос
/ 08 марта 2019

Нет, эти два сопоставления будут указывать на различные структуры, поэтому вам нужно будет обработать косвенное обращение самостоятельно, например, используя сопоставление по дням с идентификатором:

contract Example {
    mapping(uint => uint) public poolsByDay;
    mapping(uint => Pool) public poolsById;

    constructor(uint day) public {
        for (uint i = 1; i <= day; i++) {
            poolsById[i] = Pool({ id: i, amount: 0 });
            poolsByDay[i] = i;
        }
    }

    function deposit(uint day, uint amount) external {
        Pool storage pool = poolsById[poolsByDay[day]];
        pool.amount += amount; 
    }
}

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

...