Docker Smart Contracts

In addition to contracts implemented on the basis of RIDE scripts for smart accounts and smart-assets, the Waves Enterprise platform provides the option to develop and use Turing-complete smart contracts. For implementation of Turing-complete contracts an approach is used where programs are launched in an isolated Docker container environment. Application development can be performed without restrictions in terms of the programming language to be used. Each application is launched in a Docker container to ensure isolation and manage resources available to a particular application. To store smart contracts, Docker Registry with read access only (Docker images) of contracts is used for machines with nodes. The node state can be accessed through a REST API node.

Important

It is a must to run the Docker-engine and the Docker-daemon simultaneously on the node which is proccessing the Docker smart-contracts.

../../_images/docker-1.png

Creating a contract

Creating a smart contract starts with preparation of a Docker image, which consists of the contract program code, the required environment and the special scenario Dockerfile. A prepared Docker image is assembled (built) and sent to Docker Registry.

Example of Dockerfile:

FROM python:alpine3.8
ADD contract.py /
ADD run.sh /
RUN chmod +x run.sh
CMD ["/bin/sleep", "6000"]

The contract is created by publishing a special (CreateContractTransaction) transaction containing a link to the image in Docker Registry. After the transaction is received, the node downloads the image using the link specified in the “image” field, the image is checked and launched as a Docker container.

Executing a Contract

Smart contract execution is initiated by a special (CallContractTransaction) transaction containing the contract ID and call parameters. The transaction ID defines the Docker container. The container is executed unless it has been launched before. The contract launch parameters are transferred to the container. | Smart contracts change their state by updating the key-value pairs.

Contract Call Disabling

If necessary, the contract developer can disable calling the contract. To do this, a special (DisableContractTransaction) transaction is published specifying the Contract ID. The contract becomes unavailable after its disconnection, but you can get information about the contract from the the blockchain later.

Description of Transactions

The following transactions are implemented to ensure the interaction between the blockchain and the Docker Contract:

Code Transaction type Purpose
103 CreateContractTransaction Initiates the Contract. Transaction is signed by a user with the role “contract_developer”
104 CallContractTransaction Calls the Contract. Transaction is signed by the initiator of contract execution
105 ExecutedContractTransaction Records the contract execution result in the contract state. | br | Transaction is signed by the block generating node
106 DisableContractTransaction Disables calling a contract.
Transaction is signed by a user with the role “contract_developer”

Node configuration

Downloading and execution of Docker Contracts initiated by transactions with codes 103-106 are performed on nodes with enabled option docker-engine.enable = yes (for details see module “Installation and Configuration” > “Starting Docker contracts”).

REST API

The description of REST API of Docker Contracts is given in module “Use” > “Node’s REST API” > “Contracts”.

Implementation examples