Часть 1 - Создание смарт-контракта с Solidity in Remix

Здесь вы можете найти вторую часть этого руководства.

Я новичок в области Ethereum и блокчейнов. В своем стремлении учиться я просмотрел множество приложений, использующих различные интерфейсные технологии с Solidity. В итоге я сам создал несколько приложений, используя React и Vue с Web3, ganache-cli, Metamask и Solidity.

Недавно у меня возникла мысль: «Могу ли я получить доступ к методам контракта Solidity с помощью GraphQL и перенести большую часть логики на сервер?» На этот вопрос можно было ответить только одним способом ...

TL; DR; Ознакомьтесь с моим репозиторием на GitHub, чтобы увидеть полный проект:
https://github.com/redacademy/ethereum-graphql

В этой серии сообщений, состоящей из двух частей, мы реализуем сервер GraphQL с использованием Express и Node.js, чтобы общаться с простым Solidity Smart Договор предназначен для приема пожертвований.

Начиная

Что вам понадобится:
1. Редактор кода по вашему выбору (я предпочитаю VS Code)
2. Расширение для браузера Metamask
3 . Ganache-cli (npm install -g ganache-cli)
4. Node.js установлен на вашем компьютере
5. Знание JavaScript (некоторые знания Solidity тоже помогут)
6. Некоторые знания GraphQL

Если у вас есть опыт работы с Solidity и Remix, отлично! Если нет, не беспокойтесь об этом. Вы быстро это поймете.

Напишите договор

Откройте Ремикс и создайте новый файл. Синтаксис Solidity похож на JavaScript, что упрощает его изучение и понимание. Если вы знаете JavaScript, отлично! В противном случае вы почувствуете, что значит писать Solidity в следующий раз.

Сначала создайте класс с конструктором и модификатором доступа. Если вы не знаете, что такое модификатор доступа, вы можете прочитать о них подробнее здесь.

// declare what version of solidity you want to use
pragma solidity ^0.4.10;
contract Ownable {
    address owner;
    constructor() public {
        owner = msg.sender;
    }
    
    // access modifier
    modifier Owned {
        require(msg.sender == owner);
        _;
    }
}

Здесь мы создаем var owner типа address в нашем конструкторе, чтобы мы могли сохранить адрес создателя контракта как owner. Добавление модификатора доступа гарантирует, что только адрес Ethereum владельца может выполнять функции в нашем новом контракте.

Двигаясь дальше, давайте создадим способ «убить» наш контракт. Если владелец вызовет этот метод, мы больше не сможем использовать этот контракт.

contract Mortal is Ownable {
    function kill() public Owned {
        selfdestruct(owner);
    }
}

Наш контракт называется Mortal - он наследует контракт Ownable. Только владелец этого контракта может закрыть этот контракт, потому что мы использовали модификатор доступа, созданный на последнем шаге.

Теперь приступим к написанию контракта на прием пожертвований в Ethereum:

contract Donate is Mortal {
 string prize;
 event donation_made(uint _amount);
 event show_prize(string _prize);
 // Make contract payable and public
 constructor(string _prize) payable public  {
        // Check if the prize exists
        require(bytes(_prize).length > 0);                    
        // Assign initial value to the contract balance      
        balance Of[address(this)] = msg.value;
        prize = _prize; 
    }
}

Наш контракт Donate наследует контракт Mortal (что означает, что владелец может убить этот контракт в случае необходимости) и имеет конструктор, который принимает prize.

При создании экземпляра этого контракта мы проверяем, имеет ли prize значение, и если оно есть, мы присваиваем начальное значение балансу контракта (подробнее об этом позже).

Мы также написали два события, чтобы сообщить нам, когда в наш контракт поступает пожертвование и какой приз получает пользователь за пожертвование эфира. Наконец, мы присваиваем _prize prize. Супер просто!

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

function() public{
    // Fallback
    revert();
}

Теперь давайте напишем в нашем контракте функцию, которая поможет нам проверить баланс контракта. Эта функция возвращает значение uint в wei, которое представляет собой баланс нашего контракта - только владелец контракта может выполнить этот метод. (Спасибо, модификатор доступа!)

function checkContractBalance() Owned public view returns(uint) {
    return balanceOf[address(this)];
}

Наконец, давайте добавим функцию для приема пожертвования и установим новый баланс для нашего контракта:

function make_donation() payable public {
        // msg.value is the amount of eth being donated
        uint donation = msg.value;
        // Make sure donation is more than 0 eth
        require(donation > 0);    
        // Set a new balance for our contract
        balanceOf[address(this)] += donation; 
        // Emit events here
        emit donation_made(donation);
        emit show_prize(prize);
}

payable функции - это функции, которые захватывают входящий эфир. Здесь мы проверяем, не превышает ли msg.value (количество пожертвованного эфира) 0. Если да, то мы добавляем пожертвованный эфир к существующему балансу контракта и генерируем наши события.

Проверить код контракта

Потрясающие! Мы закончили писать код для нашего смарт-контракта. Теперь щелкните вкладку «Выполнить» в правом верхнем углу Remix. Используйте следующие настройки:

Среда: JavaScript VM
Значение: 10 ether

Все остальное остается прежним:

Рядом с кнопкой Развернуть мы видим текстовое поле ввода. Введите значение приза (например, «бесплатное объятие»), а затем нажмите кнопку Развернуть.

Если вы нажмете на кнопку checkContractBalance, вы должны увидеть 10 эфиров (в вэй).

Давай попробуем пожертвовать немного эфира. Введите 5 в поле Значение и нажмите кнопку make_donation. Проверьте свои журналы! Если еще раз проверить баланс, он должен быть 15 эфиров (в вэй). Большой! Мы сделали пожертвование в рамках нашего контракта на блокчейн Ethereum.

Поздравляю! Мы закончили писать наш Donation Смарт-контракт.

Во части 2 мы создадим сервер GraphQL (с помощью Express) для связи с нашим новым смарт-контрактом.

Если вам понравился этот пост и вы хотите продолжить изучение разработки приложений и веб-приложений с помощью RED Academy, обязательно подпишитесь на нас на Medium или посетите наш веб-сайт.