Browse Source

Merge branch 'master' into feat/nft-onboarding

friedger-patch-7
Patrick Gray 3 years ago
committed by GitHub
parent
commit
7d3571d469
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      .github/workflows/main.yml
  2. 2
      .vale.ini
  3. 1
      .vale/styles/Google/Colons.yml
  4. 8
      .vale/styles/Google/HeadingColons.yml
  5. 2
      .vale/styles/Google/Headings.yml
  6. 4
      .vale/styles/Google/Spacing.yml
  7. 4
      .vale/styles/Google/WordList.yml
  8. 3
      .vale/styles/Vocab/docs/accept.txt
  9. 15
      next.config.js
  10. BIN
      public/images/cloudformation-stack-name.png
  11. BIN
      public/images/microblock-states.png
  12. 1
      public/images/pages/billboard.svg
  13. BIN
      public/images/pox-cycles.png
  14. BIN
      public/images/pox-mechanism.png
  15. BIN
      public/images/pox-mining-flow.png
  16. BIN
      public/images/pox-participants.png
  17. BIN
      public/images/pox-unlocking-btc.png
  18. BIN
      public/images/pox-why-bitcoin.png
  19. BIN
      public/images/stacking-delegation-illustration.png
  20. BIN
      public/images/stacking-dynamic-minimum.png
  21. BIN
      public/images/stacking-illustration.png
  22. BIN
      public/images/stx-microblocks.png
  23. 6
      src/_data/clarity-reference.json
  24. 47
      src/common/navigation.yaml
  25. 2
      src/components/header.tsx
  26. 30
      src/pages/build-apps/examples/heystack.md
  27. 6
      src/pages/build-apps/guides/authentication.md
  28. 0
      src/pages/build-apps/guides/integrate-stacking-delegation.md
  29. 0
      src/pages/build-apps/guides/integrate-stacking.md
  30. 0
      src/pages/contributing.md
  31. 21
      src/pages/ecosystem/address-confirmation.md
  32. 71
      src/pages/ecosystem/overview.md
  33. 46
      src/pages/ecosystem/stacks-token-holders.md
  34. 55
      src/pages/ecosystem/stacks-token.md
  35. 2
      src/pages/storage-hubs/amazon-ec2-deploy.md
  36. 2
      src/pages/understand-stacks/command-line-interface.md
  37. 100
      src/pages/understand-stacks/microblocks.md
  38. 25
      src/pages/understand-stacks/mining.md
  39. 4
      src/pages/understand-stacks/network.md
  40. 9
      src/pages/understand-stacks/overview.md
  41. 35
      src/pages/understand-stacks/proof-of-transfer.md
  42. 2
      src/pages/understand-stacks/sending-tokens.md
  43. 67
      src/pages/understand-stacks/stacking.md
  44. 104
      src/pages/understand-stacks/stacks-blockchain-api.md
  45. 1
      src/pages/understand-stacks/technical-specs.md
  46. 80
      src/pages/understand-stacks/transactions.md
  47. 300
      src/pages/write-smart-contracts/billboard-tutorial.md
  48. 22
      src/pages/write-smart-contracts/clarinet.md
  49. 3
      src/pages/write-smart-contracts/counter-tutorial.md
  50. 3
      src/pages/write-smart-contracts/hello-world-tutorial.md
  51. 10
      src/pages/write-smart-contracts/overview.md

4
.github/workflows/main.yml

@ -1,5 +1,7 @@
name: Code quality
on: [push]
on:
pull_request:
branches: [master]
jobs:
code_quality:

2
.vale.ini

@ -1,5 +1,5 @@
StylesPath = .vale/styles
MinAlertLevel = suggestion
MinAlertLevel = warning
Vocab = docs
[formats]

1
.vale/styles/Google/Colons.yml

@ -3,5 +3,6 @@ message: "'%s' should be in lowercase."
link: 'https://developers.google.com/style/colons'
nonword: true
level: warning
scope: sentence
tokens:
- ':\s[A-Z]'

8
.vale/styles/Google/HeadingColons.yml

@ -0,0 +1,8 @@
extends: existence
message: "'%s' should be in uppercase."
link: 'https://developers.google.com/style/capitalization#capitalization-in-titles-and-headings'
nonword: true
level: warning
scope: heading
tokens:
- ':\s[a-z]'

2
.vale/styles/Google/Headings.yml

@ -4,6 +4,8 @@ link: 'https://developers.google.com/style/capitalization#capitalization-in-titl
level: warning
scope: heading
match: $sentence
indicators:
- ':'
exceptions:
- Azure
- CLI

4
.vale/styles/Google/Spacing.yml

@ -4,5 +4,5 @@ link: 'https://developers.google.com/style/sentence-spacing'
level: error
nonword: true
tokens:
- '[.?!] {2,}[A-Z]'
- '[.?!][A-Z]'
- '[a-z][.?!] {2,}[A-Z]'
- '[a-z][.?!][A-Z]'

4
.vale/styles/Google/WordList.yml

@ -28,6 +28,7 @@ swap:
Android device: Android-powered device
android: Android
API explorer: APIs Explorer
application: app
approx\.: approximately
authN: authentication
authZ: authorization
@ -37,6 +38,7 @@ swap:
chapter: documents|pages|sections
check box: checkbox
check: select
CLI: command-line tool
click on: click|click in
Cloud: Google Cloud Platform|GCP
Container Engine: Kubernetes Engine
@ -73,6 +75,6 @@ swap:
tablename: table name
tablet: device
touch: tap
url: URL
url: URL
vs\.: versus
World Wide Web: web

3
.vale/styles/Vocab/docs/accept.txt

@ -10,3 +10,6 @@ NFTs
SIP
Clarinet
Clarity
application
PoX
HODL

15
next.config.js

@ -8,6 +8,16 @@ const withFonts = require('next-fonts');
async function redirects() {
return [
{
source: '/understand-stacks/integrate-stacking',
destination: '/build-apps/guides/integrate-stacking',
permanent: true,
},
{
source: '/understand-stacks/integrate-stacking-delegation',
destination: '/build-apps/guides/integrate-stacking-delegation',
permanent: true,
},
{
source: '/build-apps/tutorials/todos',
destination: '/build-apps/examples/todos',
@ -23,6 +33,11 @@ async function redirects() {
destination: '/build-apps/examples/angular',
permanent: true,
},
{
source: '/ecosystem/contributing',
destination: '/contributing',
permanent: true,
},
{
source: '/browser/todo-list.html',
destination: '/build-apps/tutorials/todos',

BIN
public/images/cloudformation-stack-name.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 13 KiB

BIN
public/images/microblock-states.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 KiB

1
public/images/pages/billboard.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 91 KiB

BIN
public/images/pox-cycles.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

BIN
public/images/pox-mechanism.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

BIN
public/images/pox-mining-flow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
public/images/pox-participants.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

BIN
public/images/pox-unlocking-btc.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
public/images/pox-why-bitcoin.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
public/images/stacking-delegation-illustration.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 KiB

After

Width:  |  Height:  |  Size: 179 KiB

BIN
public/images/stacking-dynamic-minimum.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

BIN
public/images/stacking-illustration.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 126 KiB

BIN
public/images/stx-microblocks.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 28 KiB

6
src/_data/clarity-reference.json

@ -133,7 +133,7 @@
"input_type": "bool, ...",
"output_type": "bool",
"signature": "(or b1 b2 ...)",
"description": "Returns `true` if any boolean inputs are `true`. Importantly, the supplied arguments are evaluated in-order and lazily. Lazy evaluation means that if one of the arguments returns `false`, the function short-circuits, and no subsequent arguments are evaluated.",
"description": "Returns `true` if any boolean inputs are `true`. Importantly, the supplied arguments are evaluated in-order and lazily. Lazy evaluation means that if one of the arguments returns `true`, the function short-circuits, and no subsequent arguments are evaluated.",
"example": "(or true false) ;; Returns true\n(or (is-eq (+ 1 2) 1) (is-eq 4 4)) ;; Returns true\n(or (is-eq (+ 1 2) 1) (is-eq 3 4)) ;; Returns false\n(or (is-eq (+ 1 2) 3) (is-eq 4 4)) ;; Returns true\n"
},
{
@ -162,7 +162,7 @@
},
{
"name": "let",
"input_type": "((name2 AnyType) (name2 AnyType) ...), AnyType, ... A",
"input_type": "((name1 AnyType) (name2 AnyType) ...), AnyType, ... A",
"output_type": "A",
"signature": "(let ((name1 expr1) (name2 expr2) ...) expr-body1 expr-body2 ... expr-body-last)",
"description": "The `let` function accepts a list of `variable name` and `expression` pairs,\nevaluating each expression and _binding_ it to the corresponding variable name.\n`let` bindings are sequential: when a `let` binding is evaluated, it may refer to prior binding.\nThe _context_ created by this set of bindings is used for evaluating its body expressions.\n The let expression returns the value of the last such body expression.\nNote: intermediary statements returning a response type must be checked",
@ -253,7 +253,7 @@
"input_type": "VarName, AnyType",
"output_type": "bool",
"signature": "(var-set var-name expr1)",
"description": "The `var-set` function sets the value associated with the input variable to the\ninputted value.",
"description": "The `var-set` function sets the value associated with the input variable to the\ninputted value. The function always returns `true`.",
"example": "\n(define-data-var cursor int 6)\n(var-get cursor) ;; Returns 6\n(var-set cursor (+ (var-get cursor) 1)) ;; Returns true\n(var-get cursor) ;; Returns 7"
},
{

47
src/common/navigation.yaml

@ -7,17 +7,24 @@ sections:
- path: /overview
- path: /testnet
- path: /regtest
- path: /proof-of-transfer
- path: /mining
- path: /accounts
- path: /transactions
- path: /network
- path: /proof-of-transfer
- path: /mining
- path: /microblocks
- path: /stacking
- path: /command-line-interface
- path: /local-development
- path: /technical-specs
- path: /stacks-blockchain-api
sections:
- title: Community
usePageTitles: true
pages:
- external:
href: 'https://github.com/friedger/awesome-stacks-chain'
title: 'Awesome Stacks'
- title: Tutorials
usePageTitles: true
pages:
@ -27,8 +34,6 @@ sections:
- path: /running-testnet-node
- path: /running-regtest-node
- path: /running-api-node
- path: /integrate-stacking
- path: /integrate-stacking-delegation
- path: /stacking-using-CLI
- path: /write-smart-contracts
@ -45,6 +50,7 @@ sections:
- path: /hello-world-tutorial
- path: /counter-tutorial
- path: /nft
- path: /billboard-tutorial
- path: /testing-contracts
- path: /build-apps
pages:
@ -59,6 +65,8 @@ sections:
- path: /guides/authentication
- path: /guides/transaction-signing
- path: /guides/data-storage
- path: /guides/integrate-stacking
- path: /guides/integrate-stacking-delegation
- title: Example Apps
usePageTitles: true
@ -75,37 +83,37 @@ sections:
href: 'https://github.com/blockstack/connect#readme'
title: connect
- external:
href: 'https://github.com/blockstack/stacks.js/tree/master/packages/auth'
href: 'https://stacks-js-git-master-blockstack.vercel.app/modules/auth.html'
title: auth
- external:
href: 'https://github.com/blockstack/stacks.js/tree/master/packages/storage'
href: 'https://stacks-js-git-master-blockstack.vercel.app/modules/storage.html'
title: storage
- external:
href: 'https://github.com/blockstack/stacks.js/tree/master/packages/transactions'
href: 'https://stacks-js-git-master-blockstack.vercel.app/modules/transactions.html'
title: transactions
- external:
href: 'https://github.com/blockstack/stacks-blockchain-api/tree/master/client'
href: 'https://blockstack.github.io/stacks-blockchain-api/client/index.html'
title: blockchain-api-client
- external:
href: 'https://github.com/blockstack/stacks.js/tree/master/packages/stacking'
href: 'https://stacks-js-git-master-blockstack.vercel.app/modules/stacking.html'
title: 'stacking'
- external:
href: 'https://github.com/blockstack/stacks.js/tree/master/packages/keychain'
href: 'https://stacks-js-git-master-blockstack.vercel.app/modules/keychain.html'
title: 'keychain'
- external:
href: 'https://github.com/blockstack/stacks.js/tree/master/packages/network'
href: 'https://stacks-js-git-master-blockstack.vercel.app/modules/network.html'
title: 'network'
- external:
href: 'https://github.com/blockstack/stacks.js/tree/master/packages/encryption'
href: 'https://stacks-js-git-master-blockstack.vercel.app/modules/encryption.html'
title: 'encryption'
- external:
href: 'https://github.com/blockstack/stacks.js/tree/master/packages/profile'
href: 'https://stacks-js-git-master-blockstack.vercel.app/modules/profile.html'
title: 'profile'
- external:
href: 'https://github.com/blockstack/stacks.js/tree/master/packages/common'
href: 'https://stacks-js-git-master-blockstack.vercel.app/modules/common.html'
title: common
- external:
href: 'https://github.com/blockstack/stacks.js/tree/master/packages/bns'
href: 'https://stacks-js-git-master-blockstack.vercel.app/modules/bns.html'
title: bns
- title: Protocols
@ -152,11 +160,4 @@ sections:
- path: /language-keywords
- path: /language-functions
- path: /ecosystem
pages:
- path: /overview #pbc et al
- path: /stacks-token
- external:
href: 'https://github.com/friedger/awesome-stacks'
title: Awesome Stacks
- path: /contributing
- path: /contributing

2
src/components/header.tsx

@ -78,7 +78,7 @@ const nav: NavItem[] = [
},
{
label: 'Discord',
href: 'https://discord.com/invite/6PcCMU',
href: 'https://discord.gg/zrvWsQC',
},
],
},

30
src/pages/build-apps/examples/heystack.md

@ -10,17 +10,18 @@ images:
## Introduction
This example application demonstrates important features of the Stacks blockchain, and is a case study for how a frontend
web application can interact with a Clarity smart contract. The full source of the application is provided, this page
highlights important code snippets and design patterns to help you learn how to develop your own Stacks application.
web application can interact with a Clarity smart contract. The full source of the application is provided and
completely open source for you to use or modify. This page highlights important code snippets and design patterns to
help you learn how to develop your own Stacks application.
This app highlights the following platform features:
This app showcases the following platform features:
- Authenticating users with the web wallet
- Using a smart contract to store data on the blockchain
- Minting new fungible tokens with a [SIP-010][] compliant smart contract
- Creating and monitoring transactions on the Stacks blockchain using [Stacks.js][]
You can access the [online version][heystack] of the Heystack app to interact with it. The source for Heystack is also
You can access the [online version of the Heystack app][heystack] to interact with it. The source for Heystack is also
available on [Github][heystack_gh]. This page assumes some familiarity with [React][].
## Heystack overview
@ -34,10 +35,19 @@ user sends a message on the platform, they must sign the message with the [Stack
wallet) and pay a small gas fee in STX. A user spends a $HEY token to send every message, and recieves a $HEY token for
every like that their messages receive.
The following video provides a brief overview of the Heystack application:
<br /><iframe width="560" height="315" src="https://www.youtube.com/embed/2_xAIctJqGw" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
## Review smart contracts
Heystack depends on two smart contracts to execute the backend functions of the app on the Stacks blockchain: a contract
for handling the messaging content, and a contract for minting and distributing the $HEY token.
Heystack depends on two smart contracts to execute the backend functions of the app on the Stacks blockchain:
- a contract for handling the messaging content
- a contract for minting and distributing the $HEY token
As a best practice, these two contracts are separate because of the different functionality they handle. This is an
exercise in [separation of concerns][].
### Content contract
@ -589,6 +599,13 @@ const AccountNameComponent = memo(() => {
...
```
## Development walkthrough video
If you would like to learn more about the Heystack application and how it was developed, the following video presents
specific implementation details.
<br /><iframe width="560" height="315" src="https://www.youtube.com/embed/e-IfT5CI-Gw" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
[heystack]: https://heystack.xyz
[stacks.js]: https://github.com/blockstack/stacks.js
[stacks web wallet]: https://www.hiro.so/wallet/install-web
@ -617,3 +634,4 @@ const AccountNameComponent = memo(() => {
[`src/common/hooks/use-publish-hey.ts`]: https://github.com/blockstack/heystack/blob/main/src/common/hooks/use-publish-hey.ts
[`src/store/hey.ts`]: https://github.com/blockstack/heystack/blob/main/src/store/hey.ts
[`src/components/user-area.tsx`]: https://github.com/blockstack/heystack/blob/22e4e9020f8bbb404e8c1e36f32f000050f90818/src/components/user-area.tsx#L62
[separation of concerns]: https://en.wikipedia.org/wiki/Separation_of_concerns

6
src/pages/build-apps/guides/authentication.md

@ -98,7 +98,7 @@ function authenticate() {
icon: window.location.origin + '/my-app-logo.svg',
},
redirectTo: '/',
finished: () => {
onFinish: () => {
let userData = userSession.loadUserData();
// Save or otherwise utilize userData post-authentication
},
@ -114,7 +114,7 @@ function authenticate() {
The `showConnect` function accepts a number of properties within a parameter object such as:
- The app's `name` and `icon`: provided as strings comprising the `appDetails` object property.
- The `redirectTo` string: used to provide a URL to which the user should be redirected upon successful authentication. The `finished` callback serves a similar purpose by handling successful authentication within a context of a popup window.
- The `redirectTo` string: used to provide a URL to which the user should be redirected upon successful authentication. The `onFinish` callback serves a similar purpose by handling successful authentication within a context of a popup window.
- The `userSession` object initiated above.
Once the user selects the button presented in this modal, they are passed to the Stacks Wallet for authenticator with the `authRequest` token as a GET parameter. From there they can confirm authentication and generate a new _Secret Key_ or Stacks identity before doing so, as needed before coming back to the app.
@ -150,7 +150,7 @@ The authenticated state can later be detected by the `isUserSignedIn` method in
If the user has indeed confirmed authentication in the context of a popup window, the authenticator will resolve the pending authentication state automatically with the app within the parent window.
It will then trigger the `finished` function provided above, which can be used similarly to save the user's information into their session as retrieved with `userSession.loadUserData()`.
It will then trigger the `onFinish` function provided above, which can be used similarly to save the user's information into their session as retrieved with `userSession.loadUserData()`.
## Usage in React Apps

0
src/pages/understand-stacks/integrate-stacking-delegation.md → src/pages/build-apps/guides/integrate-stacking-delegation.md

0
src/pages/understand-stacks/integrate-stacking.md → src/pages/build-apps/guides/integrate-stacking.md

0
src/pages/ecosystem/contributing.md → src/pages/contributing.md

21
src/pages/ecosystem/address-confirmation.md

@ -1,21 +0,0 @@
---
title: Confirm your address
description: Learn how to confirm a Stacks address
---
## Introduction
We recommend that you confirm your address is correct by going through the following steps in the Stacks Wallet:
If you created a software wallet, using the "New Wallet" option, choose "Restore from Seed Phrase" when you start the Stacks Wallet application, then enter your Seed Phrase, and click "Restore." The address that you see on the next screen should match the address you created earlier.
## For Hardware Wallets:
If you used a hardware wallet originally, you can go through the same process again (clicking "Use a Hardware Wallet" when you first start the Stacks Wallet application), and your hardware wallet should produce the same address every time. If you used a "passphrase" make sure that you use the correct passphrase when checking your wallet address; using a different passphrase will result in generating a different address. (For more information on using passphrases with Trezor, see this page and for information with Ledger, see this page)
Make sure to store your hardware wallet's seed phrase (sometimes referred to as a "Recovery Phrase" or "Recovery Seed") in the correct order safely. We recommend in at least two locations. If you used a passphrase, you should store that as well.
## For Multi-Sig Wallets:
If you used a multi-signature wallet (for advanced users), you will need to re-enter your public keys to check your address (by clicking "Create Multi-signature Wallet").
The order that you enter the public keys into the multi-sig wallet is important. If you do not remember the order in which you entered your public keys, please contact hello@StacksToken.com.

71
src/pages/ecosystem/overview.md

@ -1,71 +0,0 @@
---
description: Learn about Stacks and decentralization
icon: BlockstackIcon
images:
large: /images/pages/ecosystem.svg
sm: /images/pages/ecosystem.svg
---
# Overview of Stacks
Stacks is a full-stack decentralized computing network that enables a new generation of applications where developers and users can interact fairly and securely. Stacks uses blockchain technology to build protocols and developer tools designed to enable a fair and open Internet that returns digital rights to developers and consumers.
## What is the Stacks Ecosystem?
The Stacks Ecosystem is the legal entities and community structures that support the Stacks technology, the apps that rely on it, and the people that work with it. The ecosystem’s mission is to foster an open and decentralized Internet that establishes and protects privacy, security and freedom for all users.
The documentation on this site focuses on the technologies produced by three entities in the ecosystem.
### Blockstack Public Benefit Corp (PBC)
Blockstack Public Benefit Corp. (PBC) started development of the Stacks
platform in 2014 and launched an alpha of the platform in early 2017. The
platform’s development philosophy followed two simple principles. First, create
backend facilities that allow blockchain applications to be both performant and
scalable. Second, provide simple, familiar development interfaces to blockchain
technology. The result of this effort is a technology platform that allows
developers to:
- Build a blockchain application in any JavaScript framework. The platform does not require learning a new programming language or extending an existing application stack.
- Use well-defined REST endpoints that simplify and encapsulate the blockchain backend. The Stacks JavaScript API reduces blockchain-backed applications to familiar `GET` and `PUT` operations.
- Access the Blockstack’s Naming System (BNS). The system has over 70K users that can immediately start using your application.
- Scale quickly to large, performant production systems. Stacks’s Gaia storage system gives fast, scalable performance on a level comparable to Amazon S3, Google Drive, or Azure.
Using Stacks’s technology developers can start building immediately on the
blockchain with the knowledge you have today. You won’t need to spend time or
effort developing expertise in specialized languages or technologies.
### Blockstack Token LLC
Through the 2017 Blockstack token offering, Blockstack Token LLC created the
Stacks token. This year's hard fork is an especially exciting milestone for the ecosystem because it distributes the first Stacks tokens to existing purchasers and recipients. This hard fork launches the Stacks blockchain v1, and enables the following two features for the Blockstack network:
- Registration of all digital assets and smart contracts for registering digital assets with the Stacks token.
- A genesis block that distributes Stacks tokens to existing purchasers.
A full technical description of the upgrade is available on [the Blockstack forum](https://forum.blockstack.org/t/blockstack-annual-hard-fork-2018/6518).
In future upgrades and hard forks, the blockchain will expand to introduce a new
scalable consensus algorithm to increase the number of transactions it can
process. This consensus algorithm is planned to be introduced in additional
hard forks in 2019.
Additionally, a future Stacks blockchain will support truly decentralized mobile
applications by removing the need to trust a remote Stacks Node.
Instead, it will be possible for light clients to calculate the economic weight
of different Stacks blockchain forks, and identify the fork with the most
economic activity. Today, light clients rely on other trusted sources for fork
selection and cannot make that decision independently. For mobile apps this
enables functionality like looking up names without having to rely on a remote
Stacks Node.
Finally, Blockstack currently supports relatively simple smart contracts that
are used to register digital assets on the network. The Stacks blockchain v2
will support general-purpose smart contracts written in a non-Turing-complete
language currently under development.
~> This communication contains forward-looking statements that are based on our beliefs and assumptions and on information currently available to us. In some cases, you can identify forward-looking statements by the following words: "will," "expect," "would," "intend," "believe," or other comparable terminology. Forward-looking statements in this document include, but are not limited to, statements about our plans for developing the platform and future utility for the Stacks Token, our Clarity smart contracting language, and potential mining operations. These statements involve risks, uncertainties, assumptions and other factors that may cause actual results or performance to be materially different. More information on the factors, risks and uncertainties that could cause or contribute to such differences is included in our filings with the SEC, including in the "Risk Factors" and "Management’s Discussion & Analysis" sections of our offering statement on Form 1-A. We cannot assure you that the forward-looking statements will prove to be accurate. These forward-looking statements speak only as of the date hereof. We disclaim any obligation to update these forward-looking statements.

46
src/pages/ecosystem/stacks-token-holders.md

@ -1,46 +0,0 @@
---
title: Stacks token holders
description: Stacks token holder documentation
---
## Introduction
The information on this page is intended for **current Stacks (STX) token holders** during Blockstack’s token sale through early 2018.
## Find your token balance and unlock date
~> If you **purchased Stacks tokens during Summer 2019**, the form below will **not** work for your allocation. Please [check your allocation using this tool instead](https://explorer.blockstack.org/verifier).
During your the initial grant process, you should have submitted a public _Stacks (STX) address_ (also known as a _wallet address_) to Blockstack. A STX address is a string of letters and numbers starting with an `SP` or `SM`, for example: `SM3KJBA4RZ7Z20KD2HBXNSXVPCR1D3CRAV6Q05MKT`
If you purchased STX tokens through CoinList, you can find your address at
[CoinList](https://coinlist.co/distributions). If you submitted your Stacks
address directly to Blockstack, you can either use the **Restore from Seed
Phrase** feature on the Stacks Wallet or contact us at <hello@stackstoken.com> for
help.
You should see a report detailing the tokens allocated to your address and when they unlock:
![](/images/unlocking-address.png)
If you have questions or concerns about your report, please contact [hello@StacksToken.com](mailto:hello@StacksToken.com).
## Understanding the timeline for unlocking your tokens
In October 2018, the Stacks blockchain launched under the STX token. With the
launch, STX tokens unlock for accredited token holders under a predetermined
unlocking schedule. The events on the unlocking schedule are the same for each
token holder, the dates of these events depend on the holders’s purchase date.
The general timeline for unlocking tokens and the capabilities that are
potentially possible, are as follows:
![](/images/unlocking.png)
Your specific unlock date depends on when you purchased or were granted tokens.
You can use the Stacks Explorer to discover how many tokens you have
registered and when they will unlock.
## Have more questions?
For a list of frequent questions and answers about STX tokens, [see the Stacks token FAQs](/references/faqs).

55
src/pages/ecosystem/stacks-token.md

@ -1,55 +0,0 @@
---
title: Stacks token
description: Learn about the native token of Stacks
icon: StacksIcon
images:
large: /images/stx.svg
sm: /images/stx.svg
---
# Learn more about the Stacks token
Stacks is the name of a token developed by Blockstack Token LLC in 2017 and
activated in the third quarter of 2018. This page discusses a brief history of
the Stacks token and deployment on the Stacks network as well as the current
role of the Stacks token.
If you are a developer interested in the specific technical changes related to
the 2018 launch, see the [announcement in the Blockstack forum](https://forum.blockstack.org/t/blockstack-annual-hard-fork-2018/6518).
## A brief history of the Stacks token
In 2017 Blockstack PBC did a token sale. Participants became token holders when they
received allocations of Stacks tokens in the genesis block. A genesis block is
the first block of a blockchain.
During the draft genesis block period token holders setup a seed phrase
(sometimes referred to as a _recovery phrase_ or a _recovery seed_ using the
Stacks Wallet software or their own hardware wallet.
It was each token holder’s responsibility to store their own seed phrase in a
private and secure location. Holders could use their wallet to verify their
holdings and allocations on the genesis block explorer. Beyond that, while in
draft state, token holders were in a lock down period.
## State of the Stacks blockchain V1
The initial block in the Stacks blockchain V1 allocates 1.32 billion
tokens. The launch is the culmination of two year’s hard work across the greater
Stacks community. With the launch, Stacks tokens unlock for accredited token
holders under a predetermined unlocking schedule. The events on the unlocking
schedule are the same for each investor, **the dates of these events** depend on the
holder's purchase date.
-> **Note:** If you are a token holder and would like to review your unlocking schedule, visit the [For current token holders](/references/faqs) page in this documentation.
The genesis block launch makes possible the following interactions:
- Token holders can purchase names and namespaces with the Stacks token. Previously, names and namespaces required the purchaser to hold Bitcoin. Initially, this process relies on the Blockstack command-line interface (CLI).
- Application developers can earn Stacks by building an application on the Stacks ecosystem.
- Any Stacks tokens held at the time of launch or after remain usable under the Stacks Blockchain platform.
Finally, in addition to the development of Stacks token, this launch enables
further development of Stacks Blockchain itself.

2
src/pages/storage-hubs/amazon-ec2-deploy.md

@ -41,7 +41,7 @@ it runs on.
3. Click **Next**.
4. Specify configuration details for your Gaia hub:
i. Enter the **Stack name**. This name must be unique within your AWS account.
i. Enter the **Stack name**. This name must be lowercase and unique within your AWS account.
![CloudFormation stack name](/images/cloudformation-stack-name.png)

2
src/pages/understand-stacks/command-line-interface.md

@ -1,5 +1,5 @@
---
title: Understanding the Stacks CLI
title: Stacks CLI
description: Learn more about the Stacks CLI capabilities
---

100
src/pages/understand-stacks/microblocks.md

@ -0,0 +1,100 @@
---
title: Microblocks
description: Guide to Stacks Microblocks
icon: TestnetIcon
images:
large: /images/pages/testnet.svg
sm: /images/pages/testnet-sm.svg
---
## Introduction
Microblocks are a protocol-level feature of the Stacks blockchain that solve the technical challenge of transaction
latency. Because each Stacks block is anchored to a Bitcoin block through the [Proof-of-Transfer consensus mechanism][],
Stacks is necessarily limited to the same block times as the Bitcoin network. Microblocks allow the Stacks blockchain to
perform state transitions with a high degree of confidence between final settlements against Bitcoin.
Microblocks are a powerful mechanism for developers to create performant, high quality applications on Stacks, while
still inheriting the security of Bitcoin.
## Transaction states
The [Stacks block production model][] is described in SIP-001. The standard outlines the mechanism by which elected
block leaders can produce blocks on the Stacks blockchain either by batching transactions or by streaming them.
Microblocks are the product of the streaming model.
If a block leader has elected to mine microblocks, the leader selects transactions from the mempool and package them
into microblocks during the current epoch. Transactions included in microblocks don't achieve finality until they've
been confirmed by an anchor block, but can be assumed to be highly likely to achieve finality in the order in which the leader
packaged them.
In most blockchains, transactions can be re-ordered and chain history can be re-written with support from enough miners.
This allows a blockchain to recover from certain types of attacks, as miners can collectively agree to rewrite history
and omit malicious blocks. As more blocks are added on top of a block that includes a transaction, the likelihood of a
transaction being reordered decreases. For example, many exchanges wait until at least 3 Bitcoin blocks have been added
to report a transaction as fully confirmed (3 block confirmation). Microblocks provide between 0 block and 1 block
confirmation.
-> If a transaction is dependent on a chain state that could by altered by previous transactions with serious
implications, you should carefully consider whether it should be performed using microblocks.
## Enabling microblocks
Miners can choose to enable or disable microblocks in their mining configuration. As a best practice, miners should enable
microblock mining. When an application or user submits a transaction, the transaction can include an argument that
requires the transaction to be in a microblock, an anchor block, or in either.
### Transactions
Transactions include an option that controls if a miner should include them in microblocks or in anchor blocks. The
[anchor mode][] transaction option is an optional argument that controls whether a transaction must be included in
an anchor block or a microblock, or is eligible for either.
### Mining
Stacks miners must enable microblocks in their miner configuration to implement the block streaming model. For more
information, see [mining microblocks][].
## Developing with microblocks
Stacks allows you to choose how any transaction should be included on the blockchain by the miners. This flexibility
means you can submit transactions that require low latency processing for inclusion in microblocks, and require that
highly order-dependent transactions wait for anchor block finality.
### Stacks.js libraries
Stacks.js provides the [AnchorMode][] argument on transaction objects so that your application can set the microblocks
preference for transactions.
### API
!> API support for microblocks is a work-in-progress. Review the [API documentation][microblocks_api] carefully to
ensure that you are up-to-date on the latest implementation details for microblocks.
The Stacks Blockchain API exposes microblocks through several endpoints. Please review the
[Stacks Blockchain API guide][] for more details.
## Best practices
Working with microblocks is a design decision that you must make for your own application. When working with
microblocks, the following best practices are recommended.
### Handling nonce
Nonce handling with microblocks is challenging because the next account nonce must take into account any nonce values
included in microblocks, which may not yet be included in an anchor block. The Stacks Blockchain API
[provides an endpoint][] to retrieve the next nonce for a given principal.
### Application design
The state of microblock transactions should be carefully communicated to users. No transaction is final until it's
included in an anchor block, and your application design should reflect this.
[proof-of-transfer consensus mechanism]: /understand-stacks/proof-of-transfer
[stacks block production model]: https://github.com/stacksgov/sips/blob/main/sips/sip-001/sip-001-burn-election.md#operation-as-a-leader
[mining microblocks]: /understand-stacks/mining#microblocks
[anchor mode]: /understand-stacks/transactions#anchor-mode
[anchormode]: https://stacks-js-git-master-blockstack.vercel.app/enums/transactions.anchormode.html
[stacks blockchain api guide]: /understand-stacks/stacks-blockchain-api#microblocks-support
[provides an endpoint]: /stacks-blockchain-api#nonce-handling
[microblocks_api]: https://stacks-blockchain-api-git-feat-microblocks-blockstack.vercel.app/#tag/Microblocks

25
src/pages/understand-stacks/mining.md

@ -1,5 +1,5 @@
---
title: Understand Mining
title: Mining
description: A guide to mining on Stacks 2.0
icon: TestnetIcon
images:
@ -15,9 +15,9 @@ This guide highlights some technical details related to mining on the Stacks 2.0
A new Stacks block may be mined once per Bitcoin block. To be considered for mining a block, a miner must have a block commit included in a Bitcoin block. If a miner wishes to update their commitment after submission, they may use Bitcoin Replace-By-Fee.
## Coinbase Rewards
## Coinbase rewards
Miners receive coinbase rewards for blocks they mine.
Miners receive coinbase rewards for blocks they win.
The reward amounts are:
@ -38,11 +38,11 @@ For transactions mined in microblocks, the miner that produces the microblock re
## Reward maturity
Miner rewards, that is, block rewards and transaction fees take 100 blocks on the bitcon blockchain to mature. After successful mining a block your rewards will appear in the Stacks account after ~24 hours.
Block rewards and transaction fees take 100 blocks on the Bitcoin blockchain to mature. After successfully mining a block your rewards appear in your Stacks account after ~24 hours.
## Mining with Proof-of-Transfer
## Mining with proof-of-transfer
Miners commit Bitcoin to **two** addresses in every leader block commit. The amount committed to each address must be the same. The addresses are chosen from the current reward set of Stacking participants. The choice of addresses is done using a verifiable-random-function, and determining the correct two addresses for a given block requires monitoring the stacks chain.
Miners commit Bitcoin to **two** addresses in every leader block commit. The amount committed to each address must be the same. The addresses are chosen from the current reward set of stacking participants. Addresses are chosen using a verifiable-random-function, and determining the correct two addresses for a given block requires monitoring the Stacks chain.
![mining with pox](/images/pages/mining-with-pox.png)
@ -62,3 +62,16 @@ To calculate the amount of BTC to send miners should:
- Guess the price BTC/STX for the next day (100 blocks later)
- Guess the total amount of BTCs committed by all miners
## Microblocks
The Stacks blockchain produces blocks at the same rate as the Bitcoin blockchain. In order to provide lower latency
transactions, miners can opt to enable microblocks. Microblocks allow the current block leader to stream transactions
and include their state transitions in the current epoch.
If a block leader opts to produce microblocks, the next leader builds the chain tip off the last microblock that the
current leader produces.
The block streaming model is described in [SIP-001][].
[sip-001]: https://github.com/stacksgov/sips/blob/main/sips/sip-001/sip-001-burn-election.md#operation-as-a-leader

4
src/pages/understand-stacks/network.md

@ -48,12 +48,16 @@ Nonces are added to all transactions and help identify them in order to ensure t
When a new [token transfer transaction](/understand-stacks/transactions#stacks-token-transfer) is constructed, the most recent nonce of the account needs to fetched and set.
-> The API provides an endpoint to [simplify nonce handling](/understand-stacks/stacks-blockchain-api#nonce-handling).
## Confirmations
The Stacks 2.0 network is anchored onto the bitcoin network. This allows transactions on Stacks to inherit the same finality and security of the Bitcoin blockchain.
The time to mine a block, to confirm transactions, will eventually match the expected "block time" of the bitcoin network: 10 minutes.
-> Transactions can also be mined in [microblocks](/understand-stacks/microblocks), reducing the latency significantly.
The block time is hardcoded and will change throughout the implementation phases of the [testnet](/understand-stacks/testnet). The current block time can be obtained through the [`GET /extended/v1/info/network_block_times`](https://blockstack.github.io/stacks-blockchain-api/#operation/get_network_block_times) endpoint:
```bash

9
src/pages/understand-stacks/overview.md

@ -14,10 +14,13 @@ Smart contracts and apps developed on the Stacks platform are natively integrate
## Capabilities
Read more about the functionality provided by the Stacks 2.0 blockchain.
Read more about the features provided by the Stacks 2.0 blockchain.
-> Check out the [technical specifications](/understand-stacks/technical-specs) for a brief overview
A detailed [comparison of the Stacks blockchain to other blockchain technologies][] is available at the Stacks
Foundation blog.
### Consensus mechanism
Stacks 2.0 implements a new mining mechanism called Proof of Transfer ("PoX").
@ -82,7 +85,7 @@ Stacks 2.0 enabled building decentralized apps that are user-owned and avoid cen
Read one of our guides to understand the ins and outs of the Stacks 2.0 blockchain.
[@page-reference | grid-small]
| /understand-stacks/accounts, /understand-stacks/transactions, /understand-stacks/network
| /understand-stacks/accounts, /understand-stacks/transactions, /understand-stacks/network, /understand-stacks/microblocks
## Try it out
@ -100,3 +103,5 @@ Developing on the Stacks blockchain is much simpler with the our tooling.
- **API**: Read and interact with the blockchain and with smart contract using the [Stacks 2.0 Blockchain API](/understand-stacks/stacks-blockchain-api)
- **CLI**: Use the [Stacks CLI](/understand-stacks/command-line-interface) inside your terminal
- **Libraries**: Use the [Stacks Javascript libraries](https://blockstack.github.io/stacks.js/) to integrate with the Stacks blockchain
[comparison of the stacks blockchain to other blockchain technologies]: https://stacks.org/stacks-blockchain

35
src/pages/understand-stacks/proof-of-transfer.md

@ -9,28 +9,31 @@ images:
## Overview
Consensus algorithms for public blockchains require computing or financial resources to secure the blockchain. The idea being to make it practically infeasible for any single malicious actor to have enough computing power or ownership stake to attack the network.
Consensus algorithms for blockchains require compute or financial resources to secure the blockchain. The general practice of decentralized consensus is to make it practically infeasible for any single malicious actor to have enough computing power or ownership stake to attack the network.
Mining mechanisms used by these algorithms are broadly divided into proof-of-work, in which nodes dedicate computing resources, and proof-of-stake, in which nodes dedicate financial resources to participate in the [consensus algorithm](/understand-stacks/stacking#stacking-consensus-algorithm).
Popular consensus mechanisms in modern blockchains include proof-of-work, in which nodes dedicate computing resources, and proof-of-stake, in which nodes dedicate financial resources to secure the network.
A variant of proof-of-work is proof-of-burn where miners compete by ‘burning’ (destroying) a proof-of-work cryptocurrency as a proxy for computing resources.
Proof-of-burn is a novel consensus mechanism where miners compete by ‘burning’ (destroying) a proof-of-work cryptocurrency as a proxy for computing resources.
Proof-of-transfer (PoX) is a new mining mechanism, that generalizes the concept of proof-of-burn. PoX uses the proof-of-work cryptocurrency of an established blockchain to secure a new blockchain. However, unlike proof-of-burn rather than burning the cryptocurrency, miners transfer the committed cryptocurrency to some other participants in the network.
Proof-of-transfer (PoX) is an extension of the proof-of-burn mechanism. PoX uses the proof-of-work cryptocurrency of an established blockchain to secure a new blockchain. However, unlike proof-of-burn, rather than burning the cryptocurrency, miners transfer the committed cryptocurrency to some other participants in the network.
This allows network participants who are adding value to the new cryptocurrency network to earn a reward in a base cryptocurrency by actively participating in the consensus algorithm, PoX encourages a model where there is one extremely secure proof-of-work blockchain, say Bitcoin.
![PoX mechanism](/images/pox-mechanism.png)
Other new blockchains can be anchored on the secure proof-of-work blockchain instead of introducing new proof-of-work chains. PoX has an interesting property where participants can earn payouts in a separate, potentially more stable, base cryptocurrency while participating in the new blockchain network. This can help solve a bootstrapping problem for new blockchains by providing incentives for early participants. Further, PoX has a potential use case for funding ecosystem developer funds.
![proof-of-transfer](/images/proof-of-transfer.png)
This allows network participants to secure the PoX cryptocurrency network and earn a reward in the base cryptocurrency. Thus, proof-of-transfer blockchains are anchored on their chosen proof-of-work chain. Stacks uses [Bitcoin](#why-bitcoin) as its anchor chain.
![PoX participants](/images/pox-participants.png)
## Why Bitcoin?
There are a multitude of reasons that Stacks chose Bitcoin as the blockchain to power consensus. It is one of the oldest blockchain protocols having launched in 2009, and has benefited from all the industry learnings that have occurred since that time. It is far and away the most valuable blockchain network, and BTC has held the highest market cap of any cryptocurrency for the past decade.
There are a number of reasons that Stacks chose Bitcoin as the blockchain to power consensus. It's the oldest blockchain protocol, having launched in 2009, and has become a recognized asset outside of the cryptocurrency community. BTC has held the highest market capitalization of any cryptocurrency for the past decade.
Bitcoin champions simplicity and stability, and has stood the test of time. Influencing or attacking the network is infeasible or impractical for any potential hackers. It's one of the only cryptocurrencies to capture public attention. Bitcoin is a household name, and is recognized as an asset by governments, large corporations, and legacy banking institutions. Lastly, Bitcoin is largely considered a reliable store of value, and provides extensive infrastructure to support the proof-of-transfer consensus mechanism.
Bitcoin champions immutability, and has stood the test of time. It has been proven that influencing or attacking the network would be infeasible or impractical for any potential hackers. It is one of the only cryptocurrencies to bridge the mainstream chasm and gain immense public attention. Bitcoin is now a household name, and is being recognized by governments, large corporations, and legacy banking institutions. Lastly, Bitcoin has been cemented as a reliable store of value, and is the perfect infrastructure to plug into the proof-of-transfer consensus mechanism.
SIP-001 provides a full [list of reasons why Bitcoin was chosen to secure Stacks](https://github.com/stacksgov/sips/blob/main/sips/sip-001/sip-001-burn-election.md).
![btc-stacks](/images/btc-stacks.png)
![btc-stacks](/images/pox-why-bitcoin.png)
## Blocks and Microblocks
## Blocks and microblocks
The Stacks blockchain allows for increased transaction throughput using a mechanism called microblocks. Bitcoin and Stacks progress in lockstep, and their blocks are confirmed simultaneously. On Stacks, this is referred to as an ‘anchor block’. An entire block of Stacks transactions corresponds to a single Bitcoin transaction. This significantly improves cost/byte ratio for processing Stacks transactions. Because of simultaneous block production, Bitcoin acts as a rate-limiter for creating Stacks blocks, thereby preventing denial-of-service attacks on its peer network.
@ -38,15 +41,15 @@ However, in between Stacks anchor blocks settling on the Bitcoin blockchain, the
![stx-microblock](/images/stx-microblocks.png)
## Unlocking Bitcoin Capital
## Unlocking Bitcoin capital
Stacks also unlocks the over $1+ trillion in capital that exists in the Bitcoin ecosystem, and gives Bitcoiners new opportunities to use and earn BTC. Bitcoin invented the art of the “HODL”, and Bitcoiners are watching and waiting for interesting applications to be built that expand BTC’s usability. Stacks made the deliberate design decision to not create a totally independent network, and instead take advantage of the preexisting network effect of Bitcoin.
Stacks also unlocks the hundreds of billions in capital in Bitcoin, and gives Bitcoiners new opportunities to use and earn BTC. Stacks is a accompaniment to the Bitcoin ecosystem, and the two networks working in tandem enables totally novel ways of using BTC. The Stacks ecosystem makes interactive cryptocurrency applications available to Bitcoin holders. Additionally, By stacking STX tokens and participating in the PoX consensus mechanism, users have the opportunity to earn BTC while securing the Stacks chain.
In this way, Stacks is an accessible accompaniment to the Bitcoin ecosystem, and the two networks working in tandem enables totally novel ways of using BTC. The dApp and DeFi ecosystem burgeoning on Stacks will encourage less active BTC addresses to begin experimenting with interactive applications of cryptocurrency. By locking up STX on the network and participating in the Stacking mechanism, users have the opportunity to earn a familiar, native currency like BTC while also enriching the Stacks protocol.
![Unlocking Bitcoin](/images/pox-unlocking-btc.png)
## Clarity and the Bitcoin State
## Clarity and the Bitcoin state
Clarity smart contracts also have unique visibility into the state of the Bitcoin blockchain. This means that contract logic in a Clarity file has the ability to trigger when specific Bitcoin transactions have been confirmed. Clarity smart contracts have a built in Simple Payment Verification (SPV) proofs for Bitcoin that make interacting with Bitcoin’s state much simpler for developers. Additionally, Clarity contracts will potentially fork with the original Bitcoin chain. Therefore, in an edge case where Bitcoin forks, developers wouldn’t have to worry about adjusting the deployment of their smart contracts.
Clarity smart contracts also have unique visibility into the state of the Bitcoin blockchain. This means that contract logic in a Clarity file has the ability to trigger when specific Bitcoin transactions are confirmed. Clarity smart contracts have a built in Simple Payment Verification (SPV) proofs for Bitcoin that make interacting with Bitcoin’s state much simpler for developers. Additionally, Clarity contracts can fork with the original Bitcoin chain. Therefore, in an edge case where Bitcoin forks, developers wouldn’t have to worry about adjusting the deployment of their smart contracts.
## See also

2
src/pages/understand-stacks/sending-tokens.md

@ -63,7 +63,7 @@ const {
const {
StacksTestnet,
StacksMainnet,
} = require ('@stacks/network);
} = require ('@stacks/network');
const { TransactionsApi, Configuration } = require('@stacks/blockchain-api-client');
const apiConfig = new Configuration({

67
src/pages/understand-stacks/stacking.md

@ -1,5 +1,5 @@
---
title: Understand Stacking
title: Stacking
description: Introduction to the reward mechanism of Proof-of-Transfer
images:
sm: /images/pages/stacking-rounded.svg
@ -17,12 +17,12 @@ Stacking is a built-in action, required by the "proof-of-transfer" (PoX) mechani
The Stacking mechanism can be presented as a flow of actions:
![stacking flow](/images/stacking-illustration.png)
![Stacking flow](/images/stacking-illustration.png)
1. Make API calls to get details about the upcoming reward cycle
2. For a specific Stacks account, confirm eligibility
3. Confirm the BTC reward address and the lockup duration
4. The transaction is broadcasted and the Stacks (STX) tokens will be locked-up. This needs to happen before the prepare phase of the next reward cycle (last 100 bitcoin blocks of the ongoing reward phase)
4. The transaction is broadcasted and the STX tokens are locked. This needs to happen before the prepare phase of the next reward cycle, the last 100 Bitcoin blocks of the ongoing reward phase
5. The Stacking mechanism executes reward cycles and sends out rewards to the set BTC reward address
6. During the lockup period, details about unlocking timing, rewards and more can be obtained
7. Once the lockup period is passed, the tokens are released and accessible again
@ -42,12 +42,12 @@ If you would like to implement this flow in your own wallet, exchange, or any ot
The Stacking flow is different for delegation use cases:
![stacking flow](/images/stacking-delegation-illustration.png)
![Delegated tacking flow](/images/stacking-delegation-illustration.png)
- Before Stacking can be initiated for a token holder, the delegator needs to be granted permission to Stack on behalf of the account owner. The permission is restricted to the maximum amount the delegator is allowed to Stack. The maximum amount is not limited by the available funds and can be set much higher. An account can only be associated with one single delegator
- The account has to define the delegation relationship. They can optionally restrict the Bitcoin reward address that must be used for payouts, and the expiration burn block height for the permission, thus limiting the time a delegator has permission to Stack
- Delegators have to lock Stacks from different accounts ("pooling phase") until they reach the minimum amount of Stacks required to participate in Stacking
- Once a delegator locks enough STX tokens, they can finalize and commit their participation in the next reward cycle(s)
- Once a delegator locks enough STX tokens, they can finalize and commit their participation in the next reward cycle
- Certain delegation relationships may allow the STX holder to receive the payout directly from the miner (step 5/6)
- The termination of the delegation relationship can either happen automatically based on set expiration rules or by actively revoking delegation rights
@ -58,42 +58,51 @@ If you would like to implement this flow in your own wallet, exchange, or any ot
## PoX mining
PoX mining is a modification of Proof-of-Burn (PoB) mining, where instead of destroying the committed Bitcoin, it is transferred to eligible Stacks (STX) holders that participate in the Stacking protocol.
PoX mining is a modification of Proof-of-Burn (PoB) mining, where instead of sending the committed Bitcoin to a burn address, it's transferred to eligible STX holders that participate in the stacking protocol.
-> A PoX miner can only receive newly minted Stacks (STX) tokens when they transfer bitcoin to eligible owners of Stacks (STX) tokens
-> A PoX miner can only receive newly minted STX tokens when they transfer Bitcoin to eligible owners of STX tokens
Miners have to run a software (mining client, aka "miner") on their machines to participate in the PoX mechanism. The mining client implements the PoX mechanism, which ensures proper handling and incentives through four key phases:
![Mining flow](/images/pox-mining-flow.png)
- Registration: Miners register for a future election by sending consensus data to the network
- Commitment: Registered miners transfer bitcoin to participate in the election. Committed bitcoin are sent to a set eligible Stacks (STX) tokens holders
- Election: A verifiable random function chooses one miner to write a new block on the Stacks blockchain
- Assembly: The elected miner writes the new block and collects rewards in form of new Stacks (STX) tokens
Miners run Stacks nodes with mining enabled to participate in the PoX mechanism. The node implements the PoX mechanism, which ensures proper handling and incentives through four key phases:
- Registration: miners register for a future election by sending consensus data to the network
- Commitment: registered miners transfer Bitcoin to participate in the election. Committed BTC are sent to a set participating STX token holders
- Election: a verifiable random function chooses one miner to write a new block on the Stacks blockchain
- Assembly: the elected miner writes the new block and collects rewards in form of new STX tokens
[@page-reference | inline]
| /start-mining/mainnet, /start-mining/testnet
## Token holder eligibility
Stacks (STX) token holders do not automatically receive Stacking rewards. Instead, they must:
Stacks (STX) token holders don't automatically receive stacking rewards. Instead, they must:
- Commit to participation before a reward cycle begins
- At the time of writing: Hold ~70,000 Stacks (STX) tokens - or pool with others to reach the minimum
- Lock up Stacks (STX) tokens for a specified period
- Set a supported Bitcoin address to receive rewards (native segwit is not supported)
- Commit the minimum amount of STX tokens to secure a reward slot, or pool with others to reach the minimum
- Lock up STX tokens for a specified period
- Provide a supported Bitcoin address to receive rewards (native segwit is not supported)
The following diagram describes how the minimum STX tokens per slot is determined. More information on
[dynamic minimums for stacking](https://stacking.club) is available at stacking.club.
![Dynamic minimum for individual eligibility](/images/stacking-dynamic-minimum.png)
Token holders have a variety of providers and tools to support their participation in Stacking. The Stacks website contains a [list of stacking providers and pools](https://stacks.org/stacking#earn).
Token holders will have a variety of providers and tools to support their participation in Stacking. Current providers, including 1-click options, pools, and more can be found [here](https://stacks.org/stacking#earn).
## Stacking in the PoX consensus algorithm
## Stacking consensus algorithm
Stacking is a built-in capability of PoX and occurs through a set of actions on the Stacks blockchain. The [full proof-of-transfer implementation details](https://github.com/blockstack/stacks-blockchain/blob/develop/sip/sip-007-stacking-consensus.md) are in SIP-007. Below is a summary of the most relevant actions of the algorithm.
Stacking is a built-in capability of PoX and is realized through a set of actions on the Stacks 2.0 network. The full implementation details can be found in [SIP-007](https://github.com/blockstack/stacks-blockchain/blob/develop/sip/sip-007-stacking-consensus.md). Below is a summary of the most relevant actions of the algorithm.
![PoX cycles](/images/pox-cycles.png)
- Progression in Stacking consensus happens over reward cycles (with a fixed length). In each reward cycle, a set of Bitcoin addresses are iterated over
- Stacking happens over reward cycles with a fixed length. In each reward cycle, a set of Bitcoin addresses associated with stacking participants receive BTC rewards
- A reward cycle consists of two phases: prepare and reward
- During the prepare phase, miners decide on an anchor block and a reward set. Mining any descendant forks of the anchor block requires transferring mining funds to the appropriate reward addresses. The reward set is the set of Bitcoin addresses which will receive funds in the reward cycle
- Miners register as leader candidates for a future election by sending a key transaction that burns cryptocurrency (proof-of-burn). The transaction also registers the leader's preferred chain tip (must be a descendant of the anchor block) and commitment of funds to 2 addresses from the reward set
- Token holders register for the next rewards cycle by broadcasting a signed message that locks up associated Stacks (STX) tokens for a protocol-specified lockup period, specifies a Bitcoin address to receive the funds, and votes on a Stacks chain tip
- During the prepare phase, miners decide on an anchor block and a reward set. Mining any descendant forks of the anchor block requires transferring mining funds to the appropriate reward addresses. The reward set is the set of Bitcoin addresses which are eligible to receive funds in the reward cycle
- Miners register as leader candidates for a future election by sending a key transaction that burns cryptocurrency. The transaction also registers the leader's preferred chain tip (must be a descendant of the anchor block) and commitment of funds to 2 addresses from the reward set
- Token holders register for the next rewards cycle by broadcasting a signed message that locks up associated STX tokens for a protocol-specified lockup period, specifies a Bitcoin address to receive the funds, and votes on a Stacks chain tip
- Multiple leaders can commit to the same chain tip. The leader that wins the election and the peers who also burn for that leader collectively share the reward, proportional to how much each one burned
- Token holders' locked up tokens automatically unlock as soon as the lockup period is completed
- Token holders' locked up tokens automatically unlock as soon as the lockup period finishes
## Stacking contract
@ -101,9 +110,9 @@ Check out the [Stacking contract reference](/references/stacking-contract) to se
## Bitcoin address
!> You must provide a BTC address in one of two formats: [Legacy (P2PKH)](https://en.bitcoin.it/wiki/Transaction#Pay-to-PubkeyHash), which starts with "1". Or, [Segregated Witness / Segwit (P2SH)](https://en.bitcoin.it/wiki/Pay_to_script_hash), which starts with "3". The "Native Segwit" format (which starts with "bc1"), for example, is not supported.
!> You must provide a BTC address in one of two formats: [Legacy (P2PKH)](https://en.bitcoin.it/wiki/Transaction#Pay-to-PubkeyHash), which starts with `1`. Or, [Segregated Witness / Segwit (P2SH)](https://en.bitcoin.it/wiki/Pay_to_script_hash), which starts with `3`. The "Native Segwit" format (which starts with "bc1"), for example, is not supported.
The Stacking contract needs a special format for the bitcoin address (the reward address). This is required in order to ensure that miners will be able to correctly construct the bitcoin transaction containing the reward address.
The Stacking contract needs a special format for the Bitcoin address (the reward address). This is required to ensure that miners are able to correctly construct the Bitcoin transaction containing the reward address.
The address must be specified in the following format using the Clarity language:
@ -115,10 +124,10 @@ The address must be specified in the following format using the Clarity language
The `version` buffer must represent what kind of bitcoin address is being submitted. It can be one of the following:
```js
SerializeP2PKH = 0x00, // hash160(public-key), same as bitcoin's p2pkh
SerializeP2SH = 0x01, // hash160(multisig-redeem-script), same as bitcoin's multisig p2sh
SerializeP2PKH = 0x00, // hash160(public-key), same as bitcoin's p2pkh
SerializeP2SH = 0x01, // hash160(multisig-redeem-script), same as bitcoin's multisig p2sh
SerializeP2WPKH = 0x02, // hash160(segwit-program-00(p2pkh)), same as bitcoin's p2sh-p2wpkh
SerializeP2WSH = 0x03, // hash160(segwit-program-00(public-keys)), same as bitcoin's p2sh-p2wsh
SerializeP2WSH = 0x03, // hash160(segwit-program-00(public-keys)), same as bitcoin's p2sh-p2wsh
```
The `hashbytes` are the 20 hash bytes of the bitcoin address. You can obtain that from a bitcoin library, for instance using [`bitcoinjs-lib`](https://github.com/bitcoinjs/bitcoinjs-lib):

104
src/pages/understand-stacks/stacks-blockchain-api.md

@ -65,7 +65,7 @@ It is important to note that the JS client requires setting the underlying HTTP
```js
import fetch from 'cross-fetch';
import { Configuration AccountsApi } from '@stacks/blockchain-api-client';
import { Configuration, AccountsApi } from '@stacks/blockchain-api-client';
(async () => {
const apiConfig = new Configuration({
@ -83,7 +83,6 @@ import { Configuration AccountsApi } from '@stacks/blockchain-api-client';
});
console.log(txs);
})().catch(console.error);
```
@ -169,23 +168,31 @@ Here is a sample response:
"limit": 10,
"offset": 0,
"total": 101922,
"results": [
{
"tx_id": "0x5e9f3933e358df6a73fec0d47ce3e1062c20812c129f5294e6f37a8d27c051d9",
"tx_status": "success",
"tx_type": "coinbase",
"fee_rate": "0",
"sender_address": "ST3WCQ6S0DFT7YHF53M8JPKGDS1N1GSSR91677XF1",
"sponsored": false,
"post_condition_mode": "deny",
"block_hash": "0x58412b50266debd0c35b1a20348ad9c0f17e5525fb155a97033256c83c9e2491",
"block_height": 3231,
"burn_block_time": 1594230455,
"canonical": true,
"tx_index": 0,
"coinbase_payload": {
"data": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
"results": [{
"tx_id": "0x924e0a688664851f5f96b437fabaec19b7542cfcaaf92a97eae43384cacd83d0",
"nonce": 308,
"fee_rate": "0",
"sender_address": "ST39F7SA0AKH7RB363W3NE2DTHD3P32ZHNX2KE7J9",
"sponsored": false,
"post_condition_mode": "deny",
"post_conditions": [],
"anchor_mode": "on_chain_only",
"block_hash": "0x17ceb3da5f36aab351d6b14f5aa77f85bb6b800b954b2f24c564579f80116d99",
"parent_block_hash": "0xe0d1e8d216a77526ae2ce40294fc77038798a179a6532bb8980d3c2183f58de6",
"block_height": 14461,
"burn_block_time": 1622875042,
"burn_block_time_iso": "2021-06-05T06:37:22.000Z",
"canonical": true,
"tx_index": 0,
"tx_status": "success",
"tx_result": { ... },
"microblock_hash": "",
"microblock_sequence": 2147483647,
"microblock_canonical": true,
"event_count": 0,
"events": [],
"tx_type": "coinbase",
"coinbase_payload": { ... }
},
{ ... }
]
@ -290,6 +297,63 @@ This API supports [v1.4.6 of the Rosetta specification](https://www.rosetta-api.
-> Find all Data and Construction Rosetta endpoints [here](https://blockstack.github.io/stacks-blockchain-api/#tag/Rosetta)
## Microblocks support
!> API support for microblocks is a work-in-progress. Review the [API documentation][microblocks_api] carefully to
ensure that you are up-to-date on the latest implementation details for microblocks.
The API allows querying the most recently streamed microblocks:
```bash
# for mainnet, remove `.testnet`
curl 'https://stacks-node-api-microblocks.testnet.stacks.co/extended/v1/microblock'
```
```json
{
"limit": 20,
"offset": 0,
"total": 8766,
"results": [
{
"canonical": true,
"microblock_canonical": true,
"microblock_hash": "0xe6897aab881208185e3fb6ba58d9d9e35c43c68f13fbb892b20cebd39ac69567",
"microblock_sequence": 0,
"microblock_parent_hash": "0xe0d1e8d216a77526ae2ce40294fc77038798a179a6532bb8980d3c2183f58de6",
"parent_index_block_hash": "0x178cd9a37bf38f6b85d9f18e65588e60782753b1463ae080fb9865938b0898ea",
"block_height": 14461,
"parent_block_height": 14460,
"parent_block_hash": "0xe0d1e8d216a77526ae2ce40294fc77038798a179a6532bb8980d3c2183f58de6",
"block_hash": "0x17ceb3da5f36aab351d6b14f5aa77f85bb6b800b954b2f24c564579f80116d99",
"txs": ["0x0622e096dec7e2f6e8f7d95f732e04d238b7381aea8d0aecffae026c53e73e05"]
}
]
}
```
## Nonce handling
In order to prevent stuck transactions, you must track the next available nonce for principals issuing transactions. The
API provides an endpoint to make nonce handling simpler:
```bash
# for mainnet, remove `.testnet`
# replace <principal> with your STX address
curl 'https://stacks-node-api-microblocks.testnet.stacks.co/extended/v1/address/<principal>/nonces'
```
```json
{
"last_executed_tx_nonce": 5893,
"last_mempool_tx_nonce": null,
"possible_next_nonce": 5894,
"detected_missing_nonces": []
}
```
You can use the `possible_next_nonce` property as the nonce for your next transaction.
## Running an API server
While Hiro provides a hosted API server of the Stacks Blockchain API, anyone can spin up their own version. Please follow the instructions in this guide to start a Docker container with the API service running:
@ -298,3 +362,5 @@ While Hiro provides a hosted API server of the Stacks Blockchain API, anyone can
| /understand-stacks/local-development
-> Once started, the API will be available on `localhost:3999`
[microblocks_api]: https://stacks-blockchain-api-git-feat-microblocks-blockstack.vercel.app/#tag/Microblocks

1
src/pages/understand-stacks/technical-specs.md

@ -61,6 +61,7 @@ description: Summary of technical specifications of Stacks 2.0
1. _originating account_ is the account that creates, _authorizes_ and sends the transaction
2. _paying account_ is the account that is billed by the leader for the cost of validating and executing the transaction
3. _sending account_ is the account that identifies who is currently executing the transaction: this can change as a transaction executes via the `as-contract` Clarity function
- Transactions can be batched or streamed into blocks. The behavior can be controlled by the anchor mode of a transaction. With streaming ([microblocks](/understand-stacks/microblocks)), a faster confirmation time is possible.
- Two types of authorizations: standard authorization is where originating account is the same as paying account. _Sponsored_ authorization is where originating account and paying account are distinct. For instance, developers or service providers could pay for users to call their smart-contracts.
- For sponsored authorization, first a user signs with the originating account and then a sponsor signs with the paying account.
- Mempool limit for concurrent pending transactions is 25 per account

80
src/pages/understand-stacks/transactions.md

@ -51,6 +51,36 @@ A sample of each transaction type can be found in the [Stacks Blockchain API res
~> Read-only contract call calls do **not** require transactions. Read more about it in the [network guide](/understand-stacks/network#read-only-function-calls).
## Anchor mode
Transactions can be mined either in an anchor block or in a [microblock](/understand-stacks/microblocks). If microblocks
are selected, the transaction can be confirmed with a lower latency than the anchor block time.
The anchor mode enum has three options:
- `OnChainOnly` The transaction MUST be included in an anchored block
- `OffChainOnly`: The transaction MUST be included in a microblock
- `Any`: The leader can choose where to include the transaction
Here is an example where the transaction must be included in a microblock:
```js
import { AnchorMode, makeSTXTokenTransfer } from '@stacks/transactions';
import { StacksTestnet, StacksMainnet } from '@stacks/network';
const BigNum = require('bn.js');
const txOptions = {
recipient: 'SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159',
amount: new BigNum(12345),
senderKey: 'b244296d5907de9864c0b0d51f98a13c52890be0404e83f273144cd5b9960eed01',
network: new StacksTestnet(), // for mainnet, use `StacksMainnet()`
anchorMode: AnchorMode.OffChainOnly, // must be included in a microblock
};
const transaction = await makeSTXTokenTransfer(txOptions);
```
## Post-conditions
Transaction post-conditions are a feature meant to limit the damage malicious smart contract developers and smart contract bugs can do in terms of destroying a user's assets. Post-conditions are executed whenever a contract is instantiated or a public method of an existing contract is executed. Whenever a post-condition fails, a transaction will be forced to abort.
@ -304,35 +334,37 @@ When called the Stacks Blockchain API or Node RPC API, transactions returned wil
```js
{
"tx_id": "0x19e25515652dad41ef675bd0670964e3d537b80ec19cf6ca6f1dd65d5bc642c6",
"tx_status": "success",
"tx_type": "token_transfer",
"tx_id": "0x77cb1bf0804f09ad24b4c494a6c00d5b10bb0afbb94a0d646fa9640eff338e37",
"nonce": 5893,
"fee_rate": "180",
"sender_address": "STJTXEJPJPPVDNA9B052NSRRBGQCFNKVS178VGH1",
"sender_address": "STB44HYPYAT2BB2QE513NSP81HTMYWBJP02HPGK6",
"sponsored": false,
"post_condition_mode": "deny",
"block_hash": "0x9080f6df3e0be0d6de67569330e547346a44c8ecd30d9d76b5edd1b49e2c22f6",
"block_height": 3190,
"burn_block_time": 1594227992,
"post_conditions": [],
"anchor_mode": "any",
"block_hash": "0xf1e54a3acd04232f1362c09d5096b095363158348303396ea5fc5092e1d8788f",
"parent_block_hash": "0x3de356eb5afa5d7b781f6a925d31d69d218b772ec995930b4e15d92bd15443f9",
"block_height": 13984,
"burn_block_time": 1622678407,
"burn_block_time_iso": "2021-06-03T00:00:07.000Z",
"canonical": true,
"tx_index": 1,
"token_transfer": {
"recipient_address": "ST1RZG804V6Y0N4XHQD3ZE2GE3XSCV3VHRKMA3GB0",
"amount": "10000",
"memo": "0x00000000000000000000000000000000000000000000000000000000000000000000"
"tx_index": 2,
"tx_status": "success",
"tx_result": {
"hex": "0x0703",
"repr": "(ok true)"
},
"events": [
{
"event_index": 0,
"event_type": "stx_asset",
"asset": {
"asset_event_type": "transfer",
"sender": "STJTXEJPJPPVDNA9B052NSRRBGQCFNKVS178VGH1",
"recipient": "ST1RZG804V6Y0N4XHQD3ZE2GE3XSCV3VHRKMA3GB0",
"amount": "10000"
}
}
]
"microblock_hash": "",
"microblock_sequence": 2147483647,
"microblock_canonical": true,
"event_count": 1,
"events": [],
"tx_type": "token_transfer",
"token_transfer": {
"recipient_address": "STZ4C5RT4WH4JGRQA5E0ZF5PPSQCVY1WRB6E2CGW",
"amount": "500000000",
"memo": "0x46617563657400000000000000000000000000000000000000000000000000000000"
}
}
```

300
src/pages/write-smart-contracts/billboard-tutorial.md

@ -0,0 +1,300 @@
---
title: Billboard
description: Learn how to store data on-chain and transfer STX tokens with Clarity
duration: 30 minutes
experience: intermediate
tags:
- tutorial
images:
large: /images/pages/billboard.svg
---
## Introduction
This tutorial demonstrates how to transfer STX tokens and handle errors in Clarity by building a simple on-chain message
store. Additionally, this tutorial provides a simple overview of testing a smart contract. This tutorial builds on
concepts introduced in the [counter tutorial][], and uses [Clarinet][] to develop and test the smart contract.
In this tutorial you will:
- Set up a development environment with Clarinet
- Define codes for error handling
- Add a data storage variable with functions to get and set the variable
- Add a STX transfer function within the variable setter
- Develop a unit test to verify the contract works as expected
The [final code for this tutorial][] is available in the Clarinet repository.
## Prerequisites
For this tutorial, you should have a local installation of [Clarinet][]. Refer to [Installing Clarinet][] for
instructions on how to set up your local environment. You should also have a text editor or IDE to edit the Clarity
smart contract.
For developing the unit test, it's recommended that you have an IDE with Typescript support, such as
[Visual Studio Code][].
If you are using Visual Studio Code, you may want to install the [Clarity Visual Studio Code plugin][].
## Step 1: set up the project
With Clarinet installed locally, open a new terminal window and create a new Clarinet project. Add a smart contract and
an empty test file to the project:
```sh
clarinet new billboard-clarity && cd billboard-clarity
clarinet contract new billboard
```
These commands create the necessary project structure and contracts for completing this tutorial. Remember that at
any point during this tutorial you can use `clarinet check` to check the validity of your Clarity syntax.
## Step 2: create message storage
Open the `contracts/billboard.clar` file in a text editor or IDE. For this tutorial, you'll use the boilerplate comments
to structure your contract for easy readability.
In this step, you'll add a variable to the contract that stores the billboard message, and define a getter function to
read the value of the variable.
Under the `data maps and vars` comment, define the `billboard-message` variable. Remember that you must define the type of
the variable, in this case `string-utf8` to support emojis and extended characters. You must also define the
maximum length of the variable, for this tutorial use the value `500` to allow for a longer message. You must also
define the initial value for the variable.
```clarity
;; data vars
(define-data-var billboard-message (string-utf8 500) u"Hello world!")
```
You also should define a read-only getter function returns the value of the `billboard-message` variable.
```clarity
;; public functions
(define-read-only (get-message)
(var-get billboard-message))
```
These are the required methods for storing and accessing the message on the billboard.
## Step 3: define set message function
Define a method to set the billboard message. Under the public functions, define a `set-message` function. This public
function takes a `string-utf8` with a max length of `500` as the only argument. Note that the type of the argument
matches the type of the `billboard-message` variable. Clarity's type checking ensures that an invalid input to the
function doesn't execute.
```clarity
;; public functions
(define-public (set-message (message (string-utf8 500)))
(ok (var-set billboard-message message))
)
```
The contract is now capable of updating the `billboard-message`.
## Step 4: transfer STX to set message
In this step, you'll modify the `set-message` function to add a cost in STX tokens, that increments by a set amount each
time the message updates.
First, you should define a variable to track the price of updating the billboard. This value is in micro-STX. Under the
`data maps and vars` heading, add a new variable `price` with type `uint` and an initial value of `u100`. The initial
cost to update the billboard is 100 micro-STX or 0.0001 STX.
```clarity
;; data vars
(define-data-var price uint u100)
```
You also should define a read-only getter function returns the value of the `price` variable. Read-only functions in
Clarity are public, and should be grouped with other public functions in the contract.
```clarity
;; public functions
(define-read-only (get-price)
(var-get price)
)
```
It's a best practice to define codes to a descriptive constant for Clarity smart contracts. This makes the code easier
to understand for readers and makes errors reusable across contract methods. Under the `constants` comment, define a STX
transfer error constant. Assign the value `u0` to the constant. There is no standard for error constants in Clarity,
this value is used because it's the first error the contract defines. Error constants should be defined at the top of
the contract, usually preceding data variables.
```clarity
;; error consts
(define-constant ERR_STX_TRANSFER u0)
```
Modify the `set-message` function to transfer the amount of STX represented by the current price of the billboard from
the function caller to the contract wallet address, and then increment the new price. The function is then executed in four steps: transferring STX from the function caller to the contract, updating the `billboard-message` variable, incrementing the
`price` variable, and returning the new price.
The new `set-message` function uses [`let`][] to define local variables for the function. Two variables are declared,
the `cur-price`, which represents the current price of updating the billboard, and the `new-price`, which represents the
incremented price for updating the billboard.
The function then calls the [`stx-transfer?`][] function to transfer the current price of the contract in STX from the
transaction sender to the contract wallet. This syntax can be confusing: the function call uses the `tx-sender`
variable, which is the principal address of the caller of the function. The second argument to [`stx-transfer?`][] uses
the [`as-contract`][] function to change the context's `tx-sender` value to the principal address that deployed the
contract.
The entire [`stx-transfer?`][] function call is wrapped in the [`unwrap!`][] function, to provide protection from
the transfer failing. The [`unwrap!`][] function executes the first argument, in this case the [`stx-transfer?`][]
function. If the execution returns `(ok ...)`, the [`unwrap!`][] function returns the inner value of the `ok`, otherwise
the function returns the second argument and exits the current control-flow, in this case the `ERR_STX_TRANSFER` error
code.
If the token transfer is successful, the function sets the new `billboard-message` and updates the `price` variable to
`new-price`. Finally, the function returns `(ok new-price)`. It's generally a good practice to have public functions
return `ok` when successfully executed.
-> This function should replace the existing `set-message` function defined previously.
```clarity
(define-public (set-message (message (string-utf8 500)))
(let ((cur-price (var-get price))
(new-price (+ cur-price u10)))
;; pay the contract
(unwrap! (stx-transfer? cur-price tx-sender (as-contract tx-sender)) (err ERR_STX_TRANSFER))
;; update the billboard's message
(var-set billboard-message message)
;; update the price
(var-set price new-price)
;; return the updated price
(ok new-price)
)
)
```
At this point, the final contract should look like this:
```clarity
;; error consts
(define-constant ERR_STX_TRANSFER u0)
;; data vars
(define-data-var billboard-message (string-utf8 500) u"Hello World!")
(define-data-var price uint u100)
;; public functions
(define-read-only (get-price)
(var-get price)
)
(define-read-only (get-message)
(var-get billboard-message)
)
(define-public (set-message (message (string-utf8 500)))
(let ((cur-price (var-get price))
(new-price (+ cur-price u10)))
;; pay the contract
(unwrap! (stx-transfer? cur-price tx-sender (as-contract tx-sender)) (err ERR_STX_TRANSFER))
;; update the billboard's message
(var-set billboard-message message)
;; update the price
(var-set price new-price)
;; return the updated price
(ok new-price)
)
)
```
Use `clarinet check` to ensure that your Clarity code is well-formed and error-free.
## Step 5: write a contract test
At this point, the contract functions as intended, and can be deployed to the blockchain. However, it's good practice
to write automated testing to ensure that the contract functions perform in the expected way. Testing can be valuable
when adding complexity or new functions, as working tests can verify that any changes you make didn't fundamentally
alter the way the functions behave.
Open the `tests/billboard_test.ts` file in your IDE. In this step, you will add a single automated test to exercise the
`set-message` and `get-message` functions of the contract.
Using the Clarinet library, define variables to get a wallet address principal from the Clarinet configuration, and the
balance of that address on the chain.
The functional part of the test is defined using the `chain.mineBlock()` function, which simulates the mining of a
block. Within that function, the test makes four contract calls (`Tx.contractCall()`), two calls to `set-message` and
two calls to `get-message`.
Once the simulated block is mined, the test can make assertions about the chain state. This is accomplished using the
`assertEquals()` function and the `expect` function. In this case, the test asserts that the once the simulated block
is mined, the block height is now equal to `2`, and that the number of receipts (contract calls) in the block are
exactly `4`.
The test can then make assertions about the return values of the contract. The test checks that the result of the
transaction calls to `get-message` match the string values that the calls to `set-message` contain. This covers the
capability of both contract functions.
Finally, the test asserts that STX are transferred from the transaction caller wallet, covering the price updating and
token transfer. The test verifies that the addresses of the wallets match the expected addresses, and that the amount
transferred is the expected amount.
```ts
import { Clarinet, Tx, Chain, Account, types } from 'https://deno.land/x/clarinet@v0.12.0/index.ts';
import { assertEquals } from 'https://deno.land/std@0.90.0/testing/asserts.ts';
Clarinet.test({
name: 'A quick demo on how to assert expectations',
async fn(chain: Chain, accounts: Map<string, Account>) {
let wallet_1 = accounts.get('wallet_1')!;
let assetMaps = chain.getAssetsMaps();
const balance = assetMaps.assets['STX'][wallet_1.address];
let block = chain.mineBlock([
Tx.contractCall('billboard', 'set-message', [types.utf8('testing')], wallet_1.address),
Tx.contractCall('billboard', 'get-message', [], wallet_1.address),
Tx.contractCall('billboard', 'set-message', [types.utf8('testing...')], wallet_1.address),
Tx.contractCall('billboard', 'get-message', [], wallet_1.address),
]);
assertEquals(block.receipts.length, 4);
assertEquals(block.height, 2);
block.receipts[1].result.expectUtf8('testing');
block.receipts[3].result.expectUtf8('testing...');
let [event] = block.receipts[0].events;
let { sender, recipient, amount } = event.stx_transfer_event;
sender.expectPrincipal('ST1J4G6RR643BCG8G8SR6M2D9Z9KXT2NJDRK3FBTK');
recipient.expectPrincipal('ST1HTBVD3JG9C05J7HBJTHGR0GGW7KXW28M5JS8QE.billboard');
amount.expectInt(100);
assetMaps = chain.getAssetsMaps();
assertEquals(assetMaps.assets['STX'][wallet_1.address], balance - 210);
},
});
```
Try running `clarinet test` to see the output of the unit test.
=> You have now learned how to store and update data on chain with a variable, and how to transfer STX tokens from
a contract caller to a new principal address. Additionally, you have learned how to write a unit test for a simple
Clarity contract using Clarinet.
[counter tutorial]: /write-smart-contracts/counter-tutorial
[clarinet]: /write-smart-contracts/clarinet
[installing clarinet]: /write-smart-contracts/clarinet#installing-clarinet
[visual studio code]: https://code.visualstudio.com/
[final code for this tutorial]: https://github.com/hirosystems/clarinet/tree/master/examples/billboard
[`let`]: /references/language-functions#let
[`stx-transfer?`]: /references/language-functions#stx-transfer
[`as-contract`]: /references/language-functions#as-contract
[`unwrap!`]: /references/language-functions#unwrap
[clarity visual studio code plugin]: https://marketplace.visualstudio.com/items?itemName=HiroSystems.clarity-lsp

22
src/pages/write-smart-contracts/clarinet.md

@ -20,14 +20,12 @@ Clarinet is a useful tool for developing smart contracts, and should be used as
that involves building and testing the contract locally, deploying the final draft contract to a testnet environment
and testing on a live blockchain, and deploying the final contract to the mainnet.
## Installing Clarinet
When developing smart contracts, you may also want to use the [Clarity Visual Studio Code plugin][].
The best way to install Clarinet is through the Rust package manager, Cargo. If you have a working installation of
[Rust](https://www.rust-lang.org/tools/install), use the following command to install Clarinet.
## Installing Clarinet
```sh
cargo install clarinet --locked
```
You can download a release from the [Clarinet repository](https://github.com/hirosystems/clarinet/releases/latest) or
try [installing it from source code](https://github.com/hirosystems/clarinet#install-from-source-using-cargo).
## Developing a Clarity smart contract
@ -75,6 +73,10 @@ depends_on = []
At this point, you can begin editing your smart contract in the `contracts` directory. At any point while you are
developing, you can use the command `clarinet check` to check the syntax of your smart contract.
For a more in-depth overview of developing with Clarinet, review this comprehensive walkthrough video.
<br /><iframe width="560" height="315" src="https://www.youtube.com/embed/zERDftjl6k8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
## Testing with Clarinet
Clarinet provides several powerful methods to test and interact with your smart contracts. As mentioned in the previous
@ -167,14 +169,15 @@ An example unit test for the `echo-number` function is provided below:
...
Clarinet.test({
name: 'the echo-number function returns the input value ok',
async fn(chain: Chain) {
async fn(chain: Chain, accounts: Map<string, Account>) {
const testNum = '42';
let deployerWallet = accounts.get('deployer')!;
let block = chain.mineBlock([
Tx.contractCall(
'ST1HTBVD3JG9C05J7HBJTHGR0GGW7KXW28M5JS8QE.my-contract',
`${deployerWallet.address}.my-contract`,
'echo-number',
[testNum],
'ST1HTBVD3JG9C05J7HBJTHGR0GGW7KXW28M5JS8QE'
deployerWallet.address,
),
]);
assertEquals(block.receipts.length, 1); // assert that the block received a single tx
@ -197,3 +200,4 @@ available Clarity calls in Deno, review the [Deno Clarinet library][].
[clarity language reference]: /references/language-functions
[asserts]: https://deno.land/std@0.90.0/testing/asserts.ts
[deno clarinet library]: https://github.com/hirosystems/clarinet/blob/master/deno/index.ts
[clarity visual studio code plugin]: https://marketplace.visualstudio.com/items?itemName=HiroSystems.clarity-lsp

3
src/pages/write-smart-contracts/counter-tutorial.md

@ -30,6 +30,8 @@ In this tutorial you will:
For this tutorial, you should have a local installation of Clarinet. Refer to [Installing Clarinet][] for instructions
on how to set up your local environment. You should also have a text editor or IDE to edit the Clarity smart contract.
If you are using Visual Studio Code, you may want to install the [Clarity Visual Studio Code plugin][].
### Optional prerequisites
While this tutorial primarily focuses on local smart contract development, you may wish to deploy your contract to
@ -259,3 +261,4 @@ the strengths of performing local development without having to wait for block t
[`+`]: /references/language-functions#-add
[clarity language reference]: /references/language-functions
[transactions]: https://explorer.stacks.co/transactions?chain=testnet
[clarity visual studio code plugin]: https://marketplace.visualstudio.com/items?itemName=HiroSystems.clarity-lsp

3
src/pages/write-smart-contracts/hello-world-tutorial.md

@ -40,6 +40,8 @@ on how to set up your local environment. You should also have a text editor or I
Note that you could also complete the coding portion of this tutorial in an online REPL such as [clarity.tools][]. If
you are using the online REPL, you can skip to [step 3][] of the tutorial and enter the code into the sandbox.
If you are using Visual Studio Code, you may want to install the [Clarity Visual Studio Code plugin][].
### Optional prerequisites
While this tutorial primarily focuses on local smart contract development, you may wish to deploy your contract to
@ -264,3 +266,4 @@ the strengths of performing local development without having to wait for block t
[read-only function]: /references/language-functions#define-read-only
[transactions]: https://explorer.stacks.co/transactions?chain=testnet
[call a contract]: https://explorer.stacks.co/sandbox/contract-call?chain=testnet
[clarity visual studio code plugin]: https://marketplace.visualstudio.com/items?itemName=HiroSystems.clarity-lsp

10
src/pages/write-smart-contracts/overview.md

@ -27,7 +27,9 @@ Because smart contracts are programs that exist in a blockchain, anyone can quer
to execute them. A smart contract execution can result in new transactions being written to the blockchain.
Apps can take advantage of smart contracts to manage a global state that is visible to the public. 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.
blockchain to independently verify that an app's global shared state has been managed correctly according to the smart contract's rules.
There is a [Clarity Visual Studio Code plugin][] available for syntax assistance and debugging.
## Use cases
@ -48,7 +50,7 @@ Clarity differs from most other smart contract languages in two essential ways:
- The language is decidable (not Turing complete)
Using an interpreted language ensures that the executed code is human-readable and auditable. A decidable language
like Clarity makes it possible to determine precisely which code will be executed, for any function.
like Clarity makes it possible to determine precisely which code is executed, for any function.
A Clarity smart contract consists of two parts, 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
@ -67,7 +69,7 @@ Note some of the key Clarity language rules and limitations.
## Try a tutorial
[@page-reference | grid]
| /write-smart-contracts/hello-world-tutorial, /write-smart-contracts/counter-tutorial, /build-apps/guides/transaction-signing, /build-apps/tutorials/public-registry
| /write-smart-contracts/hello-world-tutorial, /write-smart-contracts/counter-tutorial, /write-smart-contracts/billboard-tutorial
## Explore more
@ -75,3 +77,5 @@ For language details and references, see the following:
[@page-reference | grid]
| /write-smart-contracts/principals, /write-smart-contracts/values, /references/language-overview
[clarity visual studio code plugin]: https://marketplace.visualstudio.com/items?itemName=HiroSystems.clarity-lsp

Loading…
Cancel
Save