Работа с памятью в Solidity. Большой сборник
На канале было уже достаточно много постов про работу памяти. Пришло время собрать все в один пост, чтобы вы могли сохранить себе сборник материалов, к которым можно обращаться в любой момент.
Новички смогут получить первое представление об этом разделе языка, а более продвинутые разработчики напомнить себе некоторые нюансы.
На русском языке:
1. Большая заметка канала по работе с памятью. Тут я собрал краткие сведения по storage, memory, stack и code для удобства.
2. Структура. Хранение данных. Видео с канала Ильи
3. Memory и calldata. Видео с канала Ильи
4. Динамические массивы и мэппинги в storage. Видео с канала Ильи
На английском языке:
5. Solidity Tutorial: All About Stack
6. Understanding Ethereum Smart Contract Storage
7. Solidity Tutorial: All About Calldata
8. Solidity Tutorial: All About Code
9. Solidity Tutorial: All About Memory
10. All About Solidity Data Locations — Storage
11. Solidity Tutorial: All About Data Locations
12. Guide To Advanced Calldata
Доскональное изучение материалов может занять пару недель, но без этого будет сложно понимать внутреннюю работу смарт контрактов и проводить аудит.
Приятного обучения и хорошей недели!
#storage #memory #stack #code #calldata
На канале было уже достаточно много постов про работу памяти. Пришло время собрать все в один пост, чтобы вы могли сохранить себе сборник материалов, к которым можно обращаться в любой момент.
Новички смогут получить первое представление об этом разделе языка, а более продвинутые разработчики напомнить себе некоторые нюансы.
На русском языке:
1. Большая заметка канала по работе с памятью. Тут я собрал краткие сведения по storage, memory, stack и code для удобства.
2. Структура. Хранение данных. Видео с канала Ильи
3. Memory и calldata. Видео с канала Ильи
4. Динамические массивы и мэппинги в storage. Видео с канала Ильи
На английском языке:
5. Solidity Tutorial: All About Stack
6. Understanding Ethereum Smart Contract Storage
7. Solidity Tutorial: All About Calldata
8. Solidity Tutorial: All About Code
9. Solidity Tutorial: All About Memory
10. All About Solidity Data Locations — Storage
11. Solidity Tutorial: All About Data Locations
12. Guide To Advanced Calldata
Доскональное изучение материалов может занять пару недель, но без этого будет сложно понимать внутреннюю работу смарт контрактов и проводить аудит.
Приятного обучения и хорошей недели!
#storage #memory #stack #code #calldata
👍10🐳3🔥1💯1
Чаты и каналы
На этом канале чаще всего вы могли видеть рекомендации зарубежных аккаунтов из Твиттера, на которые можно подписаться и следить за интересными новостями из мира блокчейна и Solidity. Телеграм каналы, которые я находил и подписывался, через некоторое время прекращали свою деятельность или копипастили чужие посты. Их рекомендовать совсем не хотелось.
Сегодня поделюсь с вами некоторыми чатами и каналами, которые ведутся уже долгое время. В чатах вы можете задавать свои вопросы - не думайте, что вопрос может быть глупым или неуместным, если он поможет вам хоть немного разобраться в теме. За весь год, я еще ни разу не встретил такого пользователя в чате, который бы насмехался над проблемой. Все очень дружелюбны к новичкам и готовы дать дельный совет или поделиться ресурсом для прокачки своих навыков.
Ну, а каналы, скорее про безопасность, на английском языке. Просто нравится подача материала там.
Итак, поехали:
Чаты на тему разработки:
1. Solidity DEV (Ethereum)
2. Ethereum Ru - самый большой чат
3. Ethereum Newbie
4. Ethereum — Jobs & CVs - тут, кстати, можно найти вакансии
5. крипта и web3 чат
6. Learn solidity audit - тут можно задавать вопросы по аудиту и безопасности
7. DEV: Рубиновые тона: ЧАТ - чат от канала Ильи
Пара классных каналов:
8. Kotya security
9. Rektoff Foundation
10. DEFI Scam Check
11. Officer's Channel
Не бойтесь задавать вопросы и знакомиться. В ру сегменте дружелюбное сообщество!
#chat
На этом канале чаще всего вы могли видеть рекомендации зарубежных аккаунтов из Твиттера, на которые можно подписаться и следить за интересными новостями из мира блокчейна и Solidity. Телеграм каналы, которые я находил и подписывался, через некоторое время прекращали свою деятельность или копипастили чужие посты. Их рекомендовать совсем не хотелось.
Сегодня поделюсь с вами некоторыми чатами и каналами, которые ведутся уже долгое время. В чатах вы можете задавать свои вопросы - не думайте, что вопрос может быть глупым или неуместным, если он поможет вам хоть немного разобраться в теме. За весь год, я еще ни разу не встретил такого пользователя в чате, который бы насмехался над проблемой. Все очень дружелюбны к новичкам и готовы дать дельный совет или поделиться ресурсом для прокачки своих навыков.
Ну, а каналы, скорее про безопасность, на английском языке. Просто нравится подача материала там.
Итак, поехали:
Чаты на тему разработки:
1. Solidity DEV (Ethereum)
2. Ethereum Ru - самый большой чат
3. Ethereum Newbie
4. Ethereum — Jobs & CVs - тут, кстати, можно найти вакансии
5. крипта и web3 чат
6. Learn solidity audit - тут можно задавать вопросы по аудиту и безопасности
7. DEV: Рубиновые тона: ЧАТ - чат от канала Ильи
Пара классных каналов:
8. Kotya security
9. Rektoff Foundation
10. DEFI Scam Check
11. Officer's Channel
Не бойтесь задавать вопросы и знакомиться. В ру сегменте дружелюбное сообщество!
#chat
🔥13👍5❤1
🌟🌟🌟 День Рождения канала! 🌟🌟🌟
Сегодня ровно год, как был создан этот канал!
Когда только появилась идея учить Solidity в группе, я был абсолютно уверен, что это будет всего лишь до конца лета. Открывая канал, я был в полной уверенности, что к осени закрою его. Но все пошло куда интереснее!
На сегодняшний момент вышло более 800 постов! Практически 2,5 поста в день в течение года! Да, у меня были и недельные каникулы тишины на канале, но порой тут выходило и по 18 постов в день. До сих пор не могу поверить!
За этот год вместе с вами я прошел путь с нуля до аудитора, ежедневно обучаясь шаг за шагом. Возможно, это лучшее подтверждение принципа "Лучше регулярно, чем интенсивно".
Хочу сказать спасибо всем вам за то, что были всегда рядом: давали советы, делились ресурсами, поправляли множество моих постов и много чего еще. Здесь я нашел свое сообщество, многие из вас стали моими коллегами в сфере аудита!
Я хочу пожелать вам не останавливаться в обучении, познавать новые грани языка и блокчейна, каждый день продвигаться хоть на чуть-чуть. Так или иначе в ру сегменте блокчейн и Solidity еще в ранней стадии формирования сообществ и направлений, и вы можете стать одними из первых.
С Днем Рождения, друзья!
Сегодня ровно год, как был создан этот канал!
Когда только появилась идея учить Solidity в группе, я был абсолютно уверен, что это будет всего лишь до конца лета. Открывая канал, я был в полной уверенности, что к осени закрою его. Но все пошло куда интереснее!
На сегодняшний момент вышло более 800 постов! Практически 2,5 поста в день в течение года! Да, у меня были и недельные каникулы тишины на канале, но порой тут выходило и по 18 постов в день. До сих пор не могу поверить!
За этот год вместе с вами я прошел путь с нуля до аудитора, ежедневно обучаясь шаг за шагом. Возможно, это лучшее подтверждение принципа "Лучше регулярно, чем интенсивно".
Хочу сказать спасибо всем вам за то, что были всегда рядом: давали советы, делились ресурсами, поправляли множество моих постов и много чего еще. Здесь я нашел свое сообщество, многие из вас стали моими коллегами в сфере аудита!
Я хочу пожелать вам не останавливаться в обучении, познавать новые грани языка и блокчейна, каждый день продвигаться хоть на чуть-чуть. Так или иначе в ру сегменте блокчейн и Solidity еще в ранней стадии формирования сообществ и направлений, и вы можете стать одними из первых.
С Днем Рождения, друзья!
🔥37❤7❤🔥2🎉2
Интересный баг в протоколе EigenLayer
Недавно вышел отчет с конкурсного аудита протокола EigenLayer, до которого я смог добрать только сейчас. И вот помимо остальных проблем, найденных в его контрактах, мне приметился один забавный... если можно так сказать.
Вот ссылка на него.
Дело в том, что разработчики создавали цикл for и уже внутри него были условия if/esle. И если для условия else они поставили ++i, т.е. переход на следующий шаг цикла, то для if условия - забыли. В итоге получилось, что цикл исполнялся один раз в if, что приводило к проблемам в дальнейшем коде.
Много раз встречал, что для экономии газа, инкремент прохода в цикл лучше ставить в unchecked в конце кода вместо установки его в аргументах for, но никогда не задумывался, что может однажды случиться такой прецедент.
Будьте внимательны с циклами!
#for #loop
Недавно вышел отчет с конкурсного аудита протокола EigenLayer, до которого я смог добрать только сейчас. И вот помимо остальных проблем, найденных в его контрактах, мне приметился один забавный... если можно так сказать.
Вот ссылка на него.
Дело в том, что разработчики создавали цикл for и уже внутри него были условия if/esle. И если для условия else они поставили ++i, т.е. переход на следующий шаг цикла, то для if условия - забыли. В итоге получилось, что цикл исполнялся один раз в if, что приводило к проблемам в дальнейшем коде.
Много раз встречал, что для экономии газа, инкремент прохода в цикл лучше ставить в unchecked в конце кода вместо установки его в аргументах for, но никогда не задумывался, что может однажды случиться такой прецедент.
Будьте внимательны с циклами!
#for #loop
👍8
Контроль доступа и голосование за предложения
Интересную реализацию задумки голосования встретил в конкурсном протоколе Axelar. Опишу кратко.
В общем, там пользователи могут создавать предложения для последующего голосования за него. Если оно набирает необходимый минимум, то можно перенести в очередь на выполнение.
В обычном подходе делают как-то так: создается предложение, из которого хешируются предлагаемое действие и аргументы. Затем пользователи могут голосовать за него в нужной функции. Там предложение достается из памяти контракта, проверяется и в итоге засчитывают голос пользователя.
В Axelar голосование происходит в модификаторе!
P.S. Я сделаю более упрощенное описание процедуры для понимания ее сути.
Итак, мы создали предложение, из него сформировался уникальный хэш через keccak256 и сохранился где-то в контракте.
Далее авторизованным пользователям можно вызывать функцию, типа как:
function execute(
address target,
bytes calldata callData,
uint256 nativeValue
) external payable onlySigners {
...
}
Обратите внимание на модификатор onlySigners, там и происходит все действие!
modifier onlySigners() {
if (!signers.isSigner[msg.sender]) revert NotSigner();
bytes32 topic = keccak256(msg.data);
Voting storage voting = votingPerTopic[signerEpoch][topic];
if (voting.hasVoted[msg.sender]) revert AlreadyVoted();
voting.hasVoted[msg.sender] = true;
uint256 voteCount = voting.voteCount + 1;
if (voteCount < signers.threshold) {
voting.voteCount = voteCount;
return;
}
voting.voteCount = 0;
uint256 count = signers.accounts.length;
for (uint256 i; i < count; ++i) {
voting.hasVoted[signers.accounts[i]] = false;
}
emit MultisigOperationExecuted(topic);
_;
}
Другими словами, в модификаторе мы проверяем авторизацию пользователя, через аргументы в функции execute мы передаем данные по предложению в msg.data, который позже вытаскивается из памяти контракта.
Далее фиксируется голос пользователя. Если проходного минимума не хватает, то идет return и до выполнения самой функции execute дело не доходит!
Если же голоса набраны, то модификатор делает свое дело и execute срабатывает!
По моему, сделано прикольно! Такого я еще ни разу не видел.
#modifier
Интересную реализацию задумки голосования встретил в конкурсном протоколе Axelar. Опишу кратко.
В общем, там пользователи могут создавать предложения для последующего голосования за него. Если оно набирает необходимый минимум, то можно перенести в очередь на выполнение.
В обычном подходе делают как-то так: создается предложение, из которого хешируются предлагаемое действие и аргументы. Затем пользователи могут голосовать за него в нужной функции. Там предложение достается из памяти контракта, проверяется и в итоге засчитывают голос пользователя.
В Axelar голосование происходит в модификаторе!
P.S. Я сделаю более упрощенное описание процедуры для понимания ее сути.
Итак, мы создали предложение, из него сформировался уникальный хэш через keccak256 и сохранился где-то в контракте.
Далее авторизованным пользователям можно вызывать функцию, типа как:
function execute(
address target,
bytes calldata callData,
uint256 nativeValue
) external payable onlySigners {
...
}
Обратите внимание на модификатор onlySigners, там и происходит все действие!
modifier onlySigners() {
if (!signers.isSigner[msg.sender]) revert NotSigner();
bytes32 topic = keccak256(msg.data);
Voting storage voting = votingPerTopic[signerEpoch][topic];
if (voting.hasVoted[msg.sender]) revert AlreadyVoted();
voting.hasVoted[msg.sender] = true;
uint256 voteCount = voting.voteCount + 1;
if (voteCount < signers.threshold) {
voting.voteCount = voteCount;
return;
}
voting.voteCount = 0;
uint256 count = signers.accounts.length;
for (uint256 i; i < count; ++i) {
voting.hasVoted[signers.accounts[i]] = false;
}
emit MultisigOperationExecuted(topic);
_;
}
Другими словами, в модификаторе мы проверяем авторизацию пользователя, через аргументы в функции execute мы передаем данные по предложению в msg.data, который позже вытаскивается из памяти контракта.
Далее фиксируется голос пользователя. Если проходного минимума не хватает, то идет return и до выполнения самой функции execute дело не доходит!
Если же голоса набраны, то модификатор делает свое дело и execute срабатывает!
По моему, сделано прикольно! Такого я еще ни разу не видел.
#modifier
👍10❤1
Вышла новая версия Solidity - 0.8.21
Вчера была выпущена новая версия Solidity с большим количеством исправлений текущих багов и некоторыми улучшениями. Основные из них это:
1. Доступ к событиям из контракта. Как мы знаем, ранее доступ к событиям можно было получить через специальный журнал событий, используя разные библиотеки, например ethers.js. Теперь контракты могут брать события через emit Contract.EventName() из внешних контрактов/либ/интерфейсов.
2. Упрощения для установки immutable переменных. Ранее имелись проблемы с установкой таких переменных через try/catch или for циклов. Теперь вы также можете указать их значение изначально в контракте, а затем переустановить в конструкторе. Более того были поправлены и другие баги связанные с их инициализацией.
3. Исправлены ошибки в Code Generator и Yul Optimizer.
Вы можете прочитать обо всех изменениях в коде по этой ссылке.
#solidity
Вчера была выпущена новая версия Solidity с большим количеством исправлений текущих багов и некоторыми улучшениями. Основные из них это:
1. Доступ к событиям из контракта. Как мы знаем, ранее доступ к событиям можно было получить через специальный журнал событий, используя разные библиотеки, например ethers.js. Теперь контракты могут брать события через emit Contract.EventName() из внешних контрактов/либ/интерфейсов.
2. Упрощения для установки immutable переменных. Ранее имелись проблемы с установкой таких переменных через try/catch или for циклов. Теперь вы также можете указать их значение изначально в контракте, а затем переустановить в конструкторе. Более того были поправлены и другие баги связанные с их инициализацией.
3. Исправлены ошибки в Code Generator и Yul Optimizer.
Вы можете прочитать обо всех изменениях в коде по этой ссылке.
#solidity
👍13🔥4😱1
Различные abi.encode
В чате участник задавал вопрос про abi.encodeCall и мне захотелось сделать небольшой пост-напоминалку про различные виды кодирования abi. Думаю, многим будет полезно напомнить себе, в чем тут разница и как их использовать.
1. abi.encode - кодирует параметры, используя ABI specs. Сами закодированные параметры занимают по 32 байта. Возвращает байтовый массив данных. Если мы, к примеру, попробуем зашифровать строку "Hello" через abi.encode, то получим следующие зашифрованные данные:
1. Первые 32 байта - это, так называемый, offset (смещение), которые указывает, где начинаются данные.
2. Вторые 32 байта - размер строки.
3. Третьи 32 байта - значение строки.
Пример:
function getEncode(address _add, uint256 _value) pure public returns(bytes memory){
return abi.encode(_add, _value);
}
2. abi.encodePacked - тоже, что и abi.encode, только параметры пакуются, чтобы занимать меньше места. Например, если мы зашифруем туже строку "Hello", то вместо 3 слотов по 32 байта, получим всего 1 слот со значением строки.
function getEncodePacked(address _add, uint256 _value) pure public returns(bytes memory){
return abi.encodePacked(_add, _value);
}
P.S. При этом нужно быть аккуратным с данным видом кодирования, так как тут возможна популярная уязвимость с использованием динамических типов данных. Подробнее тут.
3. abi.encodeWithSignature - тоже, что и abi.encode, но добавляется еще подпись функции, как первый параметр.
function getEncodeWithSignature(address _add, uint256 _value) pure public returns(bytes memory){
bytes memory data = abi.encodeWithSignature("transfer(address,uint)",_add,_value);
return data;
}
4. abi.encodeWithSelector - тоже, что и abi.encode, но добавляется еще селектор функции, как первый параметр. Сам селектор кодируется с помощью keccak256 и берутся первые 4 байта.
function getEncodeWithSelector(address _add,uint256 _value) pure public returns(bytes memory){
bytes4 selector = bytes4(keccak256(bytes("transfer(address,uint)")));
bytes memory data = abi.encodeWithSelector(selector,_add,_value );
return data;
}
5. abi.encodeCall - тоже, что и abi.encode, но добавляет проверку типов данных на соответствие функции, которая была указана в аргументах. Результат кодирования схож с abi.encodeWithSelector.
function encodeCallData(address _to, uint _value) public pure returns (bytes memory) {
return abi.encodeCall(IERC20.transfer, (_to, _value));
}
6. abi.decode() - служит для расшифровывания байтовых массивов указанных выше. Принимает в качестве аргументов байтовый массив и ожидаемые типы данных.
function decodeData(bytes memory data) pure public returns(address, uint256){
(address add, uint256 value) = abi.decode(data, (address,uint256));
return (add,value);
}
Вроде как, вспомнил все abi.encode. Если что-то забыл или успели появиться новые с обновлениями языка, дайте знать в комментах.
#abi #encode
В чате участник задавал вопрос про abi.encodeCall и мне захотелось сделать небольшой пост-напоминалку про различные виды кодирования abi. Думаю, многим будет полезно напомнить себе, в чем тут разница и как их использовать.
1. abi.encode - кодирует параметры, используя ABI specs. Сами закодированные параметры занимают по 32 байта. Возвращает байтовый массив данных. Если мы, к примеру, попробуем зашифровать строку "Hello" через abi.encode, то получим следующие зашифрованные данные:
1. Первые 32 байта - это, так называемый, offset (смещение), которые указывает, где начинаются данные.
2. Вторые 32 байта - размер строки.
3. Третьи 32 байта - значение строки.
Пример:
function getEncode(address _add, uint256 _value) pure public returns(bytes memory){
return abi.encode(_add, _value);
}
2. abi.encodePacked - тоже, что и abi.encode, только параметры пакуются, чтобы занимать меньше места. Например, если мы зашифруем туже строку "Hello", то вместо 3 слотов по 32 байта, получим всего 1 слот со значением строки.
function getEncodePacked(address _add, uint256 _value) pure public returns(bytes memory){
return abi.encodePacked(_add, _value);
}
P.S. При этом нужно быть аккуратным с данным видом кодирования, так как тут возможна популярная уязвимость с использованием динамических типов данных. Подробнее тут.
3. abi.encodeWithSignature - тоже, что и abi.encode, но добавляется еще подпись функции, как первый параметр.
function getEncodeWithSignature(address _add, uint256 _value) pure public returns(bytes memory){
bytes memory data = abi.encodeWithSignature("transfer(address,uint)",_add,_value);
return data;
}
4. abi.encodeWithSelector - тоже, что и abi.encode, но добавляется еще селектор функции, как первый параметр. Сам селектор кодируется с помощью keccak256 и берутся первые 4 байта.
function getEncodeWithSelector(address _add,uint256 _value) pure public returns(bytes memory){
bytes4 selector = bytes4(keccak256(bytes("transfer(address,uint)")));
bytes memory data = abi.encodeWithSelector(selector,_add,_value );
return data;
}
5. abi.encodeCall - тоже, что и abi.encode, но добавляет проверку типов данных на соответствие функции, которая была указана в аргументах. Результат кодирования схож с abi.encodeWithSelector.
function encodeCallData(address _to, uint _value) public pure returns (bytes memory) {
return abi.encodeCall(IERC20.transfer, (_to, _value));
}
6. abi.decode() - служит для расшифровывания байтовых массивов указанных выше. Принимает в качестве аргументов байтовый массив и ожидаемые типы данных.
function decodeData(bytes memory data) pure public returns(address, uint256){
(address add, uint256 value) = abi.decode(data, (address,uint256));
return (add,value);
}
Вроде как, вспомнил все abi.encode. Если что-то забыл или успели появиться новые с обновлениями языка, дайте знать в комментах.
#abi #encode
🔥16🙏1🌭1
Организация storage в прокси контракте
В процессе аудита протокола Arcade встретился лицом к лицу с не совсем обычной организацией storage в контракте. Не совсем обычной для меня. Возможно, более опытные разработчики уже сталкивались с подобной реализацией.
Я могу ошибиться в некоторых моментах описания и прошу поправить меня, если вдруг, что не так.
P.S. В посте будут приведены ссылки на контракты из открытого конкурсного репозитория, актуального на время написания поста.
Итак, у нас есть прокси контакт - NFTBoostVault, который наследует функции от двух библиотек, которые и позволяют работать с памятью контракта так, чтобы при обновлениях не было коллизии в данных - Storage и NFTBoostVaultStorage.
Примечательно здесь то, что базовые типы данных, например address и uint, которые не поддерживают определенные места хранения в storage (как mapping), хранятся в структуре с одноименным названием, например:
struct Address {
address data;
}
Так в конструкторе или функции мы можем установить / обновить для них значения с помощью:
Storage.set(Storage.uint256Ptr("locked"), 1);
где Storage.uint256Ptr("locked") - место в памяти, а 1 - значения для установки.
Или также для типов address:
Storage.set(Storage.addressPtr("manager"), manager);
где manager - тип address из аргументов функции.
Доставать значения из такого слота памяти можно при помощи других функций из библиотеки:
function getIsLocked() public view override returns (uint256) {
return Storage.uint256Ptr("locked").data;
}
т.е. мы запрашиваем в storage слот с хешем uint256Ptr("locked") и достаем оттуда необходимые данные.
Но еще интереснее дела обстоят с работой mapping. Посмотрите на следующий код:
NFTBoostVaultStorage.Registration storage registration = _getRegistrations()[msg.sender];
Здесь мы достаем структурные данные из памяти, которые хранятся в виде mapping! Вот его другие функции:
function _getRegistrations() internal pure returns (mapping(address => NFTBoostVaultStorage.Registration) storage) {
return NFTBoostVaultStorage.mappingAddressToRegistrationPtr("registrations");
}
function mappingAddressToRegistrationPtr(
string memory name
) internal pure returns (mapping(address => Registration) storage data) {
bytes32 offset = keccak256(abi.encodePacked(REGISTRATION_TYPEHASH, name));
assembly {
data.slot := offset
}
}
Я и сейчас на 100% не уверен как работает "под капотом" преобразование данные в _getRegistrations()[msg.sender], так, чтобы получился mapping. Но выглядит интересно.
Solidity не перестает меня удивлять!
В общем, если вас это заинтересовало, то советую самим посмотреть контракты и попробовать чуть лучше разобраться. Буду также рад, если дадите свои комментарии по этому вопросу.
P.S. Отдельное спасибо @elawbek, что помог мне чуть лучше понять, как это все работает.
#storage #mapping #proxy
В процессе аудита протокола Arcade встретился лицом к лицу с не совсем обычной организацией storage в контракте. Не совсем обычной для меня. Возможно, более опытные разработчики уже сталкивались с подобной реализацией.
Я могу ошибиться в некоторых моментах описания и прошу поправить меня, если вдруг, что не так.
P.S. В посте будут приведены ссылки на контракты из открытого конкурсного репозитория, актуального на время написания поста.
Итак, у нас есть прокси контакт - NFTBoostVault, который наследует функции от двух библиотек, которые и позволяют работать с памятью контракта так, чтобы при обновлениях не было коллизии в данных - Storage и NFTBoostVaultStorage.
Примечательно здесь то, что базовые типы данных, например address и uint, которые не поддерживают определенные места хранения в storage (как mapping), хранятся в структуре с одноименным названием, например:
struct Address {
address data;
}
Так в конструкторе или функции мы можем установить / обновить для них значения с помощью:
Storage.set(Storage.uint256Ptr("locked"), 1);
где Storage.uint256Ptr("locked") - место в памяти, а 1 - значения для установки.
Или также для типов address:
Storage.set(Storage.addressPtr("manager"), manager);
где manager - тип address из аргументов функции.
Доставать значения из такого слота памяти можно при помощи других функций из библиотеки:
function getIsLocked() public view override returns (uint256) {
return Storage.uint256Ptr("locked").data;
}
т.е. мы запрашиваем в storage слот с хешем uint256Ptr("locked") и достаем оттуда необходимые данные.
Но еще интереснее дела обстоят с работой mapping. Посмотрите на следующий код:
NFTBoostVaultStorage.Registration storage registration = _getRegistrations()[msg.sender];
Здесь мы достаем структурные данные из памяти, которые хранятся в виде mapping! Вот его другие функции:
function _getRegistrations() internal pure returns (mapping(address => NFTBoostVaultStorage.Registration) storage) {
return NFTBoostVaultStorage.mappingAddressToRegistrationPtr("registrations");
}
function mappingAddressToRegistrationPtr(
string memory name
) internal pure returns (mapping(address => Registration) storage data) {
bytes32 offset = keccak256(abi.encodePacked(REGISTRATION_TYPEHASH, name));
assembly {
data.slot := offset
}
}
Я и сейчас на 100% не уверен как работает "под капотом" преобразование данные в _getRegistrations()[msg.sender], так, чтобы получился mapping. Но выглядит интересно.
Solidity не перестает меня удивлять!
В общем, если вас это заинтересовало, то советую самим посмотреть контракты и попробовать чуть лучше разобраться. Буду также рад, если дадите свои комментарии по этому вопросу.
P.S. Отдельное спасибо @elawbek, что помог мне чуть лучше понять, как это все работает.
#storage #mapping #proxy
🔥6👍4
RACE #19 Of The Secureum Bootcamp
Ранее, в начале июля, прошел 19 Race, создателем которого стал популярных аудитор Pashov. Только сейчас получилось добраться до конкурса из-за большой нагрузки этого лета, и могу сказать, что это довольно интересный тест, скорее, на внимательность, чем знание каких-либо нюансов языка.
У меня получилось 7 из 8 ответов. Для тех, кто будет проходить его рекомендую вчитываться в сами вопросы, так как порой их формирование бывает сложным для понимания.
Ссылка на Race 19.
P.S. На удивление, сейчас мне попадается довольно мало добротного материала для канала, с какими-нибудь интересными тонкостями языка или работы со смарт контрактами. Такое ощущение, что все резко стали пилить контент для начинающих, где повторяются базовые атаки, типа реентранси, и экономия газа в упаковке переменных. Если вдруг будете встречать интересные технические статьи или посты, буду благодарен, если поделитесь ими в чате.
#race
Ранее, в начале июля, прошел 19 Race, создателем которого стал популярных аудитор Pashov. Только сейчас получилось добраться до конкурса из-за большой нагрузки этого лета, и могу сказать, что это довольно интересный тест, скорее, на внимательность, чем знание каких-либо нюансов языка.
У меня получилось 7 из 8 ответов. Для тех, кто будет проходить его рекомендую вчитываться в сами вопросы, так как порой их формирование бывает сложным для понимания.
Ссылка на Race 19.
P.S. На удивление, сейчас мне попадается довольно мало добротного материала для канала, с какими-нибудь интересными тонкостями языка или работы со смарт контрактами. Такое ощущение, что все резко стали пилить контент для начинающих, где повторяются базовые атаки, типа реентранси, и экономия газа в упаковке переменных. Если вдруг будете встречать интересные технические статьи или посты, буду благодарен, если поделитесь ими в чате.
#race
❤5
Двойной тернарный
Вчера узнал, что в Solidity можно использовать двойной тернарный оператор. Например,
uint a = 100;
uint b = 10;
bool aIsSmallerOrMultiple = a < b ? true : a % b == 0 ? true : false;
(return: true)
Хоть в реальных проектах такого пока не встречал, но данный способ написания условия точно нужно понимать и уметь читать.
#ternary
Вчера узнал, что в Solidity можно использовать двойной тернарный оператор. Например,
uint a = 100;
uint b = 10;
bool aIsSmallerOrMultiple = a < b ? true : a % b == 0 ? true : false;
(return: true)
Хоть в реальных проектах такого пока не встречал, но данный способ написания условия точно нужно понимать и уметь читать.
#ternary
👍11❤1
Бешеное лето и материалы июля
У меня выдается какое-то бешеное лето! Когда я взял небольшой отпуск в конце мая на неделю, то и представить не смог, что после не будет ни минуты передышки!
Сразу после отдыха со мной связались через данный канал и попросили провести частный аудит проекта, который занял у меня две недели (3200 строк: 4 крит, 12 мед). Очень надеюсь, что команда закончит все правки, и я, наконец, смогу выложить отчет в публичный доступ.
Далее крутым событием для меня стал запуск курса! В конце июня было сделано первое объявление об этом и уже в начале июля пошли первые занятия! Там было написано 19 уроков, 2 практикума и 52 финальных вопроса для самопроверки! Ребята, бы большие молодцы, что решились на что-то новое, так держать!
К концу курса я прошел собеседование и попал на испытательный срок в крутую компанию, на позицию Security Engineer. Уже прошла первая неделя и я в полном восторге от этой работы! То, что хотел с первого дня, как решил стать аудитором!
Жаль лишь то, что из-за основной работы и курса, куда я стараюсь вкладываться по максимуму, не хватает времени на конкурсные аудиты. С начала июня на каждый из них уходит всего по несколько часов. Тем не менее, первые небольшие результаты уже есть: нашел и первые high issues, и несколько med. Очень надеюсь, что скоро все чуть устаканится и я смогу выделять больше времени на это.
Также на следующей недели я буду рассказывать про второй модуль курса! Там изменится программа, чтобы ученики быстрее вникли в идею разработки проектов и научились работать с популярными erc.
И все это, не считая своих обычных, вне-солидитишных дел!
Фух, бешеное лето!
Ну, а пока, вот небольшая ретроспектива материалов на канале, если вдруг что пропустили или забыли.
1. Нюансы при аудите контрактов с подключенным Uniswap V3
2. Манипуляция оракулами
3. Уязвимость в древе Мерка в Open Zeppelin
4. Заметка про Uniswap V4
5. Двойной overflow
6. Организация prank в Foundry
7. Работа с памятью в Solidity. Большой сборник
8. Интересный баг в протоколе EigenLayer
9. Контроль доступа и голосование за предложения
10. Различные abi.encode
11. Организация storage в прокси контракте
12. RACE #19 Of The Secureum Bootcamp
13. Двойной тернарный
14. Необычный require и работа с ошибками
Продолжаем учиться и работать!
#retro
У меня выдается какое-то бешеное лето! Когда я взял небольшой отпуск в конце мая на неделю, то и представить не смог, что после не будет ни минуты передышки!
Сразу после отдыха со мной связались через данный канал и попросили провести частный аудит проекта, который занял у меня две недели (3200 строк: 4 крит, 12 мед). Очень надеюсь, что команда закончит все правки, и я, наконец, смогу выложить отчет в публичный доступ.
Далее крутым событием для меня стал запуск курса! В конце июня было сделано первое объявление об этом и уже в начале июля пошли первые занятия! Там было написано 19 уроков, 2 практикума и 52 финальных вопроса для самопроверки! Ребята, бы большие молодцы, что решились на что-то новое, так держать!
К концу курса я прошел собеседование и попал на испытательный срок в крутую компанию, на позицию Security Engineer. Уже прошла первая неделя и я в полном восторге от этой работы! То, что хотел с первого дня, как решил стать аудитором!
Жаль лишь то, что из-за основной работы и курса, куда я стараюсь вкладываться по максимуму, не хватает времени на конкурсные аудиты. С начала июня на каждый из них уходит всего по несколько часов. Тем не менее, первые небольшие результаты уже есть: нашел и первые high issues, и несколько med. Очень надеюсь, что скоро все чуть устаканится и я смогу выделять больше времени на это.
Также на следующей недели я буду рассказывать про второй модуль курса! Там изменится программа, чтобы ученики быстрее вникли в идею разработки проектов и научились работать с популярными erc.
И все это, не считая своих обычных, вне-солидитишных дел!
Фух, бешеное лето!
Ну, а пока, вот небольшая ретроспектива материалов на канале, если вдруг что пропустили или забыли.
1. Нюансы при аудите контрактов с подключенным Uniswap V3
2. Манипуляция оракулами
3. Уязвимость в древе Мерка в Open Zeppelin
4. Заметка про Uniswap V4
5. Двойной overflow
6. Организация prank в Foundry
7. Работа с памятью в Solidity. Большой сборник
8. Интересный баг в протоколе EigenLayer
9. Контроль доступа и голосование за предложения
10. Различные abi.encode
11. Организация storage в прокси контракте
12. RACE #19 Of The Secureum Bootcamp
13. Двойной тернарный
14. Необычный require и работа с ошибками
Продолжаем учиться и работать!
#retro
🔥31
Курс Модуль 2
На прошлой неделе закончился первый модуль курса "Начинающий разработчик Solidity". Мы прошли базовые аспекты языка: типы данных и написание функций, и теперь самое время двигаться дальше.
Представляю вам обновленную программу 2 модуля:
Неделя 5
20. Транзакции: общее.
21. Глобальные переменные msg
22. Наследование
23. Интерфейсы
Неделя 6
24. Библиотеки
25. Библиотеки openzeppelin и solmate
26. Низкоуровневые вызовы: call, staticcall
27. Низкоуровневые вызовы: delegatecall
Неделя 7
28 . Стандарт ERC20. Разбор кода и EIP
29. ERC20. Особенности и разнообразие
30. ERC20. Проблемы безопасности
31. ERC20 от Open Zeppelin
Неделя 8
32. ERC721. Разбор кода и EIP
33. ERC721. Использование в проектах
34. ERC721. Проблемы безопасности
35. Другие стандарты ERC
36. Практикум
Почему были внесены изменения?
Составляя первый вариант программы, я ориентировался на свое собственное обучение. Однако первый модуль курса помог мне немного расставить приоритеты по темам для новичком таким образом, чтобы они быстрее поняли профессию разработчика и получили практические навыки.
После второго модуля вы сможете самостоятельно подключать сторонние контракты и различные библиотеки в свои проекты, а также познакомитесь с токенами "со стороны разработчика". Также внимание будет уделено сфере безопасности популярных ERC.
Ориентировочный старт: 14 августа
Старт продаж: 9 августа
Стоимость: 2000 рублей, 25 USDT / USDC / DAI
#курс
На прошлой неделе закончился первый модуль курса "Начинающий разработчик Solidity". Мы прошли базовые аспекты языка: типы данных и написание функций, и теперь самое время двигаться дальше.
Представляю вам обновленную программу 2 модуля:
Неделя 5
20. Транзакции: общее.
21. Глобальные переменные msg
22. Наследование
23. Интерфейсы
Неделя 6
24. Библиотеки
25. Библиотеки openzeppelin и solmate
26. Низкоуровневые вызовы: call, staticcall
27. Низкоуровневые вызовы: delegatecall
Неделя 7
28 . Стандарт ERC20. Разбор кода и EIP
29. ERC20. Особенности и разнообразие
30. ERC20. Проблемы безопасности
31. ERC20 от Open Zeppelin
Неделя 8
32. ERC721. Разбор кода и EIP
33. ERC721. Использование в проектах
34. ERC721. Проблемы безопасности
35. Другие стандарты ERC
36. Практикум
Почему были внесены изменения?
Составляя первый вариант программы, я ориентировался на свое собственное обучение. Однако первый модуль курса помог мне немного расставить приоритеты по темам для новичком таким образом, чтобы они быстрее поняли профессию разработчика и получили практические навыки.
После второго модуля вы сможете самостоятельно подключать сторонние контракты и различные библиотеки в свои проекты, а также познакомитесь с токенами "со стороны разработчика". Также внимание будет уделено сфере безопасности популярных ERC.
Ориентировочный старт: 14 августа
Старт продаж: 9 августа
Стоимость: 2000 рублей, 25 USDT / USDC / DAI
#курс
🔥11👍5
Самопроверка перед 2 модулем курса
На случай, если вы не были на первом модуле и хотите зайти на второй, то потребуется знать ответы на некоторые вопросы. Так вы будете уверены, что готовы к новым темам и не будете отставать от других учеников.
Вопросы для самопроверки:
1. На каких языках пишут сети блокчейна?
2. На каких языках пишут смарт контракты?
3. Какие есть сети блокчейна?
4. Дайте определение языку Solidity. Что такое статическая типизация?
5. Что такое полнота по Тьюрингу?
6. Что такое высокоуровневый язык?
7. В чем особенность смарт контрактов в блокчейне?
8. Что такое трилемма блокчейна?
9. Варианты решения трилеммы?
10. Что такое сайдчен?
11. Какие существуют сети L2?
12. Что такое роллапы? Какие виды существуют?
13. Что такое мост в блокчене?
14. Примеры использования смарт контрактов.
15. Из чего состоит смарт контракт?
16. Что такое компиляция и деплой смарт контракта?
17. Что такое газ?
18. Что такое обновление "Лондон"?
19. Что такое базовая и приоритетная комиссия?
20. Какие переменные бывают?
21. Какие бывают области видимости переменных?
22. Расскажите о типе данных bool?
23. Какое значение по умолчанию в bool?
24. Можно ли сравнивать строки? Почему?
25. Можно ли соединять строки?
26. Какие два вида адресов бывают?
27. Собственные методы адреса?
28. Что такое размерность uint?
29. Какое значение по умолчанию в uint?
30. Сколько байтов в uint128?
31. Что такое overflow?
32. Что такое кастинг uint?
33. Есть ли числа с точкой в Solidity?
34. Какие типы данных left-padded и какие right-padded?
35. Какие бывают массивы?
36. Можно ли создать динамический массив в функции?
37. Как записать значение в динамический массив?
38. Какие способы есть удаления данных из массива?
39. Что такое enum?
40. Какое значение по умолчанию в enum?
41. Для чего применяются enum?
42. Зачем нужны mapping?
43. Значение по умолчанию в mapping?
44. Можно ли сделать итерацию по мэппингу?
45. Какой тип данных может храниться в ключе и в значении мэппинга?
46. Какие бывают области видимости у функций? Чем отличаются?
47. Заем нужны view и pure функции? Их отличия?
48. Зачем нужен модификатор payable в функции?
49. Что такое receive и fallback функции?
50. Зачем нужны модификаторы в функциях?
51. Что такое struct?
52. Что такое вложения в мэппингах и структурах?
P.S. Это список вопросов из первого модуля. Такие будут после второго тоже.
Программа курса
#курс
На случай, если вы не были на первом модуле и хотите зайти на второй, то потребуется знать ответы на некоторые вопросы. Так вы будете уверены, что готовы к новым темам и не будете отставать от других учеников.
Вопросы для самопроверки:
1. На каких языках пишут сети блокчейна?
2. На каких языках пишут смарт контракты?
3. Какие есть сети блокчейна?
4. Дайте определение языку Solidity. Что такое статическая типизация?
5. Что такое полнота по Тьюрингу?
6. Что такое высокоуровневый язык?
7. В чем особенность смарт контрактов в блокчейне?
8. Что такое трилемма блокчейна?
9. Варианты решения трилеммы?
10. Что такое сайдчен?
11. Какие существуют сети L2?
12. Что такое роллапы? Какие виды существуют?
13. Что такое мост в блокчене?
14. Примеры использования смарт контрактов.
15. Из чего состоит смарт контракт?
16. Что такое компиляция и деплой смарт контракта?
17. Что такое газ?
18. Что такое обновление "Лондон"?
19. Что такое базовая и приоритетная комиссия?
20. Какие переменные бывают?
21. Какие бывают области видимости переменных?
22. Расскажите о типе данных bool?
23. Какое значение по умолчанию в bool?
24. Можно ли сравнивать строки? Почему?
25. Можно ли соединять строки?
26. Какие два вида адресов бывают?
27. Собственные методы адреса?
28. Что такое размерность uint?
29. Какое значение по умолчанию в uint?
30. Сколько байтов в uint128?
31. Что такое overflow?
32. Что такое кастинг uint?
33. Есть ли числа с точкой в Solidity?
34. Какие типы данных left-padded и какие right-padded?
35. Какие бывают массивы?
36. Можно ли создать динамический массив в функции?
37. Как записать значение в динамический массив?
38. Какие способы есть удаления данных из массива?
39. Что такое enum?
40. Какое значение по умолчанию в enum?
41. Для чего применяются enum?
42. Зачем нужны mapping?
43. Значение по умолчанию в mapping?
44. Можно ли сделать итерацию по мэппингу?
45. Какой тип данных может храниться в ключе и в значении мэппинга?
46. Какие бывают области видимости у функций? Чем отличаются?
47. Заем нужны view и pure функции? Их отличия?
48. Зачем нужен модификатор payable в функции?
49. Что такое receive и fallback функции?
50. Зачем нужны модификаторы в функциях?
51. Что такое struct?
52. Что такое вложения в мэппингах и структурах?
P.S. Это список вопросов из первого модуля. Такие будут после второго тоже.
Программа курса
#курс
👍19🔥1
Курс Solidity разработчик с нуля. Как догнать?
Поступило несколько вопросов о том, можно ли попасть на второй модуль, если не проходил первый? И можно ли как-нибудь получить материалы с первого модуля? Отвечу на оба.
На первом модуле мы разбирали основы языка Solidity, учились писать простые и сложные функции, а также познавали некоторые общие понятия про блокчейн. Список вопросов, на которые могут ответить ученики после прохождения модуля, вы можете увидеть в посте выше. Программа была достаточно детальная и направленная на практику. Последние два практикума заставили некоторых потрудиться!
Если вы хотите получить оба модуля сразу, то будет возможность купить доступы на них.
С первым модулем вы сможете сами в своем темпе проходить уроки, или вспомнить какой-то основной материал, а со вторым продолжить учиться.
Повторюсь, что этот курс рассчитан на начинающих участников, кто ни разу не сталкивался с программированием раньше. Я стараюсь давать материал просто, объясняя каждую деталь и отвечая на вопросы.
Если же хотите сами попробовать подготовиться ко 2 модулю, то рекомендую к просмотру канал Ильи. Даже в своих уроках я рекомендую его видео к просмотру, так как считаю, что он лучший русскоговорящий учитель на Ютуб. Вы можете просмотреть его уроки с 1 до 7, исключая 5. Тогда вы начнете представлять, о чем будет идти речь на курсе.
Старт продаж уже завтра! Будет возможность оплатить как на карту, так и криптой. Вся информация будет завтра.
Программа курса! Описание курса
Продажи будут открыты до конца недели!
#курс
Поступило несколько вопросов о том, можно ли попасть на второй модуль, если не проходил первый? И можно ли как-нибудь получить материалы с первого модуля? Отвечу на оба.
На первом модуле мы разбирали основы языка Solidity, учились писать простые и сложные функции, а также познавали некоторые общие понятия про блокчейн. Список вопросов, на которые могут ответить ученики после прохождения модуля, вы можете увидеть в посте выше. Программа была достаточно детальная и направленная на практику. Последние два практикума заставили некоторых потрудиться!
Если вы хотите получить оба модуля сразу, то будет возможность купить доступы на них.
С первым модулем вы сможете сами в своем темпе проходить уроки, или вспомнить какой-то основной материал, а со вторым продолжить учиться.
Повторюсь, что этот курс рассчитан на начинающих участников, кто ни разу не сталкивался с программированием раньше. Я стараюсь давать материал просто, объясняя каждую деталь и отвечая на вопросы.
Если же хотите сами попробовать подготовиться ко 2 модулю, то рекомендую к просмотру канал Ильи. Даже в своих уроках я рекомендую его видео к просмотру, так как считаю, что он лучший русскоговорящий учитель на Ютуб. Вы можете просмотреть его уроки с 1 до 7, исключая 5. Тогда вы начнете представлять, о чем будет идти речь на курсе.
Старт продаж уже завтра! Будет возможность оплатить как на карту, так и криптой. Вся информация будет завтра.
Программа курса! Описание курса
Продажи будут открыты до конца недели!
#курс
❤8👍2
Первые ученики уже на канале!
Если вы только пришли с работы, то пост для вас! Сегодня старт продаж 2 модуля нашего курса!
16 самых первых учеников уже канале!
Только сейчас вы можете купить сразу оба модуля, так как, начиная с третьего, доступ будет возможен только для текущих учеников. Программа пойдет дальше и догнать остальных будет уже сложно!
Вы получите доступ к закрытым урокам обоих каналов и сможете проходить их в удобное для себя время. Каналы не будут удаляться и все уроки останутся с вами.
Продажи открыты! Успейте занять свое место!
Программа курса. Описание курса.
Условия оплаты в посте выше.
Старт 14 августа!
#курс
Если вы только пришли с работы, то пост для вас! Сегодня старт продаж 2 модуля нашего курса!
16 самых первых учеников уже канале!
Только сейчас вы можете купить сразу оба модуля, так как, начиная с третьего, доступ будет возможен только для текущих учеников. Программа пойдет дальше и догнать остальных будет уже сложно!
Вы получите доступ к закрытым урокам обоих каналов и сможете проходить их в удобное для себя время. Каналы не будут удаляться и все уроки останутся с вами.
Продажи открыты! Успейте занять свое место!
Программа курса. Описание курса.
Условия оплаты в посте выше.
Старт 14 августа!
#курс
Курс "Разработчик смарт контрактов": Модуль 2
Сегодня я хотел бы поговорить о безопасности смарт контрактов и некоторых моментах обучения на нашем курсе.
Как правило, уязвимости контрактов изучают отдельной темой. Другими словами, вот вы научились писать протоколы, загружать их в блокчейн, а только потом понимаете, что все это время ваши контракты имели кучу багов! А все потому, что никто не говорил вам, на что нужно обращать внимание.
На первом модуле я делал небольшие заметки для учеников, которые стоит знать и понимать при работе с типами данных и функциями.
На втором модуле у нас будет еще больше отступлений в тему безопасности смарт контрактов. Если уже вы чему-то учитесь, то лучше делать это правильно с самого начала.
Правильная работа с наследованием контрактов, их версий и особенностей, безопасность вызовов между ними, а также нюансы работы с популярными ERC20 и ERC721 (токен и NFT) - вот на что будет сделан упор в данном модуле.
Научится создавать токен или NFT можно за 15 минут, благо видео на эту тему на Ютуб предостаточно. А вот сделать так, чтобы никто не смог укать ваши токены - совершенно другая сторона разработки.
Мы продолжаем обучение! Присоединяйтесь!
Программа курса! Описание курса
Условия и оплата
Старт 14 августа!
#курс
Сегодня я хотел бы поговорить о безопасности смарт контрактов и некоторых моментах обучения на нашем курсе.
Как правило, уязвимости контрактов изучают отдельной темой. Другими словами, вот вы научились писать протоколы, загружать их в блокчейн, а только потом понимаете, что все это время ваши контракты имели кучу багов! А все потому, что никто не говорил вам, на что нужно обращать внимание.
На первом модуле я делал небольшие заметки для учеников, которые стоит знать и понимать при работе с типами данных и функциями.
На втором модуле у нас будет еще больше отступлений в тему безопасности смарт контрактов. Если уже вы чему-то учитесь, то лучше делать это правильно с самого начала.
Правильная работа с наследованием контрактов, их версий и особенностей, безопасность вызовов между ними, а также нюансы работы с популярными ERC20 и ERC721 (токен и NFT) - вот на что будет сделан упор в данном модуле.
Научится создавать токен или NFT можно за 15 минут, благо видео на эту тему на Ютуб предостаточно. А вот сделать так, чтобы никто не смог укать ваши токены - совершенно другая сторона разработки.
Мы продолжаем обучение! Присоединяйтесь!
Программа курса! Описание курса
Условия и оплата
Старт 14 августа!
#курс
👍8
⚡️⚡️⚡️ Менее 12 часов до закрытия продаж! Курс для разработчиков ⚡️⚡️⚡️
Сегодня последний день продаж доступа на первый и второй модули курса. Если опоздаете, то придется ждать следующего года, так как третий и последующие модули будут доступны только текущим ученикам и тем, кто уже изучил базовый материал по Solidity.
Напомню, что на этом модуле мы будет проходить взаимодействие контрактов в сети: с другими контрактами и библиотеками, а также поговорим о самых популярных стандартах ERC для создания токенов и NFT. Вы научитесь не только создавать свои токены, но и понимать весь смысл кода контракта, в том числе аспекты его безопасности.
У нас уже набралась достаточно большая группа учеников, поэтому с понедельника, с началом курса, продаж не будет совсем!
Успейте занять свое место!
Программа курса! Описание курса
Условия и оплата
Старт 14 августа!
#курс
Сегодня последний день продаж доступа на первый и второй модули курса. Если опоздаете, то придется ждать следующего года, так как третий и последующие модули будут доступны только текущим ученикам и тем, кто уже изучил базовый материал по Solidity.
Напомню, что на этом модуле мы будет проходить взаимодействие контрактов в сети: с другими контрактами и библиотеками, а также поговорим о самых популярных стандартах ERC для создания токенов и NFT. Вы научитесь не только создавать свои токены, но и понимать весь смысл кода контракта, в том числе аспекты его безопасности.
У нас уже набралась достаточно большая группа учеников, поэтому с понедельника, с началом курса, продаж не будет совсем!
Успейте занять свое место!
Программа курса! Описание курса
Условия и оплата
Старт 14 августа!
#курс
Есть запросы?
Фух, после запуска курса как-то быстро время пошло, не успеваю уделять время на изучение новых постов и статей.
Вообще, за последнее время я немного разобрался со своими проблемными зонами в аудите и Solidity.
Во-первых, составил небольшой план проведения аудита, с учетом тех нюансов, которые я пропускал в прошедших конкурсах. Спасибо с4 за доступы к репортам, благодаря которым учишься быстрее. Теперь, надеюсь, поиск багов будет более эффективным. Узнаем на новых конкурсах!
Во-вторых, в Solidity моей слабой зоной оказался assembly и побитовые операции. И если со вторыми, посидев над задачей, я разобраться смогу, то с yul...
С assembly мне часто приходится обращаться к одному из участников канала с просьбой помочь разобраться. Все эти низкоуровневые запросы к памяти, порой абсолютно непонятны. Но после его объяснений, можно работать с кодом дальше. Очень надеюсь, что все сложится, и он станет одним из преподавателей на курсе!
Также хотел бы спросить, есть ли какие-нибудь запросы по темам от участников канала?
Этот канал ведется уже более года и тут поднималась и описывалась куча разных тем, и что самое главное, практически без повторов. Поэтому хотелось бы услышать, чего-то что не было еще.
Пожелания пишите в комментариях!
#offtop
Фух, после запуска курса как-то быстро время пошло, не успеваю уделять время на изучение новых постов и статей.
Вообще, за последнее время я немного разобрался со своими проблемными зонами в аудите и Solidity.
Во-первых, составил небольшой план проведения аудита, с учетом тех нюансов, которые я пропускал в прошедших конкурсах. Спасибо с4 за доступы к репортам, благодаря которым учишься быстрее. Теперь, надеюсь, поиск багов будет более эффективным. Узнаем на новых конкурсах!
Во-вторых, в Solidity моей слабой зоной оказался assembly и побитовые операции. И если со вторыми, посидев над задачей, я разобраться смогу, то с yul...
С assembly мне часто приходится обращаться к одному из участников канала с просьбой помочь разобраться. Все эти низкоуровневые запросы к памяти, порой абсолютно непонятны. Но после его объяснений, можно работать с кодом дальше. Очень надеюсь, что все сложится, и он станет одним из преподавателей на курсе!
Также хотел бы спросить, есть ли какие-нибудь запросы по темам от участников канала?
Этот канал ведется уже более года и тут поднималась и описывалась куча разных тем, и что самое главное, практически без повторов. Поэтому хотелось бы услышать, чего-то что не было еще.
Пожелания пишите в комментариях!
#offtop
👍6
Diamond Proxy
Делал тут небольшую презентацию про прокси контракты и вспомнил, что на канале просто упоминал про Diamond паттерн. Пора сделать чуть более подробное описание этого необычного прокси.
Итак, этот EIP был впервые представлен в феврале 2020 года и получил свой финальный вид в феврале 2020 года. Он определяет стандарт, так называемых, модульных контрактов и методов хранения информации в нем.
Кратко описывая этот паттерн, можно сказать, что у нас есть главный Diamond контракт, который хранит всю пользовательскую информацию, как и обычный Proxy (transparent, uups), а также данные об external функциях вспомогательных контрактов.
Вспомогательные контракты называются Facets.
Когда в Diamond контракт приходит вызов какой-либо функции, то он попадает в fallback, в котором идет запрос к хранилищу Diamond и ищется селектор нужной функции. По селектору определяется Facet и вызов через delegatecall перенаправляется туда.
Также существует, скажем так, главный Facet, который содержит функцию diamondCut. С помощью нее мы можем добавлять новые селекторы функций и другие адреса Facets в наш Diamond контракт.
Вообще, с помощью этого паттерна нам не нужно заботится о размере контрактов, так как с помощью такой модульной системы мы можем строить реально большие протоколы! Это бывает полезно, когда мы не знаем, насколько большим будет наш Dapp, и сколько функций потребуется в итоге.
Очень интересно организована система storage в Diamond прокси. Но об этом более подробно можно прочитать по этой прекрасной ссылке!
#diamond #proxy
Делал тут небольшую презентацию про прокси контракты и вспомнил, что на канале просто упоминал про Diamond паттерн. Пора сделать чуть более подробное описание этого необычного прокси.
Итак, этот EIP был впервые представлен в феврале 2020 года и получил свой финальный вид в феврале 2020 года. Он определяет стандарт, так называемых, модульных контрактов и методов хранения информации в нем.
Кратко описывая этот паттерн, можно сказать, что у нас есть главный Diamond контракт, который хранит всю пользовательскую информацию, как и обычный Proxy (transparent, uups), а также данные об external функциях вспомогательных контрактов.
Вспомогательные контракты называются Facets.
Когда в Diamond контракт приходит вызов какой-либо функции, то он попадает в fallback, в котором идет запрос к хранилищу Diamond и ищется селектор нужной функции. По селектору определяется Facet и вызов через delegatecall перенаправляется туда.
Также существует, скажем так, главный Facet, который содержит функцию diamondCut. С помощью нее мы можем добавлять новые селекторы функций и другие адреса Facets в наш Diamond контракт.
Вообще, с помощью этого паттерна нам не нужно заботится о размере контрактов, так как с помощью такой модульной системы мы можем строить реально большие протоколы! Это бывает полезно, когда мы не знаем, насколько большим будет наш Dapp, и сколько функций потребуется в итоге.
Очень интересно организована система storage в Diamond прокси. Но об этом более подробно можно прочитать по этой прекрасной ссылке!
#diamond #proxy
👍8🔥2❤1
Небольшая заметка про Arbitrum
Сейчас смотрел конкурсный аудит от Shell и заметил, что проект работает в сети Arbutrum. Я никогда ранее напрямую не работал с этой сетью, в плане аудита или деплоя контрактов, поэтому мне захотелось узнать чуть больше о ее технической части.
Вообще, когда вы планируете разработку своего протокола на нескольких сетях, то лучше всего не полагаться на, так называемую, "похожесть" EVM сетей, а смотреть документации и искать, где может быть проблема.
В доках Арбитрума есть специальный раздел, где описывается разница между двумя сетями, но можно назвать всего пару основных, на которые необходимо обращать внимание.
1. Запрос block.number вернет номер блока примерно приближенного к сети L1, а не самого Арбитрума. Для запроса номеров блока в Арбитруме есть свои методы.
2. Один блок Эфира может включать в себя несколько блоков Арбитрума.
3. Разные блоки могут иметь одинаковый timestamp. Тут есть описание проблемы.
4. Push0 также еще не поддерживается на этой сети
Если хотите прочитать про остальные различия, то они лучше всего описаны в этом посте, а про поддержку Solidity можно узнать тут.
P.S. Если знаете еще какие-то моменты, на которые следует обращать внимание, то дайте знать в комментариях.
UPD. Спасибо @Deathstore за ссылку http://evmdiff.com/. Тут можно посмотреть различия в сетях.
#arbitrum
Сейчас смотрел конкурсный аудит от Shell и заметил, что проект работает в сети Arbutrum. Я никогда ранее напрямую не работал с этой сетью, в плане аудита или деплоя контрактов, поэтому мне захотелось узнать чуть больше о ее технической части.
Вообще, когда вы планируете разработку своего протокола на нескольких сетях, то лучше всего не полагаться на, так называемую, "похожесть" EVM сетей, а смотреть документации и искать, где может быть проблема.
В доках Арбитрума есть специальный раздел, где описывается разница между двумя сетями, но можно назвать всего пару основных, на которые необходимо обращать внимание.
1. Запрос block.number вернет номер блока примерно приближенного к сети L1, а не самого Арбитрума. Для запроса номеров блока в Арбитруме есть свои методы.
2. Один блок Эфира может включать в себя несколько блоков Арбитрума.
3. Разные блоки могут иметь одинаковый timestamp. Тут есть описание проблемы.
4. Push0 также еще не поддерживается на этой сети
Если хотите прочитать про остальные различия, то они лучше всего описаны в этом посте, а про поддержку Solidity можно узнать тут.
P.S. Если знаете еще какие-то моменты, на которые следует обращать внимание, то дайте знать в комментариях.
UPD. Спасибо @Deathstore за ссылку http://evmdiff.com/. Тут можно посмотреть различия в сетях.
#arbitrum
👍10
Необычное использование прокси
В еще одном конкурсном аудите обнаружил для себя необычный подход к использованию прокси контрактов, которое немного перевернуло мое представление об этом паттерне.
Смотрите, в обычной реализации мы делаем как? Мы пишем прокси контракт, а затем добавляем к нему контракт Логики. Все данные хранятся в прокси, а Логику мы можем менять хоть каждый день.
В проекте Sparkn по-другому.
P.S. Репо, возможно, будет открыто только на время конкурса.
Здесь три контракта: proxy, distributor и proxyFactory.
Proxy - самая простая реализация прокси паттерна с одной лишь fallback функцией.
Distributor - контракт Логики для прокси с разными функциями, основная из которых это перечисление средств пользователям.
ProxyFactory - основной контракт для взаимодействия.
Смотрите, что получается. Контракты proxyFactory и distributor постоянные. Т.е. distributor хоть и является контрактом Логики для прокси, но в данном случае он не обновляемый, так как функционал для этого не заложен.
В proxyFactor есть функция для деплоя прокси контракта и определения его адреса наперед, основываясь на определенных параметрах, в том числе на адресе пользователя.
Итак, суть в том, что пользователь может заранее вычислить свой адрес прокси и отправить туда некоторую сумму для распределения пользователям. Затем он вызывает функцию деплоя proxy, сразу после чего идет туда вызов и с помощью delegatecall вызывается функция из distributor, которая делает рассылку активов для установленных пользователей.
Другими словами, каждый взятый пользователь может сделать деплой прокси, на котором будут лежать токены, и уже с него через фиксированный контракт distributor сделать рассылку.
Два контракта постоянных, и неограниченное количество индивидуальных контрактов для пользователей.
На мой взгляд сделано очень круто!
#proxy
В еще одном конкурсном аудите обнаружил для себя необычный подход к использованию прокси контрактов, которое немного перевернуло мое представление об этом паттерне.
Смотрите, в обычной реализации мы делаем как? Мы пишем прокси контракт, а затем добавляем к нему контракт Логики. Все данные хранятся в прокси, а Логику мы можем менять хоть каждый день.
В проекте Sparkn по-другому.
P.S. Репо, возможно, будет открыто только на время конкурса.
Здесь три контракта: proxy, distributor и proxyFactory.
Proxy - самая простая реализация прокси паттерна с одной лишь fallback функцией.
Distributor - контракт Логики для прокси с разными функциями, основная из которых это перечисление средств пользователям.
ProxyFactory - основной контракт для взаимодействия.
Смотрите, что получается. Контракты proxyFactory и distributor постоянные. Т.е. distributor хоть и является контрактом Логики для прокси, но в данном случае он не обновляемый, так как функционал для этого не заложен.
В proxyFactor есть функция для деплоя прокси контракта и определения его адреса наперед, основываясь на определенных параметрах, в том числе на адресе пользователя.
Итак, суть в том, что пользователь может заранее вычислить свой адрес прокси и отправить туда некоторую сумму для распределения пользователям. Затем он вызывает функцию деплоя proxy, сразу после чего идет туда вызов и с помощью delegatecall вызывается функция из distributor, которая делает рассылку активов для установленных пользователей.
Другими словами, каждый взятый пользователь может сделать деплой прокси, на котором будут лежать токены, и уже с него через фиксированный контракт distributor сделать рассылку.
Два контракта постоянных, и неограниченное количество индивидуальных контрактов для пользователей.
На мой взгляд сделано очень круто!
#proxy
👍5