Как стать автором
Поиск
Написать публикацию
Обновить
539.49
OTUS
Развиваем технологии, обучая их создателей

Исчерпывающее руководство по разработке смарт-контрактов на Solidity

Время на прочтение8 мин
Количество просмотров537
Автор оригинала: codebyankita

Solidity — это статически типизированный язык программирования, ориентированный на контракты и используемый в основном для написания и реализации смарт‑контрактов на блокчейне Ethereum. Создание высококачественных смарт‑контрактов обеспечивает безопасность, надежность и эффективность. В этой статье рассматриваются основные концепции, лучшие практики и примеры создания надежных смарт‑контрактов с помощью Solidity.

Введение в смарт-контракты Solidity

Смарт‑контракты — это самоисполняющиеся контракты с условиями соглашения, записанными непосредственно в коде. Они работают на децентрализованных платформах, таких как Ethereum, и Solidity — самый популярный язык, используемый для разработки таких контрактов.

Основные компоненты смарт‑контрактов включают:

  • Переменные состояния: Данные, хранящиеся в блокчейне.

  • Функции: Логика для манипулирования состоянием.

  • События: Журналы для off‑chain слушателей для отслеживания действий.

Пример контракта Solidity

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

 

contract SimpleStorage {
    // State variable to store data
    uint256 public storedData;

    // Event to log data updates
    event DataUpdated(uint256 indexed newData);
 
    // Function to update stored data
    function set(uint256 newData) public {
        storedData = newData;
        emit DataUpdated(newData);  // Trigger event
    }

    // Function to retrieve the stored data

    function get() public view returns (uint256) {
        return storedData;
    }
}

Базовая структура смарт-контракта

В основе смарт‑контракта Solidity лежат переменные состояния, функции и события.

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

contract SimpleStorage {

    // State Variables
    uint256 public storedData;
    address public owner;

    // Events
    event DataUpdated(uint256 newData);
    // Modifiers

    modifier onlyOwner() {
        require(msg.sender == owner, "Caller is not the owner");
        _;
    }

    // Constructor
    constructor() {
        owner = msg.sender;
    }

    // Functions

    function set(uint256 x) public onlyOwner {
        storedData = x;
        emit DataUpdated(x);
    }

    function get() public view returns (uint256) {
        return storedData;
    }
}

Ключевые понятия:

  • Переменные состояния: Они хранятся в блокчейне и сохраняются во время всех вызовов контракта.

  • Модификаторы: Изменяют поведение функции. В данном случае onlyOwner гарантирует, что только владелец контракта может вызывать определенные функции.

  • События: Выдают журналы, которые могут прослушивать внешние приложения (например, веб‑интерфейсы). Используются для записи активности в блокчейн.

  • Конструктор: Эта специальная функция выполняется один раз при развертывании контракта, обычно для инициализации.

  • Публичные и приватные функции: Функции могут быть публичными (доступными всем желающим) или ограниченными определенными пользователями, например владельцем контракта.

  • Функции просмотра: Это функции «только для чтения», которые не изменяют блокчейн.

Типы данных и управляющие структуры

Типы данных в Solidity:

  • uint: Беззнаковое целое число, например uint256.

  • address: Тип адреса Ethereum.

  • bool: Булево, истина или ложь.

  • string: Для хранения текста.

  • struct: Тип данных, определяемый пользователем.

  • int: целое со знаком.

Пример:

struct User {

    string name;
    uint256 age;

}

User[] public users;

Управляющие структуры:

Solidity поддерживает традиционные структуры управления, такие как if, for и while.

function calculateSum(uint limit) public pure returns (uint) {

    uint sum = 0;
    for (uint i = 0; i < limit; i++) {
        sum += i;
    }
    return sum;

}

Лучшие практики безопасности

Безопасность очень важна для разработки смарт‑контрактов, поскольку уязвимости могут привести к потере средств или управления. Ниже приведены некоторые распространенные практики для снижения рисков.

Атаки реентерабельности

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

Решение: Используйте паттерн «проверка‑эффект‑взаимодействие».

mapping(address => uint) public balances;
 

function withdraw(uint amount) public {
    require(balances[msg.sender] >= amount, "Insufficient balance");
  

    // Check-Effects-Interactions pattern
    uint previousBalance = balances[msg.sender];
    balances[msg.sender] = 0;
 

    (bool success, ) = msg.sender.call{value: amount}("");

    require(success, "Transfer failed");

    balances[msg.sender] = previousBalance - amount;

}

Использование SafeMath: Арифметические переполнения/недополнения

Ошибки переполнения и недополнения возникают, когда арифметические операции превышают или опускаются ниже предела типа данных. SafeMath предотвращает подобные проблемы. Начиная с Solidity 0.8, арифметические операции возвращаются при переполнении/недополнении, но использование SafeMath из библиотеки OpenZeppelin может помочь и в более старых версиях.

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/utils/math/SafeMath.sol";

contract SafeMathExample {
    using SafeMath for uint256;

    function addNumbers(uint256 a, uint256 b) public pure returns (uint256) {
        return a.add(b);
    }

}

Общие паттерны Solidity

Паттерн Ownable:

Этот паттерн ограничивает выполнение определенных функций владельцем контракта. Вы можете использовать контракт Ownable из OpenZeppelin.

import "@openzeppelin/contracts/access/Ownable.sol";

contract MyContract is Ownable {
    string private data;
    function setData(string memory newData) public onlyOwner {
        data = newData;
    }

    function getData() public view returns (string memory) {
        return data;
    }

}

Стандарты ERC

Стандарты Ethereum Request for Comments (ERC) определяют стандартные API для контрактов. Два наиболее распространенных стандарта — ERC-20 и ERC-721.

ERC-20 (стандарт сменных токенов)

ERC-20 определяет стандартный интерфейс для сменных токенов, то есть каждый токен неотличим от другого.

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    constructor() ERC20("MyToken", "MTK") {
        _mint(msg.sender, 1000  10 * decimals());
    }

}

Ключевые функции ERC-20:

totalSupply(): Возвращает общее количество токенов.

balanceOf(address account): Возвращает баланс токенов по определенному адресу.

transfer(address to, uint256 amount): Переводит токены на другой адрес.

ERC-721 (стандарт неплатежеспособных токенов)

ERC-721 используется для создания уникальных неплатежеспособных токенов (NFT).

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract MyNFT is ERC721 {
    uint public nextTokenId;
    address public admin;
    constructor() ERC721("MyNFT", "MNFT") {
        admin = msg.sender;
    }

    function mint(address to) external {
        require(msg.sender == admin, "Only admin can mint");
        _safeMint(to, nextTokenId);
        nextTokenId++;
    }

}

Функции ключа ERC-721:

ownerOf(uint256 tokenId): Возвращает владельца данного НМТ.

transferFrom(address from, address to, uint256 tokenId): Передает право собственности на НМТ.

Тестирование и развертывание

Тестирование и развертывание — важнейшие этапы жизненного цикла смарт‑контракта. Hardhat — это среда разработки для компиляции, тестирования и развертывания смарт‑контрактов. Тесты можно писать на JavaScript (или TypeScript).

Пример использования Hardhat:

const { expect } = require("chai");

 

describe("MyToken contract", function () {
  it("Deployment should assign total supply to the owner", async function () {
    const [owner] = await ethers.getSigners();
    const Token = await ethers.getContractFactory("MyToken");
    const myToken = await Token.deploy();
    const ownerBalance = await myToken.balanceOf(owner.address);
    expect(await myToken.totalSupply()).to.equal(ownerBalance);
  });
});

Вы можете легко развернуть контракт с помощью IDE Remix.Для этого скопируйте контракт в Remix, выберите версию компилятора и скомпилируйте контракт.

Разверните его на вкладке «Развертывание и запуск транзакций», выбрав сеть (например, Ethereum, тестовые сети Rinkeby, Sepolia и т. д.).

Лучшие практики написания высококачественных смарт-контрактов

Сохраняйте простоту контрактов: Простота сводит к минимуму возможные ошибки и уязвимости в системе безопасности.

Тщательно тестируйте: Пишите модульные тесты и моделируйте реальные сценарии с помощью Hardhat или Truffle.

Используйте библиотеки: OpenZeppelin предоставляет проверенные в боях контракты, такие как Ownable, ERC20 и стандарт SafeMath ERC.

Аудиты безопасности: Поручите аудит вашего контракта профессионалам.

Заключение

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

Разработка смарт‑контрактов продолжает развиваться, и обучение эффективному написанию, тестированию и внедрению контрактов будет иметь решающее значение для будущего технологии блокчейн. Продолжайте развивать и совершенствовать свои знания, чтобы оставаться на переднем крае этой захватывающей области!


Приглашаем вас на серию открытых уроков по курсу Solidity Developer, где вы сможете познакомиться с ключевыми аспектами разработки смарт‑контрактов и децентрализованных приложений.

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

Теги:
Хабы:
+3
Комментарии0

Публикации

Информация

Сайт
otus.ru
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия
Представитель
OTUS