Interface Definition Language

An interface is a file ending in .cci (Chaincode Interface) that defines a language neutral definition for various RPC-like functions that a given chaincode instance supports. An chaincode instance may in fact support many different interfaces at one time. This is convenient for creating a type of polymorphism within a network of chaincode instances.

Each .cci file is meant to represent an interface contract for compatibility. Items declared within a .cci file have provisions (similar to protobuf indices) for mutating structures over time that do not break forwards or backwards compatibility. Changes to a given interface should only be done in a manner which exploits this compatibility mechanism. If for some reason it is mandated that compatibility must be broken, the name of the interface should be changed.

Interface names

The name of the .cci file has direct meaning to the ABI: the name of the file will be translated into ABI tokens on the wire. This was intentionally chosen so that the filesystem itself (under ./src/interfaces) takes a role in ensuring that only one interface of a particular type is in use within a project at any given time. Likewise, if a project wishes to import and consume an interface from a different project, it is imperative that the filename be retained across both projects or the endpoints will be inadvertently namespace-isolated from one another. To put it another way, do not rename .cci files on import!

Perhaps even more importantly, interface ABI needs to be globally managed. Therefore it is advised to name .cci files in a way that is globally unique. A UUID would suffice, at the expense of being somewhat difficult to humans to deal with. Therefore, it is advised to name interfaces using DNS names as in the examples provided here.


Each interface definition loosely adheres to a protobuf-ish syntax. This was intentional, as the .cci file is actually translated into an intermediate .proto file before being handed to protoc to do the real work. The reason we did not just use protobuf syntax directly was because it was felt there were a few areas of the protobuf grammar that were suboptimal w.r.t. chaincode definition. Consider an example .cci:

message PaymentParams {
        string partySrc = 1;
        string partyDst = 2;
        int32  amount   = 3;

message Entity {
        string id = 1;

message BalanceResult {
        int32 balance = 1;

functions {
        void MakePayment(PaymentParams) = 1;
        void DeleteAccount(Entity) = 2;
        BalanceResult CheckBalance(Entity) = 3;

The message definitions are almost 1:1 with protobuf grammar. The largest divergence is w.r.t. the functions section. This section is similiar to the notion of service/rpc in protobuf grammar. We diverged from the protobuf/grpc grammar because it was felt that the lack of “field indices” was a large shortcoming in ABI compatibility. Therefore, the grammar used here retains the notion of indices even for function calls.

The main purpose of the grammar is to define RPC functions. For reasons of ABI stability, it was decided that all RPCs will have the following properties: - Be indexed (e.g. ABI depends on index stability, not function name) - Accept only 0 or 1 message as input and return only 0 (via void) or 1 message as output - We rely on the message definitions for further ABI stability.

“Appinit” interface

Every project has an implicit interface: appinit.cci. This interface is intended to define the “init” or constructor function for a given chaincode. It is also generally assumed to be not something that needs to be shared with other projects in the same manner that application-level interfaces might, thus we are not concerned about “appinit.cci” name conflicting in the way we care about other interfaces.

The interface expected to define a message “Init” with no RPCs. This message will be assumed to be the argument to the chaincode constructor.

Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License. s