Solidity. Смарт контракты и аудит
2.62K subscribers
246 photos
7 videos
18 files
547 links
Обучение Solidity. Уроки, аудит, разбор кода и популярных сервисов
Download Telegram
Массивы, они же array, могут быть, как с фиксированной длинной, которая указывается в квадратных скобках, так и динамические.

Нужно отметить, что на данный момент, в Solidity нельзя создавать массивы, в которых хранятся разные типы данных.

Если вы указали тип данных uint, то и все значения в массиве должны быть uint.

#array #массивы
👍1🔥1
Массивы могут быть вложенными.

В этом случае длина массива, например, uint[10][5] будет равна 5, а длина вложенных - 10. Т.е. длина основного массива читается с конца.

Также обратите внимание, что значения в массивах нумеруются с "0".

#array #массивы #вложенныемассивы
👍3🔥1
В динамический массив мы можем помещать значения с помощью метода push, а проверить его длину с помощью length.

Эти методы не доступны для фиксированных массивов.

#array #массивы
🔥1
Можно также создавать временные массивы массивы.

Тут важно запомнить саму конструкцию создания массива, а также то, что он должен быть обязательно фиксированной длины.

#array #массивы
🔥1
Динамические массивы и мэппинги в storage

И сразу по следам предыдущего видео мы посмотрим другой урок о storage.

Видео урок.

Здесь лектор более наглядно рассказывает о том, как располагаются значения в хранилище. Особое внимание он уделяет динамическим массивам и mapping.

В задачах на взлом контрактов мы встречали несколько упражнений, где требовалось знать работу памяти и уметь доставать значения через getStorageAt(). Поэтому эта тема является достаточно важной для обучения блокчейн разработчика!

#mapping #array #storage
👍1
Solidity hints. Часть 13

Понемногу движемся дальше и сегодня на очереди у нас:

19. Internal function calls do not create an EVM message call. They are called using simple jump statements. Same for functions of inherited contracts.

что в переводе:

Internal функции не создают EVM вызов, а используют внутренние опкоды jump. Тоже самое актуально и для наследуемых контрактов.

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

У нас есть 4 области видимости для функций: public, external, internal и private. Первые две - открытые для доступа других контрактов, вторые - закрыты.

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

Доступ к внутренним функциям возможен только внутри текущего контракта или контрактов, вытекающих из него. Они не могут быть доступны извне. Поскольку они не открыты для внешнего доступа через ABI контракта, они могут принимать параметры внутренних типов, таких как mapping или storage references.

Внутренние функции вызываются через инструкции опкоды JUMP / JUMPI, просто перепрыгивая в другую точку текущего кода. Это имеет смысл, потому что внутренние функции не меняют контекст (то есть остаются внутри одного и того же контракта при вызове).

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

Думаю, можно подытожить: если мы можем вызывать функцию извне, то это EVM вызов, если же она предназначена только для внутреннего использования - то это работа опкодов.

Следующий пункт:

20. If you have a public state variable of array type, then you can only retrieve single elements of the array via the generated getter function.

что в переводе и полной версии из документации звучит как:

Если у вас есть публичная переменная состояния типа массив, то вы можете получить только отдельные элементы массива через сгенерированную функцию getter. Этот механизм существует для того, чтобы избежать высоких газовых затрат при возврате целого массива. Вы можете использовать аргументы, чтобы указать, какой отдельный элемент возвращать, например myArray(0). Если вы хотите вернуть весь массив за один вызов, то вам нужно написать функцию, например:

contract arrayExample {

uint[] public myArray;
function myArray(uint i) public view returns (uint) {
return myArray[i];
}

function getArray() public view returns (uint[] memory) {
return myArray;
}
}


Также немного запутанный пункт и документация для начинающих разработчиков.

Смотрите, когда мы создаем переменную с областью видимости public, EVM также создает для нее специальный геттер, по которому можно прочитать значение этой переменной. Проще всего это будет понять, попытавшись создать в Ремиксе контракт с двумя переменными public и internal.

Для первой переменной у вас появится кнопка в левой панели Ремикса, для того чтобы посмотреть ее значение, но для internal - ее не будет.

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

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

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

#array #getter #jump #external
👍2💯2🌭1