Plenum is the heart of the distributed ledger technology inside Hyperledger Indy. As such, it provides features somewhat similar in scope to those found in Fabric. However, it is special-purposed for use in an identity system, whereas Fabric is general purpose.
- Details about the protocol, including a great tutorial, can be found on the wiki.
- Please have a look at aggregated documentation at indy-node-documentation which describes workflows and setup scripts common for both projects.
- plenum:
- the main codebase for plenum including Byzantine Fault Tolerant Protocol based on RBFT
- common:
- common and utility code
- crypto:
- basic crypto-related code (in particular, indy-crypto wrappers)
- ledger:
- Provides a simple, python-based, immutable, ordered log of transactions backed by a merkle tree.
- This is an efficient way to generate verifiable proofs of presence and data consistency.
- The scope of concerns here is fairly narrow; it is not a full-blown distributed ledger technology like Fabric, but simply the persistence mechanism that Plenum needs.
- state:
- state storage using python 3 version of Ethereum's Patricia Trie
- stp:
- secure transport abstraction
- it has two implementations: RAET and ZeroMQ
- Although RAET implementation is there, it's not supported anymore, and ZeroMQ is the default secure transport in plenum.
- storage:
- key-value storage abstractions
- contains leveldb implementation as the main key-valued storage used in Plenum (for ledger, state, etc.)
- Plenum makes extensive use of coroutines and the async/await keywords in Python, and as such, requires Python version 3.5.0 or later.
- Plenum also depends on libsodium, an awesome crypto library. These need to be installed separately.
- Plenum uses ZeroMQ as a secure transport
- indy-crypto
- A shared crypto library
- It's based on AMCL
- In particular, it contains BLS multi-signature crypto needed for state proofs support in Indy.
- Bugs, stories, and backlog for this codebase are managed in Hyperledger's Jira.
Use project name
INDY
. - Join us on Jira's Rocket.Chat at
#indy
and/or#indy-node
channels to discuss.
- We'd love your help; see these instructions on how to contribute.
- You may also want to read this info about maintainers.
Please have a look at Dev Setup in indy-node repo. It contains common setup for both indy-plenum and indy-node.
pip install indy-plenum
From here, you can play with the command-line interface (see the tutorial).
Note: For Windows, we recommended using either cmder or conemu.
plenum
...or run the tests.
git clone https://github.com/hyperledger/indy-plenum.git
cd indy-plenum
python -m plenum.test
Each Node needs to have keys initialized
- ed25519 transport keys (used by ZMQ for Node-to-Node and Node-to-Client communication)
- BLS keys for BLS multi-signature and state proofs support
init_plenum_keys --name Alpha --seeds 000000000000000000000000000Alpha Alpha000000000000000000000000000 --force
init_plenum_keys --name Beta --seeds 0000000000000000000000000000Beta Beta0000000000000000000000000000 --force
init_plenum_keys --name Gamma --seeds 000000000000000000000000000Gamma Gamma000000000000000000000000000 --force
init_plenum_keys --name Delta --seeds 000000000000000000000000000Delta Delta000000000000000000000000000 --force
Note: Seed can be any randomly chosen 32 byte value. It does not have to be in the format 00..<name of the node>
.
- Seed used for steward Bob's signing key pair
11111111111111111111111111111111
- Seed used for steward Bob's public private key pair
33333333333333333333333333333333
- Seed used for client Alice's signing key pair
22222222222222222222222222222222
- Seed used for client Alice's public private key pair
44444444444444444444444444444444
start_plenum_node Alpha
To update any configuration parameters, you need to update the plenum_config.py
in .plenum/YOUR_NETWORK_NAME
directory inside your home directory.
eg. To update the node registry to use 127.0.0.1
as host put these in your plenum_config.py
.
from collections import OrderedDict
nodeReg = OrderedDict([
('Alpha', (('127.0.0.1', 9701), '0490a246940fa636235c664b8e767f2a79e48899324c607d73241e11e558bbd7', 'ea95ae1c913b59b7470443d79a6578c1b0d6e1cad0471d10cee783dbf9fda655')),
('Beta', (('127.0.0.1', 9703), 'b628de8ac1198031bd1dba3ab38077690ca9a65aa18aec615865578af309b3fb', '18833482f6625d9bc788310fe390d44dd268427003f9fd91534e7c382501cd3c')),
('Gamma', (('127.0.0.1', 9705), '92d820f5eb394cfaa8d6e462f14708ddecbd4dbe0a388fbc7b5da1d85ce1c25a', 'b7e161743144814552e90dc3e1c11d37ee5a488f9b669de9b8617c4af69d566c')),
('Delta', (('127.0.0.1', 9707), '3af81a541097e3e042cacbe8761c0f9e54326049e1ceda38017c95c432312f6f', '8b112025d525c47e9df81a6de2966e1b4ee1ac239766e769f19d831175a04264'))
])
cliNodeReg = OrderedDict([
('AlphaC', (('127.0.0.1', 9702), '0490a246940fa636235c664b8e767f2a79e48899324c607d73241e11e558bbd7', 'ea95ae1c913b59b7470443d79a6578c1b0d6e1cad0471d10cee783dbf9fda655')),
('BetaC', (('127.0.0.1', 9704), 'b628de8ac1198031bd1dba3ab38077690ca9a65aa18aec615865578af309b3fb', '18833482f6625d9bc788310fe390d44dd268427003f9fd91534e7c382501cd3c')),
('GammaC', (('127.0.0.1', 9706), '92d820f5eb394cfaa8d6e462f14708ddecbd4dbe0a388fbc7b5da1d85ce1c25a', 'b7e161743144814552e90dc3e1c11d37ee5a488f9b669de9b8617c4af69d566c')),
('DeltaC', (('127.0.0.1', 9708), '3af81a541097e3e042cacbe8761c0f9e54326049e1ceda38017c95c432312f6f', '8b112025d525c47e9df81a6de2966e1b4ee1ac239766e769f19d831175a04264'))
])