Принадлежность к набору строк

Я ищу солидную помощь в хранении набора строк и проверке членства в этом наборе. У меня есть конкретный и абстрактный вопрос по этому поводу:

Конкретный

Какова структура данных в Solidity, которая дает мне набор (возможно, только для добавления), который я могу запросить на членство? например, я ищу конкретно что-то вроде:

myset = ["a", "b", "c"] # registers my set on-chain
"d" in myset            # return True or False

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

Изменится ли ответ, если mysetбудет миллион членов?

Абстрактный

Как такая штука реализована под капотом? Проверка доступа на чтение для членства кажется возможной, но поскольку цепочки неизменяемы, как практически обновлять такой список?

Ответы (1)

А mapping- это все, что вам нужно:

pragma solidity ^0.4.25;

contract Test { 
    mapping(string => bool) seen;

    function add(string foo) external {
        seen[foo] = true;
    }

    function alreadySeen(string foo) external view returns (bool) {
        return seen[foo];
    }
}

Хранилище контрактов является изменяемым. Называть блокчейн «неизменяемым», возможно, вводит в заблуждение… лучше использовать термин «только добавление». Отправляя новые транзакции в смарт-контракт, вы можете добавить их в блокчейн, и состояние в последнем блоке может отличаться от состояния в предыдущих блоках. Таким образом, все старые блоки все еще существуют и неизменяемы, но текущее состояние вашего хранилища смарт-контрактов может меняться с течением времени (поскольку «текущий» означает последний блок).

Обратите внимание, что ключи a mappingнельзя перечислить. Если вам нужно перечислить значения, которые вы добавили в свой набор, у меня есть сообщение в блоге о перечисляемых наборах, которое должно помочь: https://programtheblockchain.com/posts/2018/06/03/storage-patterns-set/ .