Processors and Evidences
This section covers the role of Contract Processors in the Blue Contracts ecosystem and how they manage contract state updates through events and evidences. Contract Processors are essential for maintaining the integrity and consistency of contracts, especially in distributed environments where multiple parties may interact with the contract independently.
Introduction
Contract Processors are entities or tools that observe events related to a contract, update the contract's state accordingly, and provide evidences to prove the correctness of their processing. There can be multiple processors for the same contract, operated by different parties. For example:
- Alice may use her private software with an open-source engine to process the contract.
- Bob may use a SaaS solution like
timeline.blue
to process the same contract. - An independent auditor may use another tool to verify the interactions within the contract.
This decentralized processing allows for transparency and trust, as different parties can independently verify the contract's state and history.
Contract Processing Flow
The typical flow for processing a contract involves three main actions:
1. Initiate Contract Action
A participant creates a contract and announces their intent to start a new contract instance by publishing an Initiate Contract Action on their Timeline.
Structure:
name: Initiate Contract Action
description: This action serves as an announcement of the participant's intent to start a new contract instance.
contract:
type: Contract
description: The contract instance which is being initiated.
- blueId: This Timeline entry has a unique
blueId
, which is considered the Contract's ID. - Purpose: Signals the creation of a new contract and provides the initial state.
2. Initiate Contract Processing Action
A party willing to process the contract (e.g., a validator or processor) publishes an Initiate Contract Processing Action on their Timeline, indicating their commitment to maintain and update the contract's state.
Structure:
name: Initiate Contract Processing Action
description: |
An action published by a party indicating their willingness to process the initiated
contract and maintain its state. This action serves as a commitment to validate and
update the contract's state based on subsequent events.
initiateContractEntry:
type: Timeline Entry
description: The original Initiate Contract Action Timeline entry. This links the processing action to the specific contract initiation.
contract:
type: Contract
description: The initial state of the contract being processed.
- initiateContractEntry: References the original contract initiation entry.
- contract: Contains the initial state of the contract.
3. Contract Update Action
Each time an event related to the contract occurs, the processor publishes a Contract Update Action on their Timeline, documenting the state changes and providing evidences.
Structure:
name: Contract Update Action
description: |
Represents an action to update a contract instance. This structure serves as the standard method for contract
processors to document and present steps in the contract lifecycle.
contractInstance:
description: The contract instance after the incoming event is applied.
contractInstancePrev:
type: Text
description: The contract instance before the incoming event is applied.
epoch:
type: Integer
description: The epoch number associated with this update action. Starts with zero for a newly initiated contract.
emittedEvents:
type: List
description: A list of events emitted during the contract processing.
initiateContractEntry:
type: Timeline Entry
description: References the original Initiate Contract Action entry.
initiateContractProcessingEntry:
type: Timeline Entry
description: References the original Initiate Contract Processing Action entry.
incomingEvent:
description: The event that triggered this contract update.
evidences:
description: Proofs provided by the processor to validate the correctness of processing.
- contractInstance: The updated state of the contract after processing the event.
- contractInstancePrev: The state of the contract before processing the event.
- epoch: A sequential number indicating the processing step.
- emittedEvents: Any events generated as a result of processing.
- evidences: Proofs to convince others that the incoming event was processed correctly and in the right order.
Contract Instances and Workflow Instances
Contract Instance
A Contract Instance represents an instantiated contract that holds the current state, workflows, and any nested contract instances.
Structure:
name: Contract Instance
description: An instantiated contract that holds the current state, workflows, and nested contract instances.
id:
type: Integer
description: The unique identifier for the contract instance. The main contract instance has id=0. Instances created within this contract have ids starting from 1 and are stored within `localContractInstances`.
contract:
description: The contract associated with this instance, reflecting any changes due to workflow executions.
startedWorkflowCount:
type: Integer
description: The number of workflow instances that have been initiated.
startedLocalContractCount:
type: Integer
description: The number of local contract instances that have been initiated.
workflowInstances:
description: A list of active workflow instances currently running. Once a workflow is terminated, it is removed from this list.
localContractInstances:
description: A list of active local contract instances currently running within this contract. Once a contract is terminated, it is removed from this list.
processingState:
description: Contains flags indicating the processing status of the contract.
terminatedWithError:
type: Boolean
value: false
completed:
type: Boolean
value: false
Workflow Instance
A Workflow Instance represents an instance of a workflow that was triggered and is being processed.
Structure:
name: Workflow Instance
description: Represents an instance of a workflow that was triggered and is being processed.
id:
type: Integer
description: The unique identifier for the workflow instance. Each new workflow instance gets a consecutive number starting from 0.
workflow:
description: The workflow for which this instance was created. This value is unchanged and reflects the state of the workflow at the moment this instance was created.
currentStepName:
type: Text
description: The name of the step at which processing stopped, if the instance is not finished.
stepResults:
description: A mapping between step names and a dictionary of returned values for all steps that have been processed by this instance and returned some value.
finished:
type: Boolean
description: Indicates whether the workflow instance is finished.
Evidences and Proofs
Processors must provide evidences to prove that:
- The incomingEvent used to update the contract is valid.
- The event was processed in the correct order.
Purpose of Evidences:
- Verification: Allows other parties to verify the correctness of the contract's state without trusting the processor.
- Transparency: Enhances trust among participants by providing a transparent history of contract processing.
Contract Requirements:
-
Contracts can specify:
- Required Processors: Designate trusted processors whose updates are considered valid.
- Required Proofs: Define the type of evidences needed to validate processing.
- Security Levels: Set security expectations, ensuring that the contract is processed securely and verifiably.
-
If a contract does not specify these requirements, parties may rely on their own policies or agreements to determine the validity of processing.
Examples
Below are examples illustrating the processing flow and the structure of messages published on Timelines.
Example 1: Initiate Contract Action
timeline:
blueId: C74uRd4sPfeawKhWBewVKqFLSACiv8B9EiYpuryYUXuR
type: Simulator Timeline Entry
timelinePrev:
blueId: BWhvLzqXHFaJnBo52W2cbBEHt9d7B5LJWm3YypVGQ6qh
message:
contract:
subscriptions:
items:
- initiateContractEntry:
blueId: BWhvLzqXHFaJnBo52W2cbBEHt9d7B5LJWm3YypVGQ6qh
type: All Events External Contract Subscription
name: Alice-Bob Chess Game
type: Chess Assisted Remotely
properties:
assistingContract:
type: Text
value: BWhvLzqXHFaJnBo52W2cbBEHt9d7B5LJWm3YypVGQ6qh
messaging:
participants:
Player White:
timeline:
blueId: C74uRd4sPfeawKhWBewVKqFLSACiv8B9EiYpuryYUXuR
type: Participant
Player Black:
timeline:
blueId: EhCzJt8S4MsawthLSaCKsuRHbLdUYQsuKyYzy2tegsKE
type: Participant
type: Initiate Contract Action
Example 2: Initiate Contract Processing Action
timeline:
blueId: DS6zx89fRP3FhsZ9wcrH54bTuhc1xS5KhrctHRGNwssq
type: Simulator Timeline Entry
timelinePrev:
blueId: DS6zx89fRP3FhsZ9wcrH54bTuhc1xS5KhrctHRGNwssq
message:
initiateContractEntry:
blueId: HcAaANK4tN8sXSUHY5k1EupT2kyYJZ7CB4DYr9hnUbcP
contract:
subscriptions:
items:
- initiateContractEntry:
blueId: BWhvLzqXHFaJnBo52W2cbBEHt9d7B5LJWm3YypVGQ6qh
type: All Events External Contract Subscription
name: Alice-Bob Chess Game
type: Chess Assisted Remotely
properties:
assistingContract:
type: Text
value: BWhvLzqXHFaJnBo52W2cbBEHt9d7B5LJWm3YypVGQ6qh
messaging:
participants:
Player White:
timeline:
blueId: C74uRd4sPfeawKhWBewVKqFLSACiv8B9EiYpuryYUXuR
type: Participant
Player Black:
timeline:
blueId: EhCzJt8S4MsawthLSaCKsuRHbLdUYQsuKyYzy2tegsKE
Example 3: Initiate Contract State, trigger Contract Initialization Event
timeline:
blueId: DS6zx89fRP3FhsZ9wcrH54bTuhc1xS5KhrctHRGNwssq
thread:
blueId: EN81k4Vz8yMovWa6AjZmjFFzAyX2KyFagjf4EEiKMQbS
type: Simulator Timeline Entry
timelinePrev:
blueId: EN81k4Vz8yMovWa6AjZmjFFzAyX2KyFagjf4EEiKMQbS
message:
initiateContractEntry:
blueId: HcAaANK4tN8sXSUHY5k1EupT2kyYJZ7CB4DYr9hnUbcP
contractInstance:
processingState:
startedLocalContractCount:
type: Integer
value: 0
terminatedWithError:
type: Boolean
value: false
completed:
type: Boolean
value: false
startedWorkflowCount:
type: Integer
value: 1
contractState:
subscriptions:
items:
- initiateContractEntry:
blueId: BWhvLzqXHFaJnBo52W2cbBEHt9d7B5LJWm3YypVGQ6qh
type: All Events External Contract Subscription
name: Alice-Bob Chess Game
type: Chess Assisted Remotely
properties:
assistingContract:
type: Text
value: BWhvLzqXHFaJnBo52W2cbBEHt9d7B5LJWm3YypVGQ6qh
winner:
description: "Indicates who won the game (e.g., 'White', 'Black', or 'None'\
\ if the game is not over or ended in a draw)"
type: Text
movesHistory:
itemType: Chess Move
description: History of moves made
type: List
playerToMove:
description: Indicates whose move it is ('white' or 'black')
type: Text
value: white
draw:
description: Indicates whether the game ended in a draw (true) or not (false)
type: Boolean
chessboard:
description: Chessboard state in FEN notation
type: Text
value: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
gameOver:
description: Indicates whether the game has ended (true) or is still in
progress (false)
type: Boolean
messaging:
secureChannel:
description: channel part
participants:
Player White:
description: Player White timeline
timeline:
blueId: C74uRd4sPfeawKhWBewVKqFLSACiv8B9EiYpuryYUXuR
type: Participant
valueType: Participant
Player Black:
description: Player Black timeline
timeline:
blueId: EhCzJt8S4MsawthLSaCKsuRHbLdUYQsuKyYzy2tegsKE
type: Participant
type: Dictionary
keyType: Text
id:
type: Integer
value: 0
emittedEvents:
items:
- initiateContractEntry:
blueId: HcAaANK4tN8sXSUHY5k1EupT2kyYJZ7CB4DYr9hnUbcP
initiateContractProcessingEntry:
blueId: EN81k4Vz8yMovWa6AjZmjFFzAyX2KyFagjf4EEiKMQbS
type: Contract Processing Event
event:
playerBlackTimeline:
blueId: EhCzJt8S4MsawthLSaCKsuRHbLdUYQsuKyYzy2tegsKE
description: "Defines the event to be triggered. \n\nImportant: Any ${} expressions\
\ within the event object will be evaluated \nat runtime. The actual triggered\
\ event will contain the evaluated values, \nnot the raw template expressions."
playerWhiteTimeline:
blueId: C74uRd4sPfeawKhWBewVKqFLSACiv8B9EiYpuryYUXuR
type: Chess Game Started Event
contractInstanceId:
type: Integer
value: 0
workflowInstanceId:
type: Integer
value: 0
incomingEvent:
type: Contract Initialization Event
epoch:
type: Integer
value: 0
initiateContractProcessingEntry:
blueId: EN81k4Vz8yMovWa6AjZmjFFzAyX2KyFagjf4EEiKMQbS
type: Contract Update Action
Example 4: Contract Update Based on Participant's Action
threadPrev:
blueId: 3ieqagjtYYzB6E6E49ggMjsjzz3ZdADtn6xvRb8iFpAR
timeline:
blueId: DS6zx89fRP3FhsZ9wcrH54bTuhc1xS5KhrctHRGNwssq
thread:
blueId: EN81k4Vz8yMovWa6AjZmjFFzAyX2KyFagjf4EEiKMQbS
type: Simulator Timeline Entry
timelinePrev:
blueId: 3ieqagjtYYzB6E6E49ggMjsjzz3ZdADtn6xvRb8iFpAR
message:
contractInstancePrev:
blueId: E6cyTeW3DACcPtctwLpX9Ky7VPXmqV5kjy3VxPpGBdti
initiateContractEntry:
blueId: HcAaANK4tN8sXSUHY5k1EupT2kyYJZ7CB4DYr9hnUbcP
contractInstance:
processingState:
startedLocalContractCount:
type: Integer
value: 0
terminatedWithError:
type: Boolean
value: false
completed:
type: Boolean
value: false
startedWorkflowCount:
type: Integer
value: 2
contractState:
subscriptions:
items:
- initiateContractEntry:
blueId: BWhvLzqXHFaJnBo52W2cbBEHt9d7B5LJWm3YypVGQ6qh
type: All Events External Contract Subscription
name: Alice-Bob Chess Game
type: Chess Assisted Remotely
properties:
assistingContract:
type: Text
value: BWhvLzqXHFaJnBo52W2cbBEHt9d7B5LJWm3YypVGQ6qh
winner:
type: Text
value: None
movesHistory:
items:
- from:
type: Text
value: e2
to:
type: Text
value: e4
type: Chess Move
playerToMove:
type: Text
value: black
chessboard:
type: Text
value: rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1
draw:
type: Boolean
value: false
gameOver:
type: Boolean
value: false
messaging:
secureChannel:
description: channel part
participants:
Player White:
description: Player White timeline
timeline:
blueId: C74uRd4sPfeawKhWBewVKqFLSACiv8B9EiYpuryYUXuR
type: Participant
valueType: Participant
Player Black:
description: Player Black timeline
timeline:
blueId: EhCzJt8S4MsawthLSaCKsuRHbLdUYQsuKyYzy2tegsKE
type: Participant
type: Dictionary
keyType: Text
id:
type: Integer
value: 0
emittedEvents:
items:
- initiateContractEntry:
blueId: HcAaANK4tN8sXSUHY5k1EupT2kyYJZ7CB4DYr9hnUbcP
workflowStepName:
type: Text
value: Emit Event
initiateContractProcessingEntry:
blueId: EN81k4Vz8yMovWa6AjZmjFFzAyX2KyFagjf4EEiKMQbS
type: Contract Processing Event
event:
playerMakingMove:
type: Text
value: white
winner:
type: Text
value: None
chessboardAfterMove:
type: Text
value: rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1
description: "Defines the event to be triggered. \n\nImportant: Any ${} expressions\
\ within the event object will be evaluated \nat runtime. The actual triggered\
\ event will contain the evaluated values, \nnot the raw template expressions."
from:
type: Text
value: e2
draw:
type: Boolean
value: false
to:
type: Text
value: e4
type: Chess Game Move Made Event
gameOver:
type: Boolean
value: false
contractInstanceId:
type: Integer
value: 0
workflowInstanceId:
type: Integer
value: 0
- initiateContractEntry:
blueId: HcAaANK4tN8sXSUHY5k1EupT2kyYJZ7CB4DYr9hnUbcP
workflowStepName:
type: Text
value: Apply Changes
initiateContractProcessingEntry:
blueId: EN81k4Vz8yMovWa6AjZmjFFzAyX2KyFagjf4EEiKMQbS
type: Contract Processing Event
event:
type: Contract Update Event
changeset:
items:
- val:
type: Text
value: rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1
op:
type: Text
value: replace
path:
type: Text
value: /properties/chessboard
- val:
type: Boolean
value: false
op:
type: Text
value: replace
path:
type: Text
value: /properties/draw
- val:
type: Text
value: None
op:
type: Text
value: replace
path:
type: Text
value: /properties/winner
- val:
type: Boolean
value: false
op:
type: Text
value: replace
path:
type: Text
value: /properties/gameOver
- val:
type: Text
value: black
op:
type: Text
value: replace
path:
type: Text
value: /properties/playerToMove
- val:
from:
type: Text
value: e2
to:
type: Text
value: e4
type: Chess Move
op:
type: Text
value: add
path:
type: Text
value: /properties/movesHistory/-
contractInstanceId:
type: Integer
value: 0
workflowInstanceId:
type: Integer
value: 0
- initiateContractEntry:
blueId: HcAaANK4tN8sXSUHY5k1EupT2kyYJZ7CB4DYr9hnUbcP
initiateContractProcessingEntry:
blueId: EN81k4Vz8yMovWa6AjZmjFFzAyX2KyFagjf4EEiKMQbS
type: Workflow Instance Started Event
contractInstanceId:
type: Integer
value: 0
workflowInstanceId:
type: Integer
value: 1
incomingEvent:
timeline:
blueId: C74uRd4sPfeawKhWBewVKqFLSACiv8B9EiYpuryYUXuR
thread:
blueId: HcAaANK4tN8sXSUHY5k1EupT2kyYJZ7CB4DYr9hnUbcP
type: Simulator Timeline Entry
message:
from:
type: Text
value: e2
to:
type: Text
value: e4
type: Chess Move
timelinePrev:
blueId: AFfP7HgfA73PEvQbn2Q6CkjyEKuMB23akmUG7Vgan8k1
epoch:
type: Integer
value: 1
initiateContractProcessingEntry:
blueId: EN81k4Vz8yMovWa6AjZmjFFzAyX2KyFagjf4EEiKMQbS
evidences:
type: Timeline.blue Entries Order Proof
entry:
blueId: ovWa6AjZmjFFzAyX2KyFagjf4EEiKMQbSEN81k4Vz8yM
group:
blueId: eawKhWBewVKqFLSACiv8B9EiYpuryYUXuRC74uRd4sPf
sequence:
type: Integer
value: 0
type: Contract Update Action