@ -21,8 +21,14 @@ In this tutorial, you learn how to implement a smart contract that stores and ma
## Prerequisites
### Complete the Hello World tutorial
Before you get started, you should complete the [Hello World tutorial](tutorial.html).
### Check the Stacks 2.0 status
The Stacks 2.0 blockchain is currently in development and could experience resets and downtimes. To make sure you're not running into any challenges related to the status of the network, please open up the [Status Checker](http://status.test-blockstack.com/) and confirm that all systems are operational. If some systems seem to have issues, it is best to wait until they are back up before you proceed with the next steps.
## Step 1: Downloading counter starter project
In this step, you initialize a starter project with additional counter tutorial files:
@ -30,14 +36,17 @@ In this step, you initialize a starter project with additional counter tutorial
Using your terminal, run the following command to create a new folder and initialize a new project:
```bash
# create and go to new `counter` project folder
mkdir counter; cd counter
npm init clarity-starter
```
You must now select a template. Type `counter` and hit ENTER:
You will be asked to select a project template. Press down with your arrow keys to choose `Counter` and hit ENTER:
```bash
? Template - one of [hello-world, counter]: counter
? Select a project template: (Use arrow keys)
Hello World
❯ Counter
```
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.
@ -77,15 +86,12 @@ It looks like we see some failed tests! That is on purpose - we will implement t
Let's get familiar with the tests to understand what the new smart contract should look like
1. Take a quick look at the test file associated with the counter smart contract:
```shell
cat test/counter.ts
```
1. In your editor, take a quick look at the test file associated with the counter smart contract: `test/counter.ts`
You should be familiar with the test set up from the Hello World tutorial. Notice how the instance of the smart contract is created on line 8:
You will see a [Mocha](https://mochajs.org/) test suite. This file describes the tests for the counter smart contract. Notice how the smart contract is instantiated on line 8 of file `counter.ts`:
```js
// this is a dummy address, not your own Stacks address
counterClient = new Client("SP3GWX3NE58KXHESRYE4DYQ1S31PQJTCRXB3PE9SB.counter", "counter", provider);
```
@ -93,18 +99,36 @@ Let's get familiar with the tests to understand what the new smart contract shou
The file was already created during the project setup.
2. With the editor of your choice, open `contracts/counter.clar` and add the following lines of code:
2. Using your editor, open `contracts/counter.clar`. You will notice the file already includes some content:
```cl
;; define counter variable
;; increment method
;; decrement method
;; counter getter
```
What you see are four one-line comments. In Clarity, a comment line is started with `;;`. As you can see, the comments indicate the structure of the smart contract we are going to implement.
Let's declare a counter variable and define a public getter method:
```cl
;; define counter variable
(define-data-var counter int 0)
(define-public (get-counter)
...
;; counter getter
(define-read-only (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.
The [`define-data-var`](https://docs.blockstack.org/core/smart/clarityref#define-data-var) statement initializes a new integer variable named `counter` and sets the value to `0`. It is important to note that all definition statements in Clarity need to be at the top of the file.
The `counter` variable is stored in the data space associated with this particular smart contract. The variable is persisted and acts as the global shared state.
The `counter` variable is stored in the data space associated of the smart contract. The variable is persisted and acts as the global shared state.
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.
@ -120,9 +144,10 @@ 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:
4. Add the following lines to the `counter.clar` file (below the increment method comment) and take a few seconds to review them:
```cl
;; increment method
(define-public (increment)
(begin
(var-set counter (+ (var-get counter) 1))
@ -133,7 +158,7 @@ Let's get familiar with the tests to understand what the new smart contract shou
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!
5. Next, 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:
@ -149,35 +174,29 @@ Let's get familiar with the tests to understand what the new smart contract shou
4 passing (586ms)
```
**Congratulations! You just implemented your first Clarity smart contract.**
## Step 4: Deploy and call the contract
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:
Your new smart contract is ready to be deployed to the Stacks 2.0 blockchain. You should be familiar with the steps from the ["Hallo, World" tutorial](https://docs.blockstack.org/core/smart/tutorial.html#deploy-the-contract).
```cl
(define-data-var counter int 0)
As soon as you successfully deploy your contract, you can play around with the contract and verify the functionality by calling all public methods you implemented. Here's a suggested order:
(define-public (get-counter)
(ok (var-get counter)))
* Call the `get-counter` method. It should return `0`
* Call the `increment` method and let the transaction complete
* Call the `get-counter` method. It should return `1`
* Call the `decrement` method and let the transaction complete
* Call the `get-counter` method. It should return `0`
(define-public (increment)
(begin
(var-set counter (+ (var-get counter) 1))
(ok (var-get counter))))
{% include note.html content="As you can see, read-only function calls don't require a transaction to complete. This is because the method doesn't require a state change." %}
(define-public (decrement)
(begin
(var-set counter (- (var-get counter) 1))
(ok (var-get counter))))
```
**Congratulations! You just implemented, deployed, and called your own Clarity smart contract.**
If you're ready to deploy and execute the contract, try [the Explorer Sandbox](tutorial.html#access-the-explorer-sandbox) or following [the instructions to run the contract in the command-line](tutorial.html#get-familiar-with-cli-optional).
---
With the completion of this tutorial, you ...
* Experienced test-driven development with Clarity
* Understood more Clarity language design principles
* Developed a working Clarity counter smart contract
* Developed a working Clarity counter smart contract and called its public methods
@ -22,7 +22,6 @@ By the end of this tutorial, you will:
* Deploy a contract to the Stacks 2.0 blockchain and call its public methods
* Understand how to use the Explorer Sandbox functionality
## Prerequisites
### Set up your Node environment
@ -33,36 +32,41 @@ You will need [NodeJS](https://nodejs.org/en/download/) `8.12.0` or higher to co
node --version
```
### Install Visual Studio Code with Clarity Extensions
### Check the Stacks 2.0 status
The Stacks 2.0 blockchain is currently in development and could experience resets and downtimes. To make sure you're not running into any challenges related to the status of the network, please open up the [Status Checker](http://status.test-blockstack.com/) and confirm that all systems are operational. If some systems seem to have issues, it is best to wait until they are back up before you proceed with the next steps.
### Optional: Install Visual Studio Code with Clarity Extensions
[Visual Studio Code](https://code.visualstudio.com/) (aka VS Code) is a free development interface for which Blockstack has created custom extensions, to make it easier to create smart contracts with Clarity.
[Install Visual Studio Code](https://code.visualstudio.com/download) and be sure to install the following extensions for the best coding experience:
[Install Visual Studio Code](https://code.visualstudio.com/download) and install the following extensions for the best coding experience:
- [Clarity](https://marketplace.visualstudio.com/items?itemName=blockstack.clarity), the official language extension by Blockstack that defines the Clarity language for VS Code and provides auto-complete and syntax highlighting.
- [clarity-lsp](https://marketplace.visualstudio.com/items?itemName=lgalabru.clarity-lsp), which adds inline help functionality for Clarity to VS Code
- [Rainbow Brackets](https://marketplace.visualstudio.com/items?itemName=2gua.rainbow-brackets), which adds helpful colorization of matching pairs of parentheses while you code
> **Note**: If you need help installing extensions, review [Extension Marketplace](https://code.visualstudio.com/docs/editor/extension-gallery) in the Visual Studio Code docs.
## Download a starter project
## Step 1:Download a starter project
Using your terminal, run the following command to create a new folder and initialize a new project:
```bash
# create and go to new `hello-world` project folder
mkdir hello-world; cd hello-world
npm init clarity-starter
```
After the starter project is loaded up, you have to select a project template. Select `hello-world`, which is the default, by hitting ENTER.
After the starter project is loaded up, you have to select a project template (using your arrow keys). Select `Hello World`, which is the default, by hitting ENTER.
```bash
? Template - one of [hello-world, counter]: (hello-world)
? Select a project template: (Use arrow keys)
❯ Hello World
Counter
```
## Review the contract
## Step 2: Review the contract
Select **File** > **Add Folder to Workspace** in VS Code, and add the `hello-world` folder you created in the previous step. Then, navigate to`contracts/hello-world.clar`.
In the project folder, open the`contracts/hello-world.clar` file with your editor.
You will see that the program and each statement is enclosed in `()` (parentheses), and the smart contract consists of two functions.
@ -80,7 +84,8 @@ On the first line, a new public function `say-hi` is declared. Public functions
The function doesn't take any parameters and simply returns "hello world" using the [`ok`](clarityRef.html#ok) response constructor.
The second function, `echo-number`, is a [read-only function](clarityRef.html#define-read-only). Read-only functions are also public, but as the name implies, they can not perform any datamap modifications. `echo-number` takes an input parameter of the type `int`. Along with integer, Clarity supports the following [types](clarityRef.html#clarity-type-system):
The second function, `echo-number`, is a [read-only function](clarityRef.html#define-read-only). Read-only functions are also public, but as the name implies, they can not change and variables or datamaps. `echo-number` takes an input parameter of the type `int`. Along with integer, Clarity supports the following [types](clarityRef.html#clarity-type-system):
* `uint`: 16-byte unsigned integer
* `principal`: spending entity, roughly equivalent to a Stacks address
* `boolean`: `true` or `false`
@ -89,57 +94,76 @@ The second function, `echo-number`, is a [read-only function](clarityRef.html#de
`echo-number` uses an [`ok`](clarityRef.html#ok) response to return the value passed to the function.
## Access the Explorer Sandbox
## Step 3: Access the Explorer Sandbox
{% include note.html content="<p>This tutorial uses a developer preview release of the <ahref='https://testnet-explorer.blockstack.org/'>Stacks 2.0 Explorer</a>. Please feel free to report issues or request enhancements on the <ahref='https://github.com/blockstack/explorer/issues/new'>blockstack/explorer</a> repository. For more details about this release, see this <ahref='https://forum.blockstack.org/t/explore-the-stacks-2-0-testnet-with-the-new-explorer-developer-preview/10889'>Blockstack forum post</a>.</p><p>If you encounter trouble using the Explorer Sandbox, try falling back to <ahref='#get-familiar-with-cli-optional'>the CLI instructions at the end of this page</a>.</p>" %}
Open up the [Stacks 2.0 Explorer Sandbox view](https://testnet-explorer.blockstack.org/sandbox). The Explorer Sandbox is a web-enabled view of the Stacks 2.0 blockchain, and has tools for validating contracts, testing out transactions, and generating tokens.
{% include note.html content="<p>This tutorial uses a developer preview release of the <ahref='https://testnet-explorer.blockstack.org/'>Stacks 2.0 Explorer</a>. Please feel free to report issues or request enhancements on the <ahref='https://github.com/blockstack/explorer/issues/new'>blockstack/explorer</a> repository. For more details about this release, see the <ahref='https://forum.blockstack.org/t/explore-the-stacks-2-0-testnet-with-the-new-explorer-developer-preview/10889'>Explore the Stacks 2.0 Testnet</a> post in the Blockstack forums.</p><p>If you encounter trouble using the Explorer Sandbox, try falling back to <ahref='#get-familiar-with-cli-optional'>the CLI instructions at the end of this page</a>.</p>" %}
Here, we will run the code from `hello-world` right in the browser and create blockchain transactions right in the browser.
Open up the [Stacks 2.0 Explorer Sandbox view](https://testnet-explorer.blockstack.org/sandbox). The Explorer Sandbox is a web-enabled view of the Testnet blockchain, and has tools for validating contracts, testing out transactions, and generating Testnet STX tokens. Here, we will run the code from `hello-world` right in the browser and create blockchain transactions right in the browser.
You will be asked to sign in with or sign up for a Blockstack ID. Your new ID will include a new Stacks address, which is essentially a wallet that holds funds like STX tokens. STX tokens are consumed as fees to register digital assets on the network and to publish/execute smart contracts, among other functions on the network.
You will be asked to sign in with or sign up for a Blockstack ID, which creates a new STX address for you on the Testnet blockchain, where you can receive tokens. Follow the steps on the screen to complete the process.
All of the following operations will happen on the Testnet. A Testnet is an alternative Stacks 2.0 blockchain, to be used for testing. Testnet STX tokens are separate and distinct from actual STX tokens, and are never supposed to have any value.
Follow the steps on the screen to complete the process.
![The faucet tab of the Stacks 2.0 Testnet Explorer](images/faucet.png)
Once completed, you will see the Sandbox screen and a confirmation, indicating you were provided with a new STX address for testing purposes.
Once completed, you will see the Sandbox view and your newly generated Stacks address for testing purposes.
## Obtain STX tokens
## Step 4: Obtain STX tokens
Uploading and calling smart contracts requires fees to be paid to the network to process the transactions. The Testnet Explorer features the capability to request STX tokens that can be used to pay the fees ("STX faucet").
On the [**STX faucet**](https://testnet-explorer.blockstack.org/sandbox?tab=faucet) screen, your new STX address will be prefilled. Click **Request STX** to receive 0.5 STX at your address.
On the [**STX faucet**](https://testnet-explorer.blockstack.org/sandbox?tab=faucet) screen, your new Stacks address will be prefilled. Click **Request STX** to receive 0.5 STX.
On the right side of the screen ("Recent transactions"), you will notice that a new transaction was generated for you. A transaction usually takes up to a minute to complete, because it needs to be broadcasted and confirmed by the network.
A confirmation for a new transaction will pop up. If you want to see the details of your faucet request, you can click **View transaction**. However, you will to refresh the page a few times, for up to a minute or so, while the transaction completes.
Wait a few seconds until the transaction completes (the loading indicator will disappear and a green dot will show up on the icon). You don't need to refresh the page manually. However, if you wish to see the details of your faucet request, you can click on the transaction.
![Screenshot of faucet request submission](images/faucet-transfer.png)
## Deploy the contract
## Step 5: Deploy the contract
A deployed contract on the Testnet is like a cloud function (comparable to serverless functions). It allows you to execute code remotely on the Stacks 2.0 network.
Go back to the Sandbox screen, switch to the [**Contract deploy**](https://testnet-explorer.blockstack.org/sandbox?tab=contract-deploy) tab, and do the following:
On the Sandbox view, switch to the [**Contract deploy**](https://testnet-explorer.blockstack.org/sandbox?tab=contract-deploy) tab, and do the following:
1. Enter a name for the contract under **Contract name** that uses lower-case letters, dashes, and numbers only.
2. Replace code in the text area under **Contract source code** with the contents of `contracts/hello-world.clar`.
2. Replace code in the text area under **Contract source code (editable)** with the contents of `contracts/hello-world.clar`.
3. Ignore the **Choose from sample** drop-down for now. After completing this tutorial you can come back to the Explorer Sandbox and use this drop-down to try other sample contracts.
3. Click **Deploy contract**.
4. Ignore the **Fee** field. It should be set to 2000 micro-STX (1 STX = 1000000 micro-STX)
5. Click **Deploy contract**.
{% include note.html content="In production, you would estimate the fees that are reuqired to be paid using methods provided by the Stacks 2.0 network. The estimate would, for instance, be based on the size of the contract. For the purpose of this tutorial, we will keep it simple and accept the default fee." %}
![deploy](images/contract-deploy.png)
A confirmation will pop up, indicating that a new contract deploy transaction was issued. As with the faucet request, you can click **View transaction** to review the pending transaction if you like, but you'll need to keep refreshing the page until the deploy transaction completes. Once you're able to see the completed deploy transaction, you will see that every smart contract's source code is publicly verifiable through the explorer.
On the right, inside the "Recent transactions" feed, you will notice that another transaction appearing.
Wait a few seconds until the transaction completes. In the meantime, you can click on the transaction and review the details. You will notice that every deployed smart contract's source code is publicly verifiable.
## Call the public method
## Step 6: Call the public method
Go back to the Sandbox screen, switch to the [**Contract call**](https://testnet-explorer.blockstack.org/sandbox?tab=contract-call) tab, and enter the following details:
On the Sandbox view, switch to the [**Contract call**](https://testnet-explorer.blockstack.org/sandbox?tab=contract-call) tab, and enter the following details:
* **Contract address**: Your generated STX address. Hover over the identity component on the right side of the screen to copy your full address and paste it in here.
* **Contract name**: Whatever you entered as your contract name in the previous step. If you forgot, you can review your recent transactions by following the link on the upper-right, and look up your contract creation transaction.
* **Contract address**: Your generated Stacks address. Hover over the "identity view" on the top right side of the screen to copy your full address and paste it in here.
* **Contract name**: Whatever you entered as your contract name in the previous step. If you forgot, you can review your recent transactions.
![Screenshot of the Sandbox's contract call screen](images/sandbox-call.png)
After clicking **Search**, you will see the two public methods implemented in the smart contract.
Locate the `(echo-number)` method, provide any integer for the `val` argument and click **Submit**. You will see the value you entered echoed back at you on the screen, as well as a confirmation that a contract call transaction was issued. Click on the transaction to review it. In the next seconds, your contract call should be completed and you will see a contract call success screen. Scroll down to the function summary section to verify your contract call:
Locate the `(echo-number)` method, provide any integer for the `val` argument (e.g. 42) and click **Submit**. You will see the value you entered echoed back to you below the button:
```cl
Result: (ok 42)
```
![sandbox-call](images/sandbox-calltx.png)
**Congratulations! You just deployed your smart contract and called a public function on the Testnet.**
**Congratulations! You just deployed your smart contract and called a public function on the Stacks 2.0 blockchain.**
---
@ -150,7 +174,7 @@ With the completion of this tutorial, you now:
* Have deployed a contract to the Stacks 2.0 blockchain and called its public methods
* Understand how to use the Explorer Sandbox functionality
## Get familiar with CLI (optional)
## Optional: Get familiar with CLI
The steps above provide an easy way to get started with contract deployment and contract calls. If you want to stay in the terminal and get access to more advanced capabilities, you should use the Blockstack CLI.
@ -162,48 +186,90 @@ Install an early release of the new Blockstack CLI for Stacks 2.0.
Create a new STX address and save keychain details, using the `-t` flag to target Testnet.
Create a new Stacks address and save keychain details, using the `-t` flag to target Testnet. The new keychain details will be stored in the file `cli_keychain.json`:
The response will include a `txId` property. This is the transaction that was initiated to transfer funds to your Stacks address.
```json
{
"success": true,
"txId": "0xabc123",
"txRaw": "8080000000040..."
}
```
You need to wait up to a minute for the transaction to complete. After that, you can confirm that your balance increase by 0.5 STX.
```shell
blockstack balance <stx_address> -t
blockstack balance -t <stx_address>
```
```json
{
// in microstacks (1 STX = 1000000 microstacks)
"balance": "500000",
"nonce": 0
}
```
Deploy a contract file to Testnet.
With sufficient funds on your account, you can deploy a contract file to Testnet. In this example, we are deploying the `hello-world.clar` contract with the name `hello-world`.
{% include note.html content="To learn more about the Blockstack CLI commands, you can run `blockstack-cli help all`." %}
The command will return a new contract deploy transaction ID. You have to wait up to a minute for the contract to be broadcasted to the network. Keep in mind that this operation will increase the `nonce` of your account.
As soon as the contract is deployed, you can call a contract method. In this example, we are calling the `echo-number` function of the previously named `hello-world` contract. The method is defined as `read-only` and will return the result without generating a new transactions.