Smart Contracts Development (C)

Développement de smart contracts avec C

weight: 430 linkTitle: “Smart Contracts C”

  1. Library (lib)

This library contains all the headers of the library, as well as the static archive lib_KalimaNodeLib.a. This archive will be used when creating the executable of the project. The headers will be used to call the methods that will be useful to us in our example.

  1. Config file (etc/ cfg)

Picture 1

Let’s see the usefulness of the different configurations:

  • LedgerName -> This is the name of the Ledger we are going to connect to. For the example it is not very useful.

  • NODE_NAME -> This is the name of the node we create. It is also not very useful for our example.

  • Privachain -> This is the privachain we will be connected into. If you want to connect to another Kalima Blockchain, you will have to change the privachain.

  • FILES_PATH -> This is the directory in which all Kalima related files will be created. When you launch your node for the first time, this directory will be created if it doesn’t already exist, and you will find inside the files for RSA, DevID and logs.

  • BLOCKCHAIN_PUBLIC_KEY -> This is the path for the blockchain public key if you need for some reasons to have it locally. It isn’t used for now.

  • SerialID -> This ID allow your node to be authorized on the Kalima Blockchain which you can obtain here: https://inscription.tuto.kalimadb.com/airdrop (you have 10 serialId received by email)

3.Makefile

Picture 2

The makefile will allow us to create the executable to run the project. First it will create the objects from source files LuaFunctions, callback and main. Finally, it will create the executable main.run from the objects created before and the archive “lib_KalimaNodeLib.a” located in the lib directory.

To execute the makefile, you just must type “make” in your terminal (you have to be in the project path in your terminal).

To clear the objects, the executable and the logs, you just need to type “make clean”.

 

4. Main project (src + inc)

  1. Main

This is the start of the main function. It contains the Kalima Node initialization functions. Here is the explanation on the useful Kalima function:

  • new_ContractList : Will create a SmartContract list which will contain every Lua smartcontracts present in the indicated directory. It will also create a watcher which will monitor the said directory to check if a        contract is added, modified or deleted and will update the list                accordingly. The second parameter specifies whether the contracts are encrypted or not (1: encrypted, 0: not encrypted).

  • create_Node : Will create a Kalima Node with information from the config file. The node is the main component which will allow communication with the Blockchain.

  • Set_contractList_log_path : if you want to have the contract list full log output, you need to put this line. It will allow the contractList.c file to use logs.

  • set_callback : Will initiate the client callback which we will see in the explanations on the callback.c file.

  • Connect_to_Notaries : Will start the connection to the Blockchain with the Node and Callback as a parameter.

When creating the node, we will also create a random deviceID that will be encrypted and written in the “DeviceID” directory that will be created in the location where you start the executable from. If this encrypted file already exists, it will not be recreated. The node will just decrypt the file and use the decrypted deviceID. This deviceID, along with the SerialID in your config file, will allow the Blockchain to identify our node and allow us to send data. An RSA directory will also be created containing a public key and a private key used to encrypt communications with the blockchain.

This example when launched will offer the user two options:

    • Sending 10 default messages

This choice sends 10 predefined messages to the blockchain on the address “/sensors”. The 10 messages will have a key ranging from key0 to key9 and a value ranging from 95 to 104. Each message will remain in the blockchain for 10 seconds before being automatically deleted.

    • Fully configurable message

Here we build the message from scratch.

First, the user is offered to choose between adding or deleting a message. Then we retrieve the address, the key and the message from the user’s terminal. Finally, we send the message. Unlike the previous example, the message will remain here indefinitely.

    1. LuaFunctions

LuaFunctions is the file where we will put the C functions that we want to use inside the contracts. Those functions follow a simple format:

As a reference, this functions is called in the contract using : “body = LuaGetBody(kmsg)” The “lua_touserdata(L,1)” specifies the data received is the first parameter inside the function call in the contract (here kmsg). It will be received as a pointer. Then we call the classic getBody function and push it in the contract with the same method seen earlier. Finally, the “return 1” is very important. If you want the function to return data to the script you need to put “1”. If no data is returned, you can put “0”

Here is an example :

This function only writes a log but return no data, so we put a “return 0”.

    1. Callback

The callback is useful to allow the user to do some actions based on what is happening inside functions in the library without having to modify the said library.

In the callback, we have 5 possible actions located in different parts of the library:

  • c_send : Isn’t really used for now.

  • onNewAddress : Same.

  • onAddressSynchronized : Same.

  • onReject : Will write a log if the join request is refused by the BlockChain.

  • PutData : Is the useful callback function for now. It will act based on data received from the Blockchain. You can change it to do whatever you want with the data received. We’ll explain what is being done in this example.

This part will turn the pointers into usable structure and create a Kmsg based on the Kmessage received from the Blockchain. We’ll then get the address from the Kmsg (Address of the data received from the Blockchain).

If we’re dealing with encrypted contracts from the Blockchain, it is necessary to decrypt them locally to use them.

First, it is necessary to understand that when you successfully connect to the Blockchain, you receive locally every data in the Blockchain memcache where you are authorized. You also receive the data necessary to decrypt the contracts.

This data will be received with address “/Kalima_scripts”. We then check if the contracts concerned are of the “.lua” type and if yes, we decrypt them.

We first get the contracts from curl requests using data received by the Blockchain, then check if the file safely arrived in the local contract directory. If yes, we get the data needed to decrypt the contract and decrypt it (the decrypted content will be saved as a string and loaded later using the string).

We only want to use the contract on new data, so we must check that the data is not from the data received at the time of connection.

Once it is done, here we check that the address of the message received is “/sensors” (which means a new data has been added to this address in the Blockchain) and if yes, we run the “sensors.lua” contract with the following method:

  • load_Contract : Will load a contract. If the contract is found in the specified folder, The contract structure will be returned. If not, NULL will be returned.

  • lua_getglobal : Will specifies which function inside the contract we are calling (here main).

  • lua_pushcfunction : Will push a C function inside the contract. It is necessary if you want to use your own C functions inside a contract.

  • lua_setglobal : Will specifies how the function pushed right before is called inside the                contract. We could for example say that a C function named “x” will be called using “y” in the contract.

  • lua_pushlightuserdata : Will push a pointer inside the main function (as entry parameter).

  • lua_pcall : Will run the contract. The “2” specifies the number of paramaters sent to the function. “0” is the number of paramaters returned from the contract and the last “0” is for the error handling.

So here we’re basically calling the main function of the sensors.lua contract. We’re then sending to the contract the functions we’ll be using inside, then we send the entry paramaters to finally run it.