Loading...
Loading...
public
не влияет на возможность изменения переменной. Переменные можно изменять только в функциях самого смарт-контракта.uint
(unsigned integer). А числа, которые могут принимать отрицательные значения, называются int
(integer). После названия типа указывается размер числа в битах, например uint8
, int16
, uint256
и т.д.Тип | Что это? | Пример данных | Размер (байт) | Начальное значение |
---|---|---|---|---|
uint8 | Беззнаковое число 8-бит | 0; 255; 100 | 1 | 0 |
uint16 | Беззнаковое число 16-бит | 0; 65535; 1000 | 2 | 0 |
uint32 | Беззнаковое число 32-бит | 0; 4294967295; 1000000 | 4 | 0 |
uint256 | Беззнаковое число 256-бит | 0; 1000000000000000000 | 32 | 0 |
int8 | Знаковое число 8-бит | -128; 127; 0; -50 | 1 | 0 |
int16 | Знаковое число 16-бит | -32768; 32767; -1000 | 2 | 0 |
int32 | Знаковое число 32-бит | -2147483648; 2147483647 | 4 | 0 |
int256 | Знаковое число 256-бит | -123456789; 1000000000 | 32 | 0 |
contract AlexFullNumberVault { // Сейфы, которые могут хранить и долги, и богатства int8 public tinySignedNumber = -128; // От -128 до 127 int16 public smallSignedNumber = -1000; // От -32,768 до 32,767 int256 public hugeSignedNumber = -123456789; // Огромный диапазон
// int без размера = int256 int public temperature = -10; // Может быть отрицательной температурой!}
function calculateDifference(int256 a, int256 b) public pure returns (int256) { return a - b; // Может быть отрицательным результатом}
contract AlexTextLibrary { string public bookTitle = "Приключения в блокчейне"; string public authorName = "Алекс Разработчик"; string public motto = "Код - это поэзия будущего!";
// Функция для объединения текстов function createBookInfo() public view returns (string memory) { return string(abi.encodePacked(bookTitle, " by ", authorName)); }}
Тип | Что это? | Пример данных | Размер (байт) | Начальное значение |
---|---|---|---|---|
string | Строка символов | "Hello"; "Alex Token"; "" | переменный | "" (пустая строка) |
string
записываются в двойных кавычках (например, "Hello") и предназначены для хранения текстовой информации переменной длины.function incorrectCompareStrings(string memory a, string memory b) public pure returns (bool) { // ❌ Строки нельзя сравнивать напрямую! // ❌ Ошибка: Operator == not compatible with types string memory and string memory return a == b;}
function compareStrings(string memory a, string memory b) public pure returns (bool) { // ✅ Нужно сравнивать их хеши return keccak256(bytes(a)) == keccak256(bytes(b));}
keccak256
или функцию работы с байтами abi.encodePacked
. Алекс решил пока отложить этот вопрос на потом. "Позже я обязательно вернусь к этому вопросу".memory
:
— «Почему у строк в функциях написано memory
, а у чисел — нет?»memory
означает "хранить во временной памяти". Числа же всегда занимают фиксированное место, поэтому не нуждаются в таком указании.Тип | Что это? | Пример данных | Размер (байт) | Начальное значение |
---|---|---|---|---|
bytes | Динамический массив байт | 0x1234; 0xabcdef123456 | переменный | 0x (пустые байты) |
bytes1 | Один байт данных | 0x41; 0xFF; 0x00 | 1 | 0x00 |
bytes4 | Четыре байта данных | 0x12345678; 0xFFFFFFFF | 4 | 0x00000000 |
bytes32 | 32 байта данных (хеш) | 0x1234567890abcdef... | 32 | 0x000...000 (32 нуля) |
contract AlexBytesLab { bytes1 public singleByte = 0x41; // Буква 'A' в шестнадцатеричном виде bytes4 public signature = 0x12345678; // Селектор функции bytes32 public hash = keccak256("Alex's secret message"); // Хеш сообщения
// Динамический массив байтов - требует указания memory в функциях bytes public dynamicData = "Hello World!";
function processData(bytes memory data) public pure returns (bytes memory) { return data; // Динамические bytes тоже требуют memory }
function getDataLength() public view returns (uint256) { return dynamicData.length; // Длина в байтах }}
bytes1
, bytes4
, bytes32
) не требуют memory
, а динамические (bytes
) — требуют, как и строки. Всё дело в том, извесен ли нам заранее размер данных, или нет.storage
— постоянное хранилище (как запись в базу данных) — данные сохраняются в блокчейне навсегда, можно читать и писать информацию из функцийmemory
— временное хранилище (как оперативная память) — данные существуют только во время выполнения функции, в них можно читать и писать временную информациюcalldata
— только для чтения (как диск без перезаписи) — данные передаются в функцию, их нельзя изменять и они не сохраняются после выполнения функцииmemory
?string
, bytes
, массивы) → нужно указать memory
uint
, int
, bool
, address
, bytes32
) → memory
не нуженcontract AlexStorageDemo { // ✅ Правильно - сложные типы требуют memory function setMessage(string memory newMessage) public pure returns (string memory) { return newMessage; }
// ✅ Правильно - простые типы НЕ требуют memory function calculateSum(uint256 a, uint256 b) public pure returns (uint256) { return a + b; }}
Тип | Что это? | Пример данных | Размер (байт) | Начальное значение |
---|---|---|---|---|
address | Адрес кошелька/контракта | 0xc257274276a4e539741ca11b590b9447b26a8051; 0x0000000000000000000000000000000000000000 | 20 | address(0) |
address payable | Адрес для получения эфира | 0xc257274276a4e539741ca11b590b9447b26a8051 | 20 | address(0) |
address(0)
, который является нулевым адресом. Этот адрес используется для обозначения отсутствия адреса. Ни один пользователь не может иметь адрес address(0)
. Например, если на нулевой адрес случайно (или намеренно) отправить эфир или баланс цифрового актива, этот баланс нельзя будет вывести ни одному пользователю. Также нулевой адрес является значением по умолчанию для типа данных address. Это означает, что если переменная с адресом не была инициализирована, она будет равна address(0)
.contract AlexAddressBook { address public myAddress; // Мой текущего смарт-контракта address public contractCreator; // Адрес создателя контракта address public someUser; // Адрес пользователя
constructor() { myAddress = address(this); // Записываем адрес текущего контракта в переменную contractCreator = msg.sender; // msg.sender – кто развернул контракт, аккаунт пользователя }
// Мягкая проверка валидности адреса function isValidAddress(address _addr) public pure returns (bool) { return _addr != address(0); // Проверяем, что адрес не нулевой }
// Получение баланса эфира на кошельке или смарт-контракте по заданному адресу function getBalance(address _addr) public view returns (uint256) { return _addr.balance; }}
contract AlexPayableDemo { address payable public wallet; // Кошелек, он может получать эфир address payable public owner; // Адрес владельца, он может получать эфир
constructor() { owner = payable(msg.sender); // Преобразуем обычный адрес в payable }
// Функция для отправки эфира на payable адрес function sendEther(address payable recipient) public payable { require(msg.value > 0, "Нужно отправить больше 0 эфира"); require(recipient != address(0), "Неверный адрес получателя");
recipient.transfer(msg.value); // Отправляем эфир }
// Вывод всех средств владельцу function withdraw() public { require(msg.sender == owner, "Только владелец может вывести средства"); owner.transfer(address(this).balance); }
// Функция для получения эфира receive() external payable { // Контракт может получать эфир }}
bool
. Он может принимать только два значения: true
или false
– правда или ложь. Логические переменные часто используются для определения, в каком состоянии находится контракт. Например, открыто ли прохождение уроков на платформе BlockFirst, или является ли пользователь инвестором.Тип | Что это? | Пример данных | Размер (байт) | Начальное значение |
---|---|---|---|---|
bool | Истина или ложь | true; false | 1 | false |
contract AlexDecisionMaker { bool public isLearning = true; bool public hasCompletedLesson = false; bool public isReadyForAdvanced = false;
function completeLesson() public { hasCompletedLesson = true; checkProgress(); }
function checkProgress() internal { if (isLearning && hasCompletedLesson) { isReadyForAdvanced = true; } }
function getStatus() public view returns (string memory) { if (isReadyForAdvanced) { return "Готов к продвинутым урокам!"; } else if (hasCompletedLesson) { return "Урок завершен, но еще учусь"; } else { return "Еще изучаю урок"; } }}
contract AlexDefaultValues { // Эти переменные не имеют явно заданных значений uint256 public defaultNumber; // Автоматически = 0 int256 public defaultSignedNumber; // Автоматически = 0 bool public defaultBool; // Автоматически = false address public defaultAddress; // Автоматически = address(0) string public defaultString; // Автоматически = "" bytes public defaultBytes; // Автоматически = 0x
// А эти переменные явно инициализированы uint256 public explicitNumber = 0; // Явно установлено 0 bool public explicitBool = false; // Явно установлено false
function showDefaultValues() public view returns ( uint256 num, int256 signedNum, bool boolean, address addr, string memory str ) { return ( defaultNumber, // Вернёт 0 defaultSignedNumber, // Вернёт 0 defaultBool, // Вернёт false defaultAddress, // Вернёт 0x0000000000000000000000000000000000000000 defaultString // Вернёт "" ); }}
contract AlexBasicDataTypes { // === ЧИСЛОВЫЕ ТИПЫ === // Беззнаковые числа (только положительные) uint8 public smallNumber = 255; // Максимум 255 uint256 public tokenBalance = 1000000; // Баланс токенов (большое число)
// Знаковые числа (могут быть отрицательными) int8 public temperature = -10; // Температура может быть отрицательной int256 public profit = -50000; // Прибыль может быть отрицательной
// === ТЕКСТОВЫЕ И БАЙТОВЫЕ ТИПЫ === string public userName = "Alex"; // Имя пользователя string public projectName = "TokenWorld"; // Название проекта
bytes1 public singleByte = 0x41; // Один байт (буква 'A') bytes32 public secretHash = keccak256("MySecret123"); // Хеш секретного сообщения
// === ЛОГИЧЕСКИЙ ТИП === bool public isLearningComplete = false; // Завершено ли обучение bool public hasAccess = true; // Есть ли доступ
// === АДРЕСНЫЕ ТИПЫ === address public contractOwner; // Владелец контракта address payable public treasuryWallet; // Кошелек для получения эфира
constructor() { contractOwner = msg.sender; // Устанавливаем владельца treasuryWallet = payable(msg.sender); // Устанавливаем payable кошелек }
// Функция для демонстрации работы с числами function calculateTokens(uint256 baseAmount) public pure returns (uint256) { return baseAmount * 2; // Удваиваем количество токенов }
// Функция для работы с логическими значениями function completeLesson() public { isLearningComplete = true; // Отмечаем урок как завершенный }
// Функция для проверки доступа function checkAccess() public view returns (string memory) { if (hasAccess && isLearningComplete) { return "Доступ разрешен! Урок завершен."; } else if (hasAccess) { return "Доступ есть, но урок не завершен"; } else { return "Доступ запрещен"; } }
// Функция для работы с адресами function isOwner(address user) public view returns (bool) { return user == contractOwner; }
// Функция для получения информации о контракте function getContractInfo() public view returns ( string memory name, uint256 balance, bool access, address owner ) { return ( projectName, tokenBalance, hasAccess, contractOwner ); }}
Загрузка...
Загрузка...
Загрузка...