An elections component for Decidim's participatory spaces based on the Vocdoni.
Vocdoni is a secure digital voting solution using decentralized technologies. The voting protocol which powers the platform is designed to be universally verifiable, secure, and resistant to attack and censorship through the use of blockchain technology, together with decentralized technologies and cryptographic mechanisms, such as zero-knowledge proofs.
This will allow administrators to set-up elections in the Vocdoni blockchain (aka Vochain), using the Vocdoni SDK.
Vocdoni will be available as a Component for a Participatory Space.
For installation instructions, skip the screenshots section.
A nice wizard to set up the election in the admin:
Final checks and blockchain synchronization:
Voting in a non-distracting booth:
Publication of results:
Add this line to your application's Gemfile:
gem "decidim-vocdoni", github: "decidim-vocdoni/decidim-module-vocdoni"
And then execute:
bundle
bin/rails decidim:upgrade
bin/rails db:migrate
EXPERTS ONLY
Under the hood, when running
bin/rails decidim:upgrade
thedecidim-vocdoni
gem will run the following (that can also be run manually if you consider):bin/rails decidim_vocdoni:install:migrations bin/rails decidim_vocdoni:webpacker:install
Depending on your Decidim version, you can choose the corresponding version to ensure compatibility:
Version | Compatible Decidim versions |
---|---|
1.x | 0.27.x |
2.x | 0.28.x |
For some of the Elections status changes, you'll need to add a task to the schedule tasks configuration of your hosting provider.
In a GNU/Linux server, can configure it with crontab -e
, for instance if you've created
your Decidim application on /home/user/decidim_application and you want that the Elections
status are checked every 15 minutes, you can do it with this configuration:
# Change Elections status on decidim-vocdoni
0/15 0 * * * cd /home/user/decidim_application && RAILS_ENV=production bin/rails decidim_vocdoni:change_election_status > /dev/null
Administrators have the possibility to use an internal or dynamic census, allowing the census to be change during the election vote period. On this case it is necessary to update it in to the Vocdoni blockchain. A common scenario for this is when you want the internal Decidim userbase to be the census. Then, an authorization method is selected in order to be able to vote and people can dynamically authorize themselves in order to vote (because they might not have the proper authorization in the moment of voting).
This process can have a cost of a few tokens, so it is not done automatically. The admin is responsible to update the census in the Vocdoni blockchain in the admin's monitoring page. The process of updating the census effectively removes the current census and creates a new one for the ongoing election, so it is advisable to do it with care and properly inform the voters at which time they will be able to vote.
In summary, the admin is responsible to update the census at all times, this is not an automatic process. Also, remember that this might have a monetary cost in terms of tokens.
TL;DR Ensure you have a working Node.js installation in the Decidim Production server with the package
@vocdoni/sdk
installed. (Node.js is already a requirement in order to precompile the Rails assets but it is not strictly necessary for running Decidim in production). If you want to use this plugin, you'll need to have Node.js installed in the production server.
This module needs to communicate with the Vocdoni API. For that, it used the SDK provided by Vocdoni that is written in Javascript and available as an NPM package.
This plugin uses this SDK using a wrapper around it by calling a Node.js instance under the hood.
So, ensure you have a working Node.js application accessible by the Decidim installation with the package @vocdoni/sdk
installed. Note that using the default auto-generated package.json
should work but it installs dependencies only needed to compile the Rails assets. If you want to optimize your production server, you can install only the dependencies needed by the SDK by running npm install @vocdoni/sdk
in the Decidim installation path or using a custom package.json file like this:
{
"dependencies": {
"@vocdoni/sdk": "^0.8.0"
}
}
The usage of the Vocdoni platform has some economic costs, as its using a Blockchain.
For using it in a production environment with guaranties, you may contact with the maintaners of this plugin PokeCode asking for a pricing. Costs will vary depending on your census size and the number of elections you want to perform.
As there could be other resellers and not only PokeCode, contact information can be configured by using the ENV variables VOCDONI_RESELLER_NAME and VOCDONI_RESELLER_EMAIL (see the configuration for more information)
By default, the module is configured to read the configuration from ENV variables.
Currently, the following ENV variables are supported:
ENV variable | Description | Default value |
---|---|---|
VOCDONI_API_ENDPOINT_ENV | The environment of the Vocdoni API. Only two values are accepted: dev , stg , prod . Read more on Vocdoni SDK Usage Environment |
stg |
VOCDONI_MINUTES_BEFORE_START | How many minutes should the setup be run before the election starts (when configured automatically) | 10 |
VOCDONI_MANUAL_START_DELAY | How many seconds after the action of starting an election manually people will be allowed to vote. Note that this time is needed in order to configure the election in the blockchain. You might want to increase it if communication with the Vocdoni API is slow. | 30 |
DECIDIM_VOCDONI_SDK_DEBUG | This is for development purposes. If set to true , any call to the Vocdoni API using the SDK ruby wrapper will be logged into the node_debug.log file (on the application main folder). |
false |
VOCDONI_RESELLER_NAME | The name of the Vocdoni reseller, the organization that manages the tokens to work with the Vocdoni platform. | PokeCode SL |
VOCDONI_RESELLER_EMAIL | The email of the Vocdoni reseller. | [email protected] |
It is also possible to configure the module using the decidim-vocdoni
initializer:
Decidim::Vocdoni.configure do |config|
config.api_endpoint_env = "stg"
config.minimum_minutes_before_start = 20
config.manual_start_time_delay = 30
end
See Decidim.
To start contributing to this project, first:
- Install the basic dependencies (such as Ruby and PostgreSQL)
- Clone this repository
Decidim's main repository also provides a Docker configuration file if you prefer to use Docker instead of installing the dependencies locally on your machine.
You can create the development app by running the following commands after cloning this project:
bundle
DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec rake development_app
Note that the database user has to have rights to create and drop a database in order to create the dummy test app database.
Then to test how the module works in Decidim, start the development server:
DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bin/rails s
Note that bin/rails
is a convenient wrapper around the command cd development_app; bundle exec rails
.
In case you are using rbenv and have the
rbenv-vars plugin installed for it, you
can add the environment variables to the root directory of the project in a file
named .rbenv-vars
. If these are defined for the environment, you can omit
defining these in the commands shown above.
As latest versions of Decidim, this repository uses Webpacker for Rails. This means that compilation of assets is required every time a Javascript or CSS file is modified. Usually, this happens automatically, but in some cases (specially when actively changes that type of files) you want to speed up the process.
To do that, start in a separate terminal than the one with bin/rails s
, and BEFORE it, the following command:
bin/webpack-dev-server
Please follow the code styling defined by the different linters that ensure we are all talking with the same language collaborating on the same project. This project is set to follow the same rules that Decidim itself follows.
Rubocop linter is used for the Ruby language.
You can run the code styling checks by running the following commands from the console:
bundle exec rubocop
To ease up following the style guide, you should install the plugin to your favorite editor, such as:
- Atom - linter-rubocop
- Sublime Text - Sublime RuboCop
- Visual Studio Code - Rubocop for Visual Studio Code
There are other linters for Javascript and CSS. These run using NPM packages. You can run the following commands:
npm run lint
: Runs the linter for Javascript files.npm run lint-fix
: Automatically fix issues for Javascript files (if possible).npm run stylelint
: Runs the linter for SCSS files.npm run stylelint-fix
: Automatically fix issues for SCSS files (if possible).
To run the tests run the following in the gem development path:
bundle
DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec rake test_app
DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec rspec
Note that the database user has to have rights to create and drop a database in order to create the dummy test app database.
In case you are using rbenv and have the
rbenv-vars plugin installed for it, you
can add these environment variables to the root directory of the project in a
file named .rbenv-vars
. In this case, you can omit defining these in the
commands shown above.
We also have some tests for the Javascript code. To run them, you can use the following commands:
npm ci
npm run test
Code coverage report is generated automatically after running the test suite, in a folder
named coverage
in the project root which contains the code coverage report. It's
available at the file ./coverage/index.html. If you're using GNU/Linux, you can open
it with xdg-open ./coverage/index.html
.
If you would like to see this module in your own language, you can help with its translation at Crowdin:
https://crowdin.com/project/decidim-module-vocdoni
This engine is distributed under the GNU AFFERO GENERAL PUBLIC LICENSE. See LICENSE-AGPLv3.txt.
As this module works with the Vocdoni SDK, see https://vocdoni.io/ for more information about their open source licenses.