Каким образом хеширование sha3 /keccak256 в Solidity?

Это не вопрос о проблеме с Ethereum, используя нестандартный sha3 . Я нашел нужную библиотеку хэширования JS и могу получить соответствующие хэши в JS и Solidity на байтовых строках. Мне интересно, как представить uint при передаче его в JS-хэш-lib, чтобы он приводил к тому же хешу, который был создан Solidity sha3.

JS
'0x' + keccak(
  1
)
// 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470

Solidity
sha3(
  1
);
// 0x5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2
19 голосов | спросил Jehan 4 AMpMon, 04 Apr 2016 04:53:13 +030053Monday 2016, 04:53:13

3 ответа


21

Ответ Jehan велик, но нам нужно объяснить еще одно: почему в sha3(1) создается b10e2d...fa0cf6?

Это связано с тем, что функция sha3 твердости хеширует свои входы на основе типов аргументов . Таким образом, значение 1 будет генерировать другой хеш, если он будет сохранен как bytes8, bytes16, bytes32 и т. Д. Поскольку sha3(1) передается 1 как числовой литерал, он преобразуется в наименьший необходимый тип, uint8 1 .

8 бит вписываются в 2 шестнадцатеричных символа, поэтому, если вы вставляете свой ввод в 2 символа, вы получите тот же результат в web3:

Javascript:

web3.sha3(leftPad((1).toString(16), 2, 0), { encoding: 'hex' })
// 5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2

Аналогично, вы можете указать номер на стороне прочности:

монолитность:

// uint is equivalent to uint256
sha3(uint(1))
// b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6

Javascript:

// note that the value is padded by 64 characters to fit 256 bits
web3.sha3(leftPad((1).toString(16), 64, 0), { encoding: 'hex' })
// b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6

Заметка о типах BigNumber:

Они не работают автоматически с web3.sha3. Сначала вы должны преобразовать их в шестнадцатеричный.

монолитность:

sha3(uint(100 ether))
// c7cc234d21c9cfbd4632749fd77669e7ae72f5241ce5895e410c45185a469273

Javascript:

// the .slice is to remove the leading '0x'
web3.sha3(leftPad(web3.toHex(web3.toWei(100)).slice(2).toString(16), 64, 0), { encoding: 'hex' })
// c7cc234d21c9cfbd4632749fd77669e7ae72f5241ce5895e410c45185a469273

EDIT:

Я написал небольшую библиотеку, которая предоставляет версию web3.sha3, которая точно соответствует поведению sha3 в Solidity. Надеюсь, это очистит все ваши хеширующие беды :). https://github.com/raineorshine/solidity-sha3

ответил Raine 16 J000000Saturday16 2016, 17:13:45
8

Сопротивление использует значения HEX внутри.

> web3.sha3(web3.toHex(1))
"5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2"
ответил anton44eg 4 PMpMon, 04 Apr 2016 12:55:25 +030055Monday 2016, 12:55:25
7

Функция sha3 для Solidity хэширует байтовое представление uint. То есть число в шестнадцатеричном виде (основание 16), заполненное до 32 байтов. 32 пустых байта в шестнадцатеричном представлении - 64 нули.

Чтобы сделать это в JS, мы можем использовать печально известный пакет левой панели:

const jsHashWeb3 = web3.sha3(leftPad((1).toString(16), 64, 0), { encoding: 'hex' })
// b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6
ответил Jehan 4 Mayam16 2016, 08:15:32

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132