Активный гражданин на «блокчейне»
@alerdenisov for @blockchain_engineersПривет, %username%!
Сегодня в телеграме поделились постом-обзором технологического решения ag.mos.ru для организации голосований:
Меня привлек проект, так как я сейчас работаю над проектом на базе консенсуса PoA, да и к mos.ru имел отношение в 2011–2012 годах.
Голосование на блокчейне
Что мы ждем, когда нам обещают голосования на блокчейне?
- Прозрачную систему приема голосов от участников;
- Прием голосов с предоставлением валидной подписи на основе крипто-ключа;
- Схему предоставления доказательств факта, что каждому участнику передан один и только один крипто-ключ. (самое сложное)
Мне интересно как mos.ru решает третий пункт. Проект с частично открытом кодом и все ответы можно найти в репозитории. Давайте разбираться вместе:
moscow-technologies/ag-blockchain
Нам на изучение предоставлен один репозиторий с тремя директориями: contracts
, monitor
, parity/config
.
Увы, кода фронтенда с которого будут приниматься голоса нет, но давайте хотя бы на контракты посмотрим:
ls -lha contracts/src total 32 drwxr-xr-x 5 aler staff 170B 12 дек 18:43 . drwxr-xr-x 6 aler staff 204B 12 дек 18:43 .. -rw-r--r-- 1 aler staff 409B 12 дек 18:43 Owned.sol -rw-r--r-- 1 aler staff 4,4K 12 дек 18:43 Poll.sol -rw-r--r-- 1 aler staff 705B 12 дек 18:43 Root.sol
Начнем с Root.sol
pragma solidity ^0.4.11; import "./Owned.sol"; contract Root is Owned { uint public Count; mapping(uint => address) _addressMap; uint[] public _pollIds; address[] public _pollAddresses; function pushAddress(uint pollId, address contracaddressMap[pollId] = contractAddress; _pollIds.push(pollId); _pollAddresses.push(contractAddress); Count++; } function getAllPollIds() constant returns(uint[]) { return _pollIds; } function getAllPollAddresses() constant returns(address[]) { return _pollAddresses; } function getAddress(uint pollId) constant returns (address contractAddress) { if (Count == 0) { return; } return _addressMap[pollId]; } }
Это реестр всех голосований. Интересно, почему нет события вроде AddPool(uint indexed poolId, address indexed poolAddress)
, было бы удобно получать список всех зарегистрированных голосований в dApp.
Интересно как они получают? Наверно дублируют в централизованной бд id.
Poll.sol
А вот тут должно быть самое интересное!
Тут много constant
функций – это точки взаимодействия для чтения состояния. Нас они не интересуют, давайте разбираться как создаются голосования и принимаются голоса:
Файл состоит из двух контрактов: Pool
и PoolQuestion
.
Pool – контейнер для PoolQuestion
PoolQuestion – повестка на голосовании, но судя по коду у повестки могут быть version
, наверно необходимо для повторного прочтения.
function vote(uint version, string userKey, uint[] options, string customAnswer, string customAnswer2) onlyOwner()
Такая внешняя функция представлена для приема мнений «граждан». Ждет указания версии, непонятного UserKey, множество опций (выбор из перечисления в предложении) и два поля для произвольного ответа.
Но меня смущает модификатор onlyOwner(), судя по наименованию модификатор ограничивает доступ к контракту.
Как правило такой модификатор оставляет право взаимодействовать с контрактом исключительно одному адресу в сети, но может это логика ограничивающая прием голосов только от известных блокчейну граждан?
Посмотрим реализацию модификатора в Owned.sol
:
modifier onlyOwner() { if (msg.sender == owner) { _; } else { AccessDenied(msg.sender); } }
Увы, но это почти стандартная реализация и мы не увидем тут решения третьего пункта ожиданий от голосований на блокчейне. Мы тут так же не увидим и первых двух!
Я бы хотел вам подробно рассказать о красоте реализации этого проекта, но увы.
Это голосование где ваши голоса записывает администратор базы данных от своего имени.
P.S. Желающие могут принять участие в дискуссии созданной на гитхабе моим коллегой – Игорем Бариновым основателем https://oracles.org:
https://github.com/moscow-technologies/ag-blockchain/issues/8#issuecomment-351087490