Сегодня, наконец, поговорим о Chisel.
По правде сказать, для меня он стал неким вызовом: материала по нему крайне мало, а описаний его практического применения и того меньше. Я потратил несколько дней, чтобы по частям собрать этот пост и показать возможности данной программы.
К слову сказать, после всех изысканий я примерно понял, почему так мало информации по нему. В целом, cast команды и remix ide могут полностью заменить его. Но для любителей работать в терминале, chisel может, вполне, стать новым инструментом.
Итак, chisel появляется у нас в системе вместе с установкой Foundry. Это также опенсорсный продукт, который разрабатывается, как я понял, сообществом, а не какой-либо коммерческой компанией.
Для того, чтобы начать с ним работать, достаточно открыть терминал и написать команду
chiselМы войдем в режим работы программы.
Все доступные команды можно посмотреть, как это обычно бывает, с помощью
chisel !helpОбратите внимание, что тут все системные команды начинаются с восклицательного знака.
Из списка не особо понятно, что может делать chisel и как с ним обращаться, поэтому дадим несколько примеров.
1. Математические операции
С chisel можно выполнять не только математические операции, но также и побитовые.
Очень удобно получать значения вычислений побитовых сдвигов влево / вправо, или такие как "побитовое И" или "побитовое ИЛИ".
Достаточно в терминале написать запрос операции, типа:
100 ^ 4Единственное то, нужно быть аккуратными с делением, так как программа эмулирует работу с Solidity. Например, если попытаться выполнить операцию 3/2, то chisel не покажет результата.
100 << 5
2. Работа с ABI
Вы также можете получать зашифрованные данные через abi.encode и keccak256. Например,
abi.encode(256, bytes32(0), "Chisel!")или
keccak256(abi.encode(256, bytes32(0), "Chisel!"))Что классно с chisel, так это то, что он показывает, как это будет храниться в памяти (memory) с указание на поинтеры.
Например, команда выше с abi.encode покажется как:
├ Hex (Tuple Encoded):
├─ Pointer ([0x00:0x20]): 0x0000000000000000000000000000000000000000000000000000000000000020
├─ Length ([0x20:0x40]): 0x00000000000000000000000000000000000000000000000000000000000000a0
└─ Contents ([0x40:..]): 0x000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000743686973656c2100000000000000000000000000000000000000000000000000
3. Переменные в chisel
В chisel можно создавать свои переменные и позже работать с ними. Например, вы можете создать переменную:
uint a = 1;А потом попробовать выполнить математическую операцию, типа:
uint b = a << 0x08;4. Функции и контракты
В chisel вы также можете создавать полноценные контракты и функции в них, а позже отслеживать пути работы!
Создадим простейший контракт прямо в терминале:
contract Test {
function get() external view returns (uint) {
return 256;
}
}
затем потребуется сохранить его в переменную, чтобы можно было позже вызывать функции оттуда:Test t = new Test()Теперь мы можем обращаться к контракту, вызывая функции из него:
t.get()Более того, если мы добавим !traces перед вызовом функции, то сможем получить расшифровку "пути" вызова! Не большой аналог -vvv при тестах в Foundry, кто знает.
5. Получение интерфейсов контрактов с Etherscan
С помощью простой команды мы можем получить интерфейс любого контракта и сохранить его в файле. Однако тут есть ограничения: сохранить можно только интерфейс верифицированных контрактов в сети Ethereum, но вскоре обещают поддержку и других сетей. Команда простая:
!fetch 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 IWETHтут мы указываем адрес контракта, интерфейс которого хотим скачать и название для файла, который будет создан для этого.