Как стать автором
Обновить

Деревья Меркла и экономия газа в смарт-контрактах Solidity

Время на прочтение13 мин
Количество просмотров3.4K
Всего голосов 8: ↑6 и ↓2+4
Комментарии7

Комментарии 7

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

Так и почему?

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

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/MerkleProof.sol#L220

С уважением!

Ситуция: мы хотим проверить, зашиврован ли хэш C в корневом корневом хэше H(AH), тогда функция verify будет принмать следующие аргументы:

proof - массив [ D, H(AB), H(EH) ]

root - H(AH), то есть сам коревой хэш, в котором мы проверяем наличие хэша C

leaf - хэш C, наличие которого мы проверяем.

Функция verify внутри себя обращается к processProof, если она вернет хэш, который равен целевому хэшу значит верификция прошла успешно, и хэш leaf действительно захеширован в root.

а там же проверяется, что [ D, H(AB), H(EH) ] входят в дерево ?
(ну или хотя бы [ H(AB), H(EH) ])

... или все строится просто на том, что вам будет трудно сконструировать хеши для попадания в целевое число root - H(AH) ?

"а там же проверяется, что [ D, H(AB), H(EH) ] входят в дерево" - не совсем так, проверяется, что входит хэш C, а [ D, H(AB), H(EH) ] это промежуточные узлы, через которые можно восстановить корневой хэш, и уже если восстановленный хэш равен root, то верификация на наличие C пройдена успешно

проверяющий же предоставляет и С и все остальное - почему там должны быть  [ D, H(AB), H(EH) ] а не  [ С1, С2, С3 ] , такие что H(C3, H(C2, H(C1, C))) == root ?
или рассчет на то, что будет трудно найти пару Сх, Су такую что Н(Сх, Су) == root ?

PS: я думаю, что если для Н найдется нулевой элемент Н0 ,такой что Н(Н0, Х) == Х и я вам передаю все эти параметры кроме root, то задача подделки сведется только к составлению блока, у которого хеш равн root, а остальные [ D, H(AB), H(EH) ] я вам передам как [ Н0, H0, H0 ]

Отправитель может предоставить все, что угодно, в примере на месте C был msg.sender, то есть адрес самого отправителя. На место C msg.sender ставится строго всегда, и мы таким образом проверяем, есть ли msg.sender в вайтлисте.

По этой причине подделку нельзя совершить, потому что в конечном итоге смотрится наличие в root адреса откуда была отправлена транзакция.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории