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