From 5e5106cf63d9d927c67aae303674501182c21811 Mon Sep 17 00:00:00 2001 From: Hank Stoever Date: Mon, 20 Apr 2020 14:07:19 -0700 Subject: [PATCH] feat: updates relating to testnet, clarity, Connect (#540) * build: update jekyll version * docs: add Connect docs * docs: fix list issue * feat: feedback * feat: add ruby-version * feat: bump ruby version * feat: tableize connect clarity args * docs: update function signatures for contract calls with connect * docs: WIP for running a neon miner * fix: better copy for `sendToSignIn` of connect * Updates from stacks-blockchain:master (#543) * updates from stacks-blockchain:master * address feedback in principals.md * feat: add notice to use beta authOrigin * fix: move tx signing notice to 'usage' Co-authored-by: Aaron Blankstein --- .ruby-version | 1 + Gemfile | 5 +- Gemfile.lock | 27 ++--- README.md | 2 +- _core/smart/neon-node.md | 90 +++++++++++++++++ _core/smart/principals.md | 95 ++++++++++++------ _data/navigation_learn.yml | 6 ++ _develop/connect/get-started.md | 144 +++++++++++++++++++++++++++ _develop/connect/overview.md | 25 +++++ _develop/connect/use-with-clarity.md | 139 ++++++++++++++++++++++++++ 10 files changed, 488 insertions(+), 46 deletions(-) create mode 100644 .ruby-version create mode 100644 _core/smart/neon-node.md create mode 100644 _develop/connect/get-started.md create mode 100644 _develop/connect/overview.md create mode 100644 _develop/connect/use-with-clarity.md diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 00000000..4fd0fe3c --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.5.1 \ No newline at end of file diff --git a/Gemfile b/Gemfile index 1459d415..6b336239 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,5 @@ source "https://rubygems.org" -ruby RUBY_VERSION +ruby '~> 2.5.1' # Hello! This is where you manage which Jekyll version is used to run. # When you want to use a different version, change it below, save the @@ -9,7 +9,7 @@ ruby RUBY_VERSION # # This will help ensure the proper Jekyll version is running. # Happy Jekylling! -gem "jekyll", "3.6.3" +gem "jekyll", "3.8.6" # This is the default theme for new Jekyll sites. You may change this to anything you like. # gem "minima", "~> 2.0" @@ -24,7 +24,6 @@ group :jekyll_plugins do gem 'jekyll-paginate', '~> 1.1' gem 'jekyll-seo-tag' gem 'jekyll-gist' - gem 'jekyll-livereload' gem 'jekyll-avatar' gem 'jekyll-titles-from-headings' gem 'jekyll-sitemap' diff --git a/Gemfile.lock b/Gemfile.lock index 0aeeef91..df056baf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,13 +5,14 @@ GEM public_suffix (>= 2.0.2, < 5.0) coderay (1.1.2) colorator (1.1.0) + concurrent-ruby (1.1.6) em-websocket (0.5.1) eventmachine (>= 0.12.9) http_parser.rb (~> 0.6.0) eventmachine (1.2.7) faraday (0.17.1) multipart-post (>= 1.2, < 3) - ffi (1.11.3) + ffi (1.12.2) formatador (0.2.5) forwardable-extended (2.6.0) guard (2.16.1) @@ -24,16 +25,20 @@ GEM shellany (~> 0.0) thor (>= 0.18.1) http_parser.rb (0.6.0) - jekyll (3.6.3) + i18n (0.9.5) + concurrent-ruby (~> 1.0) + jekyll (3.8.6) addressable (~> 2.4) colorator (~> 1.0) + em-websocket (~> 0.5) + i18n (~> 0.7) jekyll-sass-converter (~> 1.0) - jekyll-watch (~> 1.1) + jekyll-watch (~> 2.0) kramdown (~> 1.14) liquid (~> 4.0) mercenary (~> 0.3.3) pathutil (~> 0.9) - rouge (>= 1.7, < 3) + rouge (>= 1.7, < 4) safe_yaml (~> 1.0) jekyll-avatar (0.7.0) jekyll (>= 3.0, < 5.0) @@ -43,9 +48,6 @@ GEM octokit (~> 4.2) jekyll-google-tag-manager (1.0.3) jekyll (>= 3.3, < 5.0) - jekyll-livereload (0.2.2) - em-websocket (~> 0.5) - jekyll (~> 3.0) jekyll-paginate (1.1.0) jekyll-redirect-from (0.15.0) jekyll (>= 3.3, < 5.0) @@ -59,7 +61,7 @@ GEM jekyll (>= 3.3, < 5.0) jekyll-toc (0.12.2) nokogiri (~> 1.9) - jekyll-watch (1.5.1) + jekyll-watch (2.2.1) listen (~> 3.0) kramdown (1.17.0) liquid (4.0.3) @@ -84,11 +86,11 @@ GEM pry (0.12.2) coderay (~> 1.1.0) method_source (~> 0.9.0) - public_suffix (4.0.1) + public_suffix (4.0.4) rb-fsevent (0.10.3) - rb-inotify (0.10.0) + rb-inotify (0.10.1) ffi (~> 1.0) - rouge (2.2.1) + rouge (3.17.0) safe_yaml (1.0.5) sass (3.7.4) sass-listen (~> 4.0.0) @@ -106,12 +108,11 @@ PLATFORMS DEPENDENCIES guard - jekyll (= 3.6.3) + jekyll (= 3.8.6) jekyll-avatar jekyll-feed (~> 0.6) jekyll-gist jekyll-google-tag-manager - jekyll-livereload jekyll-paginate (~> 1.1) jekyll-redirect-from jekyll-seo-tag diff --git a/README.md b/README.md index fc8589f1..8a204748 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,7 @@ To run locally: 2. Build and serve locally. ``` - bundle exec jekyll serve --config _config.yml,staticman.yml + bundle exec jekyll serve --config _config.yml,staticman.yml --livereload ``` Use this format to turn on production features: diff --git a/_core/smart/neon-node.md b/_core/smart/neon-node.md new file mode 100644 index 00000000..0b1ebcfb --- /dev/null +++ b/_core/smart/neon-node.md @@ -0,0 +1,90 @@ +--- +layout: core +description: "Blockstack smart contracting language" +permalink: /:collection/:path.html +--- +# Running a Neon Testnet Node +{:.no_toc} + +"Neon" is phase 1 of the Stacks 2.0 testnet. In Neon, you can run a Stacks node and participate in proof-of-burn mining. + +* TOC +{:toc} + +### Download and build stacks-blockchain + +The first step is to ensure that you have Rust and the support software installed. + +```bash +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +``` + +From there, you can clone this repository: + +```bash +git clone https://github.com/blockstack/stacks-blockchain.git + +cd stacks-blockchain +``` + +Then build the project: + +```bash +cargo build +``` + +Building the project on ARM: + +```bash +cargo build --features "aarch64" --no-default-features +``` + +### Setup your Proof-of-Burn miner + +In this phase of the testnet, miners will be burning BTC to participate in leader election. In order to mine, you'll need to configure your node with a BTC keychain, and you'll need to fund it with BTC. We're providing a BTC faucet to make it easy to run a miner. + +Let's start by generating a keypair: + +```bash +cargo run --bin blockstack-cli generate-sk --testnet + +# Output +# { +# secretKey: "b8d99fd45da58038d630d9855d3ca2466e8e0f89d3894c4724f0efc9ff4b51f001", +# publicKey: "02781d2d3a545afdb7f6013a8241b9e400475397516a0d0f76863c6742210539b5", +# stacksAddress: "ST2ZRX0K27GW0SP3GJCEMHD95TQGJMKB7G9Y0X1MH" +# } +``` + +**TODO**: guidance / update on generating a BTC address from this keypair. + +Once you have your BTC address, head over to our testnet website to use the BTC faucet: + +**TODO**: URL, guidance for BTC faucet + +Now that you have some testnet BTC, you'll need to configure your Stacks node to use this wallet. + +Open up the file `testnet/Stacks.toml`. Find the section that starts with `[burnchain]`. Update that section so that it looks like this: + +```toml +[burnchain] +chain = "bitcoin" +mode = "neon" +peer_host = "127.0.0.1" # todo(ludo): update URL with neon.blockstack.org when deployed +burnchain_op_tx_fee = 1000 +commit_anchor_block_within = 10000 +rpc_port = 3000 +peer_port = 18444 +``` + +**TODO**: update `peer_host`, and how do you specify your BTC keychain? + +### Running your mining node + +Now that you're all set up, you can run your miner. In the command line, run: + +```bash +cargo testnet ./testnet/Stacks.toml +``` + +**TODO**: some way of confirming that the miner is running - expected logs, explorer, etc? \ No newline at end of file diff --git a/_core/smart/principals.md b/_core/smart/principals.md index 5b5e0823..b1feadec 100644 --- a/_core/smart/principals.md +++ b/_core/smart/principals.md @@ -1,9 +1,13 @@ --- +<<<<<<< HEAD layout: smart description: "Blockstack smart contracting language" +======= +layout: core +>>>>>>> Updates from stacks-blockchain:master (#543) permalink: /:collection/:path.html --- -# Understanding Principals +# Principals {:.no_toc} _Principals_ are a Clarity native type that represents a spending entity. This section discusses principals and how they are used in the Clarity. @@ -14,47 +18,80 @@ _Principals_ are a Clarity native type that represents a spending entity. This s ## Principals and tx-sender -A principal is represented by a public-key hash or multi-signature Stacks address. Assets in Clarity and the Stacks blockchain are "owned" by objects of the principal type; put another way, principal object types may own an asset. +Assets in the smart contracting language and blockchain are +"owned" by objects of the principal type, meaning that any object of +the principal type may own an asset. For the case of public-key hash +and multi-signature Stacks addresses, a given principal can operate on +their assets by issuing a signed transaction on the blockchain. _Smart +contracts_ may also be principals (reprepresented by the smart +contract's identifier), however, there is no private key associated +with the smart contract, and it cannot broadcast a signed transaction +on the blockchain. + +A Clarity contract can use a globally defined `tx-sender` variable to +obtain the current principal. The following example defines a transaction +type that transfers `amount` microSTX from the sender to a recipient if amount +is a multiple of 10, otherwise returning a 400 error code. + +```scheme +(define-public (transfer-to-recipient! (recipient principal) (amount uint)) + (if (is-eq (mod amount 10) 0) + (stx-transfer? amount tx-sender recipient) + (err u400))) +``` -A given principal operates on its assets by issuing a signed transaction on the Stacks blockchain. A Clarity contract can use a globally defined `tx-sender` variable to obtain the current principal. +## Smart contracts as principals -The following user-defined function transfers an asset, in this case, tokens, between two principals: +Smart contracts themselves are principals and are represented by the +smart contract's identifier -- which is the publishing address of the +contract _and_ the contract's name, e.g.: +```scheme +'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR.contract-name ``` -(define (transfer! (sender principal) (recipient principal) (amount int)) - (if (and - (not (eq? sender recipient)) - (debit-balance! sender amount) - (credit-balance! recipient amount)) - 'true - 'false)) -``` - -The principal's signature is not checked by the smart contract, but by the virtual machine. +For convenience, smart contracts may write a contract's identifier in the +form `.contract-name`. This will be expanded by the Clarity interpreter into +a fully-qualified contract identifier that corresponds to the same +publishing address as the contract it appears in. For example, if the +same publisher key, `SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR`, is +publishing two contracts, `contract-A` and `contract-B`, the fully +qualified identifier for the contracts would be: + +```scheme +'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR.contract-A +'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR.contract-B +``` -## Smart contracts as principals - -Smart contracts themselves are principals and are represented by the smart contract's identifier. You create the identifier when you launch the contract, for example, the contract identifier here is `hanomine`. +But, in the contract source code, if the developer wishes +to call a function from `contract-A` in `contract-B`, they can +write -```bash -clarity-cli launch hanomine /data/hano.clar /data/db +```scheme +(contract-call? .contract-A public-function-foo) ``` -A smart contract may use the special variable `contract-name` to refer to its own principal. +This allows the smart contract developer to modularize their +applications across multiple smart contracts _without_ knowing +the publishing key a priori. -To allow smart contracts to operate on assets it owns, smart contracts may use the special `(as-contract expr)` function. This function executes the expression (passed as an argument) with the `tx-sender` set to the contract's principal, rather than the current sender. The `as-contract` function returns the value of the provided expression. +In order for a smart contract to operate on assets it owns, smart contracts +may use the special `(as-contract ...)` function. This function +executes the expression (passed as an argument) with the `tx-sender` +set to the contract's principal, rather than the current sender. The +`as-contract` function returns the value of the provided expression. -For example, a smart contract that implements something like a "token faucet" could be implemented as so: +For example, a smart contract that implements something like a "token +faucet" could be implemented as so: -```cl +```scheme (define-public (claim-from-faucet) (if (is-none? (fetch-entry claimed-before (tuple (sender tx-sender)))) (let ((requester tx-sender)) ;; set a local variable requester = tx-sender (begin - (insert-entry! claimed-before (tuple (sender requester)) (tuple (claimed 'true))) - (as-contract (stacks-transfer! requester 1))))) - (err 1)) + (insert-entry! claimed-before (tuple (sender requester)) (tuple (claimed true))) + (as-contract (stx-transfer? u1 tx-sender requester)))) + (err 1))) ``` In this example, the public function `claim-from-faucet`: @@ -64,6 +101,6 @@ In this example, the public function `claim-from-faucet`: * Adds an entry to the tracking map. * Uses `as-contract` to send 1 microstack -Contract writers can use the primitive function `is-contract?` to determine whether a given principal corresponds to a smart contract. - -Unlike other principals, there is no private key associated with a smart contract. As it lacks a private key, a Clarity smart contract cannot broadcast a signed transaction on the blockchain. +Unlike other principals, there is no private key associated with a +smart contract. As it lacks a private key, a Clarity smart contract +cannot broadcast a signed transaction on the blockchain. diff --git a/_data/navigation_learn.yml b/_data/navigation_learn.yml index 52666bfa..c36b684e 100644 --- a/_data/navigation_learn.yml +++ b/_data/navigation_learn.yml @@ -12,6 +12,12 @@ - develop/deploy-tips - android/tutorial - ios/tutorial + +- title: Connect + docs: + - develop/connect/overview + - develop/connect/get-started + - develop/connect/use-with-clarity - title: Data sharing & collaboration docs: diff --git a/_develop/connect/get-started.md b/_develop/connect/get-started.md new file mode 100644 index 00000000..1c36aff7 --- /dev/null +++ b/_develop/connect/get-started.md @@ -0,0 +1,144 @@ +--- +layout: learn +permalink: /:collection/:path.html +--- +# Get Started +{:.no_toc} + +Blockstack Connect is a Javascript library for integrating your application with Stacks v2. With Connect, you get some big benefits: + + + +* TOC +{:toc} + +## Installation + +With yarn: + +```bash +yarn add @blockstack/connect +``` + +With npm: + +```bash +npm install --save @blockstack/connect +``` + +## Usage + +### AuthOptions + +Every major method you'll use with `connect` requires you to pass some options, like the name and icon of your app, and what to do when authentication is finished. In practice, this means you need to define these options, and pass them to the various API methods. + +The exact interface you'll use [is defined as](https://github.com/blockstack/connect/blob/master/src/auth.ts#L12:L24): + +```typescript +export interface AuthOptions { + redirectTo: string; + finished: (payload: FinishedData) => void; + sendToSignIn?: boolean; + userSession?: UserSession; + appDetails: { + name: string; + icon: string; + }; +} +``` + +parameter | type | default | optional | description +---|---|---|---|--- +redirectTo | string | | false | The path in your app where users go after sign in. +appDetails | object | | false | an object which includes `appName: string` and `appIcon: string`. This will speed up the process of loading your app's information during onboarding. +finished | function | | false | A callback that can be invoked after authentication. This prevents having to do a whole page refresh in a new tab. One argument is passed to this callback, which is an object with `userSession` included. If included, then the `redirectTo` path is ignored, and the user will be logged in automatically. +sendToSignIn | boolean | false | true | Whether the user should go straight to the 'sign in' flow (false) or be presented with the 'sign up' flow (true) instead. +userSession | UserSession | | false | pass a `UserSession` instance to use for authentication. If it's not passed, `@blockstack/connect` will create one for you. + + +### In React Apps + +If you're using `connect` in a React app, then the best option is to include `connect`'s React Provider and hooks in your React app. + +First, setup the `Connect` provider at the "top-level" of your app - probably next to wherever you would put a Redux provider, for example. + +```javascript +import { Connect } from '@blockstack/connect'; + +const authOptions = { + redirectTo: '/', + finished: ({ userSession }) => { + console.log(userSession.loadUserData()); + }, + appDetails: { + name: 'My Cool App', + icon: 'https://example.com/icon.png', + }, +}; + +const App = () => ( + + // the rest of your app's components + +) +``` + +Later, when you want to begin the onboarding process, use the `useConnect` hook to get `connect`'s `doOpenAuth` method. + +```javascript +import { useConnect } from '@blockstack/connect'; + +const SignInButton = () => { + const { doOpenAuth } = useConnect(); + + return ( + + ) +} +``` + +#### Sign In + +To send the user straight to sign in, call `doOpenAuth(true)`. + +### In ES6 (non-React) apps + +If you aren't using React, or just want a simpler API, then you can use the `showBlockstackConnect` method. + + +```javascript +import { showBlockstackConnect } from '@blockstack/connect'; + +const authOptions = { /** See docs above for options */ }; +showBlockstackConnect(authOptions); +``` + +#### Sign In + +To send the user straight to sign in, include `sendToSignIn: true` in your `authOptions`. + +#### Note about dependency size: + +If you're building a non-React app, note that importing `@blockstack/connect` will add React dependencies to your JavaScript bundle. We recommend using something like [Webpack resolve aliases](https://webpack.js.org/configuration/resolve/) to replace `react` with `preact` in production, which reduces your bundle size. Check out [our own webpack.config.js file](https://github.com/blockstack/ux/blob/fix/connect-modal-accessibility/packages/connect/webpack.config.js#L87:L95) to see how we use this for production builds. + +If you're using the hosted version of `@blockstack/connect` (described below), then you already have a production-optimized bundle. + +### Using a hosted version of `@blockstack/connect` + +If you aren't using ES6 imports, you can still use `connect`! We package the library so that it can be automatically used with [unpkg](https://unpkg.com/). + +First, include the script in your HTML: + +```html +