Public functions are callable from the outside by both standard principals and contract principals. Contracts that feature any interactivity will need at least one public function. The fact of them being callable does not imply that the underlying functionality is public. The developer can include assertions to make sure that only specific contract callers or inputs are valid.
Public functions must return a response type value. If the function returns an
ok type, then the function call is considered valid, and any changes made to the blockchain state will materialise. It means that state changes such as updating variables or transferring tokens will only be committed to the chain if the contract call that triggered these changes returns an
The effects of of returning an
ok or an
err are illustrated by the example below. It is a basic function that takes an unsigned integer as an input and will return an
ok if it is even or an
err if it is uneven. It will also increment a variable called
even-values at the start of the function. To check if the number is even, we calculate the remainder of a division by two and check that it is equal to zero using the
is-eq function (n mod 2 should equal 0).
(define-data-var even-values uint u0) (define-public (count-even (number uint)) (begin ;; increment the "event-values" variable by one. (var-set even-values (+ (var-get even-values) u1)) ;; check if the input number is even (number mod 2 equals 0). (if (is-eq (mod number u2) u0) (ok "the number is even") (err "the number is uneven") ) ) ) ;; Call count-even two times. (print (count-even u4)) (print (count-even u7)) ;; Will this return u1 or u2? (print (var-get even-values))
Did you notice how the final print expression returned
u1 and not
u2, even though the
even-values variable is updated at the start of the function so it seems intuitive that the number should increment on every function call.
Edit the example above and try going through the following iterations:
- Replace the uneven number
u7with an even number like
u8. Does the printout of
- Change the
errtype in the
ifexpression to an
ok. What is the value of
What happens is that the entire public function call is rolled back or reverted as soon as it returns an
err value. It is as if the function call never happened! It therefore does not matter if you update the variable at the start or end of the function.
Understanding responses and how they can affect the chain state is key to being a successful smart contract developer. The chapter on error handling will go in greater detail on how to guard your functions and the exact control flow.
(define-public (sum-three) ) (print (sum-three u3 u5 u9))