Blockchains require consensus among large numbers of people, so they can be slow. Additionally, a blockchain is not designed to hold a lot of data. This means using a blockchain for every bit of data a user might write and store is expensive. For example, imagine if an application were storing every tweet in the chain.
The command line is intended for developers only. Developers can use the command
line to test and debug Blockstack applications in ways that the Blockstack
Browser does not yet support. Using the command line, developers can:
* Generate and Broadcast all supported types of Blockstack transactions
* Load, store, and list data in Gaia hubs
* Generate owner, payment and application keys from a seed phrase
* Query Stacks Nodes
* Implement a minimum viable authentication flow
- Generate and Broadcast all supported types of Blockstack transactions
- Load, store, and list data in Gaia hubs
- Generate owner, payment and application keys from a seed phrase
- Query Stacks Nodes
- Implement a minimum viable authentication flow
{% include warning.html content="Many of the commands operate on unencrypted
private keys. For this reason, DO NOT use this tool for day-to-day tasks as you
@ -17,15 +16,16 @@ You must <a href="#installCommandLine">install the command line</a> before you
can use the commands.
## List of commands
{:.no_toc}
To see the usage and options for the command in general, enter `blockstack-cli` without any subcommands. To see a list of subcommands enter `blockstack-cli help`. Enter `blockstack-cli SUBCOMMAND_NAME help` to see a subcommand with its usage. The following are the available subcommands:
* TOC
{:toc}
- TOC
{:toc}
{% for entry in site.data.cliRef %}
## {{ entry.command }}
**Group**: {{ entry.group }}
@ -33,6 +33,7 @@ To see the usage and options for the command in general, enter `blockstack-cli`
@ -58,6 +60,7 @@ To see the usage and options for the command in general, enter `blockstack-cli`
<p><aname="installCommandLine"> </a></p>
## How to install the command line
{:.no_toc}
You must have [Node.js](https://nodejs.org/en/download/) v8 or higher (v10 recommended). macOS and Linux users can avoid `sudo` or [permissions problems](https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally) or by using [`nvm`](https://github.com/nvm-sh/nvm). These instructions assume you are using a macOS or Linux system.
@ -74,27 +77,36 @@ To install the command line, do the following:
cd cli-blockstack
```
```
3. Install the dependencies with `npm`.
```
npm install
```
```
npm install
```
4. Build the command line command.
```
npm run build
```
```
npm run build
```
5. Link the command.
```
sudo npm link
```
```
sudo npm link
```
### Troubleshooting the CLI installation
If you run into `EACCES` permissions errors, try the following:
* See https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally.
* Use [`Node Version Manager`](https://github.com/nvm-sh/nvm).
Good pull requests—patches, improvements, new features—are a fantastic help. They should remain focused in scope and avoid containing unrelated commits.
@ -66,7 +68,6 @@ includes code changes) and under the terms of the
We’ve set up a community portal with all kinds of tasks you can complete to earn Stacks tokens by contributing to and supporting the community - these stay in your account and convert into tokens when the network goes live. Many are really easy and they’re all fun and helpful for the community, more information here - https://contribute.blockstack.org/.
## Blockstack on Social Media
Musce libero nunc, dignissim quis turpis quis, semper vehicula dolor. Suspendisse tincidunt consequat quam, ac posuere leo dapibus id. Cras fringilla convallis elit, at eleifend mi interam.
The [issue tracker](https://github.com/blockstack/blockstack-browser/issues) is the preferred channel for [bug reports](#bug-reports), [features requests](#feature-requests) and [submitting pull requests](#pull-requests), but please respect the following
restrictions:
* Please **do not** use the issue tracker for personal support requests. Please use the [Forum](https://forum.blockstack.org) or [Slack](https://chat.blockstack.org) as they are better places to get help.
* Please **do not** derail or troll issues. Keep the discussion on topic and respect the opinions of others.
- Please **do not** use the issue tracker for personal support requests. Please use the [Forum](https://forum.blockstack.org) or [Slack](https://chat.blockstack.org) as they are better places to get help.
* Please **do not** post comments consisting solely of "+1" or ":thumbsup:". Use [GitHub's "reactions" feature](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments) instead. We reserve the right to delete comments which violate this rule.
- Please **do not** derail or troll issues. Keep the discussion on topic and respect the opinions of others.
- Please **do not** post comments consisting solely of "+1" or ":thumbsup:". Use [GitHub's "reactions" feature](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments) instead. We reserve the right to delete comments which violate this rule.
## Issues and labels
@ -29,7 +30,6 @@ Our bug tracker utilizes several labels to help organize and identify issues. He
For a complete look at our labels, see the [project labels page](https://github.com/blockstack/blockstack-browser/labels).
## Bug reports
A bug is a _demonstrable problem_ that is caused by the code in the repository. Good bug reports are extremely helpful, so thanks!
@ -44,7 +44,6 @@ Guidelines for bug reports:
3. **Isolate the problem**— ideally create a [reduced test case](https://css-tricks.com/reduced-test-cases/) and a live example. [This JS Bin](https://jsbin.com/lolome/edit?html,output) is a helpful template.
A good bug report shouldn't leave others needing to chase you up for more information. Please try to be as detailed as possible in your report. What is your environment? What steps will reproduce the issue? What browser(s) and OS experience the problem? Do other browsers show the bug differently? What would you expect to be the outcome? All these details will help people to fix any potential bugs.
Example:
@ -65,7 +64,6 @@ Example:
> causing the bug, and potential solutions (and your opinions on their
> merits).
## Feature requests
Feature requests are welcome. But take a moment to find out whether your idea fits with the scope and aims of the project. It's up to *you* to make a strong case to convince the project's developers of the merits of this feature. Please provide as much detail and context as possible.
Feature requests are welcome. But take a moment to find out whether your idea fits with the scope and aims of the project. It's up to _you_ to make a strong case to convince the project's developers of the merits of this feature. Please provide as much detail and context as possible.
Nulla non sollicitudin. Morbi sit amet laoreet ipsum, vel pretium mi. Morbi varius, tellus in accumsan blandit, elit ligula eleifend velit, luctus mattis ante nulla condimentum nulla. Etiam vestibulum risus vel arcu elementum eleifend. Cras at dolor eget urna varius faucibus tempus in elit.
## What can you contribute?
Nunc porta malesuada porta. Etiam tristique vestibulum dolor at ultricies. Proin hendrerit sapien sed erat fermentum, at commodo velit consectetur.
{% include image.html img="image1.png" style="wide" lightbox="true" alt="Alt for image" caption="Image in lightbox" %}
@ -61,14 +61,12 @@ To create an initial Blockstack ID, do the following:
an `id.blockstack` that you've created. You should store the words along
with their order, for example, `#1 applied` and so forth.
6. Copy your **Secret Recovery Key** and press **Continue**.
6) Copy your **Secret Recovery Key** and press **Continue**.
The system confirms you have saved your key by asking you to select two words.
7. Choose **Go to Blockstack**.
7) Choose **Go to Blockstack**.
It may take several moments for your username to be recorded on the blockchain. You can still use it but you may see a computer-friendly ID sequence such as `ID-1G9318bjf6FAZvD3gnaSyzUojM6f8xKWK1` until the recording is finalized.
Congratulations you have created your first ID. You are now ready to start using DApps.
@ -12,8 +12,8 @@ When the Blockstack App receives the request, it generates an (`authResponse`) t
During sign in, the Blockstack App generates the app-private key from the user's _identity-address private_ key and the application's `appDomain`. The app private key serves three functions:
* It is used to create the credentials that give an app access to the Gaia storage bucket for that specific app.
* It is used in the end-to-end encryption of files stored for the app in the user's Gaia storage.
* It serves as a cryptographic secret that apps can use to perform other cryptographic functions.
- It is used to create the credentials that give an app access to the Gaia storage bucket for that specific app.
- It is used in the end-to-end encryption of files stored for the app in the user's Gaia storage.
- It serves as a cryptographic secret that apps can use to perform other cryptographic functions.
Finally, the app private key is deterministic, meaning that for a given user ID and domain name, the same private key is generated each time.
description: Interacting with the Stacks 2.0 Blockchain
---
With the launch of Stacks 2.0, a new version of the Blockstack blockchain was released. There are two ways of interacting with the blockchain, either using the Stacks Blockchain API or by making RPC calls to a Stacks Core directly.
## Stacks Core API
The Stacks 2.0 blockchain's Rust implementation exposes RPC endpoints (in JSON format), which can be used to interface with the Stacks blockchain. [You can find the RPC API references here](https://docs.blockstack.org/core/smart/rpc-api.html).
## Stacks Blockchain API
The Stacks Blockchain API was built to maintain pageable materialized views of the Stacks 2.0 Blockchain. It is a server that exposes a RESTful JSON API, hosted by PBC. It introduces aidditonal functionality (e.g. get all transactions), as well as proxies calls directly to Stacks Node. [You can find the OpenAPI specification and documentation here](https://blockstack.github.io/stacks-blockchain-sidecar/).
*Note: Using this API requires you to trust the server, but provides a faster onboarding experience. It also addresses performance issues for which querying a node itself would be too slow or difficult.*
_Note: Using this API requires you to trust the server, but provides a faster onboarding experience. It also addresses performance issues for which querying a node itself would be too slow or difficult._
{% include note.html content="If you are looking for the Stacks 1.0 RPC endpoint references, please follow [this link](https://core.blockstack.org/)." %}
* A 64-bit CPU running at at least 1 GHz is *highly* recommended (but not strictly required)
* You will need ~250MB RAM and ~10 GB disk free. Do **not** attempt to use a network-attached disk for this.
* You should have at least 30,000 inodes free in your filesystem. Unless you are using a very small VM image, you almost certainly have enough (you can check with `df -i`).
* TCP port 6264 should be open and support bidirectional traffic. If you want to use SSL, then port 6263 should be open.
* A reliable Internet connection of DSL-like quality or higher
- A 64-bit CPU running at at least 1 GHz is _highly_ recommended (but not strictly required)
- You will need ~250MB RAM and ~10 GB disk free. Do **not** attempt to use a network-attached disk for this.
- You should have at least 30,000 inodes free in your filesystem. Unless you are using a very small VM image, you almost certainly have enough (you can check with `df -i`).
- TCP port 6264 should be open and support bidirectional traffic. If you want to use SSL, then port 6263 should be open.
- A reliable Internet connection of DSL-like quality or higher
## Deployment
### The Easy Way
* Install from `pip`, source code, or Docker
* Run `blockstack-core fast_sync`
* Run `blockstack-core start`
- Install from `pip`, source code, or Docker
- Run `blockstack-core fast_sync`
- Run `blockstack-core start`
### The Less Easy Way
* Install from `pip`, source code, or Docker
* Run `blockstack-core start`
* Wait a few days
- Install from `pip`, source code, or Docker
- Run `blockstack-core start`
- Wait a few days
#### Best Practices for the Less Easy Way
* Take a `blockstack-server.snapshots` database from a known-good node and pass `--expected_snapshots=/path/to/blockstack-server.snapshots`. This will force your bootstrapping node to verify that it reaches the same sequence of consensus hashes as it bootstraps (i.e. your node will detect any divergence from Blockstack's name history and abort early, instead of wasting your time).
* Make sure you're in a position to leave the node online at 100% CPU use for the duration of its bootstrapping period
- Take a `blockstack-server.snapshots` database from a known-good node and pass `--expected_snapshots=/path/to/blockstack-server.snapshots`. This will force your bootstrapping node to verify that it reaches the same sequence of consensus hashes as it bootstraps (i.e. your node will detect any divergence from Blockstack's name history and abort early, instead of wasting your time).
- Make sure you're in a position to leave the node online at 100% CPU use for the duration of its bootstrapping period
### The Hard Way
* Install `bitcoind` (version 0.16.x is recommended for now)
* Start `bitcoind` as `bitcoind -daemon -txindex=1`
* Wait for `bitcoind` to download the entire blockchain. This can take between 1 hour and 1 day.
* Install `blockstack-core` from source, `pip`, or Docker
* Run `blockstack-core configure` and enter your `bitcoind` node's IP address, port, RPC username, and RPC password when prompted
* Run `blockstack-core start`
* Wait a few days
- Install `bitcoind` (version 0.16.x is recommended for now)
- Start `bitcoind` as `bitcoind -daemon -txindex=1`
- Wait for `bitcoind` to download the entire blockchain. This can take between 1 hour and 1 day.
- Install `blockstack-core` from source, `pip`, or Docker
- Run `blockstack-core configure` and enter your `bitcoind` node's IP address, port, RPC username, and RPC password when prompted
- Run `blockstack-core start`
- Wait a few days
#### Best Practices for the Hard Way
* You're going to need ~500 GB of space for the Bitcoin blockchain state
* You can safely store its chain state on a network-attached disk, if you're doing this in a cloud-hosted environment
* Your `bitcoind` host will need TCP:8332-8333 open for bidirectional traffic
- You're going to need ~500 GB of space for the Bitcoin blockchain state
- You can safely store its chain state on a network-attached disk, if you're doing this in a cloud-hosted environment
- Your `bitcoind` host will need TCP:8332-8333 open for bidirectional traffic
## Troubleshooting
### The node stops responding to TCP:6264
* Check `dmesg` for TCP SYN flooding. The solution here is to kill and restart the node.
* To mitigate, install a rate-limiting proxy HTTP server in front of the node. We have a sample config for `nginx` [here](https://github.com/blockstack/atlas/blob/master/public_fleet/node/default).
- Check `dmesg` for TCP SYN flooding. The solution here is to kill and restart the node.
- To mitigate, install a rate-limiting proxy HTTP server in front of the node. We have a sample config for `nginx` [here](https://github.com/blockstack/atlas/blob/master/public_fleet/node/default).
### No other Blockstack nodes contact my node
* Verify that your IP address is publicly-routable, and that peers can communicate on TCP:6264
- Verify that your IP address is publicly-routable, and that peers can communicate on TCP:6264
### People are attacking my Bitcoin node
* Stick an `nginx` reverse proxy in front of your `bitcoind` node, and use our [nginx](https://github.com/blockstack/atlas/tree/master/public_fleet/bitcoind) scripts to limit APi access to only the JSON-RPC methods Blockstack actually needs. Better yet, do what we do---build a statically-linked `bitcoind` binary from source that simply omits all of the RPC methods except the ones listed in the linked config file.
- Stick an `nginx` reverse proxy in front of your `bitcoind` node, and use our [nginx](https://github.com/blockstack/atlas/tree/master/public_fleet/bitcoind) scripts to limit APi access to only the JSON-RPC methods Blockstack actually needs. Better yet, do what we do---build a statically-linked `bitcoind` binary from source that simply omits all of the RPC methods except the ones listed in the linked config file.
This document lists frequently-asked questions developers about Blockstack application development. If you are new to Blockstack, you should read the [general questions]({{site.baseurl}}/faqs/allFAQs.html) first.
@ -12,15 +13,19 @@ If you have a technical question that gets frequently asked on the
feel free to send a pull-request with the question and answer.
@ -5,7 +5,8 @@ Step-by-step instructions for deploying a Blockstack API node on Debian or Ubunt
- **Step 1:** Make sure you have a Stacks Node running locally (see [instructions](https://github.com/blockstack/blockstack-core/blob/master/README.md#quick-start)).
- **Step 2:** Make sure you have [virtualenv installed](http://docs.python-guide.org/en/latest/dev/virtualenvs/).
Making a namespace is very expensive. Given the large amount of cryptocurrency at stake in name creation, developers wanting to create their own namespaces should read [Understand Namespaces]({{ site.baseurl }}/core/naming/namespaces.html) first. You should also read this document thoroughly before creating a namespace.
@ -13,16 +12,16 @@ There are four steps to creating a namespace.
### Step 1. Send a `NAMESPACE_PREORDER` transaction
This step registers the *salted hash* of the namespace with BNS nodes, and burns the requisite amount of cryptocurrency. Additionally, this step proves to the BNS nodes that user has honored the BNS consensus rules by including a recent *consensus hash* in the transaction (see the section on [BNS forks](#bns-forks) for details).
This step registers the _salted hash_ of the namespace with BNS nodes, and burns the requisite amount of cryptocurrency. Additionally, this step proves to the BNS nodes that user has honored the BNS consensus rules by including a recent _consensus hash_ in the transaction (see the section on [BNS forks](#bns-forks) for details).
### Step 2. Send a `NAMESPACE_REVEAL` transaction
This second step reveals the salt and the namespace ID (pairing it with its
`NAMESPACE_PREORDER`). It reveals how long names last in this namespace before
they expire or must be renewed, and it sets a *price function* for the namespace
they expire or must be renewed, and it sets a _price function_ for the namespace
that determines how cheap or expensive names its will be.
The price function takes a name in this namespace as input, and outputs the amount of cryptocurrency the name will cost. The function does this by examining how long the name is, and whether or not it has any vowels or non-alphabet characters. The namespace creator has the option to collect name registration fees for the first year of the namespace's existence by setting a *namespace creator address*.
The price function takes a name in this namespace as input, and outputs the amount of cryptocurrency the name will cost. The function does this by examining how long the name is, and whether or not it has any vowels or non-alphabet characters. The namespace creator has the option to collect name registration fees for the first year of the namespace's existence by setting a _namespace creator address_.
### Step 3. Seed the namespace with `NAME_IMPORT` transactions
@ -32,7 +31,7 @@ This step is optional; Namespace creators are not required to import names.
### Step 4. Send a `NAMESPACE_READY` transaction
The final step of the process *launches* the namespace and makes the namespace available to the
The final step of the process _launches_ the namespace and makes the namespace available to the
public. Once a namespace is launched, anyone can register a name in it if they
pay the appropriate amount of cryptocurrency. Again, the appropriate amount is according to the price function
revealed in step 2.
@ -94,5 +93,3 @@ If you would like to navigate a namespace history, you can. To do this, do the f
3. Provide the id in a query to a blockchain explorer such as [Blockchain.com](https://www.blockchain.com/) or similar.
For example, a search on Blockchain returns this [page of information](https://www.blockchain.com/btc/tx/5f00b8e609821edd6f3369ee4ee86e03ea34b890e242236cdb66ef6c9c6a1b28).
| `NAME_UPDATE` | This changes the name's zone file hash. Any 20-byte string is allowed. |
| `NAME_TRANSFER` | This changes the name's public key hash. In addition, the current owner has the option to atomically clear the name's zone file hash (so the new owner won't "receive" the zone file). |
| `NAME_REVOKE` | This renders a name unresolvable. You should do this if your private key is compromised. |
@ -46,8 +47,8 @@ document for details on how to construct this transaction.
A `NAME_TRANSFER` transaction changes the name's public key hash. You would
send one of these transactions if you wanted to:
* Change your private key
* Send the name to someone else
- Change your private key
- Send the name to someone else
When transferring a name, you have the option to also clear the name's zone
The intention is that each application can create its own BNS
namespace for its own purposes. Applications can use namespaces for things like:
* Giving users a SSO system, where each user registers their public key under a
- Giving users a SSO system, where each user registers their public key under a
username. Blockstack applications do this with names in the `.id` namespace,
for example.
for example.
* Providing a subscription service, where each name is a 3rd party that provides
a service for users to subscribe to. For example, names in
`.podcast` point to podcasts that users of the [DotPodcast](https://dotpodcast.co) app can subscribe to.
* Implementing software licenses, where each name corresponds to an access key.
- Providing a subscription service, where each name is a 3rd party that provides
a service for users to subscribe to. For example, names in
`.podcast` point to podcasts that users of the [DotPodcast](https://dotpodcast.co) app can subscribe to.
- Implementing software licenses, where each name corresponds to an access key.
Unlike conventional access keys, access keys implemented as names
can be sold and traded independently. The licensing fee (paid as a name
registration) would be set by the developer and sent to a developer-controlled
blockchain address.
can be sold and traded independently. The licensing fee (paid as a name
registration) would be set by the developer and sent to a developer-controlled
blockchain address.
Names within a namespace can serve any purpose the developer wants. The ability
to collect registration fees for 1 year after creating the namespace not only
@ -102,36 +102,36 @@ transaction.
## Create a namespace
There are four steps to creating a namespace:
There are four steps to creating a namespace:
1. **Send a `NAMESPACE_PREORDER` transaction** ([live example](https://www.blocktrail.com/BTC/tx/5f00b8e609821edd6f3369ee4ee86e03ea34b890e242236cdb66ef6c9c6a1b28)).
This is the first step. This registers the *salted hash* of the namespace with BNS nodes, and burns the
requisite amount of cryptocurrency. In addition, it proves to the
BNS nodes that user has honored the BNS consensus rules by including
a recent *consensus hash* in the transaction
(see the section on [BNS forks](#bns-forks) for details).
This is the first step. This registers the _salted hash_ of the namespace with BNS nodes, and burns the
requisite amount of cryptocurrency. In addition, it proves to the
BNS nodes that user has honored the BNS consensus rules by including
a recent _consensus hash_ in the transaction
(see the section on [BNS forks](#bns-forks) for details).
2. **Send a `NAMESPACE_REVEAL` transaction** ([live example](https://www.blocktrail.com/BTC/tx/ab54b1c1dd5332dc86b24ca2f88b8ca0068485edf0c322416d104c5b84133a32)).
This is the second step. This reveals the salt and the namespace ID (pairing it with its
`NAMESPACE_PREORDER`), it reveals how long names last in this namespace before
they expire or must be renewed, and it sets a *price function* for the namespace
that determines how cheap or expensive names its will be. The price function takes
a name in this namespace as input, and outputs the amount of cryptocurrency the
name will cost (i.e. by examining how long the name is, and whether or not it
has any vowels or non-alphabet characters). The namespace creator
has the option to collect name registration fees for the first year of the
namespace's existence by setting a *namespace creator address*.
This is the second step. This reveals the salt and the namespace ID (pairing it with its
`NAMESPACE_PREORDER`), it reveals how long names last in this namespace before
they expire or must be renewed, and it sets a _price function_ for the namespace
that determines how cheap or expensive names its will be. The price function takes
a name in this namespace as input, and outputs the amount of cryptocurrency the
name will cost (i.e. by examining how long the name is, and whether or not it
has any vowels or non-alphabet characters). The namespace creator
has the option to collect name registration fees for the first year of the
namespace's existence by setting a _namespace creator address_.
3. **Seed the namespace with `NAME_IMPORT` transactions** ([live example](https://www.blocktrail.com/BTC/tx/c698ac4b4a61c90b2c93dababde867dea359f971e2efcf415c37c9a4d9c4f312)).
Once the namespace has been revealed, the user has the option to populate it with a set of
names. Each imported name is given both an owner and some off-chain state.
This step is optional---namespace creators are not required to import names.
Once the namespace has been revealed, the user has the option to populate it with a set of
names. Each imported name is given both an owner and some off-chain state.
This step is optional---namespace creators are not required to import names.
4. **Send a `NAMESPACE_READY` transaction** ([live example](https://www.blocktrail.com/BTC/tx/2bf9a97e3081886f96c4def36d99a677059fafdbd6bdb6d626c0608a1e286032)).
This is the final step of the process. It *launches* the namespace, which makes it available to the
public. Once a namespace is ready, anyone can register a name in it if they
pay the appropriate amount of cryptocurrency (according to the price funtion
revealed in step 2).
This is the final step of the process. It _launches_ the namespace, which makes it available to the
public. Once a namespace is ready, anyone can register a name in it if they
pay the appropriate amount of cryptocurrency (according to the price funtion
revealed in step 2).
The reason for the `NAMESPACE_PREORDER/NAMESPACE_REVEAL` pairing is to prevent
frontrunning. The BNS consensus rules require a `NAMESPACE_REVEAL` to be
- **Step 2:** Make sure you have a Stacks Node running locally (see [instructions](https://github.com/blockstack/blockstack-core/blob/master/README.md#quick-start)). We highly
recommend using a local node because the search subsystem issues thousands of calls to
a Stacks Node for re-indexing and remote nodes can slow down performance.
recommend using a local node because the search subsystem issues thousands of calls to
a Stacks Node for re-indexing and remote nodes can slow down performance.
- **Step 3:** Fetch the data for the .id namespace and respective profiles. Note, you may want to redirect stderr to a file, as there is a lot of debug output.
Follow the [instructions here](https://github.com/blockstack/blockstack-core/blob/master/integration_tests/README.md) to download the regtesting Docker image.
Since the subdomain registrar service runs on port 3000, we need to do two things to expose this endpoint to interact with it from the browser:
- Open port 3000 with `-p 3000:3000`
Here's the full command you'd run to start the interactive testing scenario:
@ -18,18 +18,18 @@ Apps can take advantage of smart contracts to manage a global state that is visi
Not every decentralized application requires smart contracts, but Clarity unlocks interesting capabilities for decentralized applications. Examples of use cases include, but are not limited to:
* Access control (e.g. pay to access)
* Non-fungible (e.g. collectibles) and fungible tokens (e.g. stablecoins)
* Business model templates (e.g. subscriptions)
* App-specific blockchains
* Decentralized Autonomous Organizations
- Access control (e.g. pay to access)
- Non-fungible (e.g. collectibles) and fungible tokens (e.g. stablecoins)
- Business model templates (e.g. subscriptions)
- App-specific blockchains
- Decentralized Autonomous Organizations
## Language design
Clarity differs from most other smart contract languages in two essential ways:
* The language is interpreted and broadcasted on the blockchain as is (not compiled)
* The language is decidable (not Turing complete)
- The language is interpreted and broadcasted on the blockchain as is (not compiled)
- 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 is going to be executed, for any function.
@ -37,11 +37,11 @@ A Clarity smart contract is composed of two parts — a data space and a set
Note some of the key Clarity language rules and limitations.
* The only primitive types are booleans, integers, buffers, and principals
* Recursion is illegal and there are no anonymous functions.
* Looping may only be performed via `map`, `filter`, or `fold`
* There is support for lists, however, the only variable length lists in the language appear as function inputs; There is no support for list operations like append or join.
* Variables are immutable.
- The only primitive types are booleans, integers, buffers, and principals
- Recursion is illegal and there are no anonymous functions.
- Looping may only be performed via `map`, `filter`, or `fold`
- There is support for lists, however, the only variable length lists in the language appear as function inputs; There is no support for list operations like append or join.
The Stacks 2.0 testnet is currently in development. As part of the testnet, you can run a node and connect it to a public network. This guide will walk you through downloading and running your own node in the testnet network.
### Prerequisites
Note: If you use Linux, you may need to manually install [`libssl-dev`](https://wiki.openssl.org/index.php/Libssl_API) and other packages. In your command line, run the following to get all packages:
In this tutorial, you learn how to implement a smart contract that stores and manipulates an integer value on the Stacks 2.0 blockchain. By the end of this tutorial, you will ...
* Have experienced test-driven development with Clarity
* Understand more Clarity language design principles
* Have a working Clarity counter smart contract
- Have experienced test-driven development with Clarity
- Understand more Clarity language design principles
- Have a working Clarity counter smart contract
## Overview
@ -82,7 +82,11 @@ Let's get familiar with the tests to understand what the new smart contract shou
You should be familiar with the test set up from the Hello World tutorial. Notice how the instance of the smart contract is created on line 8:
```js
counterClient = new Client("SP3GWX3NE58KXHESRYE4DYQ1S31PQJTCRXB3PE9SB.counter", "counter", provider);
That tells us that the new smart contract is named `counter` and that it should be found in the following file: `contracts/counter.clar`. Note that the `contracts` folder is assumed as the base folder and that every Clarity file has the suffix `.clar`.
@ -140,6 +144,7 @@ Let's get familiar with the tests to understand what the new smart contract shou
✓ should start at zero
✓ should increment (133ms)
✓ should decrement (177ms)
```
4 passing (586ms)
@ -166,15 +171,14 @@ Here is how the final smart contract file should look like. Note that you can fi
(ok (var-get counter))))
```
If you're ready to deploy and execute the contract, try [the Explorer Sandbox](tutorial.html#access-the-explorer-sandbox) or following [the instructions to run the contract in the command-line](tutorial.html#get-familiar-with-cli-optional).
---
## If you're ready to deploy and execute the contract, try [the Explorer Sandbox](tutorial.html#access-the-explorer-sandbox) or following [the instructions to run the contract in the command-line](tutorial.html#get-familiar-with-cli-optional).
With the completion of this tutorial, you ...
* Experienced test-driven development with Clarity
* Understood more Clarity language design principles
* Developed a working Clarity counter smart contract
- Experienced test-driven development with Clarity
- Understood more Clarity language design principles
- Developed a working Clarity counter smart contract
## Where to go next
*<ahref="clarityRef.html">Clarity language reference</a>
-<ahref="clarityRef.html">Clarity language reference</a>
@ -9,10 +9,10 @@ description: Learn to Test Clarity Contract Code with JavaScript and Mocha
| Experience | | **Advanced** |
| Duration | | **15 minutes** |
Clarity, Blockstack's smart contracting language, is based on [LISP](https://en.wikipedia.org/wiki/Lisp_(programming_language)). Clarity is an interpreted language, and [decidable](https://en.wikipedia.org/wiki/Recursive_language). In this tutorial, you will learn how to test Clarity and how use [Mocha](https://mochajs.org/) to test Clarity contracts while you develop them.
Clarity, Blockstack's smart contracting language, is based on [LISP](<https://en.wikipedia.org/wiki/Lisp_(programming_language)>). Clarity is an interpreted language, and [decidable](https://en.wikipedia.org/wiki/Recursive_language). In this tutorial, you will learn how to test Clarity and how use [Mocha](https://mochajs.org/) to test Clarity contracts while you develop them.
* Have a working Clarity starter project
* Understand how to test Clarity code using `.ts` files and Mocha.
- Have a working Clarity starter project
- Understand how to test Clarity code using `.ts` files and Mocha.
## Prerequisites
@ -83,7 +83,7 @@ Take a few seconds to review the contents of the file. You should ignore the tes
Note that we're importing modules from the `@blockstack/clarity` package:
```js
import { Client, Provider, ProviderRegistry, Result } from "@blockstack/clarity";
import { Client, Provider, ProviderRegistry, Result } from '@blockstack/clarity';
@ -15,11 +15,10 @@ Clarity, Blockstack's smart contracting language, is based on LISP and uses its
By the end of this tutorial, you will:
* Have a working Clarity starter project and local dev environment
* Understand basic Clarity language design principles
* Deploy a contract to the Stacks 2.0 blockchain and call its public methods
* Understand how to use the Explorer Sandbox functionality
- Have a working Clarity starter project and local dev environment
- Understand basic Clarity language design principles
- Deploy a contract to the Stacks 2.0 blockchain and call its public methods
- Understand how to use the Explorer Sandbox functionality
## Prerequisites
@ -79,11 +78,12 @@ On the first line, a new public function `say-hi` is declared. Public functions
The function doesn't take any parameters and simply returns "hello world" using the [`ok`](clarityRef.html#ok) response constructor.
The second function, `echo-number`, is a [read-only function](clarityRef.html#define-read-only). Read-only functions are also public, but as the name implies, they can not perform any datamap modifications. `echo-number` takes an input parameter of the type `int`. Along with integer, Clarity supports the following [types](clarityRef.html#clarity-type-system):
* `uint`: 16-byte unsigned integer
* `principal`: spending entity, roughly equivalent to a Stacks address
* `boolean`: `true` or `false`
* `buffer`: fixed-length byte buffers
* `tuple`: named fields in keys and values
- `uint`: 16-byte unsigned integer
- `principal`: spending entity, roughly equivalent to a Stacks address
- `boolean`: `true` or `false`
- `buffer`: fixed-length byte buffers
- `tuple`: named fields in keys and values
`echo-number` uses an [`ok`](clarityRef.html#ok) response to return the value passed to the function.
@ -116,7 +116,7 @@ Go back to the Sandbox screen, switch to the [**Contract deploy**](https://testn
1. Enter a name for the contract under **Contract name** that uses lower-case letters, dashes, and numbers only.
2. Replace code in the text area under **Contract source code** with the contents of `contracts/hello-world.clar`.
3. Ignore the **Choose from sample** drop-down for now. After completing this tutorial you can come back to the Explorer Sandbox and use this drop-down to try other sample contracts.
3. Click **Deploy contract**.
4. Click **Deploy contract**.
![deploy](images/contract-deploy.png)
@ -126,8 +126,8 @@ A confirmation will pop up, indicating that a new contract deploy transaction wa
Go back to the Sandbox screen, switch to the [**Contract call**](https://testnet-explorer.blockstack.org/sandbox?tab=contract-call) tab, and enter the following details:
***Contract address**: Your generated STX address. Hover over the identity component on the right side of the screen to copy your full address and paste it in here.
***Contract name**: Whatever you entered as your contract name in the previous step. If you forgot, you can review your recent transactions by following the link on the upper-right, and look up your contract creation transaction.
-**Contract address**: Your generated STX address. Hover over the identity component on the right side of the screen to copy your full address and paste it in here.
-**Contract name**: Whatever you entered as your contract name in the previous step. If you forgot, you can review your recent transactions by following the link on the upper-right, and look up your contract creation transaction.
![Screenshot of the Sandbox's contract call screen](images/sandbox-call.png)
@ -143,10 +143,10 @@ Locate the `(echo-number)` method, provide any integer for the `val` argument an
With the completion of this tutorial, you now:
* Have a working Clarity starter project and local dev environment
* Understand basic Clarity language design principles
* Have deployed a contract to the Stacks 2.0 blockchain and called its public methods
* Understand how to use the Explorer Sandbox functionality
- Have a working Clarity starter project and local dev environment
- Understand basic Clarity language design principles
- Have deployed a contract to the Stacks 2.0 blockchain and called its public methods
- Understand how to use the Explorer Sandbox functionality
## Get familiar with CLI (optional)
@ -200,5 +200,5 @@ To learn more about the Blockstack CLI commands, you can run `blockstack-cli hel
## Where to go next
*<ahref="tutorial-counter.html">Next tutorial: Writing a counter smart contract</a>
*<ahref="tutorial-test.html">Tutorial: Testing contracts with JavaScript and Mocha</a>
-<ahref="tutorial-counter.html">Next tutorial: Writing a counter smart contract</a>
-<ahref="tutorial-test.html">Tutorial: Testing contracts with JavaScript and Mocha</a>
@ -5,22 +5,22 @@ It describes the transaction formats for the Bitcoin blockchain.
## Transaction format
Each Bitcoin transaction for Blockstack contains signatures from two sets of keys: the name owner, and the payer. The owner `scriptSig` and `scriptPubKey` fields are generated from the key(s) that own the given name. The payer `scriptSig` and `scriptPubKey` fields are used to *subsidize* the operation. The owner keys do not pay for any operations; the owner keys only control the minimum amount of BTC required to make the transaction standard. The payer keys only pay for the transaction's fees, and (when required) they pay the name fee.
Each Bitcoin transaction for Blockstack contains signatures from two sets of keys: the name owner, and the payer. The owner `scriptSig` and `scriptPubKey` fields are generated from the key(s) that own the given name. The payer `scriptSig` and `scriptPubKey` fields are used to _subsidize_ the operation. The owner keys do not pay for any operations; the owner keys only control the minimum amount of BTC required to make the transaction standard. The payer keys only pay for the transaction's fees, and (when required) they pay the name fee.
This construction is meant to allow the payer to be wholly separate from the owner. The principal that owns the name can fund their own transactions, or they can create a signed transaction that carries out the desired operation and request some other principal (e.g. a parent organization) to actually pay for and broadcast the transaction.
(1) The owner `scriptSig` is *always* the first input.
(2) The `OP_RETURN` script that describes the name operation is *always* the first output.
(3) The owner `scriptPubKey` is *always* the second output.
(1) The owner `scriptSig` is _always_ the first input.
(2) The `OP_RETURN` script that describes the name operation is _always_ the first output.
(3) The owner `scriptPubKey` is _always_ the second output.
(4) The payer can use as many payment inputs as (s)he likes.
(5) At most one output will be the "change" `scriptPubKey` for the payer.
Different operations require different outputs.
@ -29,18 +29,19 @@ Different operations require different outputs.
Each Blockstack transaction in Bitcoin describes the name operation within an `OP_RETURN` output. It encodes name ownership, name fees, and payments as `scriptPubKey` outputs. The specific operations are described below.
Each `OP_RETURN` payload *always* starts with the two-byte string `id` (called the "magic" bytes in this document), followed by a one-byte `op` that describes the operation.
Each `OP_RETURN` payload _always_ starts with the two-byte string `id` (called the "magic" bytes in this document), followed by a one-byte `op` that describes the operation.
### NAME_PREORDER
Op: `?`
Description: This transaction commits to the *hash* of a name. It is the first
Description: This transaction commits to the _hash_ of a name. It is the first
transaction of two transactions that must be sent to register a name in BNS.
* `p2pkh``scriptPubkey` to the burn address (0x00000000000000000000000000000000000000)
- `OP_RETURN` payload
- Payment `scriptPubkey` script for change
- `p2pkh``scriptPubkey` to the burn address (0x00000000000000000000000000000000000000)
Notes:
* `register_addr` is a base58check-encoded `ripemd160(sha256(pubkey))` (i.e. an address). This address **must not** have been used before in the underlying blockchain.
* `script_pubkey` is either a `p2pkh` or `p2sh` compiled Bitcoin script for the payer's address.
- `register_addr` is a base58check-encoded `ripemd160(sha256(pubkey))` (i.e. an address). This address **must not** have been used before in the underlying blockchain.
- `script_pubkey` is either a `p2pkh` or `p2sh` compiled Bitcoin script for the payer's address.
*`scriptPubkey` for the owner's addess. This can be a different address than
-`OP_RETURN` payload
-`scriptPubkey` for the owner's addess. This can be a different address than
the current name owner (in which case, the name is renewed and transferred).
*`scriptPubkey` for the payer's change
*`scriptPubkey` for the burn address (to pay the name cost)
-`scriptPubkey` for the payer's change
-`scriptPubkey` for the burn address (to pay the name cost)
Notes:
* This transaction is identical to a `NAME_REGISTRATION`, except for the presence of the fourth output that pays for the name cost (to the burn address).
* Variation 1 simply renews the name. Variation 2 will both renew the name and
- This transaction is identical to a `NAME_REGISTRATION`, except for the presence of the fourth output that pays for the name cost (to the burn address).
- Variation 1 simply renews the name. Variation 2 will both renew the name and
set a new name value (in practice, the hash of a new zone file).
* Both variations are supported. Variation 1 was designed for the time when
- Both variations are supported. Variation 1 was designed for the time when
Bitcoin only supported 40-byte `OP_RETURN` outputs.
* This operation can be used to transfer a name to a new address by setting the
- This operation can be used to transfer a name to a new address by setting the
second output (the first `scriptPubkey`) to be the `scriptPubkey` of the new
*`p2pkh` script to the burn address `1111111111111111111114oLvT2`, whose public key hash is 0x00000000000000000000000000000000
-`OP_RETURN` payload
- Namespace payer `scriptPubkey` change address
-`p2pkh` script to the burn address `1111111111111111111114oLvT2`, whose public key hash is 0x00000000000000000000000000000000
Notes:
* The `reveal_addr` field is the address of the namespace revealer public key. The revealer private key will be used to generate `NAME_IMPORT` transactions.
- The `reveal_addr` field is the address of the namespace revealer public key. The revealer private key will be used to generate `NAME_IMPORT` transactions.
### NAMESPACE_REVEAL
@ -318,6 +334,7 @@ for a previously-anounced namespace hash (sent by a previous `NAMESPACE_PREORDER
* This transaction must be sent within 1 day of the `NAMESPACE_PREORDER`
* The second output (with the namespace revealer) **must** be a `p2pkh` script
* The address of the second output **must** be the `reveal_addr` in the `NAMESPACE_PREORDER`
- This transaction must be sent within 1 day of the `NAMESPACE_PREORDER`
- The second output (with the namespace revealer) **must** be a `p2pkh` script
- The address of the second output **must** be the `reveal_addr` in the `NAMESPACE_PREORDER`
Pricing:
The rules for a namespace are as follows:
* a name can fall into one of 16 buckets, measured by length. Bucket 16 incorporates all names at least 16 characters long.
* the pricing structure applies a multiplicative penalty for having numeric characters, or punctuation characters.
* the price of a name in a bucket is ((coeff) * (base) ^ (bucket exponent)) / ((numeric discount multiplier) * (punctuation discount multiplier))
- a name can fall into one of 16 buckets, measured by length. Bucket 16 incorporates all names at least 16 characters long.
- the pricing structure applies a multiplicative penalty for having numeric characters, or punctuation characters.
- the price of a name in a bucket is ((coeff) _ (base) ^ (bucket exponent)) / ((numeric discount multiplier) _ (punctuation discount multiplier))
Example:
* base = 10
* coeff = 2
* nonalpha discount: 10
* no-vowel discount: 10
* buckets 1, 2: 9
* buckets 3, 4, 5, 6: 8
* buckets 7, 8, 9, 10, 11, 12, 13, 14: 7
* buckets 15, 16+:
With the above example configuration, the following are true:
- base = 10
- coeff = 2
- nonalpha discount: 10
- no-vowel discount: 10
- buckets 1, 2: 9
- buckets 3, 4, 5, 6: 8
- buckets 7, 8, 9, 10, 11, 12, 13, 14: 7
- buckets 15, 16+:
* The price of "john" would be 2 * 10^8, since "john" falls into bucket 4 and has no punctuation or numerics.
* The price of "john1" would be 2 * 10^6, since "john1" falls into bucket 5 but has a number (and thus receives a 10x discount)
* The price of "john_1" would be 2 * 10^6, since "john_1" falls into bucket 6 but has a number and punctuation (and thus receives a 10x discount)
* The price of "j0hn_1" would be 2 * 10^5, since "j0hn_1" falls into bucket 6 but has a number and punctuation and lacks vowels (and thus receives a 100x discount)
With the above example configuration, the following are true:
- The price of "john" would be 2 \* 10^8, since "john" falls into bucket 4 and has no punctuation or numerics.
- The price of "john1" would be 2 \* 10^6, since "john1" falls into bucket 5 but has a number (and thus receives a 10x discount)
- The price of "john_1" would be 2 \* 10^6, since "john_1" falls into bucket 6 but has a number and punctuation (and thus receives a 10x discount)
- The price of "j0hn_1" would be 2 \* 10^5, since "j0hn_1" falls into bucket 6 but has a number and punctuation and lacks vowels (and thus receives a 100x discount)
### NAME_IMPORT
@ -379,6 +396,7 @@ creator can import names. See the [namespace creation section]({{ site.baseurl
* The namespace reveal `scriptSig` (with the namespace revealer's public key), or one of its first 300 extended public keys
* Any payment inputs
- The namespace reveal `scriptSig` (with the namespace revealer's public key), or one of its first 300 extended public keys
- Any payment inputs
Outputs:
*`OP_RETURN` payload
* recipient `scriptPubKey`
* zone file hash (using the 20-byte hash in a standard `p2pkh` script)
* payment change `scriptPubKey`
-`OP_RETURN` payload
- recipient `scriptPubKey`
- zone file hash (using the 20-byte hash in a standard `p2pkh` script)
- payment change `scriptPubKey`
Notes:
* These transactions can only be sent between the `NAMESPACE_REVEAL` and `NAMESPACE_READY`.
* The first `NAME_IMPORT` transaction **must** have a `scriptSig` input that matches the `NAMESPACE_REVEAL`'s second output (i.e. the reveal output).
* Any subsequent `NAME_IMPORT` transactions **may** have a `scriptSig` input whose public key is one of the first 300 extended public keys from the `NAMESPACE_REVEAL`'s `scriptSig` public key.
- These transactions can only be sent between the `NAMESPACE_REVEAL` and `NAMESPACE_READY`.
- The first `NAME_IMPORT` transaction **must** have a `scriptSig` input that matches the `NAMESPACE_REVEAL`'s second output (i.e. the reveal output).
- Any subsequent `NAME_IMPORT` transactions **may** have a `scriptSig` input whose public key is one of the first 300 extended public keys from the `NAMESPACE_REVEAL`'s `scriptSig` public key.
* Change output to the namespace revealer's `p2pkh` script
- `OP_RETURN` payload
- Change output to the namespace revealer's `p2pkh` script
Notes:
* This transaction must be sent within 1 year of the corresponding `NAMESPACE_REVEAL` to be accepted.
- This transaction must be sent within 1 year of the corresponding `NAMESPACE_REVEAL` to be accepted.
### TOKEN_TRANSFER
Op: `$`
Description: This transaction transfers tokens from one account to another. Only `STACKS` tokens can be transferred at this time. The transaction encodes the number of *micro-Stacks* to send.
Description: This transaction transfers tokens from one account to another. Only `STACKS` tokens can be transferred at this time. The transaction encodes the number of _micro-Stacks_ to send.
Collections support data portability between applications. Blockstack supplies a `Contact` collection for use by Blockstack applications. Developers can create additional collection types, use them in their own applications, and publish them so other developers can make use of them too.
In this section, you learn the coding guidelines for creating and publishing a new `Collection` type. The following topics are included:
@ -27,7 +27,7 @@ This section demonstrates how to create a new collection type using Typescript.
2. Import the `Collection` class.
```js
import { Collection, Attrs, Serializable } from 'blockstack-collections'
import { Collection, Attrs, Serializable } from 'blockstack-collections';
```
3. Extend the abstract `Collection` class from the `blockstack-collections` package.
@ -78,7 +78,7 @@ This section demonstrates how to create a new collection type using Typescript.
7. Define the `fromObject` and `fromData` serializaiton methods.
These methods serialize and deserialize your `Collection` type. You can use any serialization method you want. Data encryption is handled automatically by the parent `Collection` class, so you *should not* perform any additional encryption.
These methods serialize and deserialize your `Collection` type. You can use any serialization method you want. Data encryption is handled automatically by the parent `Collection` class, so you _should not_ perform any additional encryption.
In the following example code, data is converted to JSON string for storage.
@ -144,7 +144,7 @@ To perform additional processing of a collection, you can override the `get`, `s
## Publish your new type for others to use
While you *can* use your collection exclusively in your application, the Collections feature is intended to enable data portability between DApps. So, you should publish your new type so other developers can make use of it.
While you _can_ use your collection exclusively in your application, the Collections feature is intended to enable data portability between DApps. So, you should publish your new type so other developers can make use of it.
To publish your Collection type, do the following:
Collections is the feature designed to make data portable among Blockstack applications. Sharing is accomplished by storing a user's data in a standardized format at a known, Gaia storage location. Collections associate user data with a user's decentralized ID. When users move among apps, the same data is available to each application the user authorizes.
On this page, you learn what collections are and how to use them. You'll learn about the `Contact` collection in particular. The following topics are covered:
@ -11,7 +11,7 @@ On this page, you learn what collections are and how to use them. You'll learn a
## Understand how collections work
One of Blockstack's goals is to give users true data ownership by enabling *data portability*. Data portability allows users to login with their digital ID on any app and have access to the same data. For example, if a user adds a photo of a Hawaiian vacation in one app, that photo enters the user's data pool. Then, when the user opens a second app, that same photo is available to the second app because the user data, including the photo, is shared via the user's decentralized ID.
One of Blockstack's goals is to give users true data ownership by enabling _data portability_. Data portability allows users to login with their digital ID on any app and have access to the same data. For example, if a user adds a photo of a Hawaiian vacation in one app, that photo enters the user's data pool. Then, when the user opens a second app, that same photo is available to the second app because the user data, including the photo, is shared via the user's decentralized ID.
How do collections work? Blockstack builds a library containing commonly used data schemes. Developers use these classes and objects instead of creating their own, unique data schemes. Using a class from the collections library guarantees class data is stored in Gaia in that format; And, when retrieved, guarantees the same format is returned. This pre-release provides the `Contact` collection. A contact schema produces this structure:
@ -108,7 +108,6 @@ If you have `npm` installed, do the following to run the Contact Manager demo ap
![](images/test-contact.png)
## How to add the Contact collections to your DApp
In this section, you learn how to add `Contact` collection functionality to an existing application. Before beginning, make sure your application is using Blockstack auth and is storing data with Gaia. To start using the `Contact` collection in your Blockstack app, do the following:
@ -137,13 +136,13 @@ In this section, you learn how to add `Contact` collection functionality to an e
This scope grants your app permission to read and write to the user’s `Contact` collection.
```javascript
import { UserSession, AppConfig, makeAuthRequest } from 'blockstack'
import { Contact } from '`blockstack-collections'
import { UserSession, AppConfig, makeAuthRequest } from 'blockstack';
import { Contact } from '`blockstack-collections';
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.
| 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
@ -63,11 +63,7 @@ const authOptions = {
},
};
const App = () => (
<ConnectauthOptions={authOptions}>
// the rest of your app's components
</Connect>
)
const App = () => <ConnectauthOptions={authOptions}>// the rest of your app's components</Connect>;
```
Later, when you want to begin the onboarding process, use the `useConnect` hook to get `connect`'s `doOpenAuth` method.
@ -78,12 +74,8 @@ import { useConnect } from '@blockstack/connect';
Blockstack applications are web applications that authenticate users with Blockstack Auth and store data with Gaia. Both of these technologies can be accessed on the client side. As such, Blockstack apps tend to be simple in design and operation, since in many cases, they don’t have to host anything besides the application’s assets.
## Where to deploy your application
## Where to deploy your application
Before users can interact with your application, you must deploy it on a server that is accessible over the internet. Deploying requires that you:
* Configure or customize the files in the `public` directory.
* Build your application site for deployment.
* Copy your generated application files to your production server.
- Configure or customize the files in the `public` directory.
- Build your application site for deployment.
- Copy your generated application files to your production server.
If you first populated your application with the Blockstack application generator, your application contains the starting blocks for configuring, building, and deploying your app. For example, the React template builds out a scaffolding with the following building blocks.
@ -59,11 +59,11 @@ You can think of CORS interactions as an apartment building with Security. For e
The way you configure CORs depends on which company you use to host your web application. The application generator adds a `cors` directory to your application scaffolding. This directory contains files for Netlify (`_headers` and `_redirects`) as well as one for Firebase (`firebase.json`). The configurations in the `cors` directory make your application's `manifest.json` file accessible to other applications (for example, to the Blockstack Browser). If you are deploying to a service other than Netlify or Firebase, you must configure CORS on that service to include the following headers when serving `manifest.json`:
Blockstack Auth provides single sign on and authentication without third parties or remote servers. On this page, you'll get an overview of authentication from a developer perspective. The following topics are covered:
## Authentication flow
@ -59,9 +58,9 @@ How you implement CORS depends in part on which platform/service you use to serv
Blockstack Auth makes extensive use of public key cryptography. Blockstack uses ECDSA with the `secp256k1` curve. The following sections describe the three public-private key pairs used in the authentication process:
JWT libraries with support for this signing algorithm.
{% include note.html content="The Blockstack JWT implementation is different from other implementations because of the underlying cryptography we employ. There are libraries in <ahref='https://github.com/blockstack/jsontokens-js'>Javascript</a> and <ahref='https://github.com/blockstack/ruby-jwt-blockstack'>Ruby</a> available on the Blockstack Github to allow you to work with these tokens." %}
### Example: authRequest payload schema
```JavaScript
```JavaScript
const requestPayload = {
jti, // UUID
iat, // JWT creation time in seconds
@ -131,7 +129,6 @@ const requestPayload = {
}
```
### Example: authResponse payload schema
```JavaScript
@ -171,19 +168,14 @@ To decode the token and see what information it holds:
You can use the blockstack.js library to create and register an Blockstack username on the Stacks blockchain. This section describes the `Profile` object and contains the following topics:
@ -36,45 +35,45 @@ Follow these steps to create and register a profile for a Blockstack username (`
```es6
const profileOfNaval = {
"@context": "http://schema.org/",
"@type": "Person",
"name": "Naval Ravikant",
"description": "Co-founder of AngelList"
}
'@context': 'http://schema.org/',
'@type': 'Person',
name: 'Naval Ravikant',
description: 'Co-founder of AngelList',
};
```
## Sign a profile as a single token
```es6
import { makeECPrivateKey, wrapProfileToken, Person } from 'blockstack'
import { makeECPrivateKey, wrapProfileToken, Person } from 'blockstack';
A key feature of Radiks is support for private collaboration between multiple users. Supporting collaboration with client-side encryption and user-owned storage can be complicated, but the patterns to implement it are generally the same among most applications. Radiks supplies interfaces for collaboration, making it easy to build private, collaborative apps.
You use the <ahref="https://github.com/blockstack/radiks/blob/master/src/models/user-group.ts"target="_blank"><code>UserGroup</code></a> class to build a collaborative group with Radiks. In this section, you learn about this class.
@ -16,9 +16,9 @@ The general workflow for creating a collaborative group that can share and edit
1. The admin of the group creates a new `UserGroup`.
This group acts as the 'hub' and controls the logic around inviting and removing users.
2. The admin invites one or more other users to a group:
* The admin specifies the username of the user they want to invite
* Radiks looks up the user's public key
* Radiks creates an 'invitation' that is encrypted with the user's public key, and contains information about the `UserGroup`
- The admin specifies the username of the user they want to invite
- Radiks looks up the user's public key
- Radiks creates an 'invitation' that is encrypted with the user's public key, and contains information about the `UserGroup`
3. When the invited user 'activates' an invitation, they create a `GroupMembership`.
They use this membership instance to reference information (such as private keys and signing keys) related to the group.
@ -44,7 +44,6 @@ import { UserGroup } from 'radiks';
Calling `create` on a new `UserGroup` will create the group and activate an invitation for the group's creator.
```javascript
const group = new UserGroup({ name: 'My Group Name' });
await group.create();
@ -52,7 +51,6 @@ await group.create();
A group's creator is also the group's admin.
### Invite users to become members
Use the `makeGroupMembership` method on a `UserGroup` instance to invite a user. The only argument passed to this method is the user's `username`.
@ -70,21 +68,20 @@ console.log(invitation._id); // the ID used to later activate an invitation
You can also create a generic invitation that any user can activate, if they are provided with randomly generated secret key, which should be used to decrypt the invitation. The key is generated when the generic invitation is being created.
~~~javascript
```javascript
import { GenericGroupInvitation, UserGroup } from 'radiks';
const group = await UserGroup.findById(myGroupId);
The Blockstack Radiks feature enables Blockstack decentralized applications (DApps) to index and store across data belonging to multiple users. Radiks works with Blockstack's Gaia Storage System. Using Radiks, you can build multi-player DApps that:
- display real-time updates that reflect in progress changes
- support collaboration among sets of users
## Why use Radiks?
Many applications serve data that users create to share publicly with others. Facebook, Twitter, and Instagram are examples of such applications. Decentralized applications that want to create comparable multi-user experiences must ensure that anything a user creates for public sharing is still under control of the creator in the user's Gaia storage.
@ -33,7 +30,7 @@ Radiks can store both public and sensitive, non-public data since all data is en
## How Radiks authorizes writes
Radiks must ensure that the user is writing to their own data. To ensure this, Radiks creates and manages *signing keys*. These keys sign all writes that a user performs. Radiks server-validates all signatures before performing a write. This guarantees that a user is not able to overwrite another user's data.
Radiks must ensure that the user is writing to their own data. To ensure this, Radiks creates and manages _signing keys_. These keys sign all writes that a user performs. Radiks server-validates all signatures before performing a write. This guarantees that a user is not able to overwrite another user's data.
A Radiks server is also built to support writes in a collaborative but private situation. For example, consider a collaborative document editing application, where users can create organizations and invite users to that organization. All users in that organization should have read and write privileges to the organization data. Thus, these organizations will have a single shared key that is used to sign and encrypt data.
Radiks allows you to model your client data. You can then query this data and display it for a user in multi-player applications. A social application where users want to see the comments of other users is an example of a multi-player application. This page explains how to create a model in your distributed application using Radiks.
## Overview of Model class extension
@ -13,7 +13,7 @@ Blockstack provides a `Model` class you should extend to easily create, save, an
import { Model, User } from 'radiks';
```
Then, create a class that extends this model, and provide a schema. Refer to <ahref="https://github.com/blockstack/radiks/blob/master/src/model.ts"target="_blank">the <code>Model</code> class</a> in the `radiks` repo to get an overview of the class functionality.
Then, create a class that extends this model, and provide a schema. Refer to <ahref="https://github.com/blockstack/radiks/blob/master/src/model.ts"target="_blank">the <code>Model</code> class</a> in the `radiks` repo to get an overview of the class functionality.
Your new class must define a static `className` property. This property is used when storing and querying information. If you fail to add a `className`, Radiks defaults to the actual model's class name (`foobar.ts`) and your application will behave unpredictably.
@ -24,11 +24,12 @@ import { Model, User } from 'radiks';
class Todo extends Model {
static className = 'Todo';
static schema = { // all fields are encrypted by default
static schema = {
// all fields are encrypted by default
title: String,
completed: Boolean,
}
};
};
}
// after authentication:
const todo = new Todo({ title: 'Use Radiks in an app' });
@ -38,8 +39,9 @@ todo.update({
});
await todo.save();
const incompleteTodos = await Todo.fetchOwnList({ // fetch todos that this user created
completed: false
const incompleteTodos = await Todo.fetchOwnList({
// fetch todos that this user created
completed: false,
});
console.log(incompleteTodos.length); // 0
```
@ -55,11 +57,12 @@ Every class must have a static `schema` property which defines the attributes of
```javascript
class Todo extends Model {
static className = 'Todo';
static schema = { // all fields are encrypted by default
static schema = {
// all fields are encrypted by default
title: String,
completed: Boolean,
}
};
};
}
```
The `key` in this object is the field name and the value, for example, `String`, `Boolean`, or `Number`. In this case, the `title` is a `String` field. Alternatively, you can pass options instead of a type.
@ -86,13 +89,13 @@ class Person extends Model {
isHuman: Boolean,
likesDogs: {
type: Boolean,
decrypted: true // all users will know if this record likes dogs!
}
}
decrypted: true, // all users will know if this record likes dogs!
},
};
static defaults = {
likesDogs: true
}
likesDogs: true,
};
}
```
@ -123,13 +126,12 @@ The default `User` model defines a `username`, but you can add a `displayName` t
In this section, you learn how to use a model you have defined.
### About the _id attribute
### About the \_id attribute
All model instances have an `_id` attribute. An `_id` is used as a primary key when storing data and is used for fetching a model. Radiks also creates a `createdAt` and `updatedAt` property when creating and saving models.
If, when constructing a model's instance, you don't pass an `_id`, Radiks creates an `_id` for you automatically. This automatically created id uses the [`uuid/v4`](https://github.com/kelektiv/node-uuid) format. This automatic `_id` is returned by the constructor.
### Construct a model instance
To create an instance, pass some attributes to the constructor of that class:
@ -138,8 +140,8 @@ To create an instance, pass some attributes to the constructor of that class:
const person = new Person({
name: 'Hank',
isHuman: false,
likesDogs: false // just an example, I love dogs!
})
likesDogs: false, // just an example, I love dogs!
});
```
### Fetch an instance
@ -150,7 +152,6 @@ To fetch an existing instance of an instance, you need the instance's `id` prop
const person = await Person.findById('404eab3a-6ddc-4ba6-afe8-1c3fff464d44');
```
After calling these methods, Radiks automatically decrypts all encrypted fields.
### Access attributes
@ -169,9 +170,9 @@ To quickly update multiple attributes of an instance, pass those attributes to t
```javascript
const newAttributes = {
likesDogs: false,
age: 30
}
person.update(newAttributes)
age: 30,
};
person.update(newAttributes);
```
Important, calling `update` does **not** save the instance.
@ -217,14 +218,14 @@ class Task extends Model {
order: {
type: Number,
decrypted: true,
}
}
},
};
}
const tasks = await Task.fetchList({
completed: false,
sort: '-order'
})
sort: '-order',
});
```
You can read the [`query-to-mongo`](https://github.com/pbatey/query-to-mongo) package documentation to learn how to do complex querying, sorting, limiting, and so forth.
@ -244,7 +245,7 @@ Use the `fetchOwnList` method to find instances that were created by the current
```javascript
const tasks = await Task.fetchOwnList({
completed: false
completed: false,
});
```
@ -276,8 +277,8 @@ Whenever you save a task, you should save a reference to the project it's in:
```javascript
const task = new Task({
name: 'Improve radiks documentation',
projectId: project._id
})
projectId: project._id,
});
await task.save();
```
@ -286,7 +287,7 @@ Then, later you'll want to fetch all tasks for a certain project:
```javascript
const tasks = await Task.fetchList({
projectId: project._id,
})
});
```
Radiks lets you define an `afterFetch` method. Use this method to automatically fetch child records when you fetch the parent instance.
@ -294,12 +295,12 @@ Radiks lets you define an `afterFetch` method. Use this method to automatically
[See the MongoDB Collection reference](https://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html) for documentation about how you can interact with this collection.
## Run a custom Radiks-server
If you're using an [express.js](https://expressjs.com/) server to run your application, it's probably easiest to use the Radiks-server middleware. This way, you won't have to run a separate application server and Radiks server.
@ -50,7 +49,6 @@ setup({
Currently, only the `mongoDBUrl` option is supported.
## Migrate from Firebase (or anywhere else)
Migrating data from Firebase to Radiks-server is simple and painless. You can create a script file to fetch all the Firebase data using their API. Then, you can use your `MONGOD_URI` config to use the `mongodb` npm package.
@ -122,8 +120,8 @@ migrate()
Before you can implement the websocket function, you must configure your `Radiks-Server` with [express-ws](https://github.com/HenningM/express-ws)
```javascript
const app = express()
expressWS(app)
const app = express();
expressWS(app);
```
Here's an example for how to use the API:
@ -131,7 +129,7 @@ Here's an example for how to use the API:
```javascript
import Task from './models/task';
const streamCallback = (task) => {
const streamCallback = task => {
// this callback will be called whenever a task is created or updated.
// `task` is an instance of `Task`, and all methods are defined on it.
// If the user has the necessary keys to decrypt encrypted fields on the model,
Using Radiks with your application requires a Radiks server and a client application constructed to use the server. In this article, you learn how to install, setup, and run a pre-packaged Radiks server that connects to MongoDB. You also learn how to establish your DApp application as a client for that server.
## Task 1. Set up your Radiks server
@ -27,7 +27,6 @@ In the future, Radiks-server will support various different databases, but right
4. Create a username/password combination with `root` privileges on your new database.
### Install and start the Radiks server
The easiest way to run `radiks-server` is to use the pre-packaged `node.js` server.
@ -37,14 +36,16 @@ The easiest way to run `radiks-server` is to use the pre-packaged `node.js` serv
```bash
npm install -g radiks-server
```
Or, if you prefer `yarn`:
```bash
yarn global add radiks-server
```
The default port for Mongodb is `27017`; your instance may be configured differently. By default, Radiks-server will use `'mongodb://localhost:27017/radiks-server'` as the `MongoDB_URI` value. This is suitable for local testing, but in production, you'll want to change the hostname and possibly the database name.
3. Start the `radiks-server` in the command line to confirm your installation.
2. Start the `radiks-server` in the command line to confirm your installation.
```
$ radiks-server
@ -54,7 +55,7 @@ The easiest way to run `radiks-server` is to use the pre-packaged `node.js` serv
The `radiks-server` defaults to running on port `1260`. To change the default port, specify the `PORT` environment variable in your environment.
4. By default, the server is running at `http://localhost:1260`
3. By default, the server is running at `http://localhost:1260`
4. Stop the `radiks` server process after you confirm it runs, and your installation was a success.
@ -101,7 +102,7 @@ If you are using `blockstack.js` version 18 or earlier, you must use the Radiks
>
```
2. Create a new database for your application.
2. Create a new database for your application.
```
> show dbs
@ -133,7 +134,6 @@ If you are using `blockstack.js` version 18 or earlier, you must use the Radiks
## Task 3. Add startup code and build your application
To set up radiks.js, you only need to configure the URL that your Radiks-server instance is running on. If you're using the pre-built Radiks server, this will be `http://localhost:1260`. If you're in production or are using a custom Radiks server, you'll need to specify the exact URL where it's available.
@ -151,16 +151,16 @@ To configure your application as a `radiks` client, do the following:
import { configure } from 'radiks';
const userSession = new UserSession({
appConfig: new AppConfig(['store_write', 'publish_data'])
})
appConfig: new AppConfig(['store_write', 'publish_data']),
});
configure({
apiServer: 'http://localhost:1260',
userSession
userSession,
});
```
2. Add authentication to your application
2. Add authentication to your application
After your user logs in with Blockstack, you'll have some code to save the user's data in your applications `localStorage`. You'll want to use the same `UserSession` you configured with Radiks, which can be fetched from the `getConfig` method.
@ -178,16 +178,15 @@ To configure your application as a `radiks` client, do the following:
Calling `User.createWithCurrentUser` does the following:
* Fetch user data that Blockstack.js stores in `localStorage`
* Save the user's public data (including their public key) in Radiks-server
* Find or create a signing key that is used to authorize writes on behalf of this user
* Cache the user's signing key (and any group-related signing keys) to make signatures and decryption happen quickly later on
- Fetch user data that Blockstack.js stores in `localStorage`
- Save the user's public data (including their public key) in Radiks-server
- Find or create a signing key that is used to authorize writes on behalf of this user
- Cache the user's signing key (and any group-related signing keys) to make signatures and decryption happen quickly later on
### Build and run your application
After you have added Radiks to your application, build and run the application. Test the application by logging in with your Blockstack ID. Create some data using the application. If you inspect the MongoDB database, you should see the encrypted data stored in the database.
You can specify the `mongoDBUrl` or the `maxLimit` option when initiating the Radiks server in your application.
```javascript
@ -201,7 +200,6 @@ setup({
The `mongoDBUrl` option is the MongoDB URL for the Radiks server
The `maxLimit` option is the maximum `limit` field used inside the mongo queries. The default is 1000.
## Where to go next
Creating models for your application's data is where radiks truly becomes helpful. To learn how to use models, see the [Create and use models](radiks-models.html) section.
The Blockstack Platform stores application data in the Gaia Storage System. Transactional metadata is stored on the Blockstack blockchain and user application data is stored in Gaia storage. Storing data off of the blockchain ensures that Blockstack applications can provide users with high performance and high availability for data reads and writes without introducing central trust parties.
@ -12,7 +11,6 @@ The Blockstack Platform stores application data in the Gaia Storage System. Tran
Gaia storage is a key-value store.
## Creating a file
You use the <ahref="https://blockstack.github.io/blockstack.js/classes/usersession.html#putfile"target="_blank">UserSession.putFile</a>
@ -82,6 +80,7 @@ var userSession = new UserSession()
```
## Reading another user's unencrypted file
In order for files to be publicly readable, the app must request
You use the <ahref="https://blockstack.github.io/blockstack.js/classes/usersession.html#deletefile"target="_blank">UserSession.deleteFile</a> from the application's data store.
```JavaScript
var userSession = new UserSession()
@ -115,4 +113,5 @@ var userSession = new UserSession()
```
## Related Information
To learn more about the guarantees provided by Gaia, see [Storage write and read]({{ site.baseurl }}/storage/write-to-read.html#)
This is a comprehensive list of all the Blockstack FAQs.
@ -98,10 +98,10 @@ This is a comprehensive list of all the Blockstack FAQs.
## Important disclaimer
*The Securities and Exchange Commission (SEC) has qualified the offering statement that we have filed with the SEC under Regulation A for our offering of certain of our Stacks Tokens. The information in that offering statement is more complete than the information we are providing now, and could differ in important ways. You must read the documents filed with the SEC before investing. The offering is being made only by means of its offering statement. This document shall not constitute an offer to sell or the solicitation of an offer to buy, nor shall there be any sale of these securities in any state or jurisdiction in which such offer, solicitation or sale would be unlawful prior to registration or qualification under the securities laws of any such state or jurisdiction.*
_The Securities and Exchange Commission (SEC) has qualified the offering statement that we have filed with the SEC under Regulation A for our offering of certain of our Stacks Tokens. The information in that offering statement is more complete than the information we are providing now, and could differ in important ways. You must read the documents filed with the SEC before investing. The offering is being made only by means of its offering statement. This document shall not constitute an offer to sell or the solicitation of an offer to buy, nor shall there be any sale of these securities in any state or jurisdiction in which such offer, solicitation or sale would be unlawful prior to registration or qualification under the securities laws of any such state or jurisdiction._
*An indication of interest involves no obligation or commitment of any kind. Any person interested in investing in any offering of Stacks Tokens should review our disclosures and the publicly filed offering statement and the f<ahref='https://stackstoken.com/circular'>final offering circular</a>that is part of that offering statement. Blockstack is not registered, licensed or supervised as a broker dealer or investment adviser by the SEC, the Financial Industry Regulatory Authority (FINRA) or any other financial regulatory authority or licensed to provide any financial advice or services.*
_An indication of interest involves no obligation or commitment of any kind. Any person interested in investing in any offering of Stacks Tokens should review our disclosures and the publicly filed offering statement and the f<ahref='https://stackstoken.com/circular'>final offering circular</a> that is part of that offering statement. Blockstack is not registered, licensed or supervised as a broker dealer or investment adviser by the SEC, the Financial Industry Regulatory Authority (FINRA) or any other financial regulatory authority or licensed to provide any financial advice or services._
## Forward-looking statements
*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.*
_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._
This tutorial teaches you how to create a decentralized application using
Blockstack's iOS SDK using the following content:
@ -18,7 +18,7 @@ experienced. For best results, beginners should follow the guide as written. It
is expected that the fast or furiously brilliant will skip ahead and improvise
on this material at will. God speed one and all.
If you want to download a complete application rather than working through a tutorial, see this *alternative* sample, the <ahref="https://github.com/blockstack/photoblock-demo"target="_blank">photoblock-demo</a>.
If you want to download a complete application rather than working through a tutorial, see this _alternative_ sample, the <ahref="https://github.com/blockstack/photoblock-demo"target="_blank">photoblock-demo</a>.
## Understand the sample application flow
@ -183,8 +183,6 @@ In this section, you build an initial React.js application called
to redirect the user back to your iOS app. Later, you'll add a reference
to this handler in your iOS application.
4. Close and save the `redirect.html` file.
5. Ensure your Blockstack app compiles successfully.
1. Close and save the `redirect.html` file.
1. Ensure your Blockstack app compiles successfully.
The `npm` process should detect and compile your change.
@ -288,7 +286,6 @@ menu items and therefore these procedures may be differœent on your version.
8. Close XCode.
### Add and edit a Podfile
To use CocoaPods you need to define the XCode target to link them to.
@ -302,6 +299,7 @@ lines after.
```swift
$ cd hello-blockstack-ios
```
3. Create a Podfile.
```bash
@ -318,20 +316,20 @@ lines after.
# platform :ios, '9.0'
target 'hello-blockstack-ios' do
#Commentthe next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
s
!
#Podsfor hello-blockstack-ios
pod 'Blockstack'
s
'
target'hello-blockstack-iosTests'do
inherit! :search_paths
# Pods for testing
end
o
s
g
d
end
```
8. Save and close the `Podfile`.
6. Save and close the `Podfile`.
### Install Blockstack SDK and open the pod project
@ -368,6 +366,7 @@ lines after.
Podfile.lock hello-blockstack-ios.xcodeproj
Pods hello-blockstack-ios.xcworkspace
```
5. Start XCode and choose **Open another project**.
6. Choose the `.xcworkspace` file created in your project folder.
@ -471,10 +470,10 @@ All iOS applications require a splash page.
9. Immediately after scenes but before the close of the `</document>` tag add the following `<resources>`.
```xml
<resources>
>
<imagename="Image"width="64"height="64"/>
</resources>
</document>
>
>
```
10. Choose **Run > Run app** in the emulator.
@ -483,7 +482,6 @@ All iOS applications require a splash page.
![](images/splash.png)
### Update the Main.storyboard
Rather than have you build up your own UI in the interface builder, this section has you copy and paste a layout into the XML file source code for the **Main.storyboard** file.
@ -538,7 +536,9 @@ Rather than have you build up your own UI in the interface builder, this section
</constraints>
<viewLayoutGuidekey="safeArea"id="6Tk-OE-BBY"/>
</view>
`
```
4. Select the Main.storyboard and choose **Open as > Interface Builder - Storyboard**.
![](images/main-storyboard.png)
@ -547,7 +547,6 @@ Rather than have you build up your own UI in the interface builder, this section
![](images/new-storyboard.png)
### Add the UI variables to the ViewController file.
In this section, you edit the `ViewController.swift` file using the storyboard as a starting point.
@ -605,7 +604,6 @@ In this section, you edit the `ViewController.swift` file using the storyboard a
Your connectors will have their own `destination` and `id` values.
### Edit the ViewController.swift file
Now, you are ready to connect your application with your Blockstack Web
@ -619,13 +617,14 @@ already created for you:
This web application already has a redirect in place for you. You'll reference
this application in your mobile add for now. In XCode, do the following;
1. Open the `ViewController.swift` file.
2. Add an import both for `Blockstack`.
```
import UIKit
import Blockstack
t
k
`
```
3. Add a private `updateUI()` function.
@ -658,7 +657,7 @@ this application in your mobile add for now. In XCode, do the following;
`Blockstack.shared.loadUserData()` method to load the user data and update
the application display with the username.
5. Replace the content of the `viewDidLoad()` function so that it calls this private function.
4. Replace the content of the `viewDidLoad()` function so that it calls this private function.
```swift
override func viewDidLoad() {
@ -666,9 +665,11 @@ this application in your mobile add for now. In XCode, do the following;
// Do any additional setup after loading the view, typically from a nib.
self.updateUI()
}
`
```
9. Create a `signIn()` function that handles both sign in and out.
5. Create a `signIn()` function that handles both sign in and out.
The function uses the `Blockstack.shared.signIn()` and
`Blockstack.shared.signUserOut()` methods to sign the user into the application.
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.
Blockstack is a full-stack decentralized computing network that enables a new generation of applications where developers and users can interact fairly and securely. Blockstack 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 Blockstack Ecosystem?
The Blockstack Ecosystem is the legal entities and community structures that support the Blockstack 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 Blockstack
@ -42,9 +39,9 @@ effort developing expertise in specialized languages or technologies.
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.
- 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 genesis block that distributes Stacks tokens to existing purchasers.
A full technical description of the upgrade is available on <ahref="https://forum.blockstack.org/t/blockstack-annual-hard-fork-2018/6518"target="\blank">the Blockstack forum</a>.
It is important that you understand how to keep good security for your Stacks Wallet software and your Blockstack identity.
@ -13,10 +12,10 @@ Both your wallet seed phrase and your Secret Recovery Code are cryptographic key
The CrtypoCurrency Security Standard publishes <ahref="https://cryptoconsortium.github.io/CCSS/Details/#1.03"target="_blank">guidelines for key storage</a>. These guidelines are presented from least (Level I) to most secure (Level III). We recommend you store your keys with at least Level II security. This level states that you should:
* Back up each of your cryptographic keys.
* Store the backup in a location separate location from where you use a key. For example, if you use the key at the office, you can store the key are your office.
* Protect your backup from access by unauthorized parties. For example, a safe, safe deposit box, or lock box are good examples of protecting access to a backup.
* Employ some form of tamper mechanism that allows your to determine when if you key was accessed by someone else. For example, you could use a sealed paper envelopes with handwritten signatures over the seal as a tamper mechanism.
- Back up each of your cryptographic keys.
- Store the backup in a location separate location from where you use a key. For example, if you use the key at the office, you can store the key are your office.
- Protect your backup from access by unauthorized parties. For example, a safe, safe deposit box, or lock box are good examples of protecting access to a backup.
- Employ some form of tamper mechanism that allows your to determine when if you key was accessed by someone else. For example, you could use a sealed paper envelopes with handwritten signatures over the seal as a tamper mechanism.
You are responsible for recalling and protecting your keys. Blockstack does not store your seed phrase or **Secret Recovery Code**. If you lose your seed phrase, you lose the key to your STX tokens, which can be a very costly mistake. If you lose your **Secret Recovery Code**, you lose the key to your identity and cannot access your applications or the data you created with them.
Stacks is the name of a token developed by Blockstack Token LLC in 2017 and
@ -44,11 +43,11 @@ documentation.</div>
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).
- 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 Blockstack ecosystem.
- Application developers can earn Stacks by building an application on the Blockstack ecosystem.
* Any Stacks tokens held at the time of launch or after remain usable under the Stacks Blockchain platform.
- 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
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
{% include important.html content=" If you <strong>purchased Stacks tokens during Summer 2019</strong>, the form below will <strong>not</strong> work for your allocation. Please <ahref='https://explorer.blockstack.org/verifier'target='_blank'>check your allocation using this tool instead</a>. "%}
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`
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
@ -21,10 +19,10 @@ Phrase** feature on the Stacks Wallet or contact us at <hello@stackstoken.com> f
help.
Use the following form to check your Stacks allocation:
You use the Stacks Wallet software client alone or with a hardware wallet to send and receive Stacks (STX) tokens. On this page, you learn how to install the Stacks Wallet software. This page contains the following:
@ -14,7 +13,6 @@ attack, verify your downloaded wallet software as detailed in the installation
instructions below. Verification confirms that you received the software signed
by Blockstack PBC." %}
## Mac Installation
1. <ahref="https://wallet.blockstack.org"target="\_blank">Go to the wallet download page</a> in your browser.
@ -46,8 +44,6 @@ by Blockstack PBC." %}
6. Verify that the resulting hash (a string of letters and numbers) is the same as the latest hash published <ahref="https://github.com/blockstack/stacks-wallet/releases"target="\_blank">on this page</a>.
## Windows Installation
1. Select the **Windows Download** button <ahref="https://wallet.blockstack.org/"target="\_blank">on this page</a>.
@ -90,14 +86,11 @@ You need very small fractions of Bitcoin to fuel your Stacks Wallet transactions
If you have a paper wallet or a custodial wallet, you should set up a secondary hardware. You can then transfer small amounts to this hardware wallet for use with your Stacks Wallet. You can use any of these hardware wallets with the Stacks Wallet:
*<ahref="https://trezor.io/"target="\_blank">Trezor</a> One
*<ahref="https://www.ledger.com/"target="\_blank">Ledger</a> Nano S
* Ledger Blue
-<ahref="https://trezor.io/"target="\_blank">Trezor</a> One
-<ahref="https://www.ledger.com/"target="\_blank">Ledger</a> Nano S
- Ledger Blue
{% include note.html content="Blockstack only supports the hardware wallets listed above. Other wallets, for example, the Trezor Model T, <strong>are not supported</strong>. If you have questions about wallet support, please <ahref='emailto:support@blockstack.org'target='_blank'>contact Blockstack support</a>." %}
For information on setting up a hardware wallet, refer to the vendor's
documentation. We cannot help you set up your hardware wallet.
If you are, or plan to be a Stacks token holder, you need to think about how you
@ -12,7 +11,7 @@ receive your tokens? STX tokens are a cryptocurrency and you manage your tokens
## Wallets, addresses, and tokens
Cryptocurrency wallets are software that make sending and receiving cryptocurrency easier. Unlike the wallets you carry physical money in, a cryptocurrency wallet doesn’t
contain your tokens. A wallet has one or more cryptocurrency addresses, in the case of Stacks these are *Stacks token address*.
contain your tokens. A wallet has one or more cryptocurrency addresses, in the case of Stacks these are _Stacks token address_.
An address is public and can be viewed by other people much like your house is visible to any passerby. To open a particular address, you must know the address value and you must have the private key for that address. Wallets can read existing addresses to send from or create new addresses to send to. A wallet can show you the history of transactions for an address on the blockchain.
@ -20,7 +19,7 @@ Exchanging cryptocurrency requires moving currency from one address to another.
![](images/key.png)
Token exchanges are recorded by *transactions* on a blockchain. In the case of STX, these exchanges appear on the Stacks blockchain. The movement of tokens from Lena to Bitbook is recorded on the blockchain. The private key Lena uses is not recorded.
Token exchanges are recorded by _transactions_ on a blockchain. In the case of STX, these exchanges appear on the Stacks blockchain. The movement of tokens from Lena to Bitbook is recorded on the blockchain. The private key Lena uses is not recorded.
<divclass="uk-card uk-card-default uk-card-body">
<h5>Security tip: What to share and what not to</h5>
This page describes how to use the Stacks Wallet software to manager your Stacks (STX) tokens. This page contains the following topics:
The Stacks Wallet software is installed on your computer, it is not a web application. You should have already [downloaded, verified, and installed the wallet software](wallet-install.html).
## Key concepts you should understand
You use Stacks Wallet software to manage STX tokens. Using the wallet you can:
You use Stacks Wallet software to manage STX tokens. Using the wallet you can:
* send STX from a specific STX address
* receive STX at a specific STX address
* view balances on an address
* review transaction history associated with an address
- send STX from a specific STX address
- receive STX at a specific STX address
- view balances on an address
- review transaction history associated with an address
To send STX, you need Bitcoin in your wallet. Bitcoin is the "gas" for transactions on the Stacks blockchain. A **_very small_** amount of Bitcoin is required to send STX. The gas price fluctuates like any market and is driven by the price of Bitcoin. Gas is not required to receive STX.
@ -30,9 +30,9 @@ You can use the Stacks Wallet software by itself or together with a hardware wal
You can use any of these hardware wallets with the Stacks Wallet:
* Trezor One
* Ledger Nano S
* Ledger Blue
- Trezor One
- Ledger Nano S
- Ledger Blue
{% include note.html content="Blockstack only supports the hardware wallets listed above. Other wallets, for example, the Trezor Model T, <strong>are not supported</strong>. If you have questions about wallet support, please <ahref='emailto:support@blockstack.org'target='_blank'>contact Blockstack support</a>." %}
@ -56,7 +56,6 @@ If you used the original, v1, version of the wallet, you should instead begin us
The v2 version of the wallet required a hardware wallet to send and receive. You can connect this same hardware wallet to the v3 version of the Stacks Wallet software. If this is your situation, choose **Use existing wallet** when you first start the Stacks Wallet v3; you don't need to create a new wallet.
## Create a new or open an existing wallet
When you start the Stacks Wallet it prompts you to create a new or choose an existing wallet. You should create a new wallet if you have not previously connected a hardware device to the Stacks Wallet v3 software or if you do not have an existing 24 word seed phrase.
@ -92,7 +91,7 @@ When your hardware device is ready, do the following:
2. Double-click on the wallet software to open it.
3. Select **Create new wallet** or **Use existing wallet**.
If you connected your hardware device to an old version of the Stacks Wallet software, you choose **Create new wallet**. After you make this initial connection, the *next time* you start the wallet, you can choose **Use existing wallet**.
If you connected your hardware device to an old version of the Stacks Wallet software, you choose **Create new wallet**. After you make this initial connection, the _next time_ you start the wallet, you can choose **Use existing wallet**.
The system asks if you have a hardware wallet.
@ -119,7 +118,6 @@ When your hardware device is ready, do the following:
The Stacks Wallet shows the current wallet balance.
### Software only wallet
If you have an existing 24 word seed phrase from this or a previous version of the Stacks Wallet software, you don't need to create a new wallet, you can **Use existing wallet**. This procedure assumes you are creating a wallet for the first time.
@ -138,7 +136,7 @@ If you have an existing 24 word seed phrase from this or a previous version of t
The system generates a seed phrase for you and prompts you to write it down.
Don't lose your seed phrase. If you lose your seed phrase, you lose your STX tokens and can never get them back.
5. Write down each word and its position, for example,`1 - frog`.
5. Write down each word and its position, for example,`1 - frog`.
6. Store your written seed phrase in a secure location such as a safe deposit box.
7. Click **I've written down my seed phrase**.
@ -168,7 +166,6 @@ Stacks you have unlocked. The **Allocation** is the amount still locked up.
![](images/token-holder-balance.png)
## Receive Stacks
To receive Stacks: you give a STX address directly to a user via email or text, for
@ -190,8 +187,6 @@ example.
Blockchain transactions take time. It may be minutes or hours before the transaction is recorded in the blockchain. When the transaction is complete, you can see a receipt for the transaction in your Stacks Wallet. The **PENDING** marker goes away once the funds are recorded on the blockchain.
## Add Bitcoin gas
The Stacks Wallet uses very small amounts of Bitcoin to pay fees for sending transactions. You need very small fractions of Bitcoin (BTC) for gas. The cost of gas you need fluctuates with the market price of Bitcoin.
@ -206,9 +201,9 @@ If you attempt to send STX with your wallet and you do not have enough Bitcoin t
![](images/not-enough.png)
To increase your Bitcoin for transactions, do the following:
To increase your Bitcoin for transactions, do the following:
1. Click the <spanclass="uk-margin-small-center"uk-icon="cog"></span>
1. Click the <spanclass="uk-margin-small-center"uk-icon="cog"></span>
(settings icon) in the upper right corner of the wallet.
The system opens the **Settings** dialog.
@ -278,23 +273,20 @@ Sending stacks is a transaction you must authorize or sign. If you have connecte
Select **Refresh** if you don't immediately see the transaction in your
history.
## Reset the wallet
Resetting a wallet clears all your data from the Stacks Wallet and returns the
wallet to its original state.
* If you entered a Stacks address, resetting clears the address from the Stacks Wallet.
* If you connected to a hardware wallet, resetting removes the connection to the hardware wallet.
- If you entered a Stacks address, resetting clears the address from the Stacks Wallet.
- If you connected to a hardware wallet, resetting removes the connection to the hardware wallet.
Resetting the wallet does nothing to your addresses or their associated balances.
They are maintained.
Once you reset the wallet, you have to start over from the *Terms of Use*. If
Once you reset the wallet, you have to start over from the _Terms of Use_. If
you do not restart the wallet, you can simple close it.
1. Click the <spanclass="uk-margin-small-center"uk-icon="cog"></span>
(settings icon) in the upper right corner of the wallet.
This teaches you how to run a Gaia hub on Amazon EC2. Amazon EC2 is an affordable and convenient cloud computing provider. This example uses Amazon EC2 instance together with an [EBS](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AmazonEBS.html) disk for file storage.
<divclass="uk-card uk-card-default uk-card-body">
@ -122,6 +122,7 @@ If `watch` is not located, install it on your workstation.
}
}
</code></pre></div></div>
</li>
<li>
<p>Replace the following values in the JSON.</p>
@ -166,6 +167,7 @@ If `watch` is not located, install it on your workstation.
}
}
</code></pre></div></div>
</li>
</ol>
</div>
@ -183,15 +185,14 @@ If `watch` is not located, install it on your workstation.
The tags are not required, they just apply searchable labels to an instance on an EC2 console.
* **Key** of `Purpose` with the **Value**`gaia`
* **Key** of `Name` with the **Value**`gaia-hub`
* **Key** of `Version` with the **Value**`2.5.3` (This value is an example, your version may be different.)
- **Key** of `Purpose` with the **Value**`gaia`
- **Key** of `Name` with the **Value**`gaia-hub`
- **Key** of `Version` with the **Value**`2.5.3` (This value is an example, your version may be different.)
![](/storage/images/tag-add.png)
11. Choose **Next: Configure Security Group**.
12. Create a security group with the following three types:
11) Choose **Next: Configure Security Group**.
12) Create a security group with the following three types:
@ -224,16 +225,16 @@ If `watch` is not located, install it on your workstation.
</tr>
</table>
13. Choose **Review and Launch**.
13) Choose **Review and Launch**.
The system may warn you that the selection is not free tier eligible. You can ignore this for now.
14. Press **Launch**.
14) Press **Launch**.
The system prompts you for a key pair.
15. Select **Create a new keypair** or **Choose an existing key pair**.
16. Select **Launch Instances**.
15) Select **Create a new keypair** or **Choose an existing key pair**.
16) Select **Launch Instances**.
The system launches your instance.
@ -243,7 +244,6 @@ During the launch process the machine starts and runs some initial setup process
![](/storage/images/instance-initialize.png)
## Task 2: Connect your Gaia server to your domain
Now, you are ready to test your Gaia server. This procedure ensures the Gaia services started correctly and they are configured to the domain name you provided in **Advanced Details** above.
@ -285,7 +285,7 @@ Now, you are ready to test your Gaia server. This procedure ensures the Gaia ser
@ -300,10 +300,9 @@ Now, you are ready to test your Gaia server. This procedure ensures the Gaia ser
</tr>
</table>
8. Press **Advanced**.
9. Choose to proceed.
10. Extend the IP with the `PUBLIC_IP/hub_info` tag like so.
8) Press **Advanced**.
9) Choose to proceed.
10) Extend the IP with the `PUBLIC_IP/hub_info` tag like so.
You should see a response from your Gaia hub!
@ -314,7 +313,6 @@ Now, you are ready to test your Gaia server. This procedure ensures the Gaia ser
not required simple to run the hub services, Blockstack will only connect to
a hub and write to its storage over a valid `HTTPS` connection.
## Task 3: Configure a domain name
At this point, you can point a domain to your Gaia hub. Although it's not required, it is highly recommended. If you use a domain, you can migrate your instance to a different server (or even provider such as Azure or Dropbox) at any time, and still access it through the domain URL. Just point your domain at the IP address for your EC2 instance. Use an `A Record` DNS type.
@ -343,9 +341,9 @@ These instructions assume you have already created a free <a href="https://www.f
![Domain test](/storage/images/domain-test.png)
If you receive another **Your connection is not private** dialogs, take the option to proceed to your domain. The *Not secure* message should no longer appear in the browser bar. If the message does appear, try waiting a few minutes for your recent changes to propagate across the net domain servers. Then, refresh the page.
If you receive another **Your connection is not private** dialogs, take the option to proceed to your domain. The _Not secure_ message should no longer appear in the browser bar. If the message does appear, try waiting a few minutes for your recent changes to propagate across the net domain servers. Then, refresh the page.
9. Check the SSL certificate for your hub.
8. Check the SSL certificate for your hub.
Each browser has its own check procedure, for example, Chrome:
@ -354,7 +352,6 @@ These instructions assume you have already created a free <a href="https://www.f
At this point, you have the following. An EC2 instance running Gaia and a DNS
record pointing your domain to this instance.
## AWS hub tips and tricks
Once your Gaia storage hub is up and running on AWS, you may occassionally need to troubleshoot. This section contains some useful information for interacting with your EC2 instance.
@ -513,7 +511,7 @@ This procedures requires you to interact from a workstation command line with yo
maryhub.ml has address 34.219.71.143
```
If the command returns the correct IP, the same as appears on your EC2 dashboard, stop the process with a`CTRL-C` on your keyboard.
If the command returns the correct IP, the same as appears on your EC2 dashboard, stop the process with a`CTRL-C` on your keyboard.
3. Change the permissions on your downloaded `.pem` file.
@ -542,7 +540,7 @@ This procedures requires you to interact from a workstation command line with yo
5. SSH from your workstation to reset back to first boot:
** This process will stop Gaia Hub, Nginx and remove any existing SSL certificates. It will then start the process of retrieving certificates and setting up the services again. This will not affect any existing data stored on the server.
\*\* This process will stop Gaia Hub, Nginx and remove any existing SSL certificates. It will then start the process of retrieving certificates and setting up the services again. This will not affect any existing data stored on the server.
This process requires that you know the location of the `.pem` file you downloaded when you created the keypair.
@ -556,4 +554,5 @@ This procedures requires you to interact from a workstation command line with yo
Blockstack authentication is a bearer token-based authentication system. From an app user's perspective, login similar to third-party authentication techniques that they're familiar with. For an app developer, the flow is unlike the typical client-server flow of centralized sign-in services such as OAuth. With Blockstack the authentication flow happens entirely client-side.
@ -24,9 +23,9 @@ When a user chooses to "Sign in with Blockstack" on your DApp, the `redirectToSi
The app private key is application-specific. It is generated from the user's identity address private key using the `appDomain` as input. This key is deterministic, meaning that for a given Blockstack ID and domain name, the same private key is generated each time. The app private key is securely shared with the app on each authentication and encrypted by the Blockstack authenticator. The key serves three functions, it:
* is used to create the credentials that give an app access to the Gaia hub storage bucket for that specific app
* is used in the end-to-end encryption of files stored for the app on the user's Gaia hub
* serves as a cryptographic secret that apps can use to perform other cryptographic functions
- is used to create the credentials that give an app access to the Gaia hub storage bucket for that specific app
- is used in the end-to-end encryption of files stored for the app on the user's Gaia hub
- serves as a cryptographic secret that apps can use to perform other cryptographic functions
When an application writes to a Gaia hub, the authentication token, key, and the data are passed to the Gaia hub.
This teaches you how to run a Gaia storage hub on DigitalOcean (DO). DigitalOcean is an affordable and convenient cloud computing provider. This example uses DigitalOcean Spaces for file storage. A space is equivalent to AWS's S3 file storage solution.
DigitalOcean provides you with a compute machines known as a **Droplets** and storage called a **Spaces**. You need both to run a Gaia hub. The Gaia hub setup you create here, requires get a Digital Droplet with Docker pre-installed and a 250 GB Space. Droplets and storage each run for $5/month or a total of $10/month.
@ -19,19 +19,19 @@ DigitalOcean provides you with a compute machines known as a **Droplets** and st
## Prerequisites you need
You use DigitalOcean choose and configure assets for running droplets and spaces. To enable this, you must be sure to complete the prerequisites in this section.
You use DigitalOcean choose and configure assets for running droplets and spaces. To enable this, you must be sure to complete the prerequisites in this section.
You must create an account on <ahref="https://digitalocean.com"target="\_blank">DigitalOcean</a>. DigitalOcean requires you to supply a credit card to create an account. You are only charged for the services you use the Gaia hub as of this writing should cost $10 USD a month.
You must create an account on <ahref="https://digitalocean.com"target="\_blank">DigitalOcean</a>. DigitalOcean requires you to supply a credit card to create an account. You are only charged for the services you use the Gaia hub as of this writing should cost \$10 USD a month.
The easiest way to interact with your droplet is the DigitalOcean Console. Users who are comfortable using the secure shell (SSH) and private keys may prefer to open a local terminal on their home machine instead. To enable this, you should ensure you have the following prerequisites completed.
* Locate an existing SSH key pair on your Mac or <ahref="https://help.dreamhost.com/hc/en-us/articles/115001736671-Creating-a-new-Key-pair-in-Mac-OS-X-or-Linux"target="\_blank">create a new SSH key pair</a>. Your key should have a passphrase, do not use a key pair without one.
- Locate an existing SSH key pair on your Mac or <ahref="https://help.dreamhost.com/hc/en-us/articles/115001736671-Creating-a-new-Key-pair-in-Mac-OS-X-or-Linux"target="\_blank">create a new SSH key pair</a>. Your key should have a passphrase, do not use a key pair without one.
* Add the <ahref="https://www.digitalocean.com/docs/droplets/how-to/add-ssh-keys/to-account/"target="\_blank">SSH from your local machine to DigitalOcean</a>.
- Add the <ahref="https://www.digitalocean.com/docs/droplets/how-to/add-ssh-keys/to-account/"target="\_blank">SSH from your local machine to DigitalOcean</a>.
* Create a <ahref="https://www.digitalocean.com/docs/api/create-personal-access-token/"target="\_blank">personal access token in DigitalOcean</a>.
- Create a <ahref="https://www.digitalocean.com/docs/api/create-personal-access-token/"target="\_blank">personal access token in DigitalOcean</a>.
* Install `doctl` which is the DigitalOcean command line tool. For information on installing these, see which is the DigitalOcean command line utility. Check out their [installation instructions](https://github.com/digitalocean/doctl/blob/master/README.md#installing-doctl) to see how to install it on your computer.
- Install `doctl` which is the DigitalOcean command line tool. For information on installing these, see which is the DigitalOcean command line utility. Check out their [installation instructions](https://github.com/digitalocean/doctl/blob/master/README.md#installing-doctl) to see how to install it on your computer.
## Task 1: Create a DigitalOcean space
@ -64,7 +64,6 @@ In this task you create a **Space** which is where Gaia stores your files.
## Task 2: Enable File Listing and Set a Bucket Policy
On Digital Ocean, set **Enable File Listing**:
1. Navigate to the **Spaces** tab.
@ -88,12 +87,12 @@ On your local workstation, create a bucket policy to grant read permission on yo
```json
{
"Version":"2012-10-17",
"Version":"2012-10-17",
"Id": "read policy",
"Statement":[
"Statement":[
{
"Sid":"PublicRead",
"Effect":"Allow",
"Sid":"PublicRead",
"Effect":"Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<SPACE_NAME>/*"
@ -101,6 +100,7 @@ On your local workstation, create a bucket policy to grant read permission on yo
]
}
```
6. Edit the `Resource` line and replace the `<SPACE_NAME>` with your space name from Digital Ocean.
For example, if your space is named `meepers`, after editing the line you would have:
@ -165,7 +165,7 @@ In this task, you add a droplet to your account. The droplet is a droplet is a c
5. Select the **Docker** app from the options presented.
6. Scroll down to the **Choose a size** section and use the left arrow to display and select the **$5/mo** image.
6. Scroll down to the **Choose a size** section and use the left arrow to display and select the **\$5/mo** image.
This size gives you plenty of memory and disk space to run a personal hub.
@ -185,7 +185,6 @@ In this task, you add a droplet to your account. The droplet is a droplet is a c
At this point, your new droplet should appear in the list of resources on your DigitalOcean dashboard.
## Task 5: Open a console on your Droplet
A droplet console emulates the access you would have if you were sitting down with a keyboard and monitor attached to the actual server. In this section, you open a console on your droplet.
@ -246,7 +245,6 @@ A droplet console emulates the access you would have if you were sitting down wi
<p>If you find the output from ls difficult to read, try enter the following to change the console colors from the command line: <code>LS_COLORS="di=1;31"</code> You can also edit your console <code>.bashrc</code>. file permanently, of course.</p>
</div>
## Task 6: Create a space key
1. In the DigitalOcean dashboard, go to the **API** page.
@ -343,6 +341,8 @@ You should have the console open as `root` on your Droplet. In this section, you
}
```
````
You'll find that the `driver` is set to `aws`. The DigitalOcean space API exactly mimics the S3 API. Since Gaia doesn't have a DigitalOcean driver, you can just use the `aws` driver with some special configuration.
5. Set the `serverName` to the droplet you just created.
@ -408,38 +408,42 @@ While your console is still in the the `gaia/hub` folder, build the `gaia.hub` i
1. Enter the following `docker` command at the console command line.
```
docker build -t gaia.hub .
```
This build users the `Dockerfile` already in the `gaia/hub` folder. The output of the command is similar to the following:
added 877 packages from 540 contributors and audited 3671 packages in 38.122s
found 0 vulnerabilities
Removing intermediate container b0aef024879f
---> 5fd126019708
Step 5/5 : CMD ["npm", "run", "start"]
---> Running in ae459cc0865b
Removing intermediate container ae459cc0865b
---> b1ced6c39784
Successfully built b1ced6c39784
Successfully tagged gaia.hub:latest
````
2. Run your Gaia hub image.
```bash
docker run --restart=always -v ~/gaia/hub/config.json:/src/hub/config.json -p 3000:3000 -e CONFIG_PATH=/src/hub/config.json gaia.hub
```
```bash
docker run --restart=always -v ~/gaia/hub/config.json:/src/hub/config.json -p 3000:3000 -e CONFIG_PATH=/src/hub/config.json gaia.hub
````
This runs your Gaia hub on port `3000`. If everything runs successfully, the last line outputted from this command should be:
This runs your Gaia hub on port `3000`. If everything runs successfully, the last line outputted from this command should be:
```bash
Successfully compiled 13 files with Babel.
@ -549,7 +553,6 @@ Now, you are ready to test your Gaia server and make sure it is up and running.
in your `config.json` file, for example,
`https://meepers-hub-space.s3.amazonaws.com/`.
## Task 11: Configure a domain name
At this point, you can point a domain to your Gaia hub. Although it's not required, it is highly recommended. If you use a domain, you can migrate your Droplet to a different server (or even provider such as Azure or AWS) at any time, and still access it through the domain URL. Simply point your domain at the IP address for your Droplet. Use an `A Record` DNS type.
@ -578,7 +581,6 @@ These instructions assume you have already created a free <a href="https://www.f
![Domain test](/storage/images/domain-test.png)
## Task 12: Set up SSL
If you've configured a domain to point to your Gaia hub, then it's highly
A Gaia service can run a simple administrative service co-located with your Gaia hub. This service allows you to administer the Gaia hub with the help of an API key. Gaia hubs installed using the Gaia Amazon Machine Image (AMI) have this service integrated automatically.
In this section, you learn how to use the Gaia admin service with your Gaia hub.
@ -12,20 +12,18 @@ In this section, you learn how to use the Gaia admin service with your Gaia hub.
The examples in this section assume that Gaia and the admin service
were installed through the Configure a hub on Amazon EC2." %}
## Understand the configuration files
The admin service relies on two configuration files, the hub's configuration and the configuration of the admin service itself. The hub's configuration is mounted `/tmp/hub-config/config.json` in the `docker_admin_1` container. Your EC2 instance has the admin service configuration in the `/gaia/docker/admin-config/config.json` file.
The admin service needs to know the following:
* where the Gaia hub config file is located
* which API key(s) to use when authenticating administrative requests
* which command(s) to run to restart the Gaia hub on a config change
- where the Gaia hub config file is located
- which API key(s) to use when authenticating administrative requests
- which command(s) to run to restart the Gaia hub on a config change
The following is the standard admin service config installed with your EC2 instance.
```json
{
"argsTransport": {
@ -37,16 +35,13 @@ The following is the standard admin service config installed with your EC2 insta
"json": true
},
"port": 8009,
"apiKeys": ["hello"],
"apiKeys": ["hello"],
"gaiaSettings": {
"configPath": "/tmp/hub-config/config.json"
},
"reloadSettings": {
"command": "/bin/sh",
"argv": [
"-c",
"docker restart docker_hub_1 &"
],
"argv": ["-c", "docker restart docker_hub_1 &"],
"env": {},
"setuid": 1000,
"setgid": 1000
@ -56,7 +51,6 @@ The following is the standard admin service config installed with your EC2 insta
The `port` is the port where Gaia is running. The `apiKeys` field is key used for making calls to the hub. The `gaiaSettings`
The `argsTransport` section configures the hub logging. The service uses the `winston` logging service. Refer to their documentation for full details on the [logging configuration options](https://github.com/winstonjs/winston).
If the settings were successfully applied, the method returns a message to reload your Gaia hub. You can set multiple drivers' settings with a single call. For example, you can set:
* The driver to use (`driver`)
* The Gaia's read URL endpoint (`readURL`)
* The number of items to return when listing files (`pageSize`)
* The driver-specific settings
- The driver to use (`driver`)
- The Gaia's read URL endpoint (`readURL`)
- The number of items to return when listing files (`pageSize`)
- The driver-specific settings
The data accepted on `POST` must contain a valid Hub configuration, for example:
@ -264,12 +255,12 @@ const GAIA_CONFIG_SCHEMA = {
The same fields are returned on `GET` within a `config` object.
#### Errors
If you do not supply a valid API key, both the `GET` and `POST` method fail with HTTP 403.
Only relevant Gaia hub config fields are set. If you `POST` invalid settings
values, you get an HTTP 400 error.
## Example: Read and write driver settings
Use the `/v1/admin/config` endpoint to read and write storage driver settings. To get the current driver settings, you would run:
This page describes the considerations hub operators must take into account when creating and operating a Gaia storage hub.
## Configuration files
@ -74,7 +74,6 @@ Past users could configure this setting as a crude spam-control mechanism.
However, for the smoothest operation of your Gaia hub, set the
`proofsConfig.proofsRequired` value to `0`.
## Open or private hubs
You can configure an open-membership storage hub or a private storage hub. An open-membership hub, as it sounds, allows any user to use the hub service. A private hub limits the use of the service. In this section, you learn about configuring each type.
Once a user authenticates and a DApp obtains authentication, the application interacts with Gaia through the blockstack.js library. There are two simple methods for working with data in Gaia hub: the `putFile()` and `getFile()` methods. This section goes into greater detail about the methods, how they interact with a hub, and how to use them.
## Write-to and Read-from URL Guarantees
Gaia is built on a driver model that supports many storage services. So, with
When you use the `putFile()` method it takes the user data and POSTs it to the user's Gaia storage hub. The data POSTs directly to the hub, the blockchain is not used and no data is stored there. The limit on file upload is currently 25mb.
## Address-based access-control
Access control in a Gaia storage hub is performed on a per-address basis.