├── smart-contracts ├── packages │ ├── smart-contracts │ │ ├── migrations │ │ │ └── .gitkeep │ │ ├── .soliumignore │ │ ├── .gitignore │ │ ├── etc │ │ │ └── filter_json.sh │ │ ├── .DS_Store │ │ ├── .solhint.json │ │ ├── .soliumrc.json │ │ ├── index.js │ │ ├── package.json │ │ ├── build │ │ │ └── contracts │ │ │ │ └── Ownable.json │ │ └── contracts │ │ │ ├── Ownable.sol │ │ │ ├── LockableTransactionAuthorizer.sol │ │ │ └── VotersRegistry.sol │ ├── crypto-lib │ │ ├── .gitignore │ │ ├── .DS_Store │ │ ├── index.js │ │ ├── package.json │ │ └── src │ │ │ ├── utils.js │ │ │ ├── elGamalPartitioner.js │ │ │ └── elGamal.js │ ├── .DS_Store │ ├── voting-lib │ │ ├── .DS_Store │ │ ├── src │ │ │ ├── .DS_Store │ │ │ ├── providers.js │ │ │ ├── contracts │ │ │ │ ├── index.js │ │ │ │ ├── ownable.js │ │ │ │ ├── lockableTransactionAuthorizer.js │ │ │ │ └── votersRegistry.js │ │ │ ├── accounts.js │ │ │ └── helpers.js │ │ ├── index.js │ │ └── package.json │ └── common-deps │ │ └── package.json ├── .DS_Store ├── package.json ├── lerna.json └── readme.md ├── voting-form └── src │ ├── forms │ ├── forms │ │ └── mgik │ │ │ ├── mgd-view │ │ │ ├── manualTxt.tpl │ │ │ ├── error_exception.tpl │ │ │ ├── error_user.tpl │ │ │ └── show.tpl │ │ │ ├── mgd-golosovanie │ │ │ ├── manualTxt.tpl │ │ │ ├── error_exception.tpl │ │ │ ├── error_user.tpl │ │ │ └── templates.tpl │ │ │ └── mgd2019 │ │ │ ├── manualTxt.tpl │ │ │ ├── send.tpl │ │ │ ├── templates.tpl │ │ │ ├── error_exception.tpl │ │ │ ├── show_revocation.tpl │ │ │ ├── error_profile.tpl │ │ │ ├── template_browsers.tpl │ │ │ ├── std_person_document.tpl │ │ │ ├── std_fias.tpl │ │ │ └── show.tpl │ └── common │ │ ├── htdocs │ │ └── forms │ │ │ ├── img │ │ │ └── forms │ │ │ │ └── mgik │ │ │ │ ├── map.png │ │ │ │ ├── mgd_view.jpg │ │ │ │ ├── deputies │ │ │ │ ├── 01_01.jpg │ │ │ │ ├── 01_02.jpg │ │ │ │ ├── 01_03.jpg │ │ │ │ ├── 01_04.jpg │ │ │ │ ├── 01_05.jpg │ │ │ │ ├── 10_01.jpg │ │ │ │ ├── 10_02.jpg │ │ │ │ ├── 10_03.jpg │ │ │ │ ├── 10_04.jpg │ │ │ │ ├── 10_05.jpg │ │ │ │ ├── 30_01.jpg │ │ │ │ ├── 30_02.jpg │ │ │ │ ├── 30_03.jpg │ │ │ │ ├── 30_04.jpg │ │ │ │ ├── 30_05.jpg │ │ │ │ └── 30_06.jpg │ │ │ │ ├── mgd2019 │ │ │ │ └── remote_voting.jpg │ │ │ │ └── mgd-golosovanie │ │ │ │ ├── elections.png │ │ │ │ └── browser_icons.png │ │ │ ├── mgik │ │ │ ├── bulletin_example_1.pdf │ │ │ ├── bulletin_example_10.pdf │ │ │ └── bulletin_example_30.pdf │ │ │ └── js_v3 │ │ │ └── mgik │ │ │ ├── mgd-golosovanie.js │ │ │ ├── mgd-view.js │ │ │ ├── mgd2019.js │ │ │ ├── landing.js │ │ │ └── check.browser.js │ │ └── data │ │ ├── lib │ │ └── Form │ │ │ └── mgik │ │ │ ├── mgd │ │ │ ├── LogicException.php │ │ │ ├── TaskRevocationRequest.php │ │ │ ├── MgdAjaxHandler.php │ │ │ ├── MgdAjaxService.php │ │ │ ├── ReceiveStatusWorker.php │ │ │ ├── TaskRequest.php │ │ │ └── TaskRegistrationRequest.php │ │ │ ├── mgik.class.php │ │ │ ├── mgd2019.class.php │ │ │ ├── mgd-view.class.php │ │ │ └── mgd-golosovanie.class.php │ │ └── config │ │ └── Mgik.php │ ├── ballot │ ├── common │ │ ├── module_tpl │ │ │ └── election │ │ │ │ └── default │ │ │ │ ├── error.tpl │ │ │ │ ├── success.tpl │ │ │ │ ├── _header.tpl │ │ │ │ └── show.tpl │ │ └── module │ │ │ └── election │ │ │ ├── LogicException.php │ │ │ ├── TaskVoteRequest.php │ │ │ ├── AjaxService.php │ │ │ ├── update_dit_voting_settings_cron_task.php │ │ │ ├── Settings.php │ │ │ ├── TaskRequest.php │ │ │ ├── UpdateDitVotingSettingsCommand.php │ │ │ └── m_election.php │ ├── config │ │ └── Mgik.php │ └── static │ │ └── js │ │ └── forms │ │ ├── mgik │ │ ├── LeavingPageCheckerInit.js │ │ └── LeavingPageChecker.js │ │ └── main.min.js │ └── crypt │ └── registr │ ├── baseWsInclude.php │ └── v1 │ └── Oauth.php ├── Описание методов наблюдателя БЧ.pdf ├── encryption-keys ├── keys │ ├── private-key.json │ └── public-key.json ├── readme.md └── data │ ├── original-datums.csv │ └── encrypted-datums.csv └── README.md /smart-contracts/packages/smart-contracts/migrations/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /smart-contracts/packages/smart-contracts/.soliumignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /smart-contracts/packages/crypto-lib/.gitignore: -------------------------------------------------------------------------------- 1 | coverage/ 2 | .nyc_output/ 3 | -------------------------------------------------------------------------------- /smart-contracts/packages/smart-contracts/.gitignore: -------------------------------------------------------------------------------- 1 | coverage/ 2 | coverage.json 3 | coverageEnv 4 | -------------------------------------------------------------------------------- /smart-contracts/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moscow-technologies/blockchain-voting_2019/HEAD/smart-contracts/.DS_Store -------------------------------------------------------------------------------- /voting-form/src/forms/forms/mgik/mgd-view/manualTxt.tpl: -------------------------------------------------------------------------------- 1 |
{$error_message}
9 |Доступ к форме проверки голоса запрещен, так как Вы не участвовали в дистанционном электронном голосовании на выборах Депутатов Московской городской Думы седьмого созыва
12 | 13 | 18 | 19 | {/block} -------------------------------------------------------------------------------- /smart-contracts/packages/common-deps/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "common-deps", 3 | "version": "0.0.0", 4 | "private": true, 5 | "description": "DIT Voting Project common development deps", 6 | "devDependencies": { 7 | "@babel/core": "7.4.4", 8 | "@babel/preset-env": "7.4.4", 9 | "@babel/runtime": "7.4.4", 10 | "chai": "4.2.0", 11 | "chai-as-promised": "7.1.1", 12 | "choma": "1.2.1", 13 | "eslint": "5.16.0", 14 | "eslint-config-airbnb-base": "13.1.0", 15 | "eslint-plugin-import": "2.17.2", 16 | "mocha": "6.1.4", 17 | "nyc": "14.1.1", 18 | "rollup-plugin-babel": "4.3.2", 19 | "rollup-plugin-commonjs": "9.3.4", 20 | "rollup-plugin-istanbul": "2.0.1", 21 | "rollup-plugin-json": "4.0.0", 22 | "rollup-plugin-node-builtins": "2.1.2", 23 | "rollup-plugin-node-globals": "1.4.0", 24 | "rollup-plugin-node-resolve": "4.2.4", 25 | "rollup-plugin-terser": "4.0.4" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /encryption-keys/data/original-datums.csv: -------------------------------------------------------------------------------- 1 | 13112283206282341589939261161118909456523672818901389266279234979380668261341 2 | 9537266403378652029582253820421820507484849062574530707250565053173398215861 3 | 11068513650385046131379595998206447307025905031384686600463684674867135305179 4 | 8654421830119967172472226791428607421453434554363478910491134642343369776339 5 | 7570583526979178564777162401494767735157632987628046863419790412655369697581 6 | 6658136887333442040078197472430938843396508839855976290823159148125519218683 7 | 10718218053391635422300822262751666630598757178427546964517445539221469279235 8 | 11822287086228852504511790919996319583538429317834402402418592701636689380089 9 | 13102589922455022904473200407911868416062098992747929998728624371771659558165 10 | 12351592095745046315027495613051886574426753686984173961205723539017493804515 11 | 13059504539689535114993475564237630965339527784561332758000681387973907459229 12 | 10352928640994684251296554622674682747455489631687433374774573655642201763799 -------------------------------------------------------------------------------- /encryption-keys/keys/public-key.json: -------------------------------------------------------------------------------- 1 | { 2 | "modulo": "100627590814506256180379036786188261966005912425008608027910859704550882961591418803872072305745904601913015245097812875886798212712694662445323678201384359740027439588690880234391145675099291004487668846511981135309331094869021425403957856145722681330313515482620918593602329299394441379077427748866822254003", 3 | "generator": "20938162663634717592050150871604811965450185147804653686210341370048875526465651925988096081498977531693711058194333885660484655132497051711289316232574822094981061190270796634217228273638531730721024423591535339502392703158974687088258365877782810885461860894240185695001397437423927797525752628688868571010", 4 | "publicKey": "69869939556699578412481990448414288405398435179055114398103563207158851026044172687600238140984542441733811519355635274478280224618944886326303030593806942128698581582995535506792363556379422300596532434755856820167980500565477482309964287055106318673831750120449183092965628809034498878410377075732012129326" 5 | } 6 | -------------------------------------------------------------------------------- /smart-contracts/packages/voting-lib/src/contracts/ownable.js: -------------------------------------------------------------------------------- 1 | const ethers = require('ethers'); 2 | 3 | const { 4 | Ownable: { abi }, 5 | } = require('smart-contracts'); 6 | 7 | class Ownable { 8 | constructor(contract) { 9 | this.contract = contract; 10 | } 11 | 12 | // Fields 13 | get address() { 14 | return this.contract.address; 15 | } 16 | 17 | // Getters 18 | async getOwner() { 19 | return this.contract.getOwner(); 20 | } 21 | 22 | async isOwner() { 23 | return this.contract.isOwner(); 24 | } 25 | 26 | // "Setters" 27 | async transferOwnership(address) { 28 | const tx = await this.contract.transferOwnership(address); 29 | 30 | return tx.wait(); 31 | } 32 | 33 | // Statics 34 | static async at(address, signerAccount) { 35 | const deployedContract = new ethers.Contract(address, abi, signerAccount); 36 | 37 | await deployedContract.deployed(); 38 | 39 | return new Ownable(deployedContract); 40 | } 41 | 42 | static async deploy() { 43 | throw new Error('Can not deploy Ownable by itself!'); 44 | } 45 | } 46 | 47 | module.exports = Ownable; 48 | -------------------------------------------------------------------------------- /voting-form/src/forms/common/data/lib/Form/mgik/mgik.class.php: -------------------------------------------------------------------------------- 1 | logData['error'] = 1; 22 | 23 | if ($exception instanceof LogicException) { 24 | $data = $exception->getData(); 25 | $message = $data['errorMessage'] ?? $exception->getMessage(); 26 | $this->logTrait($message, array_merge($this->logData, $data)); 27 | } else { 28 | $this->logData['errorMessage'] = $exception->getMessage(); 29 | $this->logData['errorTrace'] = $exception->getTraceAsString(); 30 | $this->logTrait('Неизвестная ошибка', $this->logData); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /voting-form/src/ballot/common/module/election/AjaxService.php: -------------------------------------------------------------------------------- 1 | action = $action; 20 | $method = "action" . ucfirst($action); 21 | 22 | if (in_array($action, $this->allowedActions) && method_exists($this, $method)) { 23 | return call_user_func([$this, $method]); 24 | } 25 | } 26 | 27 | protected function actionHit() 28 | { 29 | $hit = $_REQUEST['hit'] ?? null; 30 | $tp = $_REQUEST['type'] ?? null; 31 | $value = $_REQUEST['value'] ?? null; 32 | $guid = preg_replace('/.*election\/([^\/]+)$/','$1',$_SERVER['HTTP_REFERER']); 33 | if ($hit) { 34 | $log = GrayLogger::create('MgicHitCounter'); 35 | $log->info($hit, ['data' => $value,'action'=>$tp,'errorMessage'=>$hit,'guid'=> $guid ?? '']); 36 | } 37 | 38 | exit; 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /voting-form/src/forms/forms/mgik/mgd-golosovanie/error_user.tpl: -------------------------------------------------------------------------------- 1 | {extends file="$base_template_path/error.tpl"} 2 | 3 | {block name="message_header"}Доступ к дистанционному электронному голосованию запрещен{/block} 4 | 5 | {block name="message_add_text" } 6 | 7 | 8 | 9 |Доступ к дистанционному электронного голосованию запрещен по одной из следующих причин:
12 | 13 |Если Вы не включены в список для дистанционного электронного голосования, Вам необходимо посетить избирательный участок, за которым Вы закреплены.
19 | 20 | 25 | 26 | {/block} -------------------------------------------------------------------------------- /voting-form/src/forms/common/data/lib/Form/mgik/mgd/MgdAjaxHandler.php: -------------------------------------------------------------------------------- 1 | action = 'action' . ucfirst($action); 22 | $this->form = $form; 23 | 24 | $result = ['result' => false]; 25 | 26 | if (in_array($action, $this->allowActions) && method_exists($this, $this->action)) { 27 | $result = call_user_func([$this, $this->action]); 28 | } 29 | 30 | return json_encode($result); 31 | } 32 | 33 | private function actionLog() 34 | { 35 | $log = $_REQUEST['log'] ?? null; 36 | 37 | if (! $log) { 38 | return ['result' => false]; 39 | } 40 | 41 | $message = $log['error'] ?? 'Неизвестная ошибка'; 42 | 43 | $this->form->logData['error'] = 1; 44 | $this->form->logData['errorMessage'] = $log; 45 | $this->form->logTrait($message, $this->form->logData); 46 | 47 | return ['result' => true]; 48 | } 49 | } -------------------------------------------------------------------------------- /voting-form/src/ballot/common/module/election/update_dit_voting_settings_cron_task.php: -------------------------------------------------------------------------------- 1 | 'UpdateDitVotingSettings', 15 | 'lockTriesInterval' => 1, 16 | 'keyLifetime' => 600, 17 | 'timeToWait' => 0 18 | ]); 19 | 20 | if (isset($argv[1]) && $argv[1] === 'release') { 21 | $mutex->release(); 22 | } 23 | 24 | try { 25 | if (!$mutex->lock()) { 26 | $logger->debug('Процесс уже запущен'); 27 | exit('Процесс уже запущен'); 28 | } 29 | 30 | $command = new UpdateDitVotingSettingsCommand($logger); 31 | $command->handle(); 32 | 33 | } catch (LogicException $e) { 34 | $data = $e->getData(); 35 | $message = $data['errorMessage'] ?? $e->getMessage(); 36 | 37 | $logger->error($message, array_merge($data, [ 38 | 'error' => 1 39 | ])); 40 | 41 | echo "$message\n"; 42 | print_r($data); 43 | 44 | } catch (\Throwable $e) { 45 | $logger->error($e->getMessage(), [ 46 | 'error' => 1, 47 | 'errorMessage' => $e->getMessage(), 48 | 'errorTrace' => $e->getTrace(), 49 | ]); 50 | 51 | echo $e->getMessage() . "\n"; 52 | echo $e->getTraceAsString(); 53 | } 54 | 55 | $mutex->release(); -------------------------------------------------------------------------------- /voting-form/src/forms/forms/mgik/mgd-golosovanie/templates.tpl: -------------------------------------------------------------------------------- 1 | 17 | 18 | 30 | 31 | {include file="$base_template_path/mgik/mgd2019/template_browsers.tpl"} -------------------------------------------------------------------------------- /smart-contracts/packages/smart-contracts/build/contracts/Ownable.json: -------------------------------------------------------------------------------- 1 | { 2 | "abi": [ 3 | { 4 | "inputs": [], 5 | "payable": false, 6 | "stateMutability": "nonpayable", 7 | "type": "constructor" 8 | }, 9 | { 10 | "anonymous": false, 11 | "inputs": [ 12 | { 13 | "indexed": true, 14 | "name": "previousOwner", 15 | "type": "address" 16 | }, 17 | { 18 | "indexed": true, 19 | "name": "newOwner", 20 | "type": "address" 21 | } 22 | ], 23 | "name": "OwnershipTransferred", 24 | "type": "event" 25 | }, 26 | { 27 | "constant": true, 28 | "inputs": [], 29 | "name": "getOwner", 30 | "outputs": [ 31 | { 32 | "name": "", 33 | "type": "address" 34 | } 35 | ], 36 | "payable": false, 37 | "stateMutability": "view", 38 | "type": "function" 39 | }, 40 | { 41 | "constant": true, 42 | "inputs": [], 43 | "name": "isOwner", 44 | "outputs": [ 45 | { 46 | "name": "", 47 | "type": "bool" 48 | } 49 | ], 50 | "payable": false, 51 | "stateMutability": "view", 52 | "type": "function" 53 | }, 54 | { 55 | "constant": false, 56 | "inputs": [ 57 | { 58 | "name": "newOwner", 59 | "type": "address" 60 | } 61 | ], 62 | "name": "transferOwnership", 63 | "outputs": [], 64 | "payable": false, 65 | "stateMutability": "nonpayable", 66 | "type": "function" 67 | } 68 | ], 69 | "bytecode": "0x" 70 | } 71 | -------------------------------------------------------------------------------- /voting-form/src/ballot/common/module_tpl/election/default/success.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | {include file="$template_path/_header.tpl"} 4 | 5 | 6 |Ниже представлен ваш зашифрованный голос.
14 |
17 | Вы можете сохранить свой зашифрованный голос и при желании расшифровать его после подведения итогов голосования.
18 | Сервис для расшифровки будет доступен по ссылке.
19 |
53 | Участие в пилотном дистанционном голосовании могут принять только жители районов указанных ниже:
22 |Для подачи заявления на включение в список избирателей для электронного дистанционого голосования на выборах депутатов Московской городской Думы, необходимо, чтобы в вашем Личном кабинете были подтверждены следующие данные:
35 | 36 | {if $profile_errors} 37 |Убедитесь, что все необходимые требования выполнены.
54 | 55 |Если в вашем Личном кабинете отсутствуют необходимые сведения, вам необходимо перейти в Личный кабинет, указать недостающие сведения и дождаться их проверки.
56 | 57 | 62 | 63 | {/block} -------------------------------------------------------------------------------- /voting-form/src/forms/forms/mgik/mgd2019/template_browsers.tpl: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /smart-contracts/packages/voting-lib/src/helpers.js: -------------------------------------------------------------------------------- 1 | const ethers = require('ethers'); 2 | const { BigInteger: BigInt } = require('jsbn'); 3 | 4 | /** 5 | * 6 | * @param {Object} txReceipt - transaction recipt 7 | * @param {any} txReceipt.logs - transaction logs object 8 | * @param {Object} contract - contract definition 9 | * @param {Object} contract.abi - contract definition 10 | * @param {Object} contract.bytecode - contract bytecode 11 | * @returns {Array.<{ 12 | * transactionLogIndex: Number, 13 | * transactionIndex: Number, 14 | * blockNumber: Number, 15 | * transactionHash: String, 16 | * address: String, 17 | * topics: Array