{"id":15789921,"url":"https://github.com/gettocat/democracyjs","last_synced_at":"2025-10-23T20:22:52.397Z","repository":{"id":57129173,"uuid":"246388921","full_name":"gettocat/democracyjs","owner":"gettocat","description":"Democracy election algorithm","archived":false,"fork":false,"pushed_at":"2020-03-10T19:26:32.000Z","size":31,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-05T22:04:13.367Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gettocat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-10T19:25:24.000Z","updated_at":"2020-04-11T00:25:00.000Z","dependencies_parsed_at":"2022-08-31T19:22:48.592Z","dependency_job_id":null,"html_url":"https://github.com/gettocat/democracyjs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gettocat%2Fdemocracyjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gettocat%2Fdemocracyjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gettocat%2Fdemocracyjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gettocat%2Fdemocracyjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gettocat","download_url":"https://codeload.github.com/gettocat/democracyjs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246516938,"owners_count":20790323,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-04T22:04:12.391Z","updated_at":"2025-10-23T20:22:52.323Z","avatar_url":"https://github.com/gettocat.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# democracyjs\nDemocracy election for decentralized systems. \n\n## App\nThis application implements consensus algorithm work. You can reimplement classess, objects, methods for your application.\n\nHave four modules, based on app.MODULE:\n\n- Peer\n- Data\n- PeerManager\n- DataManager\n- Election\n\n### Peer\nDefine connected node entry\n\n```js\nclass Peer extends app.MODULE {\n    constructor(data);//create new peer\n    getId(); //get peer id\n    signVote(vote); //vote = { id, answer }\n}\n```\n\n### PeerManager\nDefine Mapper of Peer entries. Storing, sorting, searching, etc...\n\n```js\nclass PeerMapper extends app.MODULE {\n    getPeersList();//get list of all peers\n    addPeer(peer);//add peer to list\n    addPeers(peer_list);//add peers to list\n    removePeerById(peerId);//remove peer by id\n    removePeer(peer);//remove Peer\n}\n```\n\n### Data\nDefine election data message (election/vote)\n\n```js\nclass Data extends app.MODULE {\n    constructor(data);//create new Data\n    static getTypeFieldName()//type  field name, default \"type\"\n    static getIdFieldName()//id  field name, default \"id\"\n    static getPublicKeyFieldName()//publicKey  field name, default \"pub\"\n    static getSignFieldName()//signature  field name, default \"sig\"\n    static getAnswerFieldName()//answer  field name, default \"answer\"\n    static getMethodFieldName()//method  field name, default \"method\"\n    static getAnswersFieldName() //answers  field name, default \"answes\"\n    static getStatusFieldName()//status field name, default \"status\"\n    static getUntilFieldName() //until field name, default \"until\"\n    static getBalancedFieldName()//balanced field name, default \"balanced\"\n    getType()//type can be vote or election\n    getId()//id of election\n    getPublicKey()//public key of peer who create this data\n    getSign()//EC signature\n    getAnswer()//answer, only for type = vote\n    getMethod()//method for callback, only for type = electin\n    getAnswers()//answers list for election, only for type = election\n    getStatus()//status can be pending, timeout, reached, only for type = election\n    getUntil()//time when data will be timedout, only for type = election\n    getBalanced()//balanced value, see method Election::balancing(), only for type = election and status = reached \n    isValid()//is valid data (signature and syntax)\n    setStatus(newStatus)//set new status, only for type = election\n    setBalanced(balanced)//set balanced value, only for type = election\n}\n```\n### DataMapper\nDefine Mapper of Data entries. Storing, sorting, searching, etc...\n\n```js\nclass DataMapper extends app.MODULE {\n\n    getDataList();//get all data\n    _addDataToList(data);//add data to list\n    addData(data);//add data to list with verify (recive from network)\n    getData(id);//get data by id\n    removeData(data);//remove data \n    getElectionVoteByPeer(election_id, peer_id);//get peer vote in election\n    getElectionPeers(election_id);//get publickeys of voted peers\n    getElectionVotes(election_id);//get votes in election\n    saveData(data);//save data with new parameters\n}\n```\n\n### Election\nDescribe election algorithm. \n\n```js\nclass Election extends app.MODULE {\n\n    constructor(election_config_field);//election_config_field - config section, with params for this election algorithm. See more: config sections \n    getConfig(field, defaultValue);//get config section param (or all if first param is null);\n    init()//init\n    setKeystore(ks);//set keystore {publicKey: 'hex', privateKey: 'hex'}\n    setOnEnd(cb);//set callback on finish election (timeout, reached)\n    vote(electionId, answer);//vote for electionId with answer for current keystore\n    isValidTime(time);//check time for valid\n    create(request, answers, until, method);//create new election with request (text), answers - array, until - time in future, when election will timeout\n     voteProcess(peer, voteData);//use this method when get message from another peer with vote data. voteData = {id, answer, sign}\n     balancing(id, data);//use this method for choose value when election is reached\n     getVotersList();//must be extended for valid peer list, who can voting\n}\n```\n\n## App.Extending\n\nAny class in application can be redefined before start, for example we have app methods:\n\n```js\ndefinePeerClass(man);\ndefinePeerManagerClass(man);\nsetPeerManager(man);\ndefineDataClass(man);\ndefineDataManagerClass(man);\nsetDataManager(man);\ndefineElectionClass(man);\n```\n\nTo redefine class you need create you own class and extends one from default modules:\n\n- app.PEER\n- app.DATA\n- app.PEERMANAGER\n- app.DATAMANAGER\n- app.ELECTION\n\nFor example we can create new election algorithm with another balancing algorithm and peer list:\n\n```js\nmodule.exports = function(app) {\n    class NewElection extends app.ELECTION {\n        constructor(){\n            super('election_field')\n        }\n        getVotersList() {\n            return [\n                '0x0',\n                '0x1',\n                '0x2',\n                '0x3',\n                '0x4',\n                '0x5',\n            ];\n        }   \n        balancing(id, data){//use average of all values \n            let answers = app.dataManager.getElectionVotes(id);\n            let avg = 0;\n            for (let i in answers){\n                avg += answers[i].getAnswer();\n            }\n\n            return avg/answers.length\n        }\n    }\n\n    return NewElection\n}\n```\n\nPut this code to file newcons.js, and require it:\n\n```js\n\nconst newelect = require('newelect.js');\nconst DemocracyJs = require(\"democracyjs\");\nlet config = {\n    \"election_field\":{\n        \"majority\": 0.5\n    }\n    \"node\":{ //required section\n        ///...\n    }\n};\nlet app = new DemocracyJs(config);\napp.defineElectionClass(newelect(app));\n//now you can start app with new election\napp.start();\n```\n\n\n## Config sections\n\nYou can create many config sections:\n```js\n\"section1\": {\n    \"param1\": \"value1\",\n    \"param2\": \"value2\"\n    //etc\n}\n```\n\nand use it in application: `app.config.section1.param1`\nAny eection have default config section, defined in second param of constructor, for example:\n```js\nconstructor(){\n    super('newconsensus_config_field')\n}\n```\n\nin this example we must have section `newconsensus_config_field` in config!\n\n### node\nNode section is required for application. Its describe keys of current peerm this keys will be used for signing messages\n```js\n\"node\": {\n    \"publicKey\": '0x...\u003chex\u003e',\n    \"privateKey\": '0x...\u003chex\u003e'\n},\n```\n\n### extending sections\n\nConfig sections can be extending by existing sections:\n```js\n\"section1\": {\n    \"param1\":'value1',\n    \"param2\":'value2',\n},\n\"section2\":{\n    \"extends\":\"section1\",\n    \"param3\":\"value3\"\n}\n```\n\nIn this example section2 have next params: \n```js\n\"param1\":'value1',\n\"param2\":'value2',\n\"param3\":\"value3\"\n```\n\nExtending can be nested:\n\n```js\n\"section1\": {\n    \"param1\":'value1',\n    \"param2\":'value2',\n},\n\"section2\":{\n    \"extends\":\"section1\",\n    \"param3\":\"value3\"\n},\n\"section3\": {\n    \"extends\": \"section2\",\n    \"params5\": 1,\n}\n```\n\nit will be: \n\n```js\n\"param1\":'value1',\n\"param2\":'value2',\n\"param3\":\"value3\",\n\"params5\": 1,\n```\n\nExtending config sections is used for default election algorithms, see below.\n\n### default config parameters:\n\nConfig default parameters, that can be extend and rewrite defined in `app.getDefaultConfig()`:\n```js\ngetDefaultConfig() {\n    return {\n            'election': {\n                'majority': 0.75\n            },\n            'node': {\n                'privateKey': '',\n                'publicKey': ''\n            }\n        };\n    }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgettocat%2Fdemocracyjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgettocat%2Fdemocracyjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgettocat%2Fdemocracyjs/lists"}