--- tags: onti, fintech, assignments, ethereum, msfaceapi --- Описание учебно-тренировочных сборов профиля ФТ ОНТИ 2018/19 ==== Учебно-тренировочные сборы (УТС) проводятся для того, чтобы помочь участникам финала профиля подготовиться к решению финальной задачи. Важно проводить (и участвовать в) УТС, поскольку не всегда формат или система проверки решения задач второго этапа олимпиады позволяют в полной мере сподвигнуть школьников к изучению определенных тем или приобретению определенных навыков, требуемых в финале. Сформулированные ниже задачи могут также использоваться вне подготовки к финалу олимпиады (например, в рамках хакатонов, занятий в проектных школах или тематических кружках) для практического знакомства школьников с программированием приложений для блокчейн сетей или для понимания основ функционирования систем идентификации человека по лицу. ## План учебно-тренировочных сборов ### Этап первый Используются общедоступные материалы - ноутбук с установленным ПО для написания программ на языке Python, с python-библиотекой [web3.py](https://web3py.readthedocs.io/en/stable/), клиент системы ведения версий Git. Хакатон дает навыки в написании и отладке приложения, управляющим балансом пользователя, для блокчейн сети, основанной на виртуальной машине Ethereum. ### Этап второй Используются общедоступные материалы - ноутбук с установленным ПО для написания программ на языке Python, с python-библиотекой [web3.py](https://web3py.readthedocs.io/en/stable/), с ПО для написания программ на языке [Solidity](https://solidity.readthedocs.io), интернет-браузер Chrome с установленным расширением [NiftyWallet](https://chrome.google.com/webstore/detail/nifty-wallet/jbdaocneiiinmjbjlgalhcelgbejmnid), клиент системы ведения версий Git. Хакатон знакомит участников с принципами создания и отладки децентрализованных приложений взаимодействующих со смарт-контрактами для блокчейн сети, основанной на виртуальной машине Ethereum. ### Этап третий Используются общедоступные материалы - ноутбук c камерой и с установленным ПО для написания программ на языке Python, с python-библиотекой [cognitive_face](https://github.com/Microsoft/Cognitive-Face-Python), клиент системы ведения версий Git. Также для каждого участника учебно-тренировочных сборов необходима регистрация на сервисе Microsoft Azure, а именно необходима [подписка на Cognitive Services](https://docs.microsoft.com/en-us/azure/cognitive-services/cognitive-services-apis-create-account). Учебно-тренировочные сборы знакомят участников с принципами создания и отладки приложений для идентификации человека по лицу с использованием [Microsoft Face API](https://azure.microsoft.com/en-us/services/cognitive-services/face/). ## Детальный план первого этапа ### Входные требования к участникам первого этапа Знание базовых алгоритмических конструкций языка и структур хранения данных языка программирования Python. Понимание криптографических основ функционирования блокечейн сети, основанной на виртуальной машине Ethereum, и базовых основ хранения информации о балансах пользователей. Умение использовать системы ведения версий Git для разработки программного обеспечения. ### Теоретические знания, получаемые на сборах Понимание принципов взаимодействия с узлом Ethereum через JSON-RPC, понимание функционала доступного API и предоставляемого python-библиотекой [web3.py](https://web3py.readthedocs.io/en/stable/) для получения данных из блокчейн, создания транзакций. ### Навыки, получаемые на сборах Навык создания и отладки Python приложений, через JSON-RPC запросы взаимодействующих с блокчейн сетью, основанной на виртуальной машине Ethereum. Умение выполнять базовые операции с узлом Ethereum: * получение баланса * создание транзакции на изменение баланса * получение выписки транзакции ### Оборудование Ноутбук с установленным ПО для написания программ на языке Python, с python-библиотекой [web3.py](https://web3py.readthedocs.io/en/stable/), клиент системы ведения версий Git. ### Формат участия Индивидуальный. Каждый участник самостоятельно решает задачу на своем комплекте оборудования. ### Требования к проводящему Необходим человек, который имеет опыт программирования приложений, использующих JSON-RPC запросы, для блокчейн сети на базе виртуальной машины Ethereum, а также навыки написания программ с использованием python-библиотеки `web3.py`. Рекомендация - иметь несколько ассистентов для помощи основному ведущему учебно-тренировочных сборов. Общее количество проводящих должно исчисляться по 1 человеку на каждые 8 участников. ### Почасовой план Учебно-тренировочные сборы расчитаны на 4-5 часов. | Время | Описание | | :---: | :--- | | 30 минут | Знакомство с тестовой сетью POA Sokol. Получение тестовых монет на [faucet](https://faucet-sokol.herokuapp.com/). Знакомство с [эксплорером блоков](https://blockscout.com/poa/sokol/). | | 15 минут | Краткий обзор [JSON-RPC запросов](https://wiki.parity.io/JSONRPC-eth-module), которые могут быть сделаны к узлу Ethereum | | 15 минут | Краткий обзор API, предоставляемого python-библиотекой [web3.py](https://web3py.readthedocs.io/en/stable/) и необходимого для решения задачи учебно-тренировочных сборов | | 15 минут | Рассмотрение примеров программ для отправки JSON-RPC запросов к тестовой сети POA Sokol через библиотеку `web3.py`. | | 15 минут | Постановка задачи. Описание ожидаемых входных и требуемых выходных данных. Предоставление требований к публикации кода на сервере ведения версий git. | | 3.5 часа | Решение задачи участниками учебно-тренировочных сборов. Приемка работ | ### Описание задачи Базовая операция, которая может быть выполнена практически на каждом Ethereum узле, - получить баланс на счете пользователя или переслать часть средств на другой счет. Эта минимальная функциональность выполняется той частью программного обеспечения узла, которая называется криптовалютным кошельком. Ваша задача - автоматизировать перечисленные выше функции. Вам необходимо разработать приложение (python-скрипт), которое бы принимало параметры через командную строку и в зависимости от параметров выполняло следующие функции: * вывод баланса счета; * отправка заданного количества _POA монет_ на другой счет. Имя исполняемого скрипта должно быть `qadwallet.py` Скрипт должен выполнять действия, оперируя приватным ключом Ethereum аккаунта. Приватный ключ указывается в шестнадцатиричном формате. #### Примеры использования ##### Вывод баланса Первый пример (_US-01_) использования скрипта: ```shell $ qadwallet.py --key c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 ``` Ответом должна быть строка: ``` Balance on "9cce34F7aB185c7ABA1b7C8140d620B4BDA941d6" is 2.5 poa ``` ##### Отправка poa монет Для того, чтобы отправить часть _poa монет_ принадлежащих счету, ассоциированному с приватным ключем, нужно указать адрес получателя и сумму. Адрес отправителя должен быть указан в шестнадцатиричном формате. Сумма для отправки - целое число, измеряется в _Wei_. Скрипт должен предусматривать, как отправку средств со счета, с которого еще ни разу не было совершено ни одной транзакции, так и со счетов, активно выполнявших переводы. Второй пример (_US-02_) использования скрипта: ```shell $ qadwallet.py --key c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 --to EAee08c91B13d8d7A82850b714C7c68826E9CFAe --value 500000000000000000 ``` Ответ должен быть следующим: ``` Payment of 500 finney to "EAee08c91B13d8d7A82850b714C7c68826E9CFAe" scheduled Transaction Hash: 0x27c9181caeb55d37e1105fa1a8648db7fe50f79064b98e56b8e854e3abb43728 ``` Еще один пример (_US-03_), демонстрирующий автоматическое масштабирование суммы: ```shell $ qadwallet.py --key c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 --to EAee08c91B13d8d7A82850b714C7c68826E9CFAe --value 2500000000000000000 Payment of 2.5 poa to "EAee08c91B13d8d7A82850b714C7c68826E9CFAe" scheduled Transaction Hash: 0x27d6236b24f3643fb6f55442572f0a382bc6fc3674ef64a62f706591235f0ecf ``` Масштабирование суммы - нормализация к одному из возможных значений: _poa_, _finney_, _szabo_, _gwei_, _mwei_, _kwei_, _wei_. Происходит следующим образом: * Используется минимально возможное нормализованное значение, чья целая часть больше ноля; * Дробная часть записывается с округлением до $10^{-6}$; * Завершающие нули в дробной части, полученные полсе округления, не записываются (например, 1.3, но не 1.300000). Скрипт должен оповещать пользователя, если на счету недостаточно средств для перечисления (_US-04_): ```shell $ qadwallet.py --key c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 --to EAee08c91B13d8d7A82850b714C7c68826E9CFAe --value 250000000000000000000 No enough funds for payment ``` Четверты пример (_US-05_) демонстрирует возможность получать статус транзакции, в рамках которой осуществлялся перевод: ```shell $ qadwallet.py --tx 0x27c9181caeb55d37e1105fa1a8648db7fe50f79064b98e56b8e854e3abb43728 ``` Ответом должна быть строка: ``` Payment of 500 finney to "EAee08c91B13d8d7A82850b714C7c68826E9CFAe" confirmed ``` Или, в случае, когда транзакция все еще не подтверждена (_US-06_): ```shell $ qadwallet.py --tx 0x27d6236b24f3643fb6f55442572f0a382bc6fc3674ef64a62f706591235f0ecf Delay in payment of 2.5 poa to "EAee08c91B13d8d7A82850b714C7c68826E9CFAe" ``` Попытки получить информацию о несуществующей транзакции также должны правильно обрабатываться (_US-07_): ```shell $ qadwallet.py --tx 0x27d6236b24f3643fb6f55442572f0a382bc6fc3674ef64a62f706591235ffce0 No such transaction in the chain ``` #### Примечание Скрипт должен работать с Ethereum узлом исключительно через подключение по RPC. В качестве RPC URL должен быть использован `https://sokol.poa.network`. ### Проверка решения Существует способ автоматической проверки правильности решения задачи. Для этого необходимо [создать новый проект на сервере GitLab](https://gitlab.com/projects/new). При создании проекта необходимо использовать специальный шаблон, который и позволит выполнять автоматическую проверку. * [Инструкция по созданию проекта из шаблона](https://hackmd.io/@koal/r1rM9FAvS) * [Шаблон проекта для задачи "Quick and Dirty wallet"](https://drive.google.com/file/d/1EeLQ-h5HF2kXwHBzrjg9PB6sfr8J6Bx3/view?usp=sharing) Сразу после создания проекта проверка автоматически запуститься. При этом будет сообщение об ошибках. Это нормально. Во-первых, создался только проект, а не решение. Во-вторых, аккаунт, использующийся для автоматического тестирования решения, может не иметь достаточно средств. В разделе _"Проверка решения"_ в файле `README.md` проекта описано, что нужно сделать для пополнения счета этого аккаунта. После создания шаблона нужно склонировать репозиторий на локальную машину. Каждый раз, когда будете делать `push` в данный репозиторий будет автоматически проводиться предварительная проверка решения. Результат проверки можно будет видеть в GitLab в разделе `CI/CI -> Pipelines`. ## Детальный план второго этапа ### Входные требования к участникам второго этапа Знание базовых алгоритмических конструкций языка и структур хранения данных языка программирования Python. Умение создавать и отлаживать Python приложения, взаимодействующих с блокчейн сетью, основанной на виртуальной машине Ethereum, посредством python-библиотеки [web3.py](https://web3py.readthedocs.io/en/stable/). Умение создавать аккаунт в блокчейн сети на базе виртуальной машины Ethereum, создавать транзакции для изменения баланса. Базовый уровень знания языка [Solidity](https://solidity.readthedocs.io): синтаксис, операции управления ходом программы, доступные структуры данных и их свойства, понимание основ взаимодействия смарт-контрактов Ethereum c данными в блокчейн. Умение использовать системы ведения версий Git для разработки программного обеспечения. ### Теоретические знания, получаемые на сборах Базовое понимание процесса развертывания контрактов в блокчейн сети на базе виртуальной машины Ethereum. Знание методов получения информации из базы данных, представленной блокчейн сетью: входные данные транзакции, данные контракта, результаты исполнения кода контракта. Знание методов изменения информации в базе данных, представленной блокчейн сетью, посредством вызова на исполнение кода контракта. Понимание интеграционного тестирования и возможных способов его автоматизации. ### Навыки, получаемые на сборах Навык создания и отладки простых контрактов на языке Solidity в [IDE Remix](http://remix.ethereum.org). Умение создавать приложения на языке Python для развертывания контракта в блокчейн сети базе виртуальной машины Ethereum. Умение использовать библиотеку `web3.py` для создания транзакций для вызова на исполнение кода контракта, для нетранзакционного вызова кода контракта, для доступа к данным, генерируемых контрактом, в выписке транзакции. Навыки организации интеграционного тестирования продукта, автоматизации процессов объединения нескольких компонент программного обеспечения перед проведением тестирования. Навыки командной работы в рамках одного проекта ИТ-направленности. ### Оборудование Ноутбук с установленным ПО для написания программ на языке Python, с python-библиотекой [web3.py](https://web3py.readthedocs.io/en/stable/), с ПО для написания программ на языке [Solidity](https://solidity.readthedocs.io), интернет-браузер Chrome с установленным расширением [NiftyWallet](https://chrome.google.com/webstore/detail/nifty-wallet/jbdaocneiiinmjbjlgalhcelgbejmnid), клиент системы ведения версий Git. ### Формат участия Командный (2-3 человека в команде). Каждая команда решает задачи на своем комплекте оборудования. Рекомендуемые роли: * Python-разработчик (разработка и отладка кода на python) * Solidity-разработчик (разработка контракта на solidity) * DevOps-инженер (настройка окружения для тестирования с загрузкой артефактов из репозиториев git, настройка автоматической регистрации новых версий контрактов, проведение (и возможная автоматизация) интеграционного тестирования, коммуникация с разработчиками об выявленных ошибках, отслеживание статуса их исправления) ### Требования к проводящему Необходим человек, который имеет опыт разработки контрактов для блокчейн Ethereum на языке Solidity. Также требуется опыт написания python-приложений для взаимодействия с контрактами посредством библиотеки `web3.py`. Рекомендация - иметь несколько ассистентов для помощи основному ведущему учебно-тренировочных сборов. Общее количество проводящих должно исчисляться по 1 человеку на каждые 8 участников. ### Почасовой план Учебно-тренировочные сборы расчитаны на 4-5 часов. | Время | Описание | | :---: | :--- | | 30 минут | Знакомство со средой разработки [IDE Remix](http://remix.ethereum.org). | | 15 минут | Рассмотрение примеров работы с данными в базе данных, представленной блокчейн: транзакционное изменение базы данных, нетранзакционный вызов кода контракта, данные, генерируемые контрактом и хранимые в выписке траназкции. | | 30 минут | Краткий обзор API, предоставляемого python-библиотекой [web3.py](https://web3py.readthedocs.io/en/stable/): развертывание контракта, вызов методов контракта, получение информации из выписки транзакции. | | 15 минут | Рассмотрение процесса использования кошелька [NiftyWallet](https://chrome.google.com/webstore/detail/nifty-wallet/jbdaocneiiinmjbjlgalhcelgbejmnid) для деплоймента контракта в тестовую сеть Sokol, верификация контракта, работа с данными контракта | | 15 минут | Постановка задачи. Описание ожидаемых входных и требуемых выходных данных. Предоставление требований к публикации кода на сервере ведения версий git. | | 3 часа | Решение задачи участниками учебно-тренировочных сборов. Приемка работ | ### Описание задачи Контракты в сети блокчейн могут использоваться для разных нужд - автоматически исполнять заранее заданные договоренности при достижении каких-то условий или возникнования событий, описывать ценности реального мира и взаимодействие с ними, проводить голосования, предоставлять доступ к структурированной информации, отличающейся от информации об изменении балансов. То, что код контракта, помещенный в блокчейн, не может изменяться (если это заранее не обговорено в самом контракте) позволяет гарантировать, что даже через несколько месяцев никто не сможет изменить его поведение после того, как пользователь ознакомился с контрактом. Это как раз и позволяет гарантировать исполнение заранее заданных договоренностей. Ваща задача - написать децентрализованное приложение, частью которого является контракт, отвечающий за хранение соответствий имен пользователей и аккаунтов блокчейн сети. Такой контракт может быть часть KYC (Know Your Customer) систем, которые требуются от криптовалютных бирж и обменников, чтобы не нарушать законадальство. Контракт будет обладать следующей функциональностью:: * добавление нового соответствия между именем пользователя и его аккаунтом; * удаление соответствия между именем пользователя и его аккаунтом; * получение аккаунта по имени пользователя; * получение имени пользователя по аккаунту. #### Интерфейсы контракта Ниже приводятся методы, доступ к которым контракт должен предоставлять, и описание логики их работы. 1. Регистрация соответствия имени и аккаунта ```solidity function registerName(string _name); ``` Данный метод позволяет зарегистрировать имя для аккаунта, выполняющего вызов этого метод а * Если имя уже зарегистрировано для данного аккаунта, транзакция, в рамках которой вызвается метода, откатывается. * Имя не должно быть пустой строкой. * Допускается регистрировать одно имя для разных аккаунтов. * Если имя регистрируется успешно, то испускается следующее событие (`event`): ```solidity event NameRegistered(address _address, string _name); ``` * Метод не должен потреблять больше `75000` газа (допускается привышение этого лимита если метод вызывается для регистрации шестого и последующих соответствий под данным именем зарегистрировано к моменту вызова метода не более четырех аккаунтов) 2. Удаление соответствия имени и аккаунта ```solidity function unregisterName(); ``` Данный метод позволяет удалить соответствие между именем и аккаунтом. * Удаляется соответствие для аккаунта, вызывающего метод. * Если для данного аккаунта нет зарегистрированного соответствия, транзакция, в рамках которой вызвается метода, откатывается. * Если соответствие успешно удалено, то испускается следующее событие (`event`): ```solidity event NameUnregistered(address _address); ``` * Транзакция, в ходе которой вызывается метод не должна потреблять больше `21000` газа для случая, когда для имени, с котороым удаляется соответствие, зарегистрировано 5 и меньше аккаунтов. 3. Получить имя соответствующее аккаунту ```solidity function getName(address _address) returns (string _name) ``` Метод принимает в качестве входных данных адрес аккаунта и возвращает имя, соответствующее этому адресу. * Если с адресом аккаунта никогда не ассоциировалось имя, метод возвращает пустую строку. * Если соответствие имени и данного аккаунта было удалено, метод возвращает пустую строку. 4. Получить адреса соответствующих имени ```solidity function getAddresses(string _name) returns (address [] _address); ``` Метод позволяет получить массив всех адресов, соответствующих указанному имени. * Если соответствие с именем еще никем не регистрировалось, метод возвращает пустой массив. * Если имя соответствует только одному аккаунту, то возвращается массив только с одним адресом. * Если для имени было удалено соответствие с аккаунтом, то адрес этого аккаунта не должен присутсвовать в возвращаемом массиве. Контракт должен быть написан на языке Solidity и код должен быть совместим с версией компилятора `solc` `0.5.4`. При проверке контракта будет использован флаг, включающий оптимизацию. Файл, содержащий контракт, должен называться `registrar.sol`. Контракт, который будет тестироваться, должен называться `Registrar`. #### Клиентская часть Также необходимо разработать приложение (python-скрипт), которое бы принимало параметры через командную строку, позволяло регистрировать контракт в блокчейн сети и, в зависимости от параметров, вызывало тот или иной интерфейс контракта. Имя исполняемого скрипта должно быть `registrar.py` Скрипт должен выполнять действия, включая регистрацию контракта, оперируя приватным ключом Ethereum аккаунта. Приватный ключ указывается в файле `account.json` в шестнадцатиричном формате: ```json {"account": "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"} ``` Скрипт должен работать с Ethereum узлом исключительно через подключение по RPC. Цена газа во всех транзакциях должна браться из оракула (поставщик данных из реального мира), возвращающего данные о цене в виде: ```json {"block_time":19.91,"fast":14.4,"instant":25.0,"block_number":7240426,"standard":5.0,"health":true,"slow":3.0} ``` При выборе должна использоваться цена из значения `fast`, измеряемая в `Gwei`. Оракул доступен по HTTP протоколу. Пример оракула: https://gasprice.poa.network. Ссылки на RPC узел и оракула цены газа передаются через конфигурационный файл `network.json`. Он содержит следующую информацию: * `rpcUrl` - URL для доступа к узлу по JSON RPC; * `gasPriceUrl` - URL для доступа к сервису, предоставляющему цену за газ. Пример файла: ```json {"rpcUrl": "https://sokol.poa.network", "gasPriceUrl": "https://gasprice.poa.network/"} ``` #### Примеры использования ##### Регистрация контракта (US-01) Пользователь может зарегистрировать контракт в блокчейн, чтобы в дальнейшем пользователи сервиса обращались к данному контракту по его адресу. ```shell $ registrar.py --deploy Contract address: 0xc78282BF9b270e632309bc6901D3F46416E12c5A ``` После регистрации контракта в директории, из которой запускается скрипт `registrar.py` должен создаться файл `database.json` с адресом контракта и номером блока, в котором данный контракт был зарегистрирован: ```shell $ cat database.json {"registrar": "0xc78282BF9b270e632309bc6901D3F46416E12c5A", "startBlock": 123456} ``` Последующий вызов `registrar.py --deploy` регистрирует новый контракт вне зависимости от того, есть в текущей директории файл `database.json`. ##### Цена газа для транзакции регистрации контракта (US-02) Для проведения транзакции выбирается цена из значения `fast`, возвращенного сервисом `https://gasprice.poa.network`. Сразу после регистрации контракта значение из `fast` умноженное на 1000000000 из вывода команды ```shell $ curl -X GET "https://gasprice.poa.network" -H "accept: application/json" ``` и значение `gasPrice` из самой первой транзакции в списке из вывода следующей команды: ```shell $ curl -X GET "https://blockscout.com/poa/sokol/api?module=account&action=txlist&address=<ACCOUNT>&sort=desc" -H "accept: application/json" ``` должны совпадать. ##### Регистрация имени пользователя (US-03) Пользователь может добавить в контракт соответствие имени своему аккаунту. ```shell $ registrar.py --add "Elon Musk" Successfully added by 0x27d6236b24f3643fb6f55442572f0a382bc6fc3674ef64a62f706591235f0ecf ``` Адрес контракта для регистрации пользователя берется из файла `database.json`. ##### Запрет нескольких регистраций с одного аккаунта (US-04) Пользователь не может добавить в контракт соответствие еще одного имени своему аккаунту. ```shell $ registrar.py --add "Mark Zuckerberg" One account must correspond one name ``` В сети блокчейн не создается траназакций с данного аккаунта. ##### Обработка ошибок при регистрации имени пользователя (US-05) Если на счету пользователя недостаточно средств для проведения транзакции, то выводится соответствующее сообщение: ```shell $ registrar.py --add "Vitalik Buterin" No enough funds to add name ``` ##### Цена газа для траназкции на регистрации имени пользователя (US-06) Для проведения транзакции выбирается цена из значения `fast`, возвращенного сервисом `https://gasprice.poa.network`. Сразу после добавления имени пользователя в контракт значение из `fast` умноженное на 1000000000 из вывода команды ```shell $ curl -X GET "https://gasprice.poa.network" -H "accept: application/json" ``` и значение `gasPrice` из самой первой транзакции в списке из вывода следующей команды: ```shell $ curl -X GET "https://blockscout.com/poa/sokol/api?module=account&action=txlist&address=<ACCOUNT>&sort=desc" -H "accept: application/json" ``` должны совпадать. ##### Удаление имени пользователя (US-07) Пользователь может удалить из контракта соответствие имени своему аккаунту. ```shell $ registrar.py --del Successfully deleted by 0x5442572f0a382bc6fc3674ef64a62f706591235f0ecf27d6236b24f3643fb6f5 ``` Адрес контракта для удаления пользователя берется из файла `database.json`. ##### Удаление несуществующего соответствия (US-08) Если в контракте нет соответствия имени пользователя и аккаунта, то выводится соответствующее сообщение. ```shell $ registrar.py --del No name found for your account ``` ##### Обработка ошибок при удалении имени пользователя (US-09) Если на счету пользователя недостаточно средств для проведения транзакции, то выводится соответствующее сообщение: ```shell $ registrar.py --del No enough funds to delete name ``` ##### Цена газа для траназкции на удаление имени пользователя (US-10) Для проведения транзакции выбирается цена из значения `fast`, возвращенного сервисом `https://gasprice.poa.network`. Сразу после удаления имени пользователя в контракт значение из `fast` умноженное на 1000000000 из вывода команды ```shell $ curl -X GET "https://gasprice.poa.network" -H "accept: application/json" ``` и значение `gasPrice` из самой первой транзакции в списке из вывода следующей команды: ```shell $ curl -X GET "https://blockscout.com/poa/sokol/api?module=account&action=txlist&address=<ACCOUNT>&sort=desc" -H "accept: application/json" ``` должны совпадать. ##### Получение аккаунта по имени пользователя (US-11) Любой пользователь может получить аккаунт по имени пользователя ```shell $ registrar.py --getacc "Elon Musk" Registered account is 0x9cce34f7ab185c7aba1b7c8140d620b4bda941d6. ``` Транзакция в блокчейн не отправляется. ##### Обработка ошибок при получении аккаунта по имени пользователя (US-12) Если имя пользователя не было зарегистрировано, выдается соответствующая сообщение. ```shell $ registrar.py --getacc "Vitalik Buterin" No account registered for this name ``` Транзакция в блокчейн не отправляется. ##### Получение аккаунта для удаленного соответствия (US-13) Если пользователь удалил соответствие имени и аккаунта, выдается такое же сообщение как и в том случае, когда соответствие не было зарегистрировано вообще. ```shell $ registrar.py --add "Mark Zuckerberg" Successfully added by 0xdc367624ef64a62f72706591235f0eb6f554425cf2724f3636b43ff0a382bc6f $ registrar.py --del Successfully deleted by 0xecf27d6236b24f3643fb6f55442572f0a382bc6fc3674ef64a62f706591235f0 $ registrar.py --getacc "Mark Zuckerberg" No account registered for this name ``` ##### Получение имени пользователя по аккаунту (US-14) Любой пользователь может получить имя пользователя по аккаунту ```shell $ registrar.py --getname 0x9cce34f7ab185c7aba1b7c8140d620b4bda941d6 Registered account is "Elon Musk" ``` Транзакция в блокчейн не отправляется. ##### Обработка ошибок при получении имени пользователя по аккаунту (US-15) Если имя пользователя не было зарегистрировано, выдается соответствующая сообщение. ```shell $ registrar.py --getname 0xca35b7d915458ef540ade6068dfe2f44e8fa733c No name registered for this account ``` Транзакция в блокчейн не отправляется. ##### Получение аккаунта для удаленного соответствия (US-16) Если пользователь удалил соответствие имени и аккаунта, выдается такое же сообщение как и в том случае, когда соответствие не было зарегистрировано вообще. ```shell $ registrar.py --add "Mark Zuckerberg" Successfully added by 0xdc367624ef64a62f72706591235f0eb6f554425cf2724f3636b43ff0a382bc6f $ registrar.py --del Successfully deleted by 0xecf27d6236b24f3643fb6f55442572f0a382bc6fc3674ef64a62f706591235f0 $ registrar.py --getname 0x14723a09acff6d2a60dcdf7aa4aff308fddc160c No account registered for this name ``` ##### Получение списка всех соответствий (US-17) Пользователь может получить все зарегистрированные соответствия ```shell $ registrar.py --add "Vitalik Buterin" Successfully added by 0x62f72706591235f0eb6f554425cf2724f36dc367624ef64a36b43ff0a382bc6f $ registrar.py --del Successfully deleted by 0xe0a382bc6fc3674ef64a62f706591235f0cf27d6236b24f3643fb6f55442572f $ registrar.py --list "Elon Musk": 0x9cce34f7ab185c7aba1b7c8140d620b4bda941d6 "Mark Zuckerberg": 0xdd870fa1b7c4700f2bd7f44238821c26f7392148 ``` Транзакция в блокчейн не отправляется. ##### Получение нескольких аккаунтов по одному имени пользователя (US-18) Любой пользователь получит несколько аккаунтов, если зарегистрировано несколько пользователей под этим именем ```shell $ registrar.py --getacc "Elon Musk" Registered accounts are: 0x9cce34f7ab185c7aba1b7c8140d620b4bda941d6 0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db ``` Транзакция в блокчейн не отправляется. ##### Оптимизация контракта (US-19) Если пользователь удалил соответствие имени и аккаунта, то транзакция потребила меньше `21000` газа. Если после выполнения: ```shell $ registrar.py --add "Mark Zuckerberg" Successfully added by 0xdc367624ef64a62f72706591235f0eb6f554425cf2724f3636b43ff0a382bc6f $ registrar.py --del Successfully deleted by 0xecf27d6236b24f3643fb6f55442572f0a382bc6fc3674ef64a62f706591235f0 ``` запустить ``` $ curl -X GET "https://blockscout.com/poa/sokol/api?module=transaction&action=gettxinfo&txhash=0xecf27d6236b24f3643fb6f55442572f0a382bc6fc3674ef64a62f706591235f0" -H "accept: application/json" ``` то значение `gasUsed` будет меньше `21000`. ### Проверка решения Для провреки решения данного этапа существует возможность использовать автоматическое тестирование. Для этого необходимо создать два [новых проекта на сервере GitLab](https://gitlab.com/projects/new). При создании проектов необходимо использовать специальные шаблоны, которые и позволят выполнять автоматическую проверку. * [Шаблон GitLab-проекта для задачи "Simple registrar contract"](https://drive.google.com/file/d/1f1JWXsQyc_3hBmU3VnurAaX6Cx9SFk5i/view?usp=sharing) * [Шаблон GitLab-проекта для задачи "Simple registrar on an Ethereum contract"](https://drive.google.com/file/d/1Onf5RxnsG4wCviqguCwtf0iZngN28AnX/view?usp=sharing) После создания шаблонов нужно склонировать репозитории на локальную машину. Имейте в виду, что система проверки решения задачи "Simple registrar on an Ethereum contract" подразумевает, что контракт (задача "Simple registrar contract") располагается в отдельном репозитории и подключен через _git submodules_. Как подключить _submodule_ написано в файле `README.md` в разделе "Подготовка". Каждый раз, когда будете делать `push` в репозитории проектов будет автоматически запускаться проверка решения. Результат проверки можно будет видеть в GitLab в разделе `CI/CI -> Pipelines`. ## Детальный план третьего этапа ### Входные требования к участникам третьего этапа Знание базовых алгоритмических конструкций языка и структур хранения данных языка программирования Python. Умение создавать и отлаживать Python приложения, взаимодействующих с веб-сервисами посредством REST-запросов. Умение получать посредством [Microsoft Face API](https://azure.microsoft.com/en-us/services/cognitive-services/face/) различные параметры одной фотографии c изображением лица человека. Умение использовать системы ведения версий Git для разработки программного обеспечения. ### Теоретические знания, получаемые на сборах Базовое понимание процессов тренировки системы для распознавания лиц и идентификации человека по лицу, последующее получение и интепретация результатов ее работы. Знание методов, предоставляемых _Microsoft Face API_, для написания системы с функционалом идентификации человека по лицу. ### Навыки, получаемые на сборах Навык создания и отладки простых приложений на языке Python, производящие идентификацию по лицу с использованием _Microsoft Face API_. Умение использовать библиотеку [cognitive_face](https://github.com/Microsoft/Cognitive-Face-Python) для взаимодействия с _Microsoft Face API_. Навыки организации тестирования программного продукта, с фунциями идентификации человека по лицу. ### Оборудование Ноутбук с web-камерой, с установленным ПО для написания программ на языке Python и python-библиотекой [cognitive_face](https://github.com/Microsoft/Cognitive-Face-Python), также необходим клиент системы ведения версий Git. Также для каждого участника хакатона необходима регистрация на сервисе Microsoft Azure, а именно необходима [подписка на Cognitive Services](https://docs.microsoft.com/en-us/azure/cognitive-services/cognitive-services-apis-create-account). ### Формат участия Индивидуальный. Каждый участник самостоятельно решает задачу на своем комплекте оборудования. ### Требования к проводящему Необходим человек, который имеет опыт разработки приложений с функцией идентификации человека по лицу. Также требуется опыт взаимодействия с web-сервисами посредством REST-запросов. Желателно предварительное знакомство с функционалом _Microsoft Face API_. Рекомендация - иметь несколько ассистентов для помощи основному ведущему учебно-тренировочных сборов. Общее количество проводящих должно исчисляться по 1 человеку на каждые 8 участников. ### Почасовой план Учебно-тренировочные сборы расчитаны на 4-5 часов. | Время | Описание | | :---: | :--- | | 15 минут | Знакомство с процессом работы приложения с функционалом распознавания лиц. | | 30 минут | Рассмотрение [функционала](https://westus.dev.cognitive.microsoft.com/docs/services/563879b61984550e40cbbe8d/operations/563879b61984550f30395236), предоставляемого _Microsoft Face API_ для приложений с функционалом идентификации по лицу. | | 30 минут | Краткий обзор API, предоставляемого python-библиотекой [cognitive_face](https://github.com/Microsoft/Cognitive-Face-Python). | | 15 минут | Постановка задачи. Описание ожидаемых входных и требуемых выходных данных. Предоставление требований к публикации кода на сервере ведения версий git. | | 3 часа | Решение задачи участниками учебно-тренировочных сборов. Приемка работ | ### Описание задачи Технологии для распознавания и идентификации лиц уже давно интересуют исследователей, занимающихся компьютерными науками. За год произведены наработки, часть которых выложена в публичный доступ в виде исходного кода, еще часть используется в закрытых коммерческих продуктах, а крупные компании такие как Microsoft, Google и Amazon подготовили web-сервисы, которые разработчки приложений могут использовать в своих продуктах. Таким образом, компании, которые только начинают свой путь в создании систем идентификаций человека по лицу, имеют возможность уже на самых ранних стадиях создания продукта демонстрировать основной функционал, не тратя ресурсы (время и деньги) на серьезные исследования и реализацию алгоритмов машинного обучения, решающих данную задачу. Сервис, предоставляемый _Microsoft Face API_, может быть использован на любых фазах процесса идентификации человека по лицу: 1. [Инициализация группы людей](https://westus.dev.cognitive.microsoft.com/docs/services/563879b61984550e40cbbe8d/operations/563879b61984550f30395244), для последующей идентификации конкретного человека внутри этой группы 2. [Инициализация отдельных людей](https://westus.dev.cognitive.microsoft.com/docs/services/563879b61984550e40cbbe8d/operations/563879b61984550f3039523c) внутри группы 3. [Заполнение примерами лиц](https://westus.dev.cognitive.microsoft.com/docs/services/563879b61984550e40cbbe8d/operations/563879b61984550f3039523b) хранилища для каждого человека 4. [Тренировка сервиса](https://westus.dev.cognitive.microsoft.com/docs/services/563879b61984550e40cbbe8d/operations/563879b61984550f30395249) на идентификацию лиц по загруженным примерам 5. [Идентификация](https://westus.dev.cognitive.microsoft.com/docs/services/563879b61984550e40cbbe8d/operations/563879b61984550f30395239) одного из человек в группе по изображению его лица Ваща задача - написать приложение на языке Python, которое могло бы идентифицировать человека по изображению лица. Приложение (python-скрипт) должно: * идентифицировать одного человека из группы, состоящей не менее чем из 7 людей. * собирать данные о лице пользователей из видеопотока (файл) * натренировать систему идентификации на использование собранных данных * по изображению лица пользователя взятого из видеопотока (файл) идентифицировать его * сообщать о невозможности идентификации пользователя Имя исполняемого скрипта должно быть `faceid.py` Скрипт должен работать с _Microsoft Face API_ через заранее созданный аккаунт на сервисе. Ключ подписки для использования сервиса указывается в файле `msfaceapi.json`: ```json {"key": "563879b61984550e40cbbe8d3039523c"} ``` Группа пользователей, с которой работает в данный момент скрипт задается через файл `faceid.json`: ```json {"groupId": "fintech-01"} ``` #### Примеры использования ##### Добавление пользователя (US-01) Пользователь может добавить нового человека в систему: ```shell $ faceid.py --name "Elon Musk" video.mpg 5 frames extracted PersonId: 419e345a-e6d6-4d9c-953d-667787b8d52e FaceIds ======= e27558b9-812d-41c3-b114-8e434b8f4602 44c350f2-6653-4616-a1b7-e0fe9b481b6b f945a3be-4b20-4049-b080-4142a55e4f93 855ab7c2-9bb3-49ed-8cac-1366c0274b08 9c4af288-54cd-4375-8eef-f8c29ed56685 ``` Количество кадров для добавления нового человека в систему - всегда 5. Кадры из видео берутся через равные промежутки времени, первый кадр - в начале видео, пятый - в конце. ##### Добавление новых изображений лица пользователя (US-02) Пользователь может добавить дополнительные изображения лица человека к уже существующим в системе: ```shell $ faceid.py --name "Elon Musk" video2.mpg 5 frames extracted PersonId: 419e345a-e6d6-4d9c-953d-667787b8d52e FaceIds ======= 035cc1f5-2ac3-4099-8af5-2b3f3a25bf55 0479ee7d-0572-4ac8-bc5c-6863efdbb347 bf910059-3944-49cc-b6ac-4ac15cdd8e80 e93568a3-72c8-41f1-a5b0-9547121aa50d 365ffb4f-0bfa-4a99-808e-bb7c1f19237b ``` ##### Обратботка ошибок при добавлении лиц пользователя (US-03) Если при попытке добавить новые изображения с лицом пользователя, на видео нет кадров с лицом пользователя, то выдается ошибка: ```shell $ faceid.py --name "Elon Musk" video5.mpg Video does not contain any face ``` При обработке видео, где содержится меньше 5 кадров, должна выдаваться такая же ошибка. ##### Удаление пользователя (US-04) Пользователь может удалить человека из системы идентификации: ```shell $ faceid.py --del "Elon Musk" Person with id 419e345a-e6d6-4d9c-953d-667787b8d52e deleted ``` ##### Удаление несуществующего пользователя (US-05) При попытке удалить незарегистрированного человека из системы идентификации выдается ошибка: ```shell $ faceid.py --del "Vitalik Buterin" No person with name "Vitalik Buterin" ``` ##### Инициализация системы идентификации (US-06) Пользователь может запустить обучение системы идентификации: ```shell $ faceid.py --train Training task for 7 persons started ``` ##### Идентификация пользователя (US-07) Пользователь может выполнить идентификацию человека по кадрам из видео. ```shell $ faceid.py --identify video3.mpg The person is "Elon Musk" ``` Идентификация должна проходить успешно, только если _Microsoft Face API_ для каждого из пяти разных кадров из видео указывает на одного и того же человека с высокой степенью (не менее 50%) уверенности определения. ##### Обработка ошибок идентификации пользователя (US-08) Пользователь получит сообщение о невозможности идентификации, если _Microsoft Face API_ не выдает в каждом из пяти разных кадров из видео высокую (не менее 50%) степень уверенности определения одного и тогже человека: ```shell $ faceid.py --identify video4.mpg The person cannot be identified ``` ##### Обработка ошибок инициализации (US-09) Пользователь получит сообщение об ошибке, если процесс обучения системы еще не завершен: ```shell $ faceid.py --identify video3.mpg The system is not ready yet ```