Browse Source

updates based on feedback

update-clarity-tutorial
Alex Graebe 5 years ago
parent
commit
bbae9ceaa8
  1. 21
      _core/smart/overview.md
  2. 36
      _core/smart/tutorial-counter.md
  3. 16
      _core/smart/tutorial.md

21
_core/smart/overview.md

@ -6,18 +6,17 @@ permalink: /:collection/:path.html
# Introduction to Clarity
{:.no_toc}
Clarity is a smart contracting language for use with the Stacks 2.0 Blockchain. It supports programmatic control over digital assets.
Clarity is a smart contracting language for use with the Stacks 2.0 blockchain. It supports programmatic control over digital assets.
* TOC
{:toc}
## Smart contracts
Smart contracts allow two parties to exchange anything of value (money, property, shares), in an automated, auditable, and secure way _without the services of a middleman_. Nick Szabo introduced the canonical metaphor for smart contracts, a vending machine.
In Nick Szabo's metaphor, the vending machine is the smart contract. The buyer and machine owner are the two parties. A vending machine executes a set of hard-coded actions when the buyer engages with it. The machine displays the items and their prices. A buyer enters money into the machine which determines if the amount fails to mee, meets, or exceeds an item's price. Based on the amount, the machine asks for more money, dispenses an item, or dispenses and item and change.
Smart contracts encode and enforce the rules for curating this data, and are often used to ensure that users can exchange valuable data in an automated and secure way. For example, a smart contract could allow anyone to add a new movie to a movie catalog, but require that someone first pay for a decryption key before anyone can view it. To do this, the smart contract could be written such that the movie creator had to publicly disclose the decryption key in order to receive payment. Such a system would allow movie creators to make money by adding movies to the movie catalog that people want to watch.
If you are new to smart contracts concepts, you should read <a href="https://blockgeeks.com/guides/smart-contracts/" target="_blank">a good general explanation</a> first.
Because smart contracts run on top of a blockchain, anyone can query them, and anyone can submit transactions to run their code. The blockchain stores the history of all accepted transactions, so anyone can audit the blockchain in order to independently verify that an app's global shared state has been managed correctly according to the smart contract's rules.
## Use cases
@ -26,23 +25,21 @@ Not every decentralized application requires smart contracts, but Clarity unlock
* Access control (e.g. pay to access)
* Non-fungible and fungible tokens
* Business model templates (e.g. subscriptions)
* App Chains
* App-specific blockchains
* Decentralized Autonomous Organizations
## Language design
Clarity is a [list processing (LISP) language](https://en.wikipedia.org/wiki/Lisp_(programming_language)) and differs from most other smart contract languages in two essential ways:
* The language is not intended to be compiled
* The language is not Turing complete
* The language is interpreted and broadcasted on the blockchain as is (not compiled)
* The language is decidable (not Turing complete)
These differences allow for static analysis of programs to determine properties like runtime cost and data usage. Omitting compilation prevents the possibility of error or bugs introduced at the compiler level.
Using an interpreted language ensures that the code that executes is human-readable, and is auditable by users. The fact that Clarity is a decidable language means that users can determine the set of reachable code from any function they want to call.
A Clarity smart contract is composed of two parts &mdash; a data-space and a set of functions. Only the associated smart contract may modify its corresponding data-space on the Blockchain. Functions are private unless they are defined as public functions. Users call smart contracts' public functions by broadcasting a transaction on the Blockchain which invokes the public function.
A Clarity smart contract is composed of two parts &mdash; a data-space and a set of functions. Only the associated smart contract may modify its corresponding data-space on the blockchain. Functions may be private and thus callable only from within the smart contract, or public and thus callable from other contracts. Users call smart contracts' public functions by broadcasting a transaction on the blockchain which invokes the public function. Contracts can also call public functions from other smart contracts.
Contracts can also call public functions from other smart contracts. The ability to do a static analysis of a smart contract allows a user to determine dependency between contracts.
Note some of the key Clarity language rules and limitations:
Note some of the key Clarity language rules and limitations.
* The only atomic types are booleans, integers, fixed length buffers, and principals
* Recursion is illegal and there is no lambda function.

36
_core/smart/tutorial-counter.md

@ -8,7 +8,7 @@ permalink: /:collection/:path.html
| Experience | | **Intermediate** |
| Duration | | **30 minutes** |
In this tutorial, you learn how to implement a smart contract that stores and manipulates an integer value on the Stacks 2.0 Blockchain. By the end of this tutorial, you will ...
In this tutorial, you learn how to implement a smart contract that stores and manipulates an integer value on the Stacks 2.0 blockchain. By the end of this tutorial, you will ...
* Have experienced test-driven development with Clarity
* Understand more Clarity language design principles
@ -40,11 +40,11 @@ You have to select a template and a name for your local folder. For the counter
? Project name: (clarity-counter)
```
Finally, the project dependencies are installed and your project is ready for development. Because you already completed the Hello World tutorial, the project structure is familiar to you. The main difference is that we have additional tests for a new counter smart contract.
Finally, the project dependencies are installed and your project is ready for development. Because you already completed the [Hello World tutorial](tutorial.html), the project structure is familiar to you. The main difference is that we have additional tests for a new counter smart contract.
## Step 2: Running tests
Smart contracts are often developed in a test-driven approach to ensure code quality but also to speed up the development cycle by removing the need to push every change to the Blockchain before executing it. We will do the same in this project. Now, let's run the tests and review the results:
mart contracts are often developed in a test-driven approach. This not only improves code quality, but also removes the need to push every iteration to the blockchain before executing it. We will do the same in this project. Now, let's run the tests and review the results:
Still in the project root directory, run the following command:
@ -67,7 +67,7 @@ counter contract test suite
3 failing
```
It looks like we see some failed test! That is on purpose - we will implement the new smart contract in the next steps! After every increment of the contract, we will rerun the tests to ensure we're on the right track.
It looks like we see some failed tests! That is on purpose - we will implement the new smart contract in the next steps! After every step in this tutorial, we will rerun the tests to ensure we're on the right track.
## Step 3: Developing a smart contract
@ -95,17 +95,16 @@ Let's get familiar with the tests to understand what the new smart contract shou
(define-data-var counter int 0)
(define-public (get-counter)
(ok (var-get counter))
)
(ok (var-get counter)))
```
The first line initializes a new integer variable `counter` with the value set to `0` using the [`define-data-var`](https://docs.blockstack.org/core/smart/clarityref#define-data-var) statement. It is important to note that all definition statements in Clarity need to be at the top of the file.
To provide access to the `counter` variable from outside of the current smart contract, we need to declare a public get function. The last lines of the code add a public `get-counter` function. The [`var-get`](https://docs.blockstack.org/core/smart/clarityref#var-get) statement looks for a variable in the contract's data map and returns it.
To provide access to the `counter` variable from outside of the current smart contract, we need to declare a public function to get it. The last lines of the code add a public `get-counter` function. The [`var-get`](https://docs.blockstack.org/core/smart/clarityref#var-get) statement looks for a variable in the contract's data space and returns it.
With that, you are ready to rerun the tests!
3. Run the tests and review the results:
1. Run the tests and review the results:
```shell
npm test
@ -115,22 +114,20 @@ Let's get familiar with the tests to understand what the new smart contract shou
However, we don't stop here. Let's implement increment and decrement functions.
4. Add the following lines to the bottom of the `counter.clar` file and take a few seconds to review them:
2. Add the following lines to the bottom of the `counter.clar` file and take a few seconds to review them:
```cl
(define-public (increment)
(begin
(var-set counter (+ (var-get counter) 1))
(ok (var-get counter))
)
)
(ok (var-get counter))))
```
First, the [`begin`](https://docs.blockstack.org/core/smart/clarityref#begin) statement evaluates the multi-line expressions and returns the value of the last expression. In this case, it is used to set a new value and return the new value.
Next, a [`var-set`](https://docs.blockstack.org/core/smart/clarityref#var-set) is used to set a new value for the `counter` variable. The new value is constructed using the [`+`](https://docs.blockstack.org/core/smart/clarityref#-add) (add) statement. This statement takes a number of integers and returns the result. Along with add, Clarity provides statements to subtract, multiply, and divide integers. Find more details in the [Clarity language reference](https://docs.blockstack.org/core/smart/clarityref).
5. Finally, take a few minutes and implement a new public function `decrement` to subtract `1` from the `counter` variable. You should have all knowledge needed to succeed at this!
3. Finally, take a few minutes and implement a new public function `decrement` to subtract `1` from the `counter` variable. You should have all knowledge needed to succeed at this!
Done? Great! Run the tests and make sure all of them are passing. You are looking for 4 passed tests:
@ -148,25 +145,20 @@ Let's get familiar with the tests to understand what the new smart contract shou
**Congratulations! You just implemented your first Clarity smart contract.**
6. Here is how the final smart contract file should look like. Note that you can find the `decrement` function in here - in case you want to compare with your own implementation:
4. Here is how the final smart contract file should look like. Note that you can find the `decrement` function in here - in case you want to compare with your own implementation:
```cl
(define-data-var counter int 0)
(define-public (increment)
(begin
(var-set counter (+ (var-get counter) 1))
(ok (var-get counter))
)
)
(ok (var-get counter))))
(define-public (decrement)
(begin
(var-set counter (- (var-get counter) 1))
(ok (var-get counter))
)
)
(ok (var-get counter))))
(define-public (get-counter)
(ok (var-get counter))
)
(ok (var-get counter)))
```
## Where to go next

16
_core/smart/tutorial.md

@ -78,21 +78,19 @@ Now, let's have a look at a Clarity smart contract and get familiar with the bas
You should see the contract source code. Take a few seconds to review the content.
Clarity is a programming language based on [LISP](https://en.wikipedia.org/wiki/Lisp_(programming_language)). Most notably, Clarity is designed for static analysis, not compiled, and **not** [Turing complete](https://en.wikipedia.org/wiki/Turing_completeness).
Clarity is a programming language based on [LISP](https://en.wikipedia.org/wiki/Lisp_(programming_language)). Most notably, Clarity is interpreted and decidable.
Let's go through the source code. Notice how the program and each statement is enclosed in `()` (parentheses). You'll see that the smart contract consists of two public functions. Starting at the top, let's review line by line:
```cl
(define-public (say-hi)
(ok "hello world")
)
(ok "hello world"))
(define-public (echo-number (val int))
(ok val)
)
(ok val))
```
On the first line, a new public function `say-hi` is declared. To create private functions, you would use the `define-private` function. Private functions can only be executed by the current smart contract and not from the outside. Only public functions can be called from outside e.g., through other smart contracts or applications. The need to call another smart contract can have different reasons. It allows to reuse existing smart contracts published by other developers. It may also be required because complex implementations are often split out into a set of contracts to achieve a [separation of concerns](https://en.wikipedia.org/wiki/Separation_of_concerns).
On the first line, a new public function `say-hi` is declared. To create private functions, you would use the `define-private` keyword. Private functions can only be executed by the current smart contract and not from the outside. Only public functions can be called from outside, by other smart contracts. The reason public functions exist is to enable re-using code that is already available in other smart contracts, and to enable developers to break complex smart contracts into smaller, simpler smart contracts (an exercise in [separating concerns](https://en.wikipedia.org/wiki/Separation_of_concerns)).
The function doesn't take any parameters and simply returns "hello world" using the [`ok`](https://docs.blockstack.org/core/smart/clarityref#ok) response constructor.
@ -150,7 +148,7 @@ import { Client, Provider, ProviderRegistry, Result } from "@blockstack/clarity"
### Initiliazing a client
At the test start, we are initializing contract instance `helloWorldClient` and a provider that simulates interactions with the Stacks 2.0 Blockchain.
At the test start, we are initializing contract instance `helloWorldClient` and a provider that simulates interactions with the Stacks 2.0 blockchain.
```js
let helloWorldClient: Client;
@ -162,9 +160,9 @@ provider = await ProviderRegistry.createProvider();
helloWorldClient = new Client("SP3GWX3NE58KXHESRYE4DYQ1S31PQJTCRXB3PE9SB.hello-world", "hello-world", provider);
```
Take a look at the client initialization. It requires a contract id and name in the following format: `{owner_stacks_address}.{contract_identifier}`. The second parameter indicates the location of the smart contract file, without the `.clar` suffix. By default, the location is assumed to be relative to the `contracts` folder.
Take a look at the client initialization. It requires a contract id and name in the following format: `{owner_stacks_address}.{contract_identifier}`. The second field indicates the location of the smart contract file, without the `.clar` suffix. By default, the location is assumed to be relative to the `contracts` folder.
As you can see above, a sample stacks address and contract identifier is already provided for you. You don't need to modify anything.
As you can see above, a sample Stacks address and contract identifier is already provided for you. You don't need to modify anything.
### Checking syntax

Loading…
Cancel
Save