Python Library

This page describes the Python API of the ccf.ledger module which can be used by auditors to parse a CCF ledger.

The latest version of the CCF Python tools package is available on PyPi and can be installed as follows:

$ pip install ccf

Tip

Use the read_ledger.py command line utility to display the content of a CCF ledger from the command line.

Tutorial

This tutorial demonstrates how to parse the ledger produced by a CCF node. It shows a very basic example which loops through all transactions in the ledger and displays the content of all updates to a well-known built-in table.

First, the paths to the ledger directories should be set:

ledger_dirs = ["</path/to/ledger/dir>"] # List of a single ledger directory

Note

By default, ledger directories are created under the node directory (See ledger configuration entry).

Then, import the ledger module and instantiate a ccf.ledger object:


ledger = ccf.ledger.Ledger(ledger_dirs, committed_only=False)

By default, non-committed ledger files are ignored, unless the committed_only argument is set to False.

In this particular example, a target table is set. This is a public table that can be read and audited from the ledger directly. In this example, the target table is the well-known public:ccf.gov.nodes.info table that keeps track of all nodes in the network.

target_table = "public:ccf.gov.nodes.info"

Note

In practice, it is likely that auditors will want to run more elaborate logic when parsing the ledger. For example, this might involve auditing governance operations and looping over multiple tables.

Finally, the ledger can be iterated over. For each transaction in the ledger, the public tables changed within that transaction are observed. If the target table is included, we loop through all keys and values modified in that transaction.

for chunk in ledger:
    for transaction in chunk:
        # Retrieve all public tables changed in transaction
        public_tables = transaction.get_public_domain().get_tables()

        if target_table in public_tables:
            # Ledger verification is happening implicitly in ccf.ledger.Ledger()
            for key, value in public_tables[target_table].items():
                # Note: `key` and `value` are raw bytes here.