Installation and usage of the platform

Example of a smart contract with the use of REST API

Program description and listing

This section describes an example of creating and running a simple smart contract. The contract increments the number passed to it each time it is called.

Program listing:

import json
import os
import requests
import sys


def find_param_value(params, name):
    for param in params:
        if param['key'] == name: return param['value']
    return None


def print_success(results):
    print(json.dumps(results, separators=(',', ':')))


def print_error(message):
    print(message)
    sys.exit(3)


def get_value(contract_id):
    node = os.environ['NODE_API']
    if not node:
        print_error("Node REST API address is not defined")
    token = os.environ["API_TOKEN"]
    if not token:
        print_error("Node API token is not defined")
    headers = {'X-Contract-Api-Token': token}
    url = '{0}/internal/contracts/{1}/sum'.format(node, contract_id)
    r = requests.get(url, verify=False, timeout=2, headers=headers)
    data = r.json()
    return data['value']


if __name__ == '__main__':
    command = os.environ['COMMAND']
    if command == 'CALL':
        contract_id = json.loads(os.environ['TX'])['contractId']
        value = get_value(contract_id)
        print_success([{
            "key": "sum",
            "type": "integer",
            "value": value + 1}])
    elif command == 'CREATE':
        print_success([{
            "key": "sum",
            "type": "integer",
            "value": 0}])
    else:
        print_error("Unknown command {0}".format(command))

Step-by-step description of the smart contract operation:

  • The program expects to get a data structure in json format with a ``params’’ field;

  • reads the value of the a field;

  • returns the result as the value of the field “{a}+1” in json format.

Example of input parameters:

"params":[
    {
        "key":"a",
        "type":"integer",
        "value":1
    }
]

Authorization of a smart contract with REST API

To work with the node REST API, the smart contract needs authorization. For the smart contract to work correctly with the API methods, follow these steps:

  1. The following parameters must be defined in the environment variables of the smart contract:

  • NODE_API – URL to the node REST API;

  • API_TOKEN – authorization token for the smart contract;

  • COMMAND – commands to create and call a smart contract;

  • TX – transaction required for operation of a smart contract (103 - 107).

  1. The smart contract developer assigns the value of the API_TOKEN variable to the X-Contract-Api-Token query header. In the API_TOKEN variable the node writes the JWT authorization token when the contract is created and executed.

  2. The contract code must pass the received token in the request header (X-Contract-Api-Token) every time the API of the node is accessed.

Development of a smart contract

1. Place the contract.py file with the code in the directory that will contain your smart contract files.

2. Create a run.sh shell script, which will run the smart contract code in the container:

#!/bin/sh

python contract.py

Place the run.sh file in the root directory of your smart contract.

3. Create a Dockerfile script file to build and control the startup of your smart contract. When developing in Python, your smart contract image can be based on the official Alpine Linux-based Python image python:alpine3.8.

Dockerfile example:

FROM python:alpine3.8
ADD contract.py /
ADD run.sh /
RUN chmod +x run.sh
CMD exec /bin/sh -c "trap : TERM INT; (while true; do sleep 1000; done) & wait"

Place the Dockerfile in the root directory of your smart contract.

4. Contact the Waves Enterprise Technical Support team to place your smart contract in the public repository if you are working in the Waves Enterprise Mainnet.

If you work on a private network, build your smart contract yourself and place it in your own registry.

See also