Solidity / Типы данных
Вступление
Начну с того, что solidity это строго типизированный язык, а это значит, что у каждой переменной обязательно нужно указывать ее тип:
uint a = 0 string b = "Hi NaN" bool c = true
Int / Uint
Это тип данных intenger (целые числа), int - это положительные и отрицательные числа, uint - только положительные.
uint8 uint16 uint32 uint64 uint128 uint256
Число после uint
указывает на количество бит, используемых для представления значения. Например, uint8
может представить целые числа от 0 до 255 (2^8 - 1), в то время как uint256
может представлять очень большие числа.
String
В языке программирования Solidity, тип данных string
используется для представления динамических строковых значений. Строки (string
) в Solidity могут содержать любые последовательности символов, включая буквы, цифры, специальные символы и даже пустые строки.
string myString = "Hello, World!";
Тип string
поддерживает несколько операций и функций для работы со строками. Некоторые из них включают:
string myString = "Hello, "; string anotherString = "World!"; string concatenatedString = myString + anotherString; // Результат: "Hello, World!"
string myString = "Hello"; uint length = bytes(myString).length; // Результат: 5
string string1 = "Hello"; string string2 = "World"; bool isEqual = (keccak256(abi.encodePacked(string1)) == keccak256(abi.encodePacked(string2))); // Результат: false int comparisonResult = string1.compare(string2); // Результат: -1 (если первая строка меньше), 0 (если строки равны), 1 (если первая строка больше)
string myString = "Hello"; bytes memory stringBytes = bytes(myString); bytes1 firstCharacter = stringBytes[0]; // Результат: 'H'
Важно отметить, что строки в Solidity могут быть затратными в плане газа, особенно если они длинные или изменяемые. Работа с ними может потребовать больше вычислительных ресурсов и газа, чем с целочисленными типами данных. Поэтому, если вам нужно работать с большими строками или совершать много операций со строками, важно учесть это при проектировании и тестировании вашего контракта.
Bool
Тип данных bool
представляет логическое значение, которое может быть либо true
(истина), либо false
(ложь). Тип bool
используется для условных операций и логических выражений.
Пример объявления переменной типа bool
:
bool myBool;
Тип bool
поддерживает операции и функции для работы с логическими значениями. Некоторые из них включают:
bool a = true; bool b = false; bool result1 = a && b; // Результат: false bool result2 = a || b; // Результат: true bool result3 = !a; // Результат: false
bool a = true; bool b = false; bool isEqual = (a == b); // Результат: false bool isNotEqual = (a != b); // Результат: true
bool condition = true; if (condition) { // Выполняется, если условие истинно } else { // Выполняется, если условие ложно }
function isGreaterThan(uint a, uint b) public pure returns (bool) { return a > b; }
Логические значения true
и false
могут использоваться для управления ходом выполнения программы, принятия решений и задания условий. Они широко применяются в контрактах Solidity для проверки условий выполнения и принятия соответствующих действий в зависимости от результата проверки.
Address
Тип данных address
используется для представления адресов Ethereum. Адрес Ethereum - это 20-байтовое значение, которое уникально идентифицирует счет или контракт на блокчейне Ethereum.
Пример объявления переменной типа address
:
address myAddress;
Тип address
поддерживает операции и функции для работы с адресами Ethereum. Некоторые из них включают:
address address1 = 0x1234567890123456789012345678901234567890; address address2 = 0x0987654321098765432109876543210987654321; bool isEqual = (address1 == address2); // Результат: false bool isNotEqual = (address1 != address2); // Результат: true
address myAddress = 0x1234567890123456789012345678901234567890; uint balance = myAddress.balance;
address recipient = 0x0987654321098765432109876543210987654321; uint amount = 1 ether; bool success = recipient.transfer(amount);
Тип address
также имеет встроенные члены, такие как balance
и transfer
, которые предоставляют информацию о балансе адреса и функцию для отправки Ether. Они полезны для взаимодействия с другими адресами Ethereum и управления переводами Ether.
Array
Массив (array
) представляет упорядоченную коллекцию элементов одного типа. Массивы могут быть одномерными или многомерными и могут содержать фиксированное количество элементов или быть динамическими, изменяемыми по размеру.
// Объявление одномерного фиксированного массива с размером 5 uint[5] myFixedArray; // Объявление одномерного динамического массива uint[] myDynamicArray;
// Объявление двумерного фиксированного массива с размерами 3x2 uint[3][2] myFixed2DArray; // Объявление двумерного динамического массива uint[][2] myDynamic2DArray;
Операции и функции для работы с массивами:
uint[] myArray = [1, 2, 3, 4, 5]; uint length = myArray.length; // Результат: 5
uint[] myArray = [1, 2, 3, 4, 5]; uint element = myArray[2]; // Результат: 3
solidityCopy codeuint[] myArray = [1, 2, 3, 4, 5]; myArray[2] = 10; // Изменение элемента с индексом 2 на 10
uint[] myArray; myArray.push(10); myArray.push(20);
uint[] myArray = [1, 2, 3, 4, 5]; for (uint i = 0; i < myArray.length; i++) { // Использование myArray[i] }
function doubleValues(uint[] array) public pure returns (uint[] memory) { uint[] memory result = new uint[](array.length); for (uint i = 0; i < array.length; i++) { result[i] = array[i] * 2; } return result; }
Обратите внимание, что в Solidity существуют ограничения на максимальный размер массива и использование больших массивов может быть затратным в плане газа. При работе с массивами также следует обратить внимание на возможные проблемы безопасности, такие как переполнение массива или неправильное использование индексов.
Mapping
mapping
- это структура данных, которая представляет собой ассоциативный массив (словарь) для связывания ключей с их значениями. Он позволяет хранить и получать значения по ключу.
mapping
объявляется с использованием ключевого слова mapping
, за которым следуют типы ключа и значения в угловых скобках < >
. Ключ может быть любым типом данных, за исключением динамических массивов, а значение может быть любым типом данных.
mapping(uint => string) myMapping;
mapping
может быть использован для создания простого словаря, где ключи и значения связаны между собой. Значения могут быть установлены или получены с использованием оператора доступа вида mapping[key]
.
mapping(uint => string) names; function setName(uint id, string memory name) public { names[id] = name; } function getName(uint id) public view returns (string memory) { return names[id]; }
В приведенном примере функция setName
принимает id
в качестве ключа и name
в качестве значения, которое связывается с ключом в mapping
. Функция getName
принимает id
в качестве аргумента и возвращает соответствующее ему значение из mapping
.
Важно отметить, что mapping
в Solidity не является итерируемым, то есть нельзя получить список всех ключей или значений напрямую. Также нельзя проверить наличие ключа в mapping
. Обычно используются другие структуры данных, такие как массивы или дополнительные переменные, для выполнения таких операций.
mapping
подходит для хранения и доступа к данным по ключу, что делает его полезным для многих сценариев в разработке контрактов на Ethereum, например, для отображения аккаунтов и их балансов, учета голосов, записи истории и многое другое.
Struct
struct
- это пользовательский тип данных, который позволяет объединять несколько различных типов данных в одну структуру. Структуры позволяют создавать новые типы данных, состоящие из нескольких полей, каждое из которых может иметь свой собственный тип.
Структуры определяются с использованием ключевого слова struct
, за которым следует имя структуры и список полей в фигурных скобках { }
.
struct Person { string name; uint age; address wallet; }
В приведенном примере определена структура Person
с тремя полями: name
типа string
, age
типа uint
и wallet
типа address
.
Структуры могут использоваться для создания экземпляров (объектов) этого типа данных, где каждое поле может быть заполнено соответствующим значением.
Пример создания экземпляра структуры:
Person myPerson; myPerson.name = "Alice"; myPerson.age = 30; myPerson.wallet = 0x1234567890123456789012345678901234567890;
Структуры также могут использоваться внутри других типов данных, таких как массивы, mapping
и даже другие структуры.
Структуры могут быть полезны в случаях, когда вы хотите объединить несколько связанных полей данных в одну сущность. Они позволяют более структурированное представление данных и более логичное организацию кода.
А на этом всё, надеюсь было полезно и понятно.
Телеграм: https://t.me/one_eyes
Чатик: https://t.me/one_eyes_chat