DEV: Рубиновые тона – Telegram
DEV: Рубиновые тона
3.22K subscribers
143 photos
2 videos
8 files
979 links
Анонсы новых видео о программировании (Ruby/Rails, Solidity/Ethereum, Python, JS и не только), практические советы, обзор полезных инструментов и новости из мира IT
Download Telegram
Немного о культуре общения в чатах https://www.nohello.com/ 😄
🔥1
Рубрика "удивительный мир TypeScript". Есть, к примеру, вот такой код:

abstract class Parent {
constructor(params: any) {
for (const key of Object.keys(params)) {
(<any>this)[key] = params[key];
}
}
}

class Child extends Parent {
test!: number;
}

const c = new Child({
test: 1
});

console.log(c);


Ну, короче говоря, потомок наследует конструктор и там все атрибуты объявляются. Это нужно, если есть 1 абстрактный класс-родитель и у него куча потомков со сходным функционалом, но разными атрибутами. Так вот на любой версии до es2022 это работает. На es2022 - нет, поле test всегда оказывается пустым.

А разгадка простая: нужно всё-таки писать declare:

class Parent {
constructor(params: any) {
for (const key of Object.keys(params)) {
(<any>this)[key] = params[key];
}
}
}

class Child extends Parent {
declare test: number;
}


Тогда работает. 🤪
🤯2
Друзья, если вы часто пишете тесты на Mocha и, в частности, работаете со сторонними сервисами, вам может потребоваться записывать ответы от этих сервисов в формате "кассет". В некоторых языках такое решение называется VCR, для экосистемы Node есть Nock, но его может быть сложновато настроить. Поэтому вам может пригодиться вот такая штука, которую мы выпустили некоторое время назад. Несколько строк кода - и у вас сами записываются ответы от сторонних сервисов https://github.com/bodrovis/mocha-cassettes
🔥5
Сегодня мы обсудим ещё 50 вопросов, которые могут задать соискателю на должность разработчика Solidity. В этот раз вопросы будут посложнее и мы рассмотрим много важных вещей: библиотеки, наследование, кодирование данных, низкоуровневые вызовы, инструкции assembly и многое другое! https://www.youtube.com/watch?v=NdNJiKBsjaw
👍10🔥3🎉3
Я смотрел пару интервью Юры Дудя и он задавал своим гостям вопрос: "В чём сила?". Все почему-то, как под копирку, отвечают "в правде". Вероятно, как-то засел в подкорке фильм "Брат", хотя мне это не очень понятно.

Мне кажется, что сила в любви. К своему делу, к другому человеку, к своей стране, к природе, к искусству, к славе. Да хотя бы к деньгам 😂 Ради любви люди готовы идти на многое, на очень многое. Это то, что - во многом - заставляет нас жить дальше.

https://www.youtube.com/watch?v=PBa1iM29mGI
👍22🔥1
Ещё немного вас повеселю. Какое-то время назад я всё-таки подумал, что надо бы почитать книги об известном герое, а потом сел писать на него жалобу. Вышло примерно на сто страниц текста (может и больше, уже не помню), так что всё это оформлено в виде вот такого сайта. Кстати, сайт сделан на Hugo 😄 https://harrypot.lol/
😁7
DEV: Рубиновые тона
Ещё немного вас повеселю. Какое-то время назад я всё-таки подумал, что надо бы почитать книги об известном герое, а потом сел писать на него жалобу. Вышло примерно на сто страниц текста (может и больше, уже не помню), так что всё это оформлено в виде вот такого…
Да, и, конечно же, credits. Минималистичный дизайн придуман мной и @ailura24, а вот иллюстрация сделана очень талантливой художницей из нашей команды. Если требуются скетчи, иллюстрации и рисунки - могу дать контакты. Всё-таки, тут я себя чувствую обязанным, ибо работа сделана бесплатно, а выглядит весьма круто
🔥6
Друзья, хочу поправить одну дурацкую ошибку из видео "вопросы для собеседования" (часть 1). Область видимости переменных по умолчанию всё же internal, а не private:

contract C1{
uint test = 42;
}

contract C2 is C1 {
function demo() external view returns(uint) {
return test; // вот тут test виден!
}
}

Прошу прощения.
👍13
Немного про сигнатуры и селекторы в Solidity.

Сигнатура функции - это, по факту, просто строка, которая содержит имя функции и её аргументы (без указания на место хранения). К примеру, "test(uint256)".

Но вот когда мы обращаемся к этой функции в транзакции, мы не можем просто передать её сигнатуру в виде такой строки. Она должна быть правильно закодирована:

abi.encodeWithSignature("test(uint256)", 42)


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

Но тогда возникает вопрос: а как именно кодируется сама сигнатура? Ответ следующий:

bytes4(keccak256(bytes("test(uint256)")))


То есть мы берём сигнатуру, считаем её хэш и забираем первые 4 байта этого хэша. Получившийся результат называется *селектор* и это именно, что мы используем для указания на вызываемую функцию. К примеру, если в вашем контракте есть функция test, принимающая uint256, то в ABI вы увидите что-то вроде:

"test(uint256)": "29e99f07"


По правую сторону как раз находится селектор этой функции.

При вызове функции первые 4 байта из calldata и будут содержать селектор функции. Это можно проверить либо так:

    function test(uint a) external view returns(bytes4) {
return bytes4(msg.data[0:4]);
}


Либо так:

    function test(uint a) external view returns(bytes4) {
bytes32 temp;
assembly {
temp := calldataload(0)
}
return bytes4(temp);
}


В любом случае результатом и будет тот самый 0x29e99f07. После первых 4 байт будут идти уже сами аргументы, которые передаются в функцию.

    function test(uint a) external view returns(bytes4, bytes32) {
bytes32 temp;
bytes32 _arg1;
assembly {
temp := calldataload(0)
_arg1 := calldataload(4)
}
return (bytes4(temp), _arg1);
}


При вызове функции test с аргументом 1 вернётся

    0:
bytes4: 0x29e99f07
1:
bytes32: 0x0000000000000000000000000000000000000000000000000000000000000001


Эта единичка как раз и видна в bytes32.

Правда всё несколько сложнее, к примеру, с массивами. То есть если у нас есть функция function test(uint[] memory a) и мы вызываем её с аргументом [1,2] то в msg.data будет нечто странное:

0xca1606840000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002


Да, первые 4 байта - это селектор, но зачем там какие-то двойки?

Сделаем следующее:

    function test(uint[] memory a) external view returns(bytes4, bytes32, bytes32, bytes32, bytes32, bytes memory) {
bytes32 temp;
bytes32 _startIn;
bytes32 _elCount;
bytes32 _firstEl;
bytes32 _secondEl;

assembly {
temp := calldataload(0)
_startIn := calldataload(4)
_elCount := calldataload(36)
_firstEl := calldataload(68)
_secondEl := calldataload(100)


}
return (bytes4(temp), _startIn, _elCount, _firstEl, _secondEl, msg.data);
}


Итак, после первых 4 байт идут блоки по bytes32.

* startIn - через сколько байт от начала хранится значение нашего аргумента (массива). Тут вернётся значение 0x20 (нули в начале пропускаю), что равно 32. То есть через 32 байта от начала calldata (плюс ещё 4 байта селектора) начинается наш массив
* elCount - сколько элементов массиве. Вернётся значение 0x00000...02 то есть 2 элемента
* firstEl - первый элемент массива, то есть 0x00000...01
* secondEl - второй элемент, 0x00000...02
🔥19👍1
В ближайших 2-3 уроках более подробно поговорим о написанном выше, посмотрим, как работать со слотами storage, с памятью и где хранятся локальные переменные типа value. Это полезно хотя бы для того, чтобы понимать как контракты работают.

Ну, а на сегодня немного музыки. Всем мира https://www.youtube.com/watch?v=6ey4yAgLZlw
👍12🔥4
Обычно я не публикую ничего по педагогической теме (хотя как инструктор, я время от времени почитываю соответствующие статьи), но тут наткнулся на материал один и потом глянул позиции комментаторов под этим материалом. Конечно, от такого оторопь берёт, если честно. "Учителю нужно было просто пойти к директору, учеников бы в случае чего выгнали из школы - да и всё".

Поделюсь некоторыми инсайдами - всё равно в этом институте я уже давным-давно не работаю, да и живу в другой стране. Вообще студенты никогда особенным прилежанием не отличались, но когда произошло великое слияние двух вузов (МАИ и МАТИ), то стало совсем паршиво. Суть в том, что нам новый заведующий кафедрой, которого внезапно поставили в самом начале учебного года, прямо сказал: делайте что хотите, но кафедра просто не может отчислять студентов больше, чем некий процент N (точно не помню). Иначе её признают неэффективной и могут расформировать, поэтому будь добр ставить хотя бы тройки. Особенно на старших курсах, и никого не интересует, что студент в терминале работать за 4 года не научился, потому что на занятиях не появляется.

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

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

Особенно забавно получилось потом, так как пересдачу согласился принять мой коллега и бывший начальник, параллельно с экзаменом у другой группы. Я остался - просто ради интереса. Минут через 20 я наблюдаю картину, как студентка, сидя прямо передо мной буквально в 2 метрах, преспокойно достаёт конспекты и оттуда списывает. У меня чуть челюсть не отвалилась. Ну, коллега это тоже заметил и выпроводил восвояси. Этого манёвра я не могу понять до сих, если честно.

Да много чего было, что сказать. Но такие рычаги давления есть в институтах, откуда вылететь всё-таки можно, хотя и со скрипом. А уж из школ никого выгонять не будут, это практически исключено.

https://mel.fm/vospitaniye/psikhologiya/5812790-teacher_bullying#comments
👍3👏1😢1
Сегодня интересный вопрос разбирали в школе программирования: как именно размещаются по слотам переменные в случае наследования? Ответить на этот вопрос вам поможет вот такой пример кода:

//SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

contract Parent1 {
uint public parentInt1 = 45;
uint public parentInt2 = 55;

}


contract Parent2 is Parent1 {
uint public parentInt3 = 65;
uint public parentInt4 = 75;

}

contract Parent4 {
uint public parentInt5 = 100;
uint public parentInt6 = 101;

}

contract Parent3 is Parent4 {
uint public parentInt7 = 102;
uint public parentInt8 = 103;

}

contract Demo is Parent2, Parent3 {
uint public demoInt = 76;


function readSlot(uint _n) external view returns (uint data) {
assembly {
data := sload(_n)
}
}
}


Просто указывайте номера слотов и смотрите, что получается.
👍4
GitHub продолжает вводить ачивки https://github.blog/2022-06-09-introducing-achievements-recognizing-the-many-stages-of-a-developers-coding-journey/ Правда они не сообщают, какие именно: дескать, открывайте сами. У меня парочка появилась, но, честно говоря, они какие-то дурацкие 😂
Небольшая статейка для тех, кто использует Lokalise API - в ней я показываю разные примеры на TS, Ruby, Python https://lokalise.com/blog/lokalise-apiv2-in-practice/
👍5
Yarn писал капитан, видимо
😁3👍1
В этом уроке мы обсудим, как использовать популярное решение VCR для тестирования сторонних сервисов (API и прочего). VCR записывает запрос и ответ от сервера в виде специальных кассет, после чего "проигрывает" эти кассеты в последующих тестах. https://www.youtube.com/watch?v=uc5f7vxUyHA
🔥152🎉2👍1
Все любят котиков, а уж котиков, которые показывают трюки - тем более. Так что сегодня наша кошка покажет пару фокусов https://www.youtube.com/watch?v=f6R1kfqEzkg 😄
4👍1