Installation and usage of the platform

Development and usage of smart contracts

The definition and general description of how smart contracts work on the Waves Enterprise blockchain platform are provided in the article Smart contracts.

Preparing to work

Before you start developing a smart contract, make sure that you have the Docker containerization software package installed on your machine. The principles of working with Docker are described in the official documentation.

Also make sure that the node you are using is configured for smart contract execution . If your node is running in the Waves Enterprise Mainnet, it is configured by default to install smart contacts from the open repository and has the recommended settings to ensure optimal smart contact execution.

If you are developing a smart contract to run on a private network, deploy your own registry for Docker images and specify its address and credentials on your server in the remote-registries block of the node configuration file. You can specify multiple repositories in this block if you need to define multiple storage locations for different smart contracts. You can also load a Docker contract image from a repository not specified in the node configuration file using transaction 103, which initiates the creation of a smart contract. For more information, see Development and installation of a smart contract and description of the transaction 103.

When working in the Waves Enterprise Mainnet, the Waves Enterprise open registry is pre-installed in the configuration file.

Smart contract development

Waves Enterprise blockchain platform smart contracts can be developed in any programming language you prefer and implement any algorithms. The finished smart contract code is packaged in a Docker image with smart contract authorization parameters (when using REST API) or used protobuf files (when using gRPC).

Examples of Python smart contract code using gRPC and REST API methods to exchange data with a node, as well as a step-by-step guide on how to create the corresponding Docker images are given in the following articles:

Uploading of a smart contract into a registry

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.

When working on a private network, upload a Docker image of the smart contract to your own registry:

1. Start your registry in a container:

docker run -d -p 5000:5000 --name my-registry-container my-registry:2

2. Navigate to the directory containing the smart contract files and the Dockerfile script file with commands for building the image.

3. Build an image of your smart contract:

docker build -t my-contract .

4. Specify the image name and its location address in the repository:

docker image tag my-contract my-registry:5000/my-contract

5. Run the repository container you created:

docker start my-registry-container

6. Upload your smart contract to the repository:

docker push my-registry:5000/my-contract

7. Get information about the smart contract. To do this, display the information about the container:

docker image ls|grep 'my-node:5000/my-contract'

This will give you the ID of the container. Output the information about it with the docker inspect command:

docker inspect my-contract-id

Response example:

{
"Id": "sha256:57c2c2d2643da042ef8dd80010632ffdd11e3d2e3f85c20c31dce838073614dd",
"RepoTags": [
    "wenode:latest"
],
"RepoDigests": [],
"Parent": "sha256:d91d2307057bf3bb5bd9d364f16cd3d7eda3b58edf2686e1944bcc7133f07913",
"Comment": "",
"Created": "2019-10-25T14:15:03.856072509Z",
"Container": "",
"ContainerConfig": {
    "Hostname": "",
    "Domainname": "",
    "User": "",
    "AttachStdin": false,
    "AttachStdout": false,
    "AttachStderr": false,

The Id field is the identifier of the Docker image of the smart contract, which is entered in the ImageHash field of transaction 103 when creating the smart contract.

Installing of a smart contract into the blockchain

After uploading the smart contract to the repository, install it on the network using the 103 transaction. To do this, sign the transaction via the blockchain platform client, the sign REST API method or the JavaScript SDK method.

The data returned in the method’s response is fed into transaction 103 when it is published.

Below, you will see the examples of signing and sending a transaction using the sign and broadcast methods. In the examples, the transactions are signed with the key stored in the keystore of the node.

Curl-query to sign transaction 103:

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'X-Contract-Api-Token' -d '    { \
      "fee": 100000000, \
      "image": "my-contract:latest", \
      "imageHash": "7d3b915c82930dd79591aab040657338f64e5d8b842abe2d73d5c8f828584b65", \
      "contractName": "my-contract", \
      "sender": "3PudkbvjV1nPj1TkuuRahh4sGdgfr4YAUV2", \
      "password": "", \
      "params": [], \
      "type": 103, \
      "version": 1 \
  }' 'http://my-node:6862/transactions/sign'

The response of the sign method, which is passed to the broadcast method:

{
  "type": 103,
  "id": "ULcq9R7PvUB2yPMrmBdxoTi3bcRmQPT3JDLLLZVj4Ky",
  "sender": "3N3YTj1tNwn8XUJ8ptGKbPuEFNa9GFnhqew",
  "senderPublicKey": "3kW7vy6nPC59BXM67n5N56rhhAv38Dws5skqDsjMVT2M",
  "fee": 100000000,
  "timestamp": 1550591678479,
  "proofs": [ "yecRFZm9iBLyDy93bDVaNo1PR5Qkkic7196GAgUt9TNH1cnQphq4yGQQ8Fxj4BYA4TaqYVw5qxtWzGMPQyVeKYv" ],
  "version": 1,
  "image": "my-contract:latest",
  "imageHash": "7d3b915c82930dd79591aab040657338f64e5d8b842abe2d73d5c8f828584b65",
  "contractName": "my-contract",
  "params": [],
  "height": 1619
  }

Curl-response to sign transaction 103:

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'X-Contract-Api-Token' -d '{ \
{
    "type": 103, \
    "id": "ULcq9R7PvUB2yPMrmBdxoTi3bcRmQPT3JDLLLZVj4Ky", \
    "sender": "3N3YTj1tNwn8XUJ8ptGKbPuEFNa9GFnhqew", \
    "senderPublicKey": "3kW7vy6nPC59BXM67n5N56rhhAv38Dws5skqDsjMVT2M", \
    "fee": 500000, \
    "timestamp": 1550591678479, \
    "proofs": [ "yecRFZm9iBLyDy93bDVaNo1PR5Qkkic7196GAgUt9TNH1cnQphq4yGQQ8Fxj4BYA4TaqYVw5qxtWzGMPQyVeKYv" ], \
    "version": 1, \
    "image": "my-contract:latest", \
    "imageHash": "7d3b915c82930dd79591aab040657338f64e5d8b842abe2d73d5c8f828584b65", \
    "contractName": "my-contract", \
    "params": [], \
    "height": 1619 \
}
}' 'http://my-node:6862/transactions/broadcast'

Smart contract execution

Once a smart contract is installed in the blockchain, it can be invoked with a 104 CallContract Transaction.

This transaction can also be signed and sent to the blockchain via the blockchain platform client, the sign REST API method or the JavaScript SDK method. When signing a transaction 104, specify the ID of the 103 transaction for the called smart contract in the contractId field (the id field of the sign method response).

Examples of signing and sending a transaction using the sign and broadcast methods using a key stored in the keystore of a node:

Curl-query to sign transaction 104:

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'X-Contract-Api-Token' -d '{ \
"contractId": "ULcq9R7PvUB2yPMrmBdxoTi3bcRmQPT3JDLLLZVj4Ky", \
"fee": 10, \
"sender": "3N3YTj1tNwn8XUJ8ptGKbPuEFNa9GFnhqew", \
"password": "", \
"type": 104, \
"version": 1, \
"params": [ \
    { \
        "type": "integer", \
        "key": "a", \
        "value": 1 \
    } \
] \
}' 'http://my-node:6862/transactions/sign'

The response of the sign method, which is passed to the broadcast method:

{
"type": 104,
"id": "9fBrL2n5TN473g1gNfoZqaAqAsAJCuHRHYxZpLexL3VP",
"sender": "3PKyW5FSn4fmdrLcUnDMRHVyoDBxybRgP58",
"senderPublicKey": "2YvzcVLrqLCqouVrFZynjfotEuPNV9GrdauNpgdWXLsq",
"fee": 10,
"timestamp": 1549365736923,
"proofs": [
    "2q4cTBhDkEDkFxr7iYaHPAv1dzaKo5rDaTxPF5VHryyYTXxTPvN9Wb3YrsDYixKiUPXBnAyXzEcnKPFRCW9xVp4v"
],
"version": 1,
"contractId": "2sqPS2VAKmK77FoNakw1VtDTCbDSa7nqh5wTXvJeYGo2",
"params": [
    {
    "key": "a",
    "type": "integer",
    "value": 1
    }
    ]
  }

Curl-query to broadcast the transaction 104:

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'X-Contract-Api-Token' -d '{ \
"type": 104, \
"id": "9fBrL2n5TN473g1gNfoZqaAqAsAJCuHRHYxZpLexL3VP", \
"sender": "3PKyW5FSn4fmdrLcUnDMRHVyoDBxybRgP58", \
"senderPublicKey": "2YvzcVLrqLCqouVrFZynjfotEuPNV9GrdauNpgdWXLsq", \
"fee": 10, \
"timestamp": 1549365736923, \
"proofs": [ \
    "2q4cTBhDkEDkFxr7iYaHPAv1dzaKo5rDaTxPF5VHryyYTXxTPvN9Wb3YrsDYixKiUPXBnAyXzEcnKPFRCW9xVp4v" \
], \
"version": 1, \
"contractId": "2sqPS2VAKmK77FoNakw1VtDTCbDSa7nqh5wTXvJeYGo2", \
"params": [ \
    { \
    "key": "a", \
    "type": "integer", \
    "value": 1 \
    } \
] \
}' 'http://my-node:6862/transactions/broadcast'
See also