Contract Operations API and Ledger Adapters
To manage contracts specified using CSL on various ledger backends, Deon Digital provides various software adapters to virtualize the ledger used to store the contracts via a contract management abstraction (API). The interface for contract management is specified in com.deondigital.sic.ContractOperations, implemented in the Centralized ledger adapter (com.deondigital.sic.DbLedgerContractOperations in sic-dbledger-operations library jar)
In addition to this, there exists a Distributed Ledger implementation in the Deon Digital Smart Financial Instruments (SFI) product.
Since CSL is independent of the underlying ledger details, CSL contracts and reports are completely portable across the different ledger backends by simply switching the ledger adapter. Note that ContractOperations is a typed interface and is coupled to the CSL contracts and reports it manages to ensure compile time checks can be leveraged by the application. For more details on the types and how to generate them from CSL, please refer to the code generator guide.
Note that the contract operations API does not create yet another abstraction of a distributed ledger over various supported ledger technologies. Such a design choice would require knowledge of what constitutes a good ledger abstraction and choice of tradeoffs in the implementation of the abstraction. Instead, we assume the application knows best about the ledger technology it uses. This allows us to implement low-cost adapters that maintain the guarantees (e.g., security, consistency, failure, etc.) of the underlying ledger while providing a uniform API to manage contracts across the ledgers.
Functionality
The functionality of the ledger adapters focus on lifecycle management of the contract in addition to their administration. They provide the view of a secure immutable ledger that stores contracts and allows management of their lifecycle based on the contract specification in a verifiable manner.
Contract Lifecycle Management
The contract management interface supports the following functionality:
Function |
Description |
---|---|
instantiate |
Instantiate contract on the ledger |
applyEvent |
Apply event on an instantiated contract |
getContractEvents |
Retrieve events applied on a contract |
getContracts |
Retrieve all contracts stored on the ledger |
terminateContract |
Terminate a contract |
novateContract |
Novate a contract, i.e., terminate a contract and replace it by instantiating a new contract. This happens atomically. |
nextEvents |
Compute the set of possible next events that can be applied to a contract in its present state |
execute |
Instantiate and apply events on many contracts atomically |
Note that the above functionality is exposed via an asynchronous interface which allows the caller to chain and synchronize as it deems fit.
Report Generation
The contract management interface also support the following reporting functionality:
Property |
Description |
---|---|
reports |
Compute reports by accessing this property. The reports written in CSL are available as Kotlin functions under this property. |
Since the contract management API abstracts a ledger which manages identities, the ContractOperations API also exposes functions to retrieve stored identities on the ledger and to convert identities from the CSL representation to the ledger’s representation.
Subscribing to Contract Changes (Experimental)
The contract management interface also supports the following experimental subscription functionality:
Property |
Description |
---|---|
onContractUpdated |
Subscribe to changes in contracts stored in the underlying ledger |
This functionality is not standardized yet using the ContractOperations interface, but is an experimental one supported by the the ledger adapters. The ledger adapters allow registration of callback functions that are invoked when a change happens in the ledger to a contract. A contract in the ledger is immutable and every change to it is tagged with a monotonically increasing version number. The registered callback function is invoked with arguments that describe the change and the version number. Due to its experimental nature, the subscription API is not uniform across the ledger adapters.
Consistency Model
The ContractOperations API is thread-safe and every API invocation is atomic and provides both all-or-nothing atomicity and before-or-after atomicity. In the case of a replicated ledger, APIs that perform a change in the ledger are guaranteed to be sequentially consistent while APIs that read from the ledger are guaranteed to be eventually consistent. Note that these guarantees are not baked into ContractOperations API but are a consequence of the low-cost implementation of an atomic API in the ledger adapters which expose the replication model of the ledger. To ensure programming ease, ContractOperations will provide an atomic API but the consistency guarantees under replication can vary across the ledger adapters in the future.
Failure Model
The failure model of ContractOperations API is dependent on the failure model of the underlying ledger that is used in the application architecture.
DbLedger
The centralized ledger (DbLedger) adopts a single publisher and multiple subscriber architecture. The single publisher node must not fail for operations that change the ledger to be successful while operations that read the ledger can be serviced with the local subscriber node even when the publisher node or other subscriber nodes are not available. Any operation that is successful is also guaranteed to be durable.