Clarity Smart Contract Language


Clarity of Mind Foreword Introduction


Variables are data members that can be changed over time. They are only modifiable by the current smart contract. Variables have a predefined type and an initial value.

(define-data-var var-name var-type initial-value)

Where the var-type is a type signature and initial-value a valid value for the specified type. Although you can name a variable pretty much anything, you should be mindful of the built-in keywords. Do not use keywords as variable names.

Variables can be read using the function var-get and changed using var-set.

;; Define an unsigned integer data var with an initial value of u0.
(define-data-var my-number uint u0)

;; Print the initial value.
(print (var-get my-number))

;; Change the value.
(var-set my-number u5000)

;; Print the new value.
(print (var-get my-number))

Notice the uint? That is the type signature.

Type signatures

The chapter on types covered how to express a value of a specific type. Type signatures, on the other hand, define the admitted type for a variable or function argument. Let us take a look at what the signatures look like.

Type Signature
Signed integer int
Unsigned integer uint
Boolean bool
Principal principal
Buffer (buff max-len), where max-len is a number defining the maximum length.
ASCII string (string-ascii max-len), where max-len is a number defining the maximum length.
UTF-8 string (string-utf8 max-len), where max-len is a number defining the maximum length.
List (list max-len element-type), where max-len is a number defining the maximum length and element-type a type signature. Example: (list 10 principal).
Optional (optional some-type), where some-type is a type signature. Example: (optional principal).
Tuple {key1: entry-type, key2: entry-type}, where entry-type is a type signature. Every key can have its own type. Example: {sender: principal, amount: uint}.
Response (response ok-type err-type), where ok-type is the type of returned ok values and err-type is the type of returned err values. Example: (response bool uint).

We can see that some types indicate a maximum length. It goes without saying that the length is strictly enforced. Passing a value that is too long will result in an analysis error. Try changing the following example by making the "This works." string too long.

(define-data-var message (string-ascii 15) "This works.")

Like other kinds of definition statements, define-data-var may only be used at the top level of a smart contract definition; that is, you cannot put a define statement in the middle of a function body.

Remember that whitespace can be used to make your code more readable. If you are defining a complicated tuple type, simply space it out:

(define-data-var high-score
    ;; Tuple type definition:
        score: uint,
        who: (optional principal),
        at-height: uint
    ;; Tuple value:
        score: u0,
        who: none,
        at-height: u0

;; Print the initial value.
(print (var-get high-score))

;; Change the value.
(var-set high-score
    {score: u10, who: (some tx-sender), at-height: block-height}

;; Print the new value.
(print (var-get high-score))