Если вам интересна тема разработки продуктов использующих смартконтракты, но вы хотите понять полный цикл создания таких приложений, то этот урок специально для вас (надеюсь). Из него вы узнаете как разработать, оттестировать, залить в сеть и интегрировать в ваше приложение смартконтракт для блокчейна Ethereum.  Для примера я взял знакомый всем с детства финансовый инструмент — копилку. Для того чтобы продемонстрировать всю мощь смарт-контрактов, я добавил возможность указать лимит, который не позволит снять деньги пока на счету не накопится определенная сумма. Все материалы урока вы можете найти в репозитории PiggyBank, который содержит скрипты и UI для запуска примера.  Цель урока показать полный цикл разработки, поэтому код местами значительно упрощен. В повседневной разработке я советую применять иструменты вроде Truffle.  Помимо написания самого смарт-контракта, необходимо проделать следущие шаги: Чтобы запустить приложение вам понадобится запустить тестовую сеть. Сделать это можно командой node bin/testnet.js. Для начала напишем контракт. Алгоритм работы контаркта следующий: Приведу код контракта из файла contract.sol: После того, как контракт создан можно приступить к решению инфраструктурных задач.  Файл 1-account.js. Данный скрипт создает тестовый аккаунт с определенным балансом. При вызове из консоли файла 0-account.js вам будет предложенно ввести пароль и сумму в ether на вашем счету. После успешного выполнения секретный ключ и сумма будут записаны в файл account.json.  расскажу подробнее о ключах. Для создания аккаунта необходимо создать секретный ключ. Из секретного ключа будут в дальнейшем получен адрес кошелька и публичный ключ. Секретный ключ это шестнадцатиричное число размером 256 бит, представленное в виде строки длинной 64 символа, содержащей префикс 0x. Лучше всего получить подобное значение с помощью генератора случайных чисел: Но для тестовых нужд мы будем получать sha3-хеш из введенного пользователем пароля: Что на выходе даст нам: Чтобы работать с кошельком созданным вручную вам понадобится добавить его через web3 API. И хотя в данном уроке вам это не понадобится я все же покажу как это делается: После этого вы сможете отправлять транзакции с помощью сгенерированного вами ключа. Это может понадобится если ваше приложение будет самостоятельно создавать аккаунты, особенно, если их много. Стандартный метод web3.eth.personal.newAccount будет записывать ключи на диск в директорию ~/.ethereum/keystore, что может быть по каким-либо причинам не желательно.  Про менеджмент ключей и использование собственных ключей, я постараюсь рассказать отдельно. Файл 2-compile.js. Данный скрипт компилирует исходный код из файла contract.sol и сохраняет результат в code.json, который будет использоваться в дальнейшем для деплоя и взаимодействия с контрактом. Контакты в сети Ethereum хранятся в бинаром представлении, поэтому перед тем как использовать контракт нам необходимо скомпилирвоать исходный код. Делается это с помощью инструмента solc и в случае nodejs пакета solc (это скомпилированный с помощью emscripten solc). После компиляции мы получим на выходе бинарный код bytecode, а так же описание интерфейса контракта. Вот как будет представлен метод withdraw в интерфейсе: На выходе solc возвращает все контракты, которые найдет в исходном коде. Нам понадобится выбрать один, в нашем случае это PiggyBank: Файл 3-deploy.js. Скрипт берет скомплированный код из code.json. А затем создает контракт и заливает код в тестнет от имени пользователя. Полученный в результате адрес и интерфейс контракта записываются в файл contract.json. Сначала создается пустой инстанс с интерфейсом и настройками по умолчанию (from и gas). From — адрес от имени которого будут вызыватсья методы контракта. Gas или бензин — это топливо для контракта, которое тратится в процессе работы приложения. Он нужен для того, чтобы избежать бесконечных циклов, способных остановить работу сети. И так, все готово к заливке контракта: Вызов конструктора происходит в момент деплоя, поэтому мы сразу передаем в него аргументы. В случае с PiggyBank конструктор содержит один аргумент uint _limit. После выполнения данного кода с нас списали средства отдельно за проведение транзакции и отдельно за выполнение кода конструктора. Все готов к запуску, останется только сохранить адрес контракта: Файл 4-run.js. Запуск npm start. Скрипт запускает веб-сервер на порту $PORT или 8080 с простым интерфейсом для взаимодействия с контрактом. Открыв в браузере http://localhost:8080 вы сможете перечислить деньги на счет (deposit) или перевести на счет владельца (withdraw). Рассмотрим что происходит немного подробнее. Для начала мы создаем инстанс контракта ссылающийся на тот, что мы задеплоили ранее: К вызову конструктора добавился еще один аргумент — address, который указывает на то, что это действующий контракт. Давайте посмотрим что мы можем с ним сделать. Как вы помните у нас есть методы deposit, canWithdraw и withdraw. Чтобы пополнить счет нам необходимо вызвать метод deposit и отправть несколько монет в копилку. Ethereum использует в расчетах 18 знаков после запятой и при этом не поддерживает типы с плавающей точкой. Рассчеты производятся в веях, а затем конвертируются в эзеры. Для этого перед отправкой мы конвертируем ether в wei с помощью метода web3.utils.toWei. Которая в свою очередь использует библиотеку BigNumber.js, для
рассчетов со значениями превышающими макисмально допустимые для типа Number. Вызов метода canWithdraw будет отличаться, так как этот метод не вносит никаких изменений (constant), то для вызова вместо send используется call. Такая операция не вызовет списания средств и расходование бензина: Метод для отправки монет в копилку может выглядеть так: Файл 5-destroy.js. Скрипт уничтожает контракт и удаляет из блокчена данные контракта. Не смотря на то, что вы все еще можете перречислить деньги на контракт, выполнить иные операции вы уже не сможете. Файл test/test.spec.js. Запуск npm test. Для тестирвоания используется билиотека mocha. Перед тем как запустить тесты нам понадобится запустить изолированный тестнет с предустановленными данными. Для этого необходимо: Вот как это может выглядеть инициализация новой сети: Мы создаем тестнет с двумя пользователями, а затем инициализируем инстанс web3. Тестнет готов. Можно приступать к тестированию. Например оттестируем конструктор: В данном примере мы написали очень простое приложение, не обладающее сверхсложным поведением, но наглядно иллюстрирующее жизненный цикл контракта. Надеюсь это будет полезно тем, кто только начинает осваивать разработку для Ethereum. Developer and tech writer