Вернуть полные сопоставления/массивы

В контракте (только демо) у меня есть:

struct Bank {
    string name;
    mapping(address => uint) balances;
}

mapping(address => uint) userIsAtBank;
Bank[] banks;

Теперь я хотел бы иметь функцию, которая копирует сопоставление userIsAtBank/банков массива, не проходя через него (как все значения в одном возврате), и устанавливает новое сопоставление с теми же значениями. В моем примере: userIsAtBankNew = userIsAtBank - и:banksNew=banks. Это возможно?

Если это невозможно, как лучше всего пройти длину 25 000 (если, например, последним банком являетсяbanks[25000]), чтобы транзакция не была отклонена или не была слишком дорогой?

Ответы (1)

Вы на правильном пути, поскольку вы думаете об увеличении затрат.

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

Предлагаемый подход не совсем блокчейн. Предположим, что клиент Алиса получает список из 25 000 банков. Зачем ей снова приносить его? Если она слушает журналы событий, то узнает о банке номер 25 001, когда он будет добавлен. Зачем ей спрашивать?

Вы можете использовать двухсторонний подход.

  1. Ни одной операции с n итерациями и возрастающей стоимостью. 25 000 операций с фиксированной стоимостью газа - одинаково при любом масштабе. Доставайте их по одному.
  2. Используйте журналы событий, чтобы информировать клиентов обо всех важных изменениях состояния — создание, получение, обновление, удаление. Действительно, прослушивание журналов событий и внесение изменений в локальные таблицы может быть единственной необходимой вам клиентской стороной.

Взгляните на Mapped Struct with Index здесь: Существуют ли хорошо решенные и простые шаблоны хранения для Solidity?

Структура данных начинается точно по вашему шаблону. Далее следуют функции для работы с отдельными экземплярами за раз. Объяснение с обоснованием и более полным примером здесь: https://medium.com/@robhitchens/solidity-crud-part-1-824ffa69509a

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

ps Я должен упомянуть, что невозможно перечислить или подсчитать ключи в a mappingили передать сопоставления одним глотком. Вы можете сделать это с динамическими массивами, но это не полностью поддерживается и не работает между контрактами. По одной строке за раз позволяет избежать ограничений и проблем с масштабированием.