В контракте (только демо) у меня есть:
struct Bank {
string name;
mapping(address => uint) balances;
}
mapping(address => uint) userIsAtBank;
Bank[] banks;
Теперь я хотел бы иметь функцию, которая копирует сопоставление userIsAtBank/банков массива, не проходя через него (как все значения в одном возврате), и устанавливает новое сопоставление с теми же значениями. В моем примере: userIsAtBankNew = userIsAtBank - и:banksNew=banks. Это возможно?
Если это невозможно, как лучше всего пройти длину 25 000 (если, например, последним банком являетсяbanks[25000]), чтобы транзакция не была отклонена или не была слишком дорогой?
Вы на правильном пути, поскольку вы думаете об увеличении затрат.
Возможно, вам удастся немного сдвинуть ограничение с повышением эффективности, но единственный способ решить проблему — пересмотреть подход, чтобы каждая транзакция выполнялась за O(1)... одну операцию.
Предлагаемый подход не совсем блокчейн. Предположим, что клиент Алиса получает список из 25 000 банков. Зачем ей снова приносить его? Если она слушает журналы событий, то узнает о банке номер 25 001, когда он будет добавлен. Зачем ей спрашивать?
Вы можете использовать двухсторонний подход.
Взгляните на Mapped Struct with Index здесь: Существуют ли хорошо решенные и простые шаблоны хранения для Solidity?
Структура данных начинается точно по вашему шаблону. Далее следуют функции для работы с отдельными экземплярами за раз. Объяснение с обоснованием и более полным примером здесь: https://medium.com/@robhitchens/solidity-crud-part-1-824ffa69509a
Надеюсь, поможет.
ps Я должен упомянуть, что невозможно перечислить или подсчитать ключи в a mapping
или передать сопоставления одним глотком. Вы можете сделать это с динамическими массивами, но это не полностью поддерживается и не работает между контрактами. По одной строке за раз позволяет избежать ограничений и проблем с масштабированием.