Читая код geth и различные сообщения здесь, я думаю, что теперь хорошо понимаю, как данные хранятся в Ethereum (пожалуйста, поправьте меня, если я ошибаюсь в какой-то момент).
На самом низком уровне у нас есть база данных ключ-значение
На следующем уровне у нас есть общая структура данных, называемая trie.
А на уровне блокчейна Ethereum у нас есть что-то вроде (названы только соответствующие части):
block -> state trie -> account* -> storage trie
[Q1] : Для проверки состояния пути представляют адреса учетных записей. Каковы пути в хранилище? Индексы хранения?
[Q2] : Если у нас есть простой контракт в форме:
contract C {
uint256 public x = 100;
}
Когда мы создаем два экземпляра этого контракта. Будет ли у них одинаковый корневой хэш хранилища? Если да, будут ли они совместно использовать одну и ту же пару ключ/значение в базе данных (на самом низком уровне) и, соответственно, один и тот же узел дерева в дереве хранилища?
Для проверки состояния пути представляют адреса учетных записей. Каковы пути в хранилище? Индексы хранения?
Это правильно, за исключением того, что адреса и индексы хэшируются перед сохранением в дереве. Это сделано для защиты от DoS: почему ключи хешируются в Merkle Patricia Trie?
Когда мы создаем два экземпляра этого контракта. Будет ли у них одинаковый корневой хэш хранилища?
Да.
будут ли они совместно использовать одну и ту же пару ключ/значение в базе данных (на самом низком уровне), соответственно один и тот же узел дерева в дереве хранилища?
Да, поскольку корень trie одинаков для обоих контрактов, они совместно используют ключ/значение в базовой базе данных. Поначалу кажется нелогичным или небезопасным, что 2 контракта «разделяют одно и то же хранилище», однако, поскольку структура дерева неизменяема, всякий раз, когда в дерево добавляется новая запись, создается модифицированный экземпляр с собственным корнем. Старое немодифицированное дерево все еще существует в базовой базе данных, и другие контракты все еще могут указывать на него.
Вы можете попробовать создать 2 контракта с одним и тем же хранилищем, а затем прочитать их корни и содержимое хранилища, используя этот код nodejs https://ethereum.stackexchange.com/a/40280/18932 .
Контракты на самом деле имеют корневой хэш хранилища и корневой хэш кода (который является не столько корневым хэшем, сколько обычным хэшем, поскольку код представляет собой один большой двоичный объект). Если два контракта имеют один и тот же код и, следовательно, один и тот же хэш кода, то большой двоичный объект, который соответствует этому хешу, должен быть сохранен в базе данных узлом только один раз, но я не могу сказать, действительно ли они это делают. который.
То же самое и с корневым хэшем состояния контракта, но, поскольку он может меняться от блока к блоку, в базе данных это может быть немного сложнее. Я предполагаю, что он не дублируется, поскольку БД в основном является хранилищем ключей и значений, но я не могу быть уверен.
ивикаа
Медведев1088
ивикаа