Skip to content

HPCI-Lab/yProvTrace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

yProvTrace

A comprehensive permissioned blockchain network implementation with dynamic organization management and chaincode deployment.

fabric-logo docker-logo node-logo shell-logo javascript-logo license-logo


📖 Introduction

yProv is a collaborative initiative between the University of Trento and CMCC, aimed at developing a comprehensive system for managing and exploring provenance information.

Within this ecosystem, yProvTrace introduces a blockchain-based layer that strengthens the trustworthiness and auditability of provenance information. Built on Hyperledger Fabric, it enables the secure and immutable recording of provenance data, promoting transparency, accountability and integrity in collaborative research environments.

This repository accompanies a Master’s Thesis and focuses on the design and implementation of a configurable, extensible Fabric network with dynamic organization management and chaincode lifecycle automation.


📋 Table of Contents


📊 Project Overview

This project consists of two main components:

Module Description Folder
Network Complete Hyperledger Fabric network with dynamic organization management network/
Chaincode Smart contract defining resource lifecycle operations chaincode/

🚀 Getting Started

Prerequisites

To run this project, ensure that all the following dependencies are installed and available:

Tool Version Purpose
🐳 Docker Engine v28.5 or lower Container runtime
🟢 Node.js v18+ Chaincode development

Installation

Clone the repository and move into the project directory:

git clone https://github.com/HPCI-Lab/yProvTrace.git
cd yProvTrace

Quick Start

To deploy a complete test network with minimal setup:

  1. Install the Requirements:

    cd network/scripts
    ./install-requirements.sh
  2. Package the Chaincode:

    ./chaincode-package.sh
  3. Run the Test Networks:

    ./test-3-orgs.sh 

Tip

To better understand the default setup, refer to the Basic Setup section.


🌐 Network Module

Folder Structure

network/
├── 📁 compose/                     # Docker Compose definitions
├── 📁 config/                      # Network and Fabric configuration
|   ├── 📁 crypto/                  # Organization configuration files
|   ├── 📁 fabric/                  # Fabric configuration files
|   └── network.yaml                
├── 📁 configtx/                    # Channel configuration                 
├── 📁 scripts/                     # Automation scripts
└── 📁 templates/                   # Connection profiles (CCPs)

Configuration

The network is fully parameterized through config/network.yaml, which defines:

  • Network name and channel
  • Chaincode parameters (name, version, language)
  • Fabric parameters (version)
  • Docker parameters (project name)
  • Paths definitions

Example Configuration

network:
  name: "yprovtrace-network"
  channel: "mychannel"
  chaincode:
    name: "cc-test"
    language: "javascript"
    version: "1.0"

docker:
  project: "testbed"

fabric:
  version: "2.5.14"

# Paths ...

Network Lifecycle

Warning

All operational scripts must be executed from network/scripts. Please refer to the Script Reference section for detailed information about each script.

cd network/scripts

Initially, a leader organization among the network members should be chosen, ensuring critical operations are executed only once.

Moreover, network/identities and network/channel folders must be shared among all the organizations, as they contain public certificates and channel artifacts needed for network operations.

Requirements Installation

If not already done, install Fabric binaries and dependencies:

./install-requirements.sh

Warning

Before proceeding, please ensure that all binaries are available under the network/bin folder.

Cryptographic Material Generation

Each organization independently generates its private credentials:

./network-prepare.sh <organization-config.yaml>

Private keys remain local, while public certificates are saved under network/identities in order to be shared.

Genesis Block Generation (Leader Only)

./network-init.sh

The generated genesis block must be distributed to all participants before channel joining.

Containers startup and channel joining

./docker-up.sh <docker-compose.yaml>

If this is an orderer organization:

./network-join-orderer.sh

If this is a peer organization:

./network-join-peer.sh

Orderer and peer organizations follow distinct join procedures.

Note

Orderer and peer organizations follow distinct join procedures.

Chaincode Lifecycle

The chaincode lifecycle follows the Fabric v2.x model:

  1. Package
  2. Install
  3. Approve (all organizations)
  4. Commit (once)
# 1️⃣ Package the chaincode 
./chaincode-package.sh

# 2️⃣ Install chaincode on the peer of each organization
./chaincode-install.sh

# 3️⃣ All orgs: approve chaincode
./chaincode-approve.sh 

# 4️⃣ Commit chaincode to channel (only once)
./chaincode-commit.sh

Important

As design choice, unanimous chaincode approval is enforced to ensure strong consensus among network members.

Dynamic Organization Management

The network supports runtime addition and removal of organizations through channel configuration updates.

Operations include:

  • Join/leave request generation
  • Multi-organization approval
  • Configuration commitment

This approach avoids full network restarts and aligns with real-world consortium governance models.

Example of Runtime Joining

In the following example, the Basic Setup with 3 organizations is extended by adding a 4th organization (organization4).

To add a organization4, it must first generate its private credentials and start its peer container:

./network-prepare.sh organization4.yaml
./docker-up.sh docker-compose-organization4.yaml

Then, the addition process can begin, following the steps described below:

  1. Create join request
  2. Approve join request (majority network members)
  3. Commit join request (once)
# 1️⃣ Create join request (by an existing org, e.g. organization1)
./network-join-request.sh configtx-organization4.yaml

# 2️⃣ Approve the request (majority required)
./network-approve-update.sh org4_update_in_envelope.pb

# 3️⃣ Commit the update (only once)
./network-commit-update.sh org4_update_in_envelope.pb

At this point, the new organization can join the channel and set its anchor peer.

./network-join-peer.sh
./network-set-anchor-peer.sh

Finally, the chaincode must be installed and approved by the new member, followed by a re-commit by an existing organization.

Caution

After organization4 has joined the channel, all network members must approve the chaincode definition again to include the new organization. Please refer to the Chaincode Lifecycle section for more details.

Example of Runtime Removal

In the following example, the network described in Example of Runtime Joining is reduced by removing the 4th organization (organization4) following the steps described below:

  1. Create leave request
  2. Approve leave request (majority network members)
  3. Commit leave request (once)
# 1️⃣ Create leave request
./network-leave-request.sh configtx-organization4.yaml

# 2️⃣ Approve the request (majority required)
./network-approve-update.sh org4_update_in_envelope.pb

# 3️⃣ Commit the update (only once)
./network-commit-update.sh org4_update_in_envelope.pb

Finally, organization4 can remove its public identity from the shared folder and optionally delete its local private credentials.

./network-leave-organization.sh --hard
./docker-down.sh docker-compose-organization4.yaml

Script Reference

Script Description Parameters Example
install-requirements.sh Installs Hyperledger Fabric binaries and dependencies. (none) ./install-requirements.sh
network-prepare.sh Generates the private credentials and create/add the public identity to the shared folder. <organization-config.yaml> ./network-prepare.sh organization.yaml
network-init.sh Creates the genesis block (leader org only). (none) ./network-init.sh
docker-up.sh Starts network containers defined in the given compose file. <docker-compose.yaml> ./docker-up.sh docker-compose-org1.yaml
docker-down.sh Stops and removes containers for the given organization. If the optional --hard flag is provided, it also prunes volumes and removes orphaned containers. <docker-compose.yaml> [--hard] ./docker-down.sh docker-compose-org1.yaml
./docker-down.sh docker-compose-org1.yaml --hard
network-join-orderer.sh Joins an orderer organization to the channel. (none) ./network-join-orderer.sh
network-join-peer.sh Joins a peer organization to the channel. (none) ./network-join-peer.sh
network-set-anchor-peer.sh Sets the anchor peer for the given organization. (none) ./network-set-anchor-peer.sh
chaincode-package.sh Packages the chaincode source into a deployable tarball. (none) ./chaincode-package.sh
chaincode-install.sh Installs the packaged chaincode on an organization’s peer(s). (none) ./chaincode-install.sh
chaincode-approve.sh Approves the chaincode definition for an organization. (none) ./chaincode-approve.sh
chaincode-commit.sh Commits the chaincode definition to the channel. (none) ./chaincode-commit.sh
chaincode-invoke.sh Executes a transaction (invoke) on the chaincode. For testing only. (none) ./chaincode-invoke.sh
chaincode-query.sh Queries the chaincode state. For testing only. (none) ./chaincode-query.sh
network-join-request.sh Creates a join request proposal to add a new organization. <configtx.yaml> ./network-join-request.sh configtx-joining.yaml
network-approve-update.sh Approves a pending channel update. <proposal-file> ./network-approve-update.sh joining_update_in_envelope.pb
network-commit-update.sh Commits a channel update after approvals. <proposal-file> ./network-commit-update.sh joining_update_in_envelope.pb
network-leave-request.sh Creates a request to remove an organization from the channel. <configtx.yaml> ./network-leave-request.sh configtx-joining.yaml
network-leave-organization.sh Removes the organization public identity from the shared folder. If the optional --hard flag is provided, it also deletes the local private credentials. (none) ./network-leave-organization.sh

Tip

Most of the above scripts need a organization-specific configuration to be loaded before execution. This is automatically handled by implicitly sourcing common.sh, which interactively allow the selection of the configuration file.


Basic Setup

./test-3-orgs.sh

In this scenario, three peer organizations (R1, R2, R3) and three ordering organizations (R4, R5, R6) have jointly decided that they will establish a network. This network has a configuration, CC1, which all of the organizations have agreed to and which lists the definition of the organizations as well as the policies which define the roles each organization will play on the channel (i.e. configtx.yaml file).

On this channel, R1, R2 and R3 will join peers, named P1, P2 and P3, to the channel mychannel, while R4, R5 and R6 owns respectively O1, O2 and O3, the ordering services of the channel. All of these nodes will contain a copy of the ledger (L1) of the channel, which is where transactions are recorded.

In this example, the chaincode cc-test has been installed on every peer.

Security Considerations

  • Private keys are stored locally under the network/organizations directory of each organization
  • Public certificates are shared via the network/identities folder
  • TLS enabled for all communications
  • Digital signatures are used for identity verification
  • MSP-based access control

Troubleshooting

Docker Volume Permission Issues

In this specific setup, the Docker Compose files assume directories like /data_hlf1/fabric/... to exist.

Solutions (choose one):

  1. Modify the Compose files

    Remove the user binding (1000:988) from each service and change the volume definitions to let Docker manage them:

# In docker-compose-ord1.yaml
volumes:
    orderer_ord1_data:
        driver: local

# Do the same for the other compose files...
  1. Create the required directories locally

    Manually create the directories and set ownership to match the Compose configuration:

sudo mkdir -p /data_hlf1/fabric/orderer_ord1_data
sudo mkdir -p /data_hlf1/fabric/peer0_org1_data
# create also the other required directories...

sudo chown -R 1000:988 /data_hlf1/fabric/

After applying either solution, you can run the basic network using:

./test-3-orgs.sh
Docker Broken Pipe / Build Errors

The "broken pipe" occurs because the internal library Fabric uses to talk to Docker is incompatible with the way newer Docker Engines (from v29+) handle the socket communication during the image build process.

Solution: Downgrade your Docker Engine to version 28.5.0 or lower.


🧱 Chaincode Module

Folder Structure

chaincode/
└── 📁 cc-test/                     # Chaincode name
    ├── 📁 lib/                     # Business logic
    │   └── resource-events.js      
    └── index.js

Chaincode Functions

Function Type Description
CreateResource Submit Creates a new resource on the ledger
UpdateResourceStatus Submit Updates the status of a resource
ReadResource Evaluate Retrieves a resource by PID
GetResourcesByTimestamp Evaluate Returns resources within a timestamp range
ReadAllResources Evaluate Returns all resources
ResourceExists Evaluate Checks if a resource exists

Resource Schema

{
    pid: string,           
    uri: string,           
    hash: string,          
    timestamp: string,     
    owners: string[],      
    status: integer        // 0: unknown, 1: valid, 2: revoked
}

🙏 Acknowledgments

This work builds upon the Hyperledger Fabric ecosystem and related open-source contributions.


📚 Additional Resources


📄 License

license-logo

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors