Blockstack is a platform with a vision of building a decentralized internet. Users are in control of their identity and data. It is a revolutionary shift in how people could use the software, create it and can get benefit from the internet. It puts people back in control.
As we know in today’s world, the need for a smart contract over Blockchain has become a necessity, so Blockstack came up with their own language and architecture to implement smart contract over Stacks Blockchain.
They have introduced Clarity, through which we can write smart contracts to control digital assets over Stacks Blockchain. Digital assets include BNS names, Stacks Token and so forth.
What Is Clarity:
Clarity is different from other smart contract languages mainly in two ways:
- It is not intended to be compiled
- It is not Turing complete
The reason that Clarity is not intended to be compiled is to avoid compilation level bugs. Turing incompleteness makes it prone to smart contracts issues such as reentrancy attacks, halting, and transaction fees prediction.
Because of these differences, it allows the static analysis of programs which can be helpful to determine runtime cost and data usage over the Blockchain.
The architecture of Clarity smart contract consists of two parts; a data-space and set of functions. A smart contract may only modify data-space to which it is associated. All the functions are private unless they are defined public.
Users can call a smart contract’s public function by broadcasting transactions on the Blockchain.
Just like Solidity and other smart contract languages, a contract can call public and read-only functions of another smart contract as well.
Basic Architecture Of Clarity:
Basic building blocks of Clarity are atoms and list. An atom is basically a number of strings or characters. For example:
Native functions, user-defined functions, values, and variables that are in the program can be an atom. In Clarity, if a function mutates data it is terminated with an ! exclamation point. For example: change-name!
The sequence of atoms enclosed with ( ) parenthesis is a List. A list can also contain other lists. For example:
(get-block info time 18)
(and ‘false ‘true)
(is-none? (get id (fetch-entry names-map (tuple (name \”clarity\”)))))
Clarity supports comments using ;; (double semicolons). Inline and standalone comments are supported.
;; Transfers tokens to a specified principal (principal is equivalent to Stacks address)
(define-public (transfer (recipient principal) (amount int) )
(transfer! Tx-sender recipient amount)) ;; returns: boolean
Language Limitations And Rules:
The Clarity smart contract has the following limitations:
- The atomic types only include booleans, integers, fix length buffers (includes string and bytes) and principals
- Recursion is illegal
- Lambda functions are not supported
- Looping can be performed through ‘map’, ‘filter’ or ‘fold’
- Variables are created by ‘let’, binding and mutating functions like ‘set’ are not supported
- Atomic types lists are supported. List operations like ‘append’ or ‘join’ are not supported
Let's Write Or First Smart Contract Now!
As clarity will go live in the next Stacks Blockchain fork, you can run Clarity on a local virtual test environment. The environment can be run in a Docker container. Before you begin this tutorial, make sure you have Docker installed on your workstation.
Now, for our first smart contract, we will be writing a simple contract which takes an integer as an input and returns that same integer as an output.
Task 1: Setting up the test environment:
- Pull the Blockstack core ‘clarity-developer-preview’ image from Docker Hub.
$ docker pull blockstack/blockstack-core:clarity-developer-preview
2. Start the Blockstack Core test environment with a bash shell.
$ docker run -it -v $HOME/blockstack-dev-data:/data blockstack/blockstack-core:clarity-developer-preview bash
The command launches a container with the Clarity test environment and opens a bash shell into the container. The -v flag creates a local $HOME/blockstack-dev-data directory in your workstation and mounts it at the /data directory inside the container. The shell opens into the src/blockstack-core directory. This directory contains the source for a core and includes Clarity contract samples you can run.
3. Make sure you have ‘nano’ and ‘sqlite3’ packages installed inside the container by running commands nano and sqlite3. If packages are not present you can easily install them using these commands.
$ apt-get update
$ apt-get install nano
$ apt-get install sqlite3 libsqlite3-dev
Task 2: Writing the contract:
As you navigate to the path /src/blockstack-core and use ls to view the directories, you will see ‘sample_programs’ directory. This directory contains two sample contracts. We will write our contract in this directory. Let’s write!
- Make a .clar file using touch int_return.clar
- Copy and paste this contract code into that file using nano int_return.clar
(define-public (num-return (input int))
(begin (print (+ 2 input))
This contract has a public function which can be invoked outside of the contract and takes an integer parameter and then returns the parameter.
Task 3: Deploying and executing smart contract:
In this task, we will be interacting with our contract using ‘clarity-cli’ command line.
1. Initialize a new ‘db’ database in /data/ directory using this command
$ clarity-cli initialize /data/db
You will see the response ‘Database created’. The command creates an SQLite database.
2. Type check the int_return contract, to see if there are no errors.
$ clarity-cli check int_return.clar /data/db
As a result of the above command, you will see message ‘Checks passed’
3. Generate a new address for your contract, this address will be used to name your contract at launch time. Now you can use this command:
$ clarity-cli generate_address
4. Add your address in the environment variable.
$ export DEMO_ADDRESS=SP1QCGQ6VB483TAEJ7RKCFMXPW9ERS1CPPF1XQZ5
5. Launch the int_return contract and assign it to your DEMO_ADDRESS address. You use the launch command to instantiate a contract on the Stacks Blockchain.
$ clarity-cli launch $DEMO_ADDRESS.int_return int_return.clar /data/db
So, you will see ‘Contract initialized!’ message. In short, the contract is now deployed on the Blockchain
6. Now it’s time to run our smart contract’s public function num-return by using this command:
$ clarity-cli execute /data/db $DEMO_ADDRESS.int_return num-return $DEMO_ADDRESS 8
Therefore, you will see this response;
‘Transaction executed and committed. Returned: 8’
To sum up, you have deployed your first smart contract on the Stacks Blockchain using Clarity and clarity-cli on your local test environment. So, kudos to you! You can now view the transactions and block data from the database using ‘sqlite3’ cli.
Xord can help you build Blockchain projects and give you free Blockchain consultation, connect with us and get started now!