DEV: Рубиновые тона – Telegram
DEV: Рубиновые тона
3.22K subscribers
143 photos
2 videos
8 files
976 links
Анонсы новых видео о программировании (Ruby/Rails, Solidity/Ethereum, Python, JS и не только), практические советы, обзор полезных инструментов и новости из мира IT
Download Telegram
Ещё раз напомню, что для написания комментариев нужно зайти в наш чат https://news.1rj.ru/str/+MxYT6-01eeA1NTYy К сожалению, очень много прилетает спама, приходится как-то защищаться
3
У меня вышел небольшой пост о том, что такое интернационализация и почему это не то же самое, что локализация https://lokalise.com/blog/what-is-i18n/
🔥72
Как уже отметил наш постоянный зритель несколько месяцев назад, токены Толкина действительно были пущены в оборот. Кто бы мог подумать пару лет назад... (отсылка к старым стримам по ERC20) https://www.reddit.com/media?url=https%3A%2F%2Fi.redd.it%2Fjust-arrived-in-the-mail-today-v0-fkqtrcac6wgc1.jpeg%3Fs%3D9df19cbd93dcc9ece791fb096a2e6d15e0a9d7ec
😁7👍1
Некоторые замечают, что при использовании Metamask в тестовой среде с Hardhat происходят какие-то дополнительные странные вызовы. В частности, если попытаться отправить обычную транзакцию, в журнале Hardhat может вылезти ещё штук пять сообщений вроде "unrecognized selector". Откуда это берётся?

Я провёл небольшое расследование, и дело в том, что Metamask пытается вызывать функции supportsInterface() (ERC165), а также функции типа decimals() и symbol(), тк совпадают селекторы, к примеру bytes4(keccak256(bytes("symbol()"))) вернёт 0x95d89b41, это как раз один из неопознанных селекторов. Любопытно, что это вызывается, даже если вы не используете ERC20.

Так что варианта два - просто игнорировать, либо добавить пустую функцию fallback (плюс добавить наследование от контракта ERC165). Ну, то есть можно сделать пустые функции decimals, symbol, но это как-то странно, если контракт не связан с токенами.
🔥10👍1
И тут я вспоминаю об этом нашем кавере и хочется танцевать так, как будто никто не видит (тем более, что никто и не видит) https://soundcloud.com/ravens-die-laughing/zvezdy
👍9😱2😐2
По этой теме было много вопросов, так что во вторник проведём стрим.

Мы поговорим о новом весьма хайповом "стандарте" ERC404, который на самом деле и не стандарт вовсе. В любом случае, это подход позволяет создавать комбинацию токенов ERC20 и ERC721, вводя для NFT понятие "долей". Мы разберём, в чём польза этого подхода и как он работает.

https://youtube.com/live/7TZFpbge83A
🔥7👍21👏1
Что ж, цикл "Воспоминания" Тэффи завершён. К сожалению, завершился он на довольно грустной ноте, которая подозрительно похожа на происходящее сегодня, так что добавил ещё две бонусные главы. В ближайшие дни ещё будут "воспоминания" о таком известном человеке, как Григорий Распутин, а также об Алексее Толстом (это который "не Лев") https://youtu.be/GOx8e0-8Tws
4👍3🆒21
Вышел Hardhat 2.20 с поддержкой предстоящего хард-форка Cancun (выходит в середине марта), который должен добавить быстродействия и безопасности. Также поддерживается Solc 0.8.24. https://github.com/NomicFoundation/hardhat/releases/tag/hardhat%402.20.0
👍7
Ребята из MIT выложили некоторые свои курсы в открытый доступ (но там, кажется, ограниченный срок записи). Вот, к примеру - https://www.edx.org/learn/computer-science/massachusetts-institute-of-technology-introduction-to-computer-science-and-programming-using-python Это самые основы, для тех, кому не хватает фундамента (кое-что из этого мы разбирали в плейлисте Алгоритмы)
🔥15
Придумал забавный "тест ложки" для английского. Грубо говоря, если вы на 100% понимаете этот текст, то у вас уже вполне приличный уровень языка
🔥116🤯4💯1
Продолжаем конкурс лучших комментариев. В этот раз из закрытого чата, куда пригласили постримить. And the Oscar goes to...
🤣28😁8👍3😎31🤝1
В этом уроке мы поговорим про паттерн Extension, который можно использовать, если ваш контракт слишком громоздкий и не вписывается в максимально допустимый размер Ethereum. Этот паттерн довольно простой, но позволяет эффективно решать данную проблему. https://www.youtube.com/watch?v=p-XgxfCB50I
🔥10🙏1
Недавно написал пост, в котором исследуется любопытный вопрос - как вытащить все страницы сайта для последующей обработки? Перечислены разные варианты, в том числе с помощью скрипта на Python https://www.scrapingbee.com/blog/how-to-find-all-urls-on-a-domains-website-multiple-methods/
👍81
Последний наверное год-полтора мы периодически заходили в местную китайскую забегаловку с аутентичной едой и такой непринуждённой атмосферой лёгкой неприбранности. Моя жена сильно похожа на китаянку, так что мы в один момент как-то разговорились с владелицей заведения, и с тех пор каждый раз перетирали за жизнь. Конечно, на английском, хотя на базовом уровне она латышский тоже освоила. Да и я, сказать честно, не мастер в этом плане - хотя тут мне пеняют на то, что я и в русском ударению ставлю неправильно. Что поделать, мог бы вообще говорить с характерным акцентом.

Мне казалось, что имя Элайджа совсем простое, но нашей знакомой оно показалось каким-то сверх-сложным 😂 Помню ещё, я пытался провести аналогию с Элайджей Вудом - актёром из Властелина колец, но, оказывается, этот фильм совершенно неизвестен в Китае. Ну, я, как фанат Толкина, был уверен, что профессора знают по всему миру 🤓

Вообще, интересно подмечать, как всё-таки люди отличаются друг от друга, но всё равно могут найти общий язык. Поэтому, думается, стоит путешествовать, общаться с представителями разных культур. И поэтому, к сожалению, тоталитарные режимы пытаются оградить граждан от "тлетворного влияния". Потому что когда ты знакомишься с людьми "оттуда", ты понимаешь, что с ними вполне можно взаимодействовать...

К сожалению, с начала года, проходя мимо этого заведения, мы всё время видели за прилавком неизвестную девушку, кажется, местную. Раньше периодически "на хозяйстве" была дочка владельцев, но теперь и она куда-то исчезла. А на той неделе я с удивлением обнаружил, что на здании сменилась вывеска, и там теперь какие-то кебабы (kebabs, это шаурма). Искал в интернете какие-то сведения, ничего не нашёл. Странно, и жаль.

А тут ещё другие азиатские друзья - корейский ресторан - тоже переехал чёрт знает куда, только на велосипеде доедешь. Как-то всё разом 🤪

Это, конечно, в общем и целом пост наигранной весёлости, так как весёлого мало, но жаль, когда люди, с которыми ты, вроде, был в каком-то контакте, исчезают. https://www.youtube.com/watch?v=bsTxR64s5Kc
😢3👍2🌭1
В этом уроке мы поговорим о EIP2929 и EIP2930, о газе и его оптимизации. Мы узнаем, что такое холодное и горячее (hot/warm) обращение и почему это важно. Кроме того, мы узнаем, что такое accessList в транзакциях и как он может помочь заранее "разогреть слоты" для экономии газа. В конце мы используем этот подход в паттерне Extension. https://www.youtube.com/watch?v=RRXLzfUgcLE
🔥102👏1
К вопросу об указателях, в том числе и умных, в Rust

Система владения и заимствования в Rust, а также наличие разнообразных указателей может сильно запутать поначалу, особенно когда выясняется, что указатели бывают умные, а бывают - не очень. Это не говоря о том, что у нас есть referencing, а есть ещё dereferencing, и всё это вместо нужно как-то увязать. Попробуем разобраться.

Есть вот такой код:

let a = 5;
let b = &a;


a будет иметь тип i32, эта переменная "знает", где лежит число 5. Так как это простой тип данных, то число лежит в стеке. Кроме того, помним, что a "владеет" этим числом и в нужный момент должна удалить соответствующие данные.

В случае с b мы используем оператор referencing &, то есть фактически делаем указатель. Тип b будет &i32, эта переменная знает, у кого спросить, где находится нужное число (знает это а). При этом b не получает владение этим числом. Больше того, мы не можем даже сравнить а и b напрямую, код a == b; вернёт ошибку - типы разные, мы не можем сравнить само число i32 и указатель на него.

Однако никто не мешает нам сказать "дай мне то значение, которое лежит по этому указателю". Для этого используется оператор dereferencing, "звёздочка":

a == *b;


Теперь сравнение работает. Причём мы можем даже присвоить это значение другой переменной:

let mut c = *b;
c = c + 1;


Но значит ли это, что изменение c приведёт к измению a и/или b? На самом деле, нет. Мы опять же работаем с простым типом данных, и присваивание приводит к тому, что значение копируется для другой переменной, то есть a и c имеют разные, независимые значения.

С типами вроде vec и string ситуация похожая, но становится несколько сложнее.

let a = vec![1, 2, 3];


Мы создали вектор из трёх элементов, и мы знаем, что он будет хранится в heap, потому что потенциально его длина может меняться. В стек Rust может поместить только значения, размер которых точно известен во время компиляции, и вектор к такому типу (в отличие от фиксированного массива) не относится.

Но тогда вопрос: что же содержит в себе переменная a? Она по крайней мере должна знать, с какого адреса в heap начинается наш вектор и какой у него размер. То есть выходит, что это тоже какой-то указатель. Но "простой" указатель в духе &b данными не владеет, а просто ссылается на них. В нашем же случае мы явно ожидаем, что a владеет вектором, ведь кто-то же должен в итоге очистить память.

Ответ заключается в том, что vector (как и string) - это умный указатель, smart pointer, который действительно указывает на heap, но при этом владеет данными там и имеет пристыкованные метаданные.

Значит, если мы напишем

let b = &a;


то мы фактически тоже создадим указатель, который в свою очередь будет ссылатьcя на "умный указатель", и это, как говорится, две большие разницы.

К подобным типам данных тоже можно попытаться применить dereferencing, но вот такая строка выдаст ошибку:

let c = *b;


В отличие от простых типов данных, вектора и строки при присваивании не копируются, а переносятся. То есть к примеру вот такое

let a = vec![1, 2, 3];
let d = a;


приведёт к тому, что вектор "перенесётся" в d, ну то есть на него теперь указывает другая переменная. Когда же мы делаем let c = *b;, то мы фактически пытаемся через b влезть в данные a и сделать перемещение. Компилятору такой манёвр не сильно нравится, а скопировать весь вектор автоматом тоже не выходит, такую команду мы должны отдать сами:

let c = (*b).clone();


Это сработает, но мы именно полностью копируем вектор, он будет независим от вектора a.

Но тут можно задать новый вопрос - раз a тоже является указателем, можем мы сможем сделать dereferencing для него? Можно попробовать:

let b = *a;


Тип b определится как [i32], но программа не скомпилируется. Фактически мы пытается влезть напрямую в данные, на которые указывает умный указатель, и это получается просто массив. Массивы в Rust фиксированные и лежат в стеке, но Rust не может сунуть этот конкретный массив в стек, потому что неизвестна его длина в текущий момент времени!

Если вы думаете, что это всё, то ничуть не бывало. Есть ещё метод, который называется .deref():
👍6