Blue Contracts
Blue Contracts are documents written in Blue Language that define the state and behavior of a contract through a combination of properties and workflows. Blue Contracts enable deterministic state transitions based on incoming events, ensuring that given the same initial contract and sequence of events, any compliant implementation will reach the same final state.
Introduction
Blue Contracts are specialized documents that encapsulate both data and behavior within the Blue Language framework. They define:
- State: Stored in the
properties
section. - Behavior: Defined by
workflows
that specify how the contract can change in response to events.
The primary goal of Blue Contracts is to ensure that, given the same initial state and sequence of events, any observer or participant can deterministically arrive at the same final state. This consistency is crucial for distributed systems where multiple parties need to agree on the contract state without centralized control.
Contract Structure
A Blue Contract follows a specific structure, defining its components and how they interact:
name: Contract
messaging:
participants:
type: Dictionary
keyType: Text
valueType: Participant
secureChannel:
description: Channel for secure communication
subscriptions:
type: List
itemType: Contract Subscription
properties:
description: Contract state properties
workflows:
description: Contract workflows
type: List
itemType: Workflow
Explanation:
- name: The name of the contract.
- messaging: Contains information about participants and communication channels.
- participants: A dictionary mapping participant names to their details, including timelines.
- timelines: Represent the timelines of participants who can perform actions.
- secureChannel: Details about the secure communication channel. If not available, implies public, unencrypted communication.
- participants: A dictionary mapping participant names to their details, including timelines.
- subscriptions: A list of contract subscriptions to external or local contracts.
- properties: Stores the contract's state variables and data.
- workflows: Defines the behaviors and state transitions of the contract.
- type: List of
Workflow
items.
- type: List of
Supported Workflow Steps
Initiate Contract Processing Action
name: Initiate Contract Processing Action
type: Workflow Step
description: |
An action published by a party indicating their willingness to process the initiated contract and maintain its state.
initiateContractEntry:
type: Timeline Entry
description: The original entry that initiated the contract.
contract:
type: Contract
description: The initial state of the contract being processed.
Update Step
-
Purpose: Modify the contract's state.
-
Usage: The only step type allowed to change document. Any section of document can be changed.
-
Syntax:
- type: Update Step
changeset:
- op: replace
path: /properties/gameOver
val: true
JavaScript Code Step
-
Purpose: Execute custom JavaScript code for complex logic or data manipulation.
-
Usage: Offers flexibility to perform operations not covered by predefined steps.
-
Syntax:
- type: JavaScript Code Step
code: |
let currentPlayer = contract("/properties/playerToMove");
if (currentPlayer !== event.player) {
throw new RejectAndAwaitNextEventException("Not your turn!");
}
return { nextPlayer: currentPlayer === 'white' ? 'black' : 'white' };
Trigger Event Step
-
Purpose: Emit a new event, possibly triggering other workflows.
-
Usage: Used to notify participants or trigger additional workflows.
-
Syntax:
- type: Trigger Event Step
event:
type: Player Move Event
player: ${contract("/properties/playerToMove")}
move: ${event.move}
Expect Event Step
-
Purpose: Wait for a specific event before proceeding.
-
Usage: Pauses the workflow until the expected event occurs.
-
Syntax:
- type: Expect Event Step
event:
type: Player Confirmation Event
player: ${contract("/properties/playerToMove")}
Initialize Local Contract Step
-
Purpose: Create and initialize a new local contract instance.
-
Usage: Allows a contract to manage its own local contracts, initiating them as part of a workflow.
-
Syntax:
- type: Initialize Local Contract Step
description: |
A specialized workflow step designed to create and initialize a new local
contract instance.
contract:
description: |
Specifies the content of the contract that will be initialized.
This contract is defined within the main contract and can interact
with it through local subscriptions.
Workflow Function Step
-
Purpose: Execute predefined functions within the workflow.
-
Usage: Enhances modularity by reusing common operations.
-
Syntax:
- type: Workflow Function Step
function: calculateScore
args:
player: ${contract("/properties/playerToMove")}
Expressions and Conditions
-
Expressions:
${}
syntax allows embedding JavaScript expressions within the contract. -
Conditions: Steps can have a
condition
field, which, if evaluates tofalse
, skips the step. -
Usage in Steps:
- type: Update Step
condition: ${contract('/properties/gameOver') === false}
changeset:
- op: add
path: /properties/score
val: ${steps.CalculateScore.result}
Example Contracts
Chess Contract
A contract representing a game of chess between two players.
name: Chess
type: Contract
messaging:
participants:
Player White:
description: Player White timeline
Player Black:
description: Player Black timeline
properties:
chessboard:
description: Chessboard state in FEN notation
type: Text
value: 'startpos'
winner:
type: Text
draw:
type: Boolean
gameOver:
type: Boolean
value: false
playerToMove:
type: Text
value: white
movesHistory:
type: List
itemType: Chess Move
workflows:
- trigger:
event:
type: Contract Initialization Event
steps:
- type: Trigger Event Step
event:
type: Chess Game Started Event
playerWhiteTimeline:
blueId: ${contract('/messaging/participants/Player White/timeline/blueId')}
playerBlackTimeline:
blueId: ${contract('/messaging/participants/Player Black/timeline/blueId')}
- name: Move
trigger:
event:
type: Timeline Entry
message:
type: Chess Move
steps:
- name: Check Player
type: JavaScript Code Step
code: |
let playerToMove = contract("/properties/playerToMove");
let expectedTimeline = playerToMove === 'white' ?
contract("/messaging/participants/Player White/timeline") :
contract("/messaging/participants/Player Black/timeline");
if (event.timeline.blueId !== expectedTimeline.blueId) {
throw new RejectAndAwaitNextEventException('Not your move!');
}
return {};
- name: ProcessMove
type: JavaScript Code Step
code: |
// Chess logic processing
// Assume chessModule is available
let result = chessModule.processMove(contract("/properties/chessboard"), event.message);
if (!result.legal) {
throw new RejectAndAwaitNextEventException('Illegal move');
}
return { result };
- name: Emit Event
type: Trigger Event Step
event:
type: Chess Game Move Made Event
playerMakingMove: ${contract("/properties/playerToMove")}
move: ${event.message}
newBoardState: ${steps.ProcessMove.result.position}
gameOver: ${steps.ProcessMove.result.gameOver}
winner: ${steps.ProcessMove.result.winner}
- name: Apply Changes
type: Update Step
changeset:
- op: replace
path: /properties/chessboard
val: ${steps.ProcessMove.result.position}
- op: replace
path: /properties/gameOver
val: ${steps.ProcessMove.result.gameOver}
- op: replace
path: /properties/winner
val: ${steps.ProcessMove.result.winner}
- op: replace
path: /properties/playerToMove
val: '${contract("/properties/playerToMove") === "white" ? "black" : "white"}'
- op: add
path: /properties/movesHistory/-
val: ${event.message}
Conditions Contract
Demonstrates the use of conditions and expressions within workflows.
name: Conditions Contract
type: Contract
properties:
condition:
type: Boolean
value: false
workflows:
- trigger:
event:
type: Contract Initialization Event
steps:
- type: Update Step
condition: ${contract('/properties/condition')}
changeset:
- op: add
path: /properties/x
val: x
- type: Update Step
changeset:
- op: add
path: /properties/y
val: y
- type: Trigger Event Step
condition: ${contract('/properties/y') === 'y'}
event:
x: 1
- type: Expect Event Step
condition: ${contract('/properties/x') === 'x'}
event:
type: Timeline Entry
message:
a: 1
b: 2
- type: Update Step
changeset:
- op: add
path: /properties/z
val: z
JS Complete Contract
Illustrates how a contract can be completed based on custom logic.
name: JS Complete Contract
type: Contract
messaging:
participants:
Alice:
timeline: 124
properties:
abc:
type: Integer
value: 234
workflows:
- trigger:
event:
type: Contract Initialization Event
steps:
- type: Update Step
changeset:
- op: add
path: /properties/x
val: 1
- type: JavaScript Code Step
code: |
const a = 1;
if (a === 1) {
return completeContract("All phases completed successfully");
}
throw new TerminateContractWithErrorException("Unreachable code");
- type: Update Step
changeset:
- op: add
path: /properties/y
val: 2
Local Contracts Contract
Demonstrates initializing and interacting with local contracts.
name: Local Contracts Contract
type: Contract
messaging:
participants:
Alice:
timeline:
blueId: main-contract-participant-id
subscriptions:
- type: Local Contract Subscription
contractInstanceId: 22
workflows:
- trigger:
event:
type: Contract Initialization Event
steps:
- type: Initialize Local Contract Step
contract:
name: My Local Contract
type: Contract
messaging:
participants:
Alice:
timeline:
description: Populated from main contract
subscriptions:
- type: Local Contract Subscription
contractInstanceId: 0
event:
type: Contract Update Event
changeset:
- path: /properties/x
- type: Update Step
changeset:
- op: add
path: /properties/x
val: 1
Local Subscription Contract
Shows how contracts can subscribe to events from local contracts.
name: Local Subscription Contract
type: Contract
subscriptions:
- type: Local Contract Subscription
contractInstanceId: 22
workflows:
- trigger:
event:
type: Contract Initialization Event
steps:
- type: Initialize Local Contract Step
contract:
name: My Local Contract
type: Contract
subscriptions:
- type: Local Contract Subscription
contractInstanceId: 0
event:
type: Contract Update Event
changeset:
- path: /properties/x
- type: Update Step
changeset:
- op: add
path: /properties/x
val: 1
Determinism and State Consistency
- Deterministic Execution: Blue Contracts are designed so that any compliant implementation, given the same initial state and sequence of events, will produce the same final state.
- Event Ordering: The order of incoming events is crucial. All participants must process events in the same sequence.
- Simple Algorithm: The execution model is straightforward, making it easy to implement in various programming languages.