Loading...
Loading...

Тип | Что это? | Пример данных | Размер (байт) | Начальное значение |
|---|---|---|---|---|
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 означает "хранить во временной памяти". Числа же всегда занимают фиксированное место, поэтому не нуждаются в таком указании.storage — постоянное хранилище (как запись в базу данных) — данные сохраняются в блокчейне навсегда, можно читать и писать информацию из функцийmemory — временное хранилище (как оперативная память) — данные существуют только во время выполнения функции, в них можно читать и писать временную информациюcalldata — только для чтения (как диск без перезаписи) — данные передаются в функцию, их нельзя изменять и они не сохраняются после выполнения функцииmemory?string, bytes, массивы) → нужно указать memoryuint, 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; }}Тип | Что это? | Пример данных | Размер (байт) | Начальное значение |
|---|---|---|---|---|
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) — требуют, как и строки. Всё дело в том, известен ли нам заранее размер данных, или нет.Тип | Что это? | Пример данных | Размер (байт) | Начальное значение |
|---|---|---|---|---|
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 { // Контракт может получать эфир }}contract AlexAdvancedDataTypes { // === ТЕКСТОВЫЕ ТИПЫ === string public userName = "Alex"; // Имя пользователя string public projectName = "TokenWorld"; // Название проекта
// === БАЙТОВЫЕ ТИПЫ === bytes1 public singleByte = 0x41; // Один байт (буква 'A') bytes32 public secretHash = keccak256("MySecret123"); // Хеш секретного сообщения bytes public dynamicData = "Hello World!"; // Динамические байты
// === АДРЕСНЫЕ ТИПЫ === address public contractOwner; // Владелец контракта address payable public treasuryWallet; // Кошелек для получения эфира
constructor() { contractOwner = msg.sender; // Устанавливаем владельца treasuryWallet = payable(msg.sender); // Устанавливаем payable кошелек }
// Функция для работы со строками function updateUserName(string memory newName) public { require(msg.sender == contractOwner, "Только владелец может изменить имя"); userName = newName; }
// Функция для сравнения строк function compareNames(string memory name) public view returns (bool) { return keccak256(bytes(userName)) == keccak256(bytes(name)); }
// Функция для работы с байтами function createHash(string memory message) public pure returns (bytes32) { return keccak256(bytes(message)); }
// Функция для работы с адресами function isOwner(address user) public view returns (bool) { return user == contractOwner; }
// Функция для получения информации о контракте function getContractInfo() public view returns ( string memory name, string memory project, address owner, bytes32 hash ) { return ( userName, projectName, contractOwner, secretHash ); }
// Функция для работы с динамическими байтами function updateDynamicData(bytes memory newData) public { require(msg.sender == contractOwner, "Только владелец может обновить данные"); dynamicData = newData; }
// Функция для получения длины динамических данных function getDataLength() public view returns (uint256) { return dynamicData.length; }}

