Skip to content

Smart contracts

The Koinos Blockchain Framework is a bare bones minimal blockchain implementation that is fully customizable through the use of smart contracts. Smart contracts can implement both feature rich decentralized applications and core system functionality. The information in this documented is intended to be SDK agnostic and explain the core functionality of the Koinos Virtual Machine and its implementation.

Because Koinos uses Fizzy for its WASM (WebAssembly) virtual machine, the blockchain is agnostic to the language the smart contract has been written -- this allows support for a multitude of programming languages for development.

Smart contracts come in two flavors: user and system. User contracts have a basic set of features that allow the developer to write decentralized applications. System contracts have all the features available to user contracts, with the additional ability of access the system contract space.

Contract space

Each smart contract has access to an object_space, which essentially defines a key value store. The object_space is defined as follows:

message object_space {
   bool system = 1;
   bytes zone = 2;
   uint32 id = 3;
}

User space

In the case of a user contract system will be set to false, the zone will be set to the bytes of the public address of the contract, and id is used as a unique identifier distinguishing between multiple key value stores. A contract may have different key value stores by incrementing the id.

System space

The system contract is special in that it may access a global space denoted by system being true and the zone being set to an empty byte array, otherwise known as kernel space. This allows for system contracts to read and manipulate a pool of shared key value stores.

Entry points

To inform the blockchain which function you are calling within a smart contract an entry point is provided. The Koinos Blockchain Framework will take the request, whether it is a read or write, load up the contract and pass the entry point as a parameter. The main function will then instantiate the contract class or execute procedurally and execute the corresponding code whether it is a member function or inline code. Entry points come in two flavors: read and write.

Read-only entry points

Read-only entry points are often used to implement "getter" functions and can be called outside of a transaction. Most commonly, the read only entry points are called using the RPC method read_contract. Smart contract code that is executed in read-only mode is prevented from writing to any key value store. If the contract attempts to perform a write during read-only mode it will be abruptly trapped and a permission denied exception will be thrown.

Given the following RPC request and response definitions:

message read_contract_request {
   bytes contract_id = 1 [(btype) = CONTRACT_ID];
   uint32 entry_point = 2;
   bytes args = 3;
}
message read_contract_response {
   bytes result = 1;
   repeated string logs = 2;
}

   sequenceDiagram
      Client->>+RPC microservice: read_contract_request
      RPC microservice->>+Koinos Chain: read_contract_request
      Koinos Chain->>+Koinos Virtual Machine: contract execution
      Koinos Virtual Machine->>-Koinos Chain: contract execution
      Koinos Chain->>-RPC microservice: read_contract_response
      RPC microservice->>-Client: read_contract_response

Figure 1. A diagram demonstrating the data path of a read_contract_request from an RPC client.

Writable entry points

Writable entry points have no restrictions with regards to reading or writing data. If the smart contract code attempts to write to a key value store, it must be executed in writable mode. This is accomplished by calling the contract from within a transaction.

Using the call_contract_operation defined below, a user may submit a transaction containing the operation which in turn calls the smart contract in a writable mode.

message call_contract_operation {
   bytes contract_id = 1 [(btype) = CONTRACT_ID];
   uint32 entry_point = 2;
   bytes args = 3;
}

Given the following RPC request and response definitions:

message submit_transaction_request {
   protocol.transaction transaction = 1;
   bool broadcast = 2;
}
message submit_transaction_response {
   protocol.transaction_receipt receipt = 1;
}

   sequenceDiagram
      Client->>+RPC microservice: submit_transaction_request
      RPC microservice->>+Koinos Chain: submit_transaction_request
      Koinos Chain->>+Koinos Virtual Machine: contract execution
      Koinos Virtual Machine->>-Koinos Chain: contract execution
      Koinos Chain->>-RPC microservice: submit_transaction_response
      RPC microservice->>-Client: submit_transaction_response

Figure 2. A diagram demonstrating the data path of a submit_transaction_request from an RPC client.

Contract buffers

Because Koinos passes data between the system and contracts using a serialized protocol buffer format, a buffer is used in the interchange of data. There is a cost in CPU cycles when allocating data within the VM and therefore it costs mana. It is recommended you set your contract buffer to the lowest size possible that will fit both your contract inputs and contract outputs in order to maintain efficiency with regards to resource usage.

Intercontract communication

Smart contracts do not necessarily operate in a silo. Any contract has to capability to call upon another contract. This is achieve through a system call, call. Similar to both read_contract and contract_call_operation it takes similar paremeters and is defined as:

message call_arguments {
   bytes contract_id = 1 [(btype) = CONTRACT_ID];
   uint32 entry_point = 2;
   bytes args = 3;
}

With the corresponding response:

message call_result {
   bytes value = 1;
}

It is up to the developer to serialize the contract input and output data correctly to ensure the integrity of the call between contracts.


   sequenceDiagram
      Smart contract 1->>+Koinos Chain: call_arguments
      Koinos Chain->>+Smart contract 2: call_arguments
      Smart contract 2->>-Koinos Chain: call_result
      Koinos Chain->>-Smart contract 1: call_result

Figure 3. A diagram demonstrating the data path of a smart contract calling another smart contract.