Chainscript

Chainscript is a data format that provides immutability and auditability of every step in your process.

Chainscript leverages cryptographic hashes to form a directed acyclic graph of auditable events.

At the core of ChainScript there are two main data structures:

  • Links
  • Segments

Links are immutable and contain the details of an event. Links can reference other links to form a graph. The links graph forms the audit trail of your business process.

A link can optionnally be wrapped inside a segment to add mutable data. The main reason for that is that we want to be able to enrich a link with external proofs of its existence. For example we can post a link's hash on the Bitcoin blockchain to prove that this link existed at some point in time. We can then use the block header and a merkle path as externally-verifiable evidence for that claim. This information cannot be added to the link itself because it is immutable, hence the need to wrap links in a mutable container.

A link contains all the data representing a single step in your business process.

Here is what a link looks like in json:

{
  "data": "eyJ1c2VyX2lkIjo0MiwidXNlcl9uYW1lIjoic3BvbmdlYm9iIn0=",
  "meta": {
    "action": "init",
    "clientId": "github.com/stratumn/go-chainscript",
    "data": "eyJhZ2UiOjQyLCJsb2NhdGlvbiI6ImZyYW5jZSJ9",
    "mapId": "my_map",
    "outDegree": -1,
    "prevLinkHash": "mSe7SbLFboaOYhDxLEnXham6xuESNQAjcmR8+95KQyA=",
    "priority": 42,
    "process": { "name": "proc", "state": "initialized" },
    "refs": [{ "linkHash": "Kioq", "process": "some other process" }],
    "step": "init",
    "tags": ["t1", "t2"]
  },
  "signatures": [
    {
      "payloadPath": "[version,data,meta]",
      "publicKey": "LS0tLS1CRUdJTiBFRDI1NTE5IFBVQkxJQyBLRVktLS0tLQpNQ293QlFZREsyVndBeUVBRC9jeEJpWW0vaUo0Ty9sY1dNV3BKZ0IzeGU1eFFPQVRjL0RXTGk3SXBzQT0KLS0tLS1FTkQgRUQyNTUxOSBQVUJMSUMgS0VZLS0tLS0K",
      "signature": "LS0tLS1CRUdJTiBNRVNTQUdFLS0tLS0KU0w2aGc1VXdQSnFMVFdyY3lQMDh0a0pabDZtM29YRkxTN3czM3oxdWlmNXdpbjZOdEIzbzQ4TjBHeVZsM0ZPaQpaeHpKMmxCWGkyd21TdmkxblIvV0RnPT0KLS0tLS1FTkQgTUVTU0FHRS0tLS0tCg==",
      "version": "1.0.0"
    }
  ],
  "version": "1.0.0"
}

We won't detail each field here. You can find the complete list on the Chainscript page in the Concepts section.

Segment

A segment wraps a link to provide some kind of external evidence. Evidences encompass a broad range of features:

  • An evidence can prove that a link was created at a certain point in time (by posting the link hash to a public blockchain for example)
  • An evidence can prove that a link was accepted by a known entity (by showing a digital signature of that entity)
  • ...

Here is what a segment looks like in json:

{
  "link": {},
  "meta": {
    "linkHash": "mSe7SbLFboaOYhDxLEnXham6xuESNQAjcmR8+95KQyA=",
    "evidences": [
      {
        "backend": "bitcoin",
        "proof": "Kg==",
        "provider": "testnet:3",
        "version": "1.0.0"
      }
    ]
  }
}

We won't detail each field here. You can find the complete list on the Chainscript page in the Concepts section.

Modeling a Chainscript process

The first step when defining your process will be to choose how to map it to Chainscript links. You should identify the different actions that can be taken and the changes in process state that these actions trigger.

You will also need to consider how your steps will be linked to other steps and how to use Chainscript maps.

When you're ready, head over to the next section to get started with a concrete example.