Нашел интересную статью о метаданных в смарт контрактах. Я, вроде как, за три года ведения канала ни разу толком о них не писал, поэтому разберем эту тему на простых примерах.
Когда solidity генерирует байткод для развертываемого смарт-контракта, он добавляет метаданные о компиляции в конец байткода. Мы рассмотрим данные, содержащиеся в этом байткоде.
Давайте посмотрим на вывод компилятора простейшего смарт-контракта solidity:
//SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
contract Empty {
constructor() payable {}
}
Контракт буквально ничего не делает. Мы можем скомпилировать его, чтобы увидеть код инициализации с помощью
solc --optimize-runs 1000 --bin contractFile.sol
Мы получим следующий вывод:
======= contractFile.sol:Empty =======
Binary:
6080604052603e80600 f5f395ff3fe60806040525f80fdfea26469706673582212203082dbb4f4db7e5d53b235f44d3e38f839dc82075e2cda9df05b88e6585bca8164736f6c63430008140033
Это кажется ужасно большим для контракта, который ничего не делает, верно? Давайте разберемся, что представляет собой весь этот байткод.
Когда мы компилируем код с помощью
solc --optimize-runs 1000 --bin --no-cbor-metadata contractFile.sol
мы получаем следующий результат:
======= contractFile.sol:Empty =======
Binary:
6080604052600880600 f5f395ff3fe60806040525f80fd
Это гораздо меньше! Но что же это за дополнительная информация?
Метаданные Solidity
По умолчанию компилятор Solidity добавляет метаданные в конец «фактического» initcode, который сохраняется в блокчейне после завершения выполнения конструктора. Ниже приведен «дополнительный» код:
fea26469706673582212203082dbb4f4db7e5d53b235f44d3e38f839dc82075e2cda9df05b88e6585bca8164736f6c63430008140033
Последние два байта 0033 означают «посмотрите назад на 0x33 байта, это метаданные». Это относится ко всему коду между ведущим fe (который является операционным кодом INVALID) и конечным 0033. Мы можем проверить, что это действительно 0x33 байта.
# fe and 0033 are not included
>>>hex(len('a26469706673582212203082dbb4f4db7e5d53b235f44d3e38f839dc82075e2cda9df05b88e6585bca8164736f6c6343000814') // 2)
# '0x33'
Так что же это за строка 0x33 (51 decimal)?
Мы можем получить подсказку, если внесем в исходный код одно крошечное, казалось бы, несущественное изменение. Это изменение - буквально дополнительный комментарий:
//SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
contract Empty {
// nothing
constructor() payable {}
}
На скриншоте выше показаны результаты до и после.
А как они расшифровываются, узнаем из следующего поста.
#metadata
