diff --git a/Gemfile b/Gemfile
index 4a90445c..827cdc36 100644
--- a/Gemfile
+++ b/Gemfile
@@ -9,7 +9,7 @@ ruby RUBY_VERSION
#
# This will help ensure the proper Jekyll version is running.
# Happy Jekylling!
-gem "jekyll", "3.5"
+gem "jekyll", "3.6.3"
# This is the default theme for new Jekyll sites. You may change this to anything you like.
# gem "minima", "~> 2.0"
diff --git a/Gemfile.lock b/Gemfile.lock
index 57056118..9eb9db3c 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -13,16 +13,16 @@ GEM
ffi (1.9.25)
forwardable-extended (2.6.0)
http_parser.rb (0.6.0)
- jekyll (3.5.0)
+ jekyll (3.6.3)
addressable (~> 2.4)
colorator (~> 1.0)
jekyll-sass-converter (~> 1.0)
jekyll-watch (~> 1.1)
- kramdown (~> 1.3)
+ kramdown (~> 1.14)
liquid (~> 4.0)
mercenary (~> 0.3.3)
pathutil (~> 0.9)
- rouge (~> 1.7)
+ rouge (>= 1.7, < 3)
safe_yaml (~> 1.0)
jekyll-avatar (0.6.0)
jekyll (~> 3.0)
@@ -43,7 +43,7 @@ GEM
jekyll-watch (1.5.1)
listen (~> 3.0)
kramdown (1.17.0)
- liquid (4.0.0)
+ liquid (4.0.1)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
@@ -58,10 +58,10 @@ GEM
rb-fsevent (0.10.3)
rb-inotify (0.9.10)
ffi (>= 0.5.0, < 2)
- rouge (1.11.1)
+ rouge (2.2.1)
ruby_dep (1.5.0)
safe_yaml (1.0.4)
- sass (3.5.7)
+ sass (3.6.0)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
@@ -74,7 +74,7 @@ PLATFORMS
ruby
DEPENDENCIES
- jekyll (= 3.5)
+ jekyll (= 3.6.3)
jekyll-avatar
jekyll-feed (~> 0.6)
jekyll-gist
diff --git a/README.md b/README.md
index cef5c5f1..f8251f74 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,9 @@
-## Docs site
+# README for the documentation site
+
+
+## Building after a fork
+
+## Run locally
To run locally:
@@ -34,3 +39,7 @@ To deploy to Netlify:
```
git push -f origin
```
+
+# Writing content
+
+## Constructing links
diff --git a/_common/mining_faq.md b/_common/mining_faq.md
new file mode 100644
index 00000000..a374c893
--- /dev/null
+++ b/_common/mining_faq.md
@@ -0,0 +1,5 @@
+---
+layout: externalurl
+redirect_url: https://app.co/mining#faq
+title: "Mining FAQ"
+---
diff --git a/_config.yml b/_config.yml
index 3f779cde..2e0e1ccd 100644
--- a/_config.yml
+++ b/_config.yml
@@ -151,6 +151,9 @@ collections:
core:
output: true
basepath: "blockstack/blockstack-core/blob/master/docs"
+ develop:
+ output: true
+ basepath: "moxiegirl/docs.blockstack"
storage:
output: true
basepath: "blockstack/gaia/blob/master/docs"
diff --git a/_data/navigation_learn.yml b/_data/navigation_learn.yml
index bb9603b3..86216560 100644
--- a/_data/navigation_learn.yml
+++ b/_data/navigation_learn.yml
@@ -1,3 +1,7 @@
+- title: Introduction
+- docs:
+ - develop/dapp_principles
+
- title: Try a tutorial
docs:
- browser/hello-blockstack
@@ -9,7 +13,14 @@
- android/tutorial
- ios/tutorial
+- title: Application mining
+ docs:
+ - develop/mining_intro
+ - develop/mining_enroll
+
- title: Reference
docs:
- core/faq_developer
+ - common/mining_faq
- common/javascript_ref
+ - common/core_ref
diff --git a/_develop/dapp_principles.md b/_develop/dapp_principles.md
new file mode 100644
index 00000000..3b717c8e
--- /dev/null
+++ b/_develop/dapp_principles.md
@@ -0,0 +1,127 @@
+---
+layout: learn
+permalink: /:collection/:path.html
+---
+# Principles of Blockstack applications
+{:.no_toc}
+
+There are as many perspectives on what makes a decentralized app (DApp) as there
+are DApp developers. This section defines the principles that Blockstack
+advocates for DApps operating within its platform.
+
+* TOC
+{:toc}
+
+
+## Blockstack DApp principles
+
+An application is considered a Blockstack DApp if it adheres to three
+principles.
+
+### I. Users own their data
+
+DApps do not store or replicate user data. Users own their application
+data independent of and *outside of* the application. A Blockstack application
+is only considered decentralized if its users control where their data is
+hosted and can prove that they created the data.
+
+Blockstack applications meet this principle if they use the Gaia storage system.
+Users may sign and/or encrypt their data in Gaia end-to-end. All files in Gaia
+are addressed by a user identifier, an application's hostname, and a filename.
+Through Gaia, users can prove data ownership and restrict access.
+
+In the future, users will be able to choose on an app-by-app basis which Gaia
+hub serves their application data.
+
+### II. Users own their identities
+
+Users are the sole administer of their own independent and unique
+identifiers. Within an applications, users must be distinguishable by unique
+identifiers. The DApp cannot mask or take away a user's identifier, and a user
+must be able to bind their identifier to the data they create.
+
+Blockstack DApps anticipate that each user can own one or more IDs. In turn,
+these IDs are owned by a private key under the user's control. The IDs are
+acquired through the Blockstack naming system. First time users that log into
+the Blockstack application get a free `blockstack.id` in the Blockstack namespace.
+
+Blockstack IDs are replicated to all peers via a blockchain, this means
+Blockstack cannot hide IDs. Blockstack IDs each have a public key assigned to
+them via the blockchain records that encode their operational history. This
+public key allows users to bind data to their Blockstack IDs through
+cryptographic signatures.
+
+### III. Users have free choice of clients
+
+Identities and _data_ are application independent. An application cannot be
+considered a DApp unless it allows users to interact with their identities and
+data such that the user can later do so via a different DApp.
+
+For example, a user that creates data in client 'X' must be able access that
+data from a different client, 'Y', provided the client allows compatible
+mechanisms. Ultimately, the user has the freedom to write their own client that
+interacts with their own data.
+
+Blockstack's APIs and SDKs make it easy to build applications that adhere to
+this principle. Existing Blockstack applications have this property today simply
+because they don't have any irreplaceable server-side logic.
+
+In the future, Blockstack applications must continue to meet the first two
+principles but need not meet this one. For example, an application could
+encrypt data in-transit between the application's client and the user's chosen
+storage provider. Unless the app divulges the encryption key to the user, then
+the user does not have free choice of clients; they can only use clients that
+the app's servers choose to interact with.
+
+## Non-Principles
+
+You'll notice the Blockstack principles avoid adherence to a particular network
+topology or architecture. Many DApps have defining characteristics that are
+implementation-specific rather than expressions of overall DApp design goals.
+These aspects are mentioned here as specific non-goals of Blockstack
+applications.
+
+### DApps have smart contracts
+
+Decentralized apps pre-date blockchains and smart contracts, and even today
+there are popular DApps that do not need them. Examples include pre-Microsoft
+Skype (which was peer-topeer), Mastadon, IRC, and email.
+
+Another word for "smart contract" is "replicated state machine." Some DApps
+need each peer to execute the same sequence of operations in order to fulfill
+their business needs (in which case a smart contract would be appropriate),
+but many do not.
+
+Blockstack DApps do not use smart contracts at all.
+
+### DApps have tokens and/or non-fungible assets
+
+Similar to smart contracts, DApps pre-date tokens and non-fungible assets.
+While having a crypto token or asset can help incentivize DApp deployment and
+usage, they are not strictly necessary for their operation.
+
+### DApps use a blockchain
+
+Blockchains are a new tool for DApp developers to help coordinate peers, but
+they are just that -- a tool. Sometimes blockchains are the right tool for the
+job, and sometimes they are not.
+
+
+## Dapps serve users
+
+Fundamentally, DApps should serve users by preserving user autonomy. Developers
+should not profit from abusive features or neglectful designs.
+Blockstack principles seek to prevent developers from profiting by either (a) building
+abusive features into DApps like ad networks, or (b) neglecting users by failing
+to build vital safety features like shadowbans.
+
+Because Blockstack applications allow users to own their identity and data and
+gives them free choice of clients, any user can simply stop or avoid using bad DApps
+with near-zero switching cost.
+
+This isn't to say that DApps can't be profitable. DApps can still make money for
+their developers, such as by offering content subscriptions or paid-for add-ons.
+They can broker with third parties on behalf of their users to watch ads or
+share data in exchange for tokens.
diff --git a/_develop/images/decaying.png b/_develop/images/decaying.png
new file mode 100644
index 00000000..7d2a5d51
Binary files /dev/null and b/_develop/images/decaying.png differ
diff --git a/_develop/images/mining-image.png b/_develop/images/mining-image.png
new file mode 100644
index 00000000..1e27446e
Binary files /dev/null and b/_develop/images/mining-image.png differ
diff --git a/_develop/images/model.png b/_develop/images/model.png
new file mode 100644
index 00000000..93f22c96
Binary files /dev/null and b/_develop/images/model.png differ
diff --git a/_develop/mining_enroll.md b/_develop/mining_enroll.md
new file mode 100644
index 00000000..98068d7a
--- /dev/null
+++ b/_develop/mining_enroll.md
@@ -0,0 +1,31 @@
+---
+layout: learn
+permalink: /:collection/:path.html
+---
+# How to enroll
+
+Application mining pays developers for building decentralized applications
+(Dapps). Enrolling in app mining also makes your application eligible for
+rewards.
+
+After you enroll, Blockstack verifies your information and your Dapp appears in
+the list of registered apps. You must enroll by the end of each month to be
+eligible for the following month.
+
+To apply, do the following:
+
+1. Integrate Blockstack Auth into your app.
+
+2. Add your app to App.co.
+
+ Make sure you choose Blockstack from the Authentication list on the form.
+
+3. Email with the domain you used to register for your app.
+
+ Blockstack will respond via email with a set of verification materials.
+
+4. Fill out and return the completed verification materials.
+
+ Be sure you provide us with the BTC address for receipt of mining and rewards funds.
+
+Once your enrollment is received, you appear in the enrollment list. For more information, see the frequently asked questions [on the App.co site](https://app.co/mining#faq).
diff --git a/_develop/mining_intro.md b/_develop/mining_intro.md
new file mode 100644
index 00000000..400e82b1
--- /dev/null
+++ b/_develop/mining_intro.md
@@ -0,0 +1,115 @@
+---
+layout: learn
+permalink: /:collection/:path.html
+---
+# Understand app mining
+
+Traditionally the term _mining_ in cryptocurrency refers to the process of
+contributing compute resources to the network and earning a reward. On the
+Blockstack network, however, instead of just mining through computation,
+developers can mine by contributing apps to the ecosystem and making
+applications the community wants.
+
+![](images/mining-image.png)
+
+Founders that build apps using Blockstack developer tools like Blockstack Auth
+get paid each month, in amounts proportional to that month’s app quality
+ranking. Blockstack PBC, in cooperation with App.co, currently administers the
+payouts. A set of independent _App reviewers_ determines the monthly ranking
+during the pilot phase.
+
+
+## How apps are reviewed
+
+Blockstack worked with a team of Ph.D. game theorist and economists from
+Princeton and NYU to put together a ranking algorithm which is fair and
+resistant to abuse. Blockstack partnered with two different third-party
+reviewers, Product Hunt and Democracy.earth. These reviewers are independent,
+and generally rely on their own proprietary data and insights to generate
+rankings.
+
+### Product Hunt
+
+Product Hunt is the place to find the best new products in tech. They have a
+massive trove of user data (upvotes, comments, etc), that they use for ranking.
+Product Hunt comes up with two different scores for each app — a “community”
+score and a “team” score.
+
+Their community score is determined only by the number of upvotes an app
+received on Product Hunt, relative to other apps that are registered. For
+example, if an app got more upvotes than any other app in a cohort, their
+community score would be 100. If a different app got 60% as many upvotes, they’d
+get a score of 60.
+
+Their team score is determined by internal team members conducting reviews on
+different aspects of an app. They judge based on a few criteria, like execution,
+uniqueness, and desirability. Each app gets ranked 1-10 on each criterion, and
+their final score is the average of each criterion. Finally, this average is
+multiplied by 10, so the highest score you can get is 100.
+
+Once each app has a community and team score, Blockstack converts these scores into
+_z-scores_, more about z-scores below.
+
+### Democracy Earth
+
+Democracy Earth is a platform for borderless peer-to-peer democracy. They’ve
+built a platform that anyone can use to gather votes in a trust-less,
+decentralized way.
+
+Democracy Earth has built a platform for Stacks token holders to vote on how
+apps should be ranked. Each token holder gets a certain number of votes, and
+they can distribute those votes however they want. It’s possible to give all of
+your votes to a single app, and you can also “downvote” an app with one of your
+votes.
+
+After a voting period, each app has a certain amount of upvotes and downvotes.
+First, Blockstack calculates the percentage of total votes that are upvotes. If
+you got 90 upvotes and 10 downvotes, you’d get a “likability score” of 90.
+Secondly, Blockstack calculates a “traction score”, which ranks how many total
+votes (including downvotes) an app received, relative to other apps.
+
+## Reaching the final scores
+
+Once the reviewer-partners generate reviews, each app has 4 raw scores between 0
+and 100 for the following:
+
+* Product Hunt community score
+* Product Hunt team score
+* Democracy Earth likability score
+* Democracy Earth traction score
+
+First Blockstack's determine a ‘z-score’ for each ranking category community,
+team, likability, and traction. This is a statistical technique to account for
+different distributions of scores within categories. Second, Blockstack computes
+the average and standard deviation of each category. Finally, for each app’s
+score in that category, Blockstack determines how many standard deviations it is
+away from the average score in that category.
+
+For example, let’s say a category has an average score of 60, with a standard
+deviation of 15. A score of 90 would get a z-score of 2, because it’s 2 standard
+deviations higher than the average.
+
+Once each app has a calculated a z-score in every category, the average of those
+4 z-scores results in a final number. A higher number is better than a lower
+one, and so apps are ranked from highest to lowest.
+
+## Determining how much an app is paid
+
+For each app mining cohort, there is determined a “pot” of total earnings that will
+get paid to apps. For the Alpha run, Blockstack paid a total of $25,000 USD. Starting in
+December 2018, Blockstack will pay $100,000 USD and the awards will be paid out in Bitcoin.
+
+The top app gets paid 20% of the total pot. So, for a pot of $100k, the top app
+receives $20,000 USD. The next app gets paid 20% of the remaining pot. The
+remaining pot is $80k, and 20% of that is $16,000. This process continues until
+every app has been paid.
+
+Here is a chart that visualizes the decay in rewards, depending on rank:
+
+![](images/decaying.png)
+
+This first release of App Mining uses the initial version of our ranking and
+payout mechanism. Blockstack has taken care to be thoughtful and fair, but
+things may change as we learn more and get feedback from the community. Please
+let us know what you think by commenting in our forum or by emailing us at !
diff --git a/_develop/mining_review.md b/_develop/mining_review.md
new file mode 100644
index 00000000..89221283
--- /dev/null
+++ b/_develop/mining_review.md
@@ -0,0 +1,38 @@
+---
+layout: learn
+permalink: /:collection/:path.html
+---
+# App reviewer instructions
+
+Reviewers submit their app rankings to Blockstack every month. The first day of
+the month Blockstack will email reviewers a spreadsheet on which to record rankings.
+
+To submit app rankings, please complete the following steps:
+
+1. Download the spreadsheet for that month.
+
+ The spreadsheet is sent to the email address Blocksack has on file for you. The sheet lists all apps eligible for ranking.
+
+2. Record your rankings on the spreadsheet.
+
+ Place a the rank value in the **Ranking** column next to each app you would
+ like to rank. You can rank only those apps you want and omit ranking others.
+ Rank each application numerically where 1 (one) is the highest. For reviewer
+ partners, rank apps for the month using the methodology of your
+ organization.
+
+ Please avoid modifying the spreadsheet in apart from adding your rankings.
+ The `App ID` column, in particular, must be preserved to process your rankings
+ accurately.
+
+3. Return your rankings by the 15th of each month to .
+
+ {% include important.html content="Blockstack must receive your rankings by the 15th of the month or they won't be considered!" %}
+
+4. Attach your completed spreadsheet to your return email.
+
+ Include in the email a brief explanation summarizing your methodology or
+ thoughts when ranking. Please mention any app you want to highlight for the
+ month.
+
+After receiving the rankings from the reviews, Blockstack will calculated each applications final z-scores.
diff --git a/_includes/footer.html b/_includes/footer.html
index 0fab5536..90ded464 100644
--- a/_includes/footer.html
+++ b/_includes/footer.html
@@ -25,7 +25,7 @@
{% include social-networks.html %}
-->
-
In accumsan lacus ac neque maximus dictum. Phasellus eleifend leo id mattis bibendum. Curabitur et purus turpis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
Cras at dolor eget urna varius faucibus tempus in elit. Cras a dui imperdiet, tempus metus quis, pharetra turpis. Phasellus at massa sit amet ante semper fermentum sed eget lectus. Quisque id dictum magna turpis.
@@ -359,27 +400,24 @@ modify the hello-world to interact with t
Create a hello-blockstack directory.
-
mkdir hello-blockstack
-
-
+
mkdir hello-blockstack
+
Change into your new directory.
-
cd hello-blockstack
-
-
+
cd hello-blockstack
+
Use Yeoman and the Blockstack application generator to create your initial hello-blockstack application.
-
yo blockstack:react
-
-
+
yo blockstack:react
+
You should see several interactive prompts.
-
$ yo blockstack:react
+
$ yo blockstack:react
==========================================================================
We are constantly looking for ways to make yo better!
May we anonymously report usage statistics to improve the tool over time?
@@ -388,8 +426,8 @@ modify the hello-world to interact with t
_-----_ ╭──────────────────────────╮
| | │ Welcome to the │
- |--(o)--| │ Blockstack app │
- --------- │ generator! │
+ |--(o)--| │ Blockstack app │
+ --------- │ generator! │
( _U_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
@@ -397,28 +435,26 @@ modify the hello-world to interact with t
|° Y
? Are you ready to build a Blockstack app in React? (Y/n)
-
-
+
Respond to the prompts to populate the initial app.
After the process completes successfully, you see a prompt similar to the following:
-
[fsevents] Success:
+
[fsevents] Success:
"/Users/theuser/repos/hello-blockstack/node_modules/fsevents/lib/binding/Release/node-v59-darwin-x64/fse.node"
is installed via remote npm notice created a lockfile as package-lock.json.
You should commit this file. added 1060 packages in 26.901s
-
-
+
Run the initial application.
-
$ npm start
+
$ npm start
- > hello-blockstack@0.0.0 start /Users/moxiegirl/repos/hello-blockstack
- > webpack-dev-server
+ > hello-blockstack@0.0.0 start /Users/moxiegirl/repos/hello-blockstack
+ > webpack-dev-server
Project is running at http://localhost:8080/
webpack output is served from /
@@ -435,8 +471,7 @@ modify the hello-world to interact with t
[2] (webpack)/buildin/global.js 509 bytes {0}[built]
[3] (webpack)/buildin/module.js 517 bytes {0}[built]
webpack: Compiled successfully.
-
-
+
The system opens a browser displaying your running application.
@@ -481,14 +516,13 @@ application directory.
This endpoint on the web version of your app will redirect Android users back
to your mobile app.
Blockstack apps are identified by their domain names. The endpoint will
receive a get request with the query parameter authResponse=XXXX and
@@ -784,7 +817,7 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
When you are done, your imports should appear as follows:
-
+
importandroid.support.v7.app.AppCompatActivityimportandroid.os.Bundle
@@ -795,13 +828,12 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
importorg.blockstack.android.sdk.Scopeimportorg.blockstack.android.sdk.UserDataimportjava.net.URI
-
-
+
Add a variable for the Blockstack session before onCreate.
-
classMainActivity:AppCompatActivity(){
+
classMainActivity:AppCompatActivity(){privatevar_blockstackSession:BlockstackSession?=null
@@ -811,13 +843,12 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
setContentView(R.layout.activity_main)}}
-
-
+
Replace the existing the onCreate function with the following:
overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)
@@ -856,8 +887,7 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
handleAuthResponse(intent)}}
-
-
+
This new onCreate does several things:
@@ -877,14 +907,13 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
Add a private function to reflect when a user successfully signs in.
-
privatefunonSignIn(userData:UserData){
+
privatefunonSignIn(userData:UserData){userDataTextView.text="Signed in as ${userData.decentralizedID}"signInButton.isEnabled=false}
-
-
+
Handle sign in requests with an onNewIntent function if the activity was already opened when signing in
@@ -892,20 +921,19 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
Retrieve the authentication token from the custom protocol handler call and
send it to the Blockstack session.
privatefunhandleAuthResponse(intent:Intent){valresponse=intent.dataStringif(response!=null){valauthResponseTokens=response.split(':')
@@ -924,13 +952,12 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
}}}
-
-
+
Add the convenience method to access the blockstack session.
-
funblockstackSession():BlockstackSession{
+
funblockstackSession():BlockstackSession{valsession=_blockstackSessionif(session!=null){returnsession
@@ -938,13 +965,12 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
throwIllegalStateException("No session.")}}
-
-
+
Verify your final MainActivity.kt code looks like this:
-
classMainActivity:AppCompatActivity(){
+
classMainActivity:AppCompatActivity(){privatevar_blockstackSession:BlockstackSession?=null
@@ -1025,8 +1051,7 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
}
-
-
+
@@ -1066,6 +1091,71 @@ know about your experience by tweeting to
+
+
@@ -1164,74 +1254,6 @@ know about your experience by tweeting to
-
-
-
-
-
+{"url":"https://docs.blockstack.org/browser/blockstack_storage.html","headline":"Blockstack Storage Tutorial","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/browser/blockstack_storage.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Blockstack Storage Tutorial","@type":"BlogPosting","@context":"http://schema.org"}
@@ -116,6 +116,23 @@
+
@@ -195,13 +239,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -259,10 +303,9 @@ the application, you need to have already registered
Use Yeoman and the Blockstack application generator to create your initial publik application.
-
yo blockstack:react
-
-
+
yo blockstack:react
+
You should see several interactive prompts.
-
$ yo blockstack:react
+
$ yo blockstack:react
? ==========================================================================
We're constantly looking for ways to make yo better!
May we anonymously report usage statistics to improve the tool over time?
@@ -340,27 +378,24 @@ existing projects.
´ ` |° ´ Y `
? Are you ready to build a Blockstack app in React? (Y/n)
-
-
+
Respond to the prompts to populate the initial app.
After the process completes successfully, you see a prompt similar to the following:
-
[fsevents] Success:
+
[fsevents] Success:
"/Users/theuser/repos/publik/node_modules/fsevents/lib/binding/Release/node-v59-darwin-x64/fse.node"
is installed via remote npm notice created a lockfile as package-lock.json.
You should commit this file. added 1060 packages in 26.901s
-
-
+
Run the initial application.
-
npm start
-
-
+
npm start
+
The system prompts you to accept incoming connections.
@@ -404,23 +439,21 @@ stored on Gaia are made visible to others via the handleSignIn handler method.
-
By default, authentication requests include the store_write scope which
enables storage. This is what allows you to store information to Gaia.
@@ -454,18 +487,17 @@ delete grocery lists.
A single file collection stores items as an array nested inside each grocery
list:
-
// grocerylists.json
+
// grocerylists.json{
- "3255":{
- "items":[
+ "3255":{
+ "items":["1 Head of Lettuce","Haralson apples"]},// ...more lists with items}
-
-
+
This is conceptually the simplest way to manage grocery lists. When you read a
/grocerylists.json file with getFile(), you get back one or more grocery
@@ -504,28 +536,26 @@ or remove a grocery list; updating a list has no impact.
The Person object holds a Blockstack profile. Add putFile, getFile,
and lookupProfile after Person.
-
When you are done, the import statement should look like the following:
-
-
+
When you are done, the import statement should look like the following:
+
Replace the constructor() initial state so that it holds the key properties required by the app.
This code constructs a Blockstack Person object to hold the profile. Your constructor should look like this:
-
constructor(props){
- super(props);
+
constructor(props){
+ super(props);this.state={person:{
@@ -543,8 +573,7 @@ or remove a grocery list; updating a list has no impact.
isLoading:false};}
-
-
+
Locate the render() method.
@@ -553,10 +582,10 @@ or remove a grocery list; updating a list has no impact.
The following code echos the person.name and person.avatarURL
properties from the profile on the display:
render(){
+ const{handleSignOut}=this.props;
+ const{person}=this.state;
+ const{username}=this.state;return(!isSignInPending()&&person?
@@ -569,8 +598,8 @@ or remove a grocery list; updating a list has no impact.
src={person.avatarUrl()?person.avatarUrl():avatarFallbackImage}className="img-rounded avatar"id="avatar-image"
- />
-<divclassName="username">
+ />
+ <divclassName="username"><h1><spanid="heading-name">{person.name()?person.name():'Nameless Person'}</span>
@@ -590,8 +619,8 @@ or remove a grocery list; updating a list has no impact.
value={this.state.newStatus}onChange={e=>this.handleNewStatusChange(e)}placeholder="Enter a status"
- />
-</div>
+ />
+ </div>
<divclassName="col-md-12"><buttonclassName="btn btn-primary btn-lg"
@@ -607,8 +636,7 @@ or remove a grocery list; updating a list has no impact.
</div> : null
);}
-
-
+
This code allows the application to post statuses. It also displays the
user’s Blockstack ID. To display this, your app must extract the ID from the
@@ -620,19 +648,18 @@ user profile data.
You’ll use the Blockstack loadUserData() method to access the username.
@@ -694,7 +719,7 @@ the statuses back to the user as a blog entry.
Right after this opening div element, add this block.
-
<divclassName="col-md-12 statuses">
+
<divclassName="col-md-12 statuses">{this.state.isLoading&&<span>Loading...</span>}
{this.state.statuses.map((status)=>(<divclassName="status"key={status.id}>
@@ -703,17 +728,16 @@ the statuses back to the user as a blog entry.
))}</div>
-
-
+
This loads existing state. Your code needs to fetch statuses on page load.
Add a new method called fetchData() after the statuses.unshift(status) section.
-
+
fetchData(){this.setState({isLoading:true})
- constoptions={decrypt:false}
+ constoptions={decrypt:false}getFile('statuses.json',options).then((file)=>{varstatuses=JSON.parse(file||'[]')
@@ -728,18 +752,16 @@ the statuses back to the user as a blog entry.
this.setState({isLoading:false})})}
-
-
+
Call fetchData() from the componentDidMount() method
-
+
componentDidMount(){this.fetchData()}
-
-
+
Save the file.
@@ -758,7 +780,7 @@ the statuses back to the user as a blog entry.
Replace the content with the following:
-
/* Globals */
+
/* Globals */a,a:focus,a:hover{color:#fff;}html,body{height:100%;text-align:center;background-color:#191b22;}body{color:#fff}
@@ -793,8 +815,7 @@ the statuses back to the user as a blog entry.
/* Statuses */.statuses{padding-top:30px;}.status{margin:15px0px;padding:20px;background-color:#2e2e2e;border-radius:6px}
-
-
+
Save and close the src/styles/style.css file.
@@ -826,49 +847,44 @@ other users’ profiles by visiting http://local
Install react-router:
-
npm install --save react-router-dom
-
-
+
npm install --save react-router-dom
+
Edit src/index.js file.
Add an import to the file at the top:
-
import{BrowserRouter}from'react-router-dom'
-
-
+
import{BrowserRouter}from'react-router-dom'
+
Change the ReactDOM.render() method in src/index.js to:
You use isLocal() to check if the user is viewing the local user profile or another user’s profile. If it’s the local user profile, the app runs the getFile() function you added in an earlier step. Otherwise, the app looks up the profile belonging to the username using the lookupProfile() method.
Modify the fetchData() method like so:
-
fetchData(){
+
fetchData(){this.setState({isLoading:true})if(this.isLocal()){
- constoptions={decrypt:false}
+ constoptions={decrypt:false}getFile('statuses.json',options).then((file)=>{varstatuses=JSON.parse(file||'[]')
@@ -949,7 +961,7 @@ process URL paths that contain the . (dot
this.setState({isLoading:false})})}else{
- constusername=this.props.match.params.username
+ constusername=this.props.match.params.usernamelookupProfile(username).then((profile)=>{
@@ -963,8 +975,7 @@ process URL paths that contain the . (dot
})}}
-
-
+
NOTE: For https deployments, the default Blockstack Core API endpoint for name
lookups should be changed to point to a core API served over https.
@@ -976,7 +987,7 @@ process URL paths that contain the . (dot
Add the following block to fetchData() right after the call to lookupProfile(username)... catch((error)=>{..} block:
-
constoptions={username:username,decrypt:false}
+
constoptions={username:username,decrypt:false}getFile('statuses.json',options).then((file)=>{varstatuses=JSON.parse(file||'[]')
@@ -991,8 +1002,7 @@ process URL paths that contain the . (dot
.finally(()=>{this.setState({isLoading:false})})
-
-
+
This fetches the user statuses.
@@ -1001,10 +1011,10 @@ process URL paths that contain the . (dot
render(){
+ const{handleSignOut}=this.props;
+ const{person}=this.state;
+ const{username}=this.state;return(!isSignInPending()&&person?
@@ -1017,8 +1027,8 @@ process URL paths that contain the . (dot
src={person.avatarUrl()?person.avatarUrl():avatarFallbackImage}className="img-rounded avatar"id="avatar-image"
- />
-<divclassName="username">
+ />
+ <divclassName="username"><h1><spanid="heading-name">{person.name()?person.name():'Nameless Person'}</span>
@@ -1040,8 +1050,8 @@ process URL paths that contain the . (dot
value={this.state.newStatus}onChange={e=>this.handleNewStatusChange(e)}placeholder="What's on your mind?"
- />
-</div>
+ />
+ </div>
<divclassName="col-md-12 text-right"><buttonclassName="btn btn-primary btn-lg"
@@ -1066,10 +1076,9 @@ process URL paths that contain the . (dot
</div> : null
);}
-
-
+
-
### This checks to ensure that users are viewing their own profile, by wrapping the Logout button and inputs with the {isLocal()&&...} condition.
+
### This checks to ensure that users are viewing their own profile, by wrapping the Logout button and inputs with the {isLocal() && ...} condition.
@@ -1080,9 +1089,8 @@ process URL paths that contain the . (dot
Restart the application so that the disabling of the . (dot) rule takes effect.
-
npm start
-
-
+
npm start
+
Point your browser to http://localhost:8080/your_blockstack.id to see the final application.
@@ -1097,6 +1105,71 @@ about Blockstack. To use a working version of the app go
+
+
@@ -1195,74 +1268,6 @@ about Blockstack. To use a working version of the app go
-
-
-
-
-
+{"url":"https://docs.blockstack.org/browser/browser-introduction.html","headline":"Get the Blockstack Browser","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/browser/browser-introduction.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Get the Blockstack Browser","@type":"BlogPosting","@context":"http://schema.org"}
@@ -159,13 +159,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -209,11 +209,10 @@ Browser is itself, a simple Dapp. It allows you to:
find and launch Dapps
-
There are editorions of the Blockstack Browser, the web edition is an
-application you access through your web browser by simply visit the
-applications’ address in your computer’s
-browser. You can also install the browser as a client application on your
-computer.
+
There are two editions of the Blockstack Browser, the web edition is an
+application you access through your web browser by simply visiting the application’s
+address in your computer’s browser. You can also install the browser as a
+client application on your computer.
If all you want to do is create, manage, and fund an identity and then interact
with Dapps, you can simply use the web edition. If you have concerns about net
@@ -244,15 +243,14 @@ may find it useful to install the client edition.
The Blockstack Browser installer is a multiple-context installer. If you
run it as a user, the installation is avalable only for that user. If you
install as administrator, the installation installs for all users. To find an
-installer for your operating system, visit the Blockstack install
-page.
Note: The Blockstack script used in this procedure runs docker commands. Depending on how you installed and configure Dockered on your system, it may or may not be necessary to have root or sudo privileges. For this reason, the commands below show the use of sudo when interacting with the script or the docker executable. If your installation allows running Docker with lower privileges, you can omit it.
@@ -541,6 +527,71 @@ but that is not explained here.
+
+
@@ -639,74 +690,6 @@ but that is not explained here.
-
-
-
-
-
+{"url":"https://docs.blockstack.org/browser/browser-nav.html","headline":"Browser Nav","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/browser/browser-nav.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"On this page, you learn more about working with IDs, the Wallet, and Settings.","@type":"BlogPosting","@context":"http://schema.org"}
@@ -159,13 +159,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -187,6 +187,71 @@ the .blockstack namespace has the
+
+
@@ -285,74 +350,6 @@ the .blockstack namespace has the
-
-
-
-
-
-
+{"url":"https://docs.blockstack.org/browser/faq_general.html","headline":"Users Frequently Asked Questions (FAQ)","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/browser/faq_general.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Users Frequently Asked Questions (FAQ)","@type":"BlogPosting","@context":"http://schema.org"}
@@ -159,13 +159,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -259,6 +259,71 @@ started with them right away.
+
+
@@ -357,74 +422,6 @@ started with them right away.
-
-
-
-
-
+{"url":"https://docs.blockstack.org/browser/hello-blockstack.html","headline":"Hello, Blockstack Tutorial","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/browser/hello-blockstack.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Hello, Blockstack Tutorial","@type":"BlogPosting","@context":"http://schema.org"}
@@ -116,6 +116,23 @@
+
@@ -195,13 +239,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -258,10 +302,9 @@ the application, you need to have already registered a Blockstack ID.
The tutorial relies on the npm dependency manager. Before you begin, verify
you have installed npm using the which command to verify.
Use Yeoman and the Blockstack application generator to create your initial hello-world-tutorial application.
-
yo blockstack
-
-
+
yo blockstack
+
You should see several interactive prompts.
-
$ yo blockstack
+
$ yo blockstack
_-----_ ╭──────────────────────────╮
| | │ Welcome to the │
- |--(o)--| │ Blockstack app │
- `---------´ │ generator! │
+ |--(o)--| │ Blockstack app │
+ `---------´ │ generator! │
( _´U`_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
@@ -332,15 +370,14 @@ existing projects.
´ ` |° ´ Y `
? Are you ready to build a Blockstack app in React? (Y/n)
-
-
+
Respond to the prompts to populate the initial app.
After the process completes successfully, you see a prompt similar to the following:
-
...
+
...
create public/icon-192x192.png
create public/index.html
create public/robots.txt
@@ -348,8 +385,7 @@ create public/manifest.json
I'm all done. Running npm install for you to install the required dependencies. If this fails, try running the command yourself.
-
-
+
@@ -451,9 +487,8 @@ and open your browser ‘http://localhost:5000’. From the root of your new ap
Start the application server.
-
npm start
-
-
+
npm start
+
The first time you run it, your system prompts you to accept incoming connections.
@@ -514,30 +549,27 @@ in the public/app.css file. Open this fil
All of the code in the file is wrapped in an event
listener.
You can find the redirectUserToSignIn() function is part of the Blockstack Javascript documentation. There is also a sign out button handler. This handler deletes the local user data and signs the user out:
Each getElementById() function refers to elemments in the index.html file.
@@ -563,7 +594,7 @@ several states the user can be in:
The application handles these situtations as followed:
-
if(blockstack.isUserSignedIn()){
+
if(blockstack.isUserSignedIn()){varprofile=blockstack.loadUserData().profileshowProfile(profile)}elseif(blockstack.isSignInPending()){
@@ -571,8 +602,7 @@ several states the user can be in:
window.location=window.location.origin})}
-
-
+
When the user is signed in, Blockstack loads the user data from local storage
and displays the profile with the showProfile() function. When the user has a
@@ -585,18 +615,17 @@ user back to the home page.
configurations dictate how the application is displayed in auth views and on
user home screens. The contents are very simple:
-
Push your new code to the master branch of the remote repo:
-
git push origin master
-
-
+
git push origin master
+
@@ -647,6 +672,71 @@ You’re well on your way to becoming a Blockstack app legend.
+
+
@@ -745,74 +835,6 @@ You’re well on your way to becoming a Blockstack app legend.
-
-
-
-
-
+{"url":"https://docs.blockstack.org/browser/ids-creating.html","headline":"Working with IDS","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/browser/ids-creating.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Working with IDS","@type":"BlogPosting","@context":"http://schema.org"}
@@ -159,13 +159,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -212,6 +212,71 @@ unusual.
+
+
@@ -310,74 +375,6 @@ unusual.
-
-
-
-
-
+{"url":"https://docs.blockstack.org/browser/ids-introduction.html","headline":"Get and use a Blockstack ID","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/browser/ids-introduction.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Get and use a Blockstack ID","@type":"BlogPosting","@context":"http://schema.org"}
@@ -159,13 +159,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -416,6 +416,71 @@ recovery key rather than your code to restore your identity.
+
+
@@ -514,74 +579,6 @@ recovery key rather than your code to restore your identity.
-
-
-
-
-
+{"url":"https://docs.blockstack.org/browser/multi-player-storage.html","headline":"Manage Data with Gaia","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/browser/multi-player-storage.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Manage Data with Gaia","@type":"BlogPosting","@context":"http://schema.org"}
@@ -116,6 +116,23 @@
+
@@ -195,13 +239,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -259,10 +303,9 @@ the application, you need to have already register
Use Yeoman and the Blockstack application generator to create your initial publik application.
-
yo blockstack:react
-
-
+
yo blockstack:react
+
You should see several interactive prompts.
-
$ yo blockstack:react
+
$ yo blockstack:react
? ==========================================================================
We're constantly looking for ways to make yo better!
May we anonymously report usage statistics to improve the tool over time?
@@ -340,27 +378,24 @@ existing projects.
´ ` |° ´ Y `
? Are you ready to build a Blockstack app in React? (Y/n)
-
-
+
Respond to the prompts to populate the initial app.
After the process completes successfully, you see a prompt similar to the following:
-
[fsevents] Success:
+
[fsevents] Success:
"/Users/theuser/repos/publik/node_modules/fsevents/lib/binding/Release/node-v59-darwin-x64/fse.node"
is installed via remote npm notice created a lockfile as package-lock.json.
You should commit this file. added 1060 packages in 26.901s
-
-
+
Run the initial application.
-
npm start
-
-
+
npm start
+
The system prompts you to accept incoming connections.
@@ -404,23 +439,21 @@ stored on Gaia are made visible to others via the handleSignIn handler method.
-
By default, authentication requests include the store_write scope which
enables storage. This is what allows you to store information to Gaia.
@@ -454,18 +487,17 @@ delete grocery lists.
A single file collection stores items as an array nested inside each grocery
list:
-
// grocerylists.json
+
// grocerylists.json{
- "3255":{
- "items":[
+ "3255":{
+ "items":["1 Head of Lettuce","Haralson apples"]},// ...more lists with items}
-
-
+
This is conceptually the simplest way to manage grocery lists. When you read a
/grocerylists.json file with getFile(), you get back one or more grocery
@@ -504,28 +536,26 @@ or remove a grocery list; updating a list has no impact.
The Person object holds a Blockstack profile. Add putFile, getFile,
and lookupProfile after Person.
-
When you are done, the import statement should look like the following:
-
-
+
When you are done, the import statement should look like the following:
+
Replace the constructor() initial state so that it holds the key properties required by the app.
This code constructs a Blockstack Person object to hold the profile. Your constructor should look like this:
-
constructor(props){
- super(props);
+
constructor(props){
+ super(props);this.state={person:{
@@ -543,8 +573,7 @@ or remove a grocery list; updating a list has no impact.
isLoading:false};}
-
-
+
Locate the render() method.
@@ -553,10 +582,10 @@ or remove a grocery list; updating a list has no impact.
The following code echos the person.name and person.avatarURL
properties from the profile on the display:
render(){
+ const{handleSignOut}=this.props;
+ const{person}=this.state;
+ const{username}=this.state;return(!isSignInPending()&&person?
@@ -569,8 +598,8 @@ or remove a grocery list; updating a list has no impact.
src={person.avatarUrl()?person.avatarUrl():avatarFallbackImage}className="img-rounded avatar"id="avatar-image"
- />
-<divclassName="username">
+ />
+ <divclassName="username"><h1><spanid="heading-name">{person.name()?person.name():'Nameless Person'}</span>
@@ -590,8 +619,8 @@ or remove a grocery list; updating a list has no impact.
value={this.state.newStatus}onChange={e=>this.handleNewStatusChange(e)}placeholder="Enter a status"
- />
-</div>
+ />
+ </div>
<divclassName="col-md-12"><buttonclassName="btn btn-primary btn-lg"
@@ -607,8 +636,7 @@ or remove a grocery list; updating a list has no impact.
</div> : null
);}
-
-
+
This code allows the application to post statuses. It also displays the
user’s Blockstack ID. To display this, your app must extract the ID from the
@@ -620,19 +648,18 @@ user profile data.
You’ll use the Blockstack loadUserData() method to access the username.
@@ -694,7 +719,7 @@ the statuses back to the user as a blog entry.
Right after this opening div element, add this block.
-
<divclassName="col-md-12 statuses">
+
<divclassName="col-md-12 statuses">{this.state.isLoading&&<span>Loading...</span>}
{this.state.statuses.map((status)=>(<divclassName="status"key={status.id}>
@@ -703,17 +728,16 @@ the statuses back to the user as a blog entry.
))}</div>
-
-
+
This loads existing state. Your code needs to fetch statuses on page load.
Add a new method called fetchData() after the statuses.unshift(status) section.
-
+
fetchData(){this.setState({isLoading:true})
- constoptions={decrypt:false}
+ constoptions={decrypt:false}getFile('statuses.json',options).then((file)=>{varstatuses=JSON.parse(file||'[]')
@@ -728,18 +752,16 @@ the statuses back to the user as a blog entry.
this.setState({isLoading:false})})}
-
-
+
Call fetchData() from the componentDidMount() method
-
+
componentDidMount(){this.fetchData()}
-
-
+
Save the file.
@@ -758,7 +780,7 @@ the statuses back to the user as a blog entry.
Replace the content with the following:
-
/* Globals */
+
/* Globals */a,a:focus,a:hover{color:#fff;}html,body{height:100%;text-align:center;background-color:#191b22;}body{color:#fff}
@@ -793,8 +815,7 @@ the statuses back to the user as a blog entry.
/* Statuses */.statuses{padding-top:30px;}.status{margin:15px0px;padding:20px;background-color:#2e2e2e;border-radius:6px}
-
-
+
Save and close the src/styles/style.css file.
@@ -826,49 +847,44 @@ other users’ profiles by visiting http://local
Install react-router:
-
npm install --save react-router-dom
-
-
+
npm install --save react-router-dom
+
Edit src/index.js file.
Add an import to the file at the top:
-
import{BrowserRouter}from'react-router-dom'
-
-
+
import{BrowserRouter}from'react-router-dom'
+
Change the ReactDOM.render() method in src/index.js to:
You use isLocal() to check if the user is viewing the local user profile or another user’s profile. If it’s the local user profile, the app runs the getFile() function you added in an earlier step. Otherwise, the app looks up the profile belonging to the username using the lookupProfile() method.
Modify the fetchData() method like so:
-
fetchData(){
+
fetchData(){this.setState({isLoading:true})if(this.isLocal()){
- constoptions={decrypt:false}
+ constoptions={decrypt:false}getFile('statuses.json',options).then((file)=>{varstatuses=JSON.parse(file||'[]')
@@ -949,7 +961,7 @@ process URL paths that contain the . (dot
this.setState({isLoading:false})})}else{
- constusername=this.props.match.params.username
+ constusername=this.props.match.params.usernamelookupProfile(username).then((profile)=>{
@@ -963,8 +975,7 @@ process URL paths that contain the . (dot
})}}
-
-
+
NOTE: For https deployments, the default Blockstack Core API endpoint for name
lookups should be changed to point to a core API served over https.
@@ -976,7 +987,7 @@ process URL paths that contain the . (dot
Add the following block to fetchData() right after the call to lookupProfile(username)... catch((error)=>{..} block:
-
constoptions={username:username,decrypt:false}
+
constoptions={username:username,decrypt:false}getFile('statuses.json',options).then((file)=>{varstatuses=JSON.parse(file||'[]')
@@ -991,8 +1002,7 @@ process URL paths that contain the . (dot
.finally(()=>{this.setState({isLoading:false})})
-
-
+
This fetches the user statuses.
@@ -1001,10 +1011,10 @@ process URL paths that contain the . (dot
render(){
+ const{handleSignOut}=this.props;
+ const{person}=this.state;
+ const{username}=this.state;return(!isSignInPending()&&person?
@@ -1017,8 +1027,8 @@ process URL paths that contain the . (dot
src={person.avatarUrl()?person.avatarUrl():avatarFallbackImage}className="img-rounded avatar"id="avatar-image"
- />
-<divclassName="username">
+ />
+ <divclassName="username"><h1><spanid="heading-name">{person.name()?person.name():'Nameless Person'}</span>
@@ -1040,8 +1050,8 @@ process URL paths that contain the . (dot
value={this.state.newStatus}onChange={e=>this.handleNewStatusChange(e)}placeholder="What's on your mind?"
- />
-</div>
+ />
+ </div>
<divclassName="col-md-12 text-right"><buttonclassName="btn btn-primary btn-lg"
@@ -1066,10 +1076,9 @@ process URL paths that contain the . (dot
</div> : null
);}
-
-
+
-
### This checks to ensure that users are viewing their own profile, by wrapping the Logout button and inputs with the {isLocal()&&...} condition.
+
### This checks to ensure that users are viewing their own profile, by wrapping the Logout button and inputs with the {isLocal() && ...} condition.
@@ -1080,9 +1089,8 @@ process URL paths that contain the . (dot
Restart the application so that the disabling of the . (dot) rule takes effect.
-
npm start
-
-
+
npm start
+
Point your browser to http://localhost:8080/your_blockstack.id to see the final application.
@@ -1097,6 +1105,71 @@ about Blockstack. To use a working version of the app go
+
+
@@ -1195,74 +1268,6 @@ about Blockstack. To use a working version of the app go
-
-
-
-
-
+{"url":"https://docs.blockstack.org/browser/purchase-id.html","headline":"Purchase your own domain ID","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/browser/purchase-id.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Purchase your own domain ID","@type":"BlogPosting","@context":"http://schema.org"}
@@ -159,13 +159,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -199,6 +199,71 @@ consequat. Aliquam hendrerit a neque id tempor. Sed porta id ligula in iaculis.<
+
+
@@ -297,74 +362,6 @@ consequat. Aliquam hendrerit a neque id tempor. Sed porta id ligula in iaculis.<
-
-
-
-
-
+{"url":"https://docs.blockstack.org/browser/todo-list.html","headline":"Todo List Application Tutorial","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/browser/todo-list.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Todo List Application Tutorial","@type":"BlogPosting","@context":"http://schema.org"}
@@ -116,6 +116,23 @@
+
$ yarn install
yarn install v1.9.2
info No lockfile found.
...
@@ -293,8 +334,7 @@ These instructions assume you are cloning.
[5/5] 📃 Building fresh packages...
success Saved lockfile.
✨ Done in 19.90s.
-
-
+
@@ -335,17 +375,15 @@ These instructions assume you are cloning.
Make sure you are in the root of the code base.
-
$ pwd /Users/moxiegirl/repos/blockstack-todos
+
$ pwd /Users/moxiegirl/repos/blockstack-todos
Start the application.
-
@@ -460,16 +497,15 @@ in and sign out is handled in each of these files:
The src/components/Landing.vue code calls a redirectToSignIn() function which generates the authRequest and redirects the user to the Blockstack authenticator:
Once the user authenticates, the application handles the authResponse in the src/App.vue file. :
-
if(blockstack.isUserSignedIn()){
+
if(blockstack.isUserSignedIn()){this.user=blockstack.loadUserData().profile}elseif(blockstack.isSignInPending()){blockstack.handlePendingSignIn()
@@ -477,18 +513,16 @@ in and sign out is handled in each of these files:
window.location=window.location.origin})}
-
-
+
If blockstack.isUserSignedIn() is true, the user was previously signed in so Blockstack pulls the data from the browser and uses it in our application. If the check on blockstack.isSignInPending() is true, a previous authResponse was sent to the application but hasn’t been processed yet. The handlePendingSignIn() function processes any pending sign in.
Signout is handled in src/components/Dashboard.vue.
The method allows the application creator to decide where to redirect the user upon Sign Out:
@@ -509,44 +543,42 @@ command:
You should see a JSON with the todos you just added:
-
[
+
[{
- "id":2,
- "text":"Software package manager secured by the blockchain",
- "completed":false
+ "id":2,
+ "text":"Software package manager secured by the blockchain",
+ "completed":false},{
- "id":1,
- "text":"Mutable torrents with human readable names",
- "completed":false
+ "id":1,
+ "text":"Mutable torrents with human readable names",
+ "completed":false},{
- "id":0,
- "text":"Decentralized twitter",
- "completed":false
+ "id":0,
+ "text":"Decentralized twitter",
+ "completed":false}]
-
-
+
Add another todo and check it off. When you fetch the newly generated file
using the Javascript console, the results reflect your change. Look for "completed":true:
-
[
+
[{
- "id":3,
- "text":"Blockstack Todo",
- "completed":true
+ "id":3,
+ "text":"Blockstack Todo",
+ "completed":true},{
- "id":2,
- "text":"Software package manager secured by the blockchain",
- "completed":false
+ "id":2,
+ "text":"Software package manager secured by the blockchain",
+ "completed":false},...]
-
-
+
Now that you have seen the application in action, dig into how it works.
@@ -557,17 +589,16 @@ application interactions with your Gaia Hub originate in the
src/components/Dashboard.vue file. First, examine where the changes to the
Todos are processed:
-
todos:{
+
todos:{handler:function(todos){
- constblockstack=this.blockstack
+ constblockstack=this.blockstack// encryption is now enabled by defaultreturnblockstack.putFile(STORAGE_FILE,JSON.stringify(todos))},
- deep:true
+ deep:true}
-
-
+
The todos JSON object is passed in and the
blockstack.putFile()
@@ -575,8 +606,8 @@ method to store it in a Gaia Hub.
The code needs to read the Todo items from the storage with the blockstack.getFile() method which returns a promise:
-
fetchData(){
- constblockstack=this.blockstack
+
fetchData(){
+ constblockstack=this.blockstackblockstack.getFile(STORAGE_FILE)// decryption is enabled by default.then((todosText)=>{vartodos=JSON.parse(todosText||'[]')
@@ -587,8 +618,7 @@ method to store it in a Gaia Hub.
this.todos=todos})},
-
-
+
The todos data is retrieved from the promise.
@@ -604,6 +634,71 @@ method to store it in a Gaia Hub.
+
+
@@ -702,74 +797,6 @@ method to store it in a Gaia Hub.
-
-
-
-
-
+{"url":"https://docs.blockstack.org/common/construction.html","headline":"Excuse our dust!","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/common/construction.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Excuse our dust!","@type":"BlogPosting","@context":"http://schema.org"}
@@ -151,13 +151,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -170,6 +170,71 @@
+
+
@@ -255,74 +320,6 @@
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/atlas/howitworks.html","headline":"How Atlas Works","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/atlas/howitworks.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"How Atlas Works","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -429,7 +429,7 @@ find out which chunks they each have. Atlas nodes download chunks from
neighbors in rarest-first order in order to prioritize data replication for the
chunks that are currently most at-risk for disappearing due to node failure.
-
Name operation | chunk hashes | chunk data | Inventory
+
Name operation | chunk hashes | chunk data | Inventory
history | as name state | | vector
+-------------------+
@@ -457,20 +457,18 @@ it has and which ones it does not, and announces it to other Atlas peers so
they can fetch chunks they are missing. In this example, the node's
inventory vector is [1, 0, 1], since the 0th and 2nd chunks are present
but the 1st chunk is missing.
-
-
+
Querying Chunk Inventories
Developers can query a node’s inventory vector as follows:
The variable result['inv'] here is a big-endian bit vector, where the ith
bit is set to 1 if the ith chunk in the chunk sequence is present. The bit at
@@ -484,6 +482,71 @@ which ones are missing which chunks can be found
+
+
@@ -582,74 +645,6 @@ which ones are missing which chunks can be found
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/atlas/howtouse.html","headline":"How to Use the Atlas Network","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/atlas/howtouse.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"How to Use the Atlas Network","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -321,7 +321,7 @@ chunk data. A client can query up to 100 chunks in one RPC call.
the returned payload will be a dict with a zonefiles key that maps the chunk
hashes to their respective data.
-
>>>importblockstack
+
>>>importblockstack>>>data=blockstack.lib.client.get_zonefiles('https://node.blockstack.org:6263',['1b89a685f4c4ea245ce9433d0b29166c22175ab4'])>>>printdata['zonefiles']['1b89a685f4c4ea245ce9433d0b29166c22175ab4']$ORIGINduckduckgo_tor.id
@@ -329,8 +329,7 @@ hashes to their respective data.
torTXT"3g2upl4pq6kufc4m.onion">>>
-
-
+
(This particular chunk happens to be associated with the BNS name
duckduckgo_tor.id).
@@ -356,15 +355,14 @@ Browser
for doing this.
Once the name operation is confirmed, you can announce the data to the
Atlas network. You can do so with the Python client as follows:
-
>>>importblockstack
+
>>>importblockstack>>>importbase64>>>data="..."# this is the chunk data you will announce>>>data_b64=base64.b64encode(data)>>>result=blockstack.lib.client.put_zonefiles('https://node.blockstack.org:6263',[data_b64])>>>assertresult['saved'][0]==1>>>
-
-
+
At most five chunks can be announced in one RPC call.
Note that the data must be base64-encoded before it can be announced.
@@ -392,7 +390,7 @@ peer graph, and replicate the chunk to each of them as well.
For example, this code will replicate the chunk to not only
https://node.blockstack.org:6263, but also to its immediate neighbors.
-
>>>importblockstack
+
>>>importblockstack>>>importbase64>>>data="..."# this is the chunk you will replicate widely>>>data_b64=base64.b64encode(data)
@@ -407,8 +405,7 @@ peer graph, and replicate the chunk to each of them as well.
...assertresult['saved'][0]==1...>>>
-
-
+
This is not strictly necessary, but it does help accelerate chunk replication
and makes it less likely that a chunk will get lost due to individual node
@@ -418,6 +415,71 @@ failures.
+
+
@@ -516,74 +578,6 @@ failures.
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/atlas/overview.html","headline":"Overview of the Atlas network","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/atlas/overview.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Overview of the Atlas network","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -328,7 +328,7 @@ propagate them to the Atlas network. BNS API endpoints, including our
will automatically fetch zone files from Atlas when they need to look
up data in Gaia (such as profiles and app data).
-
+--------------+ +---------------+ +----------------+
clients | Blockstack | | blockstack.js | | BNS API module |
| Browser | | | | |
+--------------+ +---------------+ +----------------+
@@ -363,8 +363,7 @@ up zone files for names using the name's stat value as a zone file hash. Client
can broadcast zone files to the network if they match a previously-announced
hash. In practice, zone files store URLs to a name owner's Gaia hubs, thereby
allowing Blockstack apps to read and write data in Gaia.
-
-
+
Nevertheless, Atlas is a general-purpose content-addressed storage
system that advanced developers can use to host data in an immutable
@@ -472,6 +471,71 @@ as part of the protocol.
+
+
@@ -570,74 +634,6 @@ as part of the protocol.
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/faq_developer.html","headline":"Developer FAQs","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/faq_developer.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Developer FAQs","@type":"BlogPosting","@context":"http://schema.org"}
@@ -116,6 +116,23 @@
+
Yes! Blockstack is geared primarily towards Web developers. All of your
+
Yes! Blockstack is geared primarily towards web developers. All of your
existing knowledge is immediately applicable to Blockstack. Anything you can do
-in a Web browser, you can do in a Blockstack app.
+in a web browser, you can do in a Blockstack app.
-
I’m a non-Web developer. Can I build on Blockstack?
+
I’m a non-web developer. Can I build on Blockstack?
Yes! Blockstack implements a RESTful API which
lets you interact with Blockstack from any language and any runtime. In fact,
@@ -244,34 +288,33 @@ the reference client
wrapper around these RESTful API calls, so you won’t be missing much by using a
language other than Javascript.
-
What’s the difference between a Web app and a Blockstack app?
+
What’s the difference between a web app and a Blockstack app?
-
Blockstack apps are built like single-page Web
-apps—they are, in
-fact, a type of Web application.
+
Blockstack apps are built like single-page web
+apps— they are, in
+fact, a type of web application.
-
Blockstack apps are a subset of Web applications that use Blockstack’s
-technology to preserve the user’s control over their identities and data.
-As such, they tend to be simpler
-in design and operation, since in many cases they don’t have to host anything
-besides the application’s assets.
+
Blockstack apps are a subset of web applications that use Blockstack’s
+technology to preserve the user’s control over their identities and data. As
+such, they tend to be simple in design and operation, since in many cases they
+don’t have to host anything besides the application’s assets.
Do I need to learn any new languages or frameworks?
-
No. Blockstack applications are built using existing Web frameworks and programming
+
No. Blockstack applications are built using existing web frameworks and programming
The only new thing you need to learn is either blockstack.js or
the Blockstack RESTful API.
-
How does my Web app interact with Blockstack?
+
How does my web app interact with Blockstack?
The blockstack.js library gives
-any Web application the ability to interact with Blockstack’s authentication and
+any web application the ability to interact with Blockstack’s authentication and
storage services. In addition, we supply a public RESTful API.
What does blockstack.js do?
This is the reference client implementation for Blockstack. You use it in your
-Web app to do the following:
@@ -342,7 +383,7 @@ names. This is currently in development.
Can I programmatically register Blockstack Subdomains?
-
Yes! Once you deploy your own subdomain registrar, you can have your Web app
+
Yes! Once you deploy your own subdomain registrar, you can have your web app
send it requests to register subdomains on your Blockstack ID. You can also
create a program that drives subdomain registration on your Blockstack ID.
@@ -367,13 +408,78 @@ principle applies to a lot of useful decentralized applications.
Can Blockstack applications interact with Bitcoin? Ethereum? Smart contracts? Other blockchains?
-
Yes! Since Blockstack applications are built like Web applications, all you need to do is include the
+
Yes! Since Blockstack applications are built like web applications, all you need to do is include the
relevant Javascript library into your application.
+
+
@@ -472,74 +578,6 @@ relevant Javascript library into your application.
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/faq_technical.html","headline":"Blockstack Technical FAQ","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/faq_technical.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Blockstack Technical FAQ","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -492,6 +492,71 @@ by asking a subdomain registrar to create one for you.
+
+
@@ -590,74 +655,6 @@ by asking a subdomain registrar to create one for you.
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/install-api.html","headline":"Blockstack API","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/install-api.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Blockstack API","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -302,7 +302,7 @@ Ubuntu are below.
+-------------------------------------------------------+
RESTful | +----------------+ +--------------------+ |
+--------+ API | | | private API | | |
| client |<------------>| BNS API module |<----------->| BNS indexer module | |
@@ -339,8 +339,7 @@ the blochchain via a blockchain peer, over the blockchain's peer network.
Blockstack Core currently implements the API module and indexer module as separate
daemons (`blockstack api` and `blockstack-core`, respectively). However, this
is an implementation detail, and may change in the future.
-
-
+
The BNS indexer implements the blockchain consensus rules and network protocols.
Its main responsibility is to build up and replicate all of the name state. It does
@@ -381,6 +380,71 @@ the reader to client-specific documentation for registering and managing names.<
+
+
@@ -479,74 +543,6 @@ the reader to client-specific documentation for registering and managing names.<
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/naming/comparison.html","headline":"Naming system feature comparison","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/comparison.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Naming system feature comparison","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -518,6 +518,71 @@ slightly more valuable.
+
+
@@ -616,74 +681,6 @@ slightly more valuable.
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/naming/creationhowto.html","headline":"Creating a Namespace","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/creationhowto.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Creating a Namespace","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -350,6 +350,71 @@ cryptocurrency at stake.
+
+
@@ -448,74 +513,6 @@ cryptocurrency at stake.
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/naming/did.html","headline":"Decentralized Identifiers (DIDs)","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/did.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Decentralized Identifiers (DIDs)","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -293,14 +293,13 @@ specification for decentralized identifiers (DIDs).
Each name in BNS has an associated DID. The DID format for BNS is:
-
did:stack:v0:{address}-{index}
-
-
+
did:stack:v0:{address}-{index}
+
Where:
-
{address} is an on-chain public key hash (e.g. a Bitcoin address).
-
{index} refers to the nth name this address created.
+
{address} is an on-chain public key hash (e.g. a Bitcoin address).
+
{index} refers to the nth name this address created.
For example, the DID for personal.id is
@@ -350,20 +349,20 @@ for subdomains, so the software can determine which code-path to take.
-
For on-chain BNS names, the {address} is the same as the Bitcoin address
+
For on-chain BNS names, the {address} is the same as the Bitcoin address
that owns the name. Currently, both version byte 0 and version byte 5
addresses are supported (i.e. addresses starting with 1 or 3, meaning p2pkh and
p2sh addresses).
-
For off-chain BNS subdomains, the {address} has version byte 63 for
+
For off-chain BNS subdomains, the {address} has version byte 63 for
subdomains owned by a single private key, and version byte 50 for subdomains
owned by a m-of-n set of private keys. That is, subdomain DID addresses start
with S or M, respectively.
-
The {index} field for a subdomain’s DID is distinct from the {index} field
+
The {index} field for a subdomain’s DID is distinct from the {index} field
for a BNS name’s DID, even if the same created both names and subdomains.
For example, the name abcdefgh123456.id has the DID did:stack:v0:16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg-0,
because it was the first name created by 16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg.
@@ -377,7 +376,7 @@ second is encoded with version byte 63).
You can see this play out in practice with the following code snippit:
-
>>>importblockstack
+
>>>importblockstack>>>blockstack.lib.client.get_name_record('jude.statism.id',hostport='https://node.blockstack.org:6263')['address']u'16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg'>>>importvirtualchain
@@ -385,13 +384,77 @@ second is encoded with version byte 63).
'SSXMcDiCZ7yFSQSUj7mWzmDcdwYhq97p2i'>>>blockstack.lib.client.resolve_DID('did:stack:v0:SSXMcDiCZ7yFSQSUj7mWzmDcdwYhq97p2i-0',hostport='https://node.blockstack.org:6263'){'public_key':'020fadbbcea0ff3b05f03195b41cd991d7a0af8bd38559943aec99cbdaf0b22cc8'}
-
-
+
+
+
@@ -490,74 +553,6 @@ second is encoded with version byte 63).
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/naming/forks.html","headline":"BNS Forks","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/forks.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"BNS Forks","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -423,6 +423,71 @@ to the fork-set with the highest cumulative burn.
+
+
@@ -521,74 +586,6 @@ to the fork-set with the highest cumulative burn.
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/naming/introduction.html","headline":"Blockstack Naming Service (BNS)","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/introduction.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Blockstack Naming Service (BNS)","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -505,6 +505,71 @@ between these name objects is presented below:
+
+
@@ -603,74 +668,6 @@ between these name objects is presented below:
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/naming/manage.html","headline":"Manage BNS Names","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/manage.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Manage BNS Names","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -413,6 +413,71 @@ document for details on how to construct this transaction.
+
+
@@ -511,74 +576,6 @@ document for details on how to construct this transaction.
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/naming/namespaces.html","headline":"Understand Namespaces","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/namespaces.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Understand Namespaces","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -427,6 +427,71 @@ between these name objects is presented below:
+
+
@@ -525,74 +590,6 @@ between these name objects is presented below:
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/naming/pickname.html","headline":"Choose a name","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/pickname.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Choose a name","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -292,10 +292,10 @@ following sections:
@@ -305,13 +305,14 @@ following sections:
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 app can subscribe to.
+.podcast point to podcasts that users of the DotPodcast 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
@@ -327,20 +328,19 @@ gives them a way to measure economic activity.
Developers can query individual namespaces and look up names within them using
the BNS API.
A recent consensus hash is required to create a NAMESPACE_PREORDER transaction. The reference
BNS clients do this automatically. See the transaction format
@@ -400,7 +397,7 @@ transaction.
-
Send a NAMESPACE_PREORDER transaction (live example).
+
Send a NAMESPACE_PREORDER transaction (live example).
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
@@ -408,7 +405,7 @@ a recent consensus hash in the transaction
(see the section on BNS forks for details).
-
Send a NAMESPACE_REVEAL transaction (live example).
+
Send a NAMESPACE_REVEAL transaction (live example).
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
@@ -420,13 +417,13 @@ has the option to collect name registration fees for the first year of the
namespace’s existence by setting a namespace creator address.
-
Seed the namespace with NAME_IMPORT transactions (live example).
+
Seed the namespace with NAME_IMPORT transactions (live example).
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.
-
Send a NAMESPACE_READY transaction (live example).
+
Send a NAMESPACE_READY transaction (live example).
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
@@ -450,7 +447,7 @@ create the same namespace, the one that successfully confirms both the
do this, then the namespace they created disappears (along with all the names
they imported).
-
Developers wanting to create their own namespaces should read the namespace creation section document. It is highly recommended that
+
Developers wanting to create their own namespaces should read the namespace creation section document. It is highly recommended that
developers request individual support before creating their own space, given the large amount of
cryptocurrency at stake.
@@ -458,6 +455,71 @@ cryptocurrency at stake.
+
+
@@ -556,74 +618,6 @@ cryptocurrency at stake.
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/naming/register.html","headline":"Register a name","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/register.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Register a name","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -367,13 +367,12 @@ ignored.
Note the use of jq -r to select the "name_price" field. This API
endpoint may return other ancilliary data regarding transaction fee estimation,
@@ -381,12 +380,11 @@ but this is the only field guaranteed by this specification to be present.
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/naming/resolving.html","headline":"Resolve a name","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/resolving.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Resolve a name","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -384,7 +384,7 @@ to do the following:
Look up a name’s public key and zone file (reference)
$ curl https://core.blockstack.org/v1/names?page=0
["judecn.id",
"3.id",
@@ -420,8 +419,7 @@ to the zonefile_hash field.
"df.id",
...
]
-
-
+
Each page returns 100 names. While no specific ordering is mandated by the
protocol, the reference implementation orders names by their order of creation
@@ -429,7 +427,7 @@ in the blockchain.
Look up the history of states a name was in (reference)
$ curl https://core.blockstack.org/v1/names/patrickstanley.id/history
{"445838": [{
@@ -532,8 +530,7 @@ in the blockchain.
}]}
-
-
+
All of the above information is extracted from the blockchain. Each top-level
field encodes the states the name transitioned to at the given block height (e.g.
@@ -557,7 +554,7 @@ under its previous owner, if the name expired and was reregistered.
Look up the list of names owned by a given public key hash (reference)
$ curl https://core.blockstack.org/v1/addresses/bitcoin/16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg
{"names": ["judecn.id",
@@ -569,8 +566,7 @@ under its previous owner, if the name expired and was reregistered.
"jude.statism.id"]}
-
-
+
Note that this API endpoint includes names and
subdomains.
@@ -579,6 +575,71 @@ under its previous owner, if the name expired and was reregistered.
+
+
@@ -677,74 +738,6 @@ under its previous owner, if the name expired and was reregistered.
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/naming/search.html","headline":"How to build a Profile Search Index","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/search.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"How to build a Profile Search Index","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -305,9 +305,8 @@ with data that follows structure of
Step 2: Make sure you have Blockstack Core running locally (see instructions). We highly
@@ -334,38 +332,34 @@ Blockstack Core 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.
@@ -490,6 +480,71 @@ bin/elasticsearch -d (on linux)
+
+
@@ -588,74 +643,6 @@ bin/elasticsearch -d (on linux)
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/naming/subdomains.html","headline":"BNS Subdomains","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/subdomains.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"BNS Subdomains","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -342,7 +342,7 @@ stored.
For example, the name verified.podcast once wrote the zone file hash 247121450ca0e9af45e85a82e61cd525cd7ba023,
which is the hash of the following zone file:
$ curl https://core.blockstack.org/v1/names/1yeardaily.verified.podcast
{"address": "1MwPD6dH4fE3gQ9mCov81L1DEQWT7E85qH",
"blockchain": "bitcoin",
@@ -370,8 +369,7 @@ For example, 1yeardaily.verified.podcast"zonefile_hash": "e7acc97fd42c48ed94fd4d41f674eddbee5557e3",
"zonefile_txt": "$ORIGIN 1yeardaily\n$TTL 3600\n_http._tcp URI 10 1 \"https://ph.dotpodcast.co/1yeardaily/head.json\"\n"}
-
-
+
This information was extracted from the 1yeardailyTXT resource record in the zone
file for verified.podcast.
@@ -386,7 +384,7 @@ updates; only the owner of 1yeardaily.verified.p
The lifecycle of a subdomain and its operations is shown in Figure 2.
-
subdomain subdomain subdomain
+
subdomain subdomain subdomain
creation update transfer
+----------------+ +----------------+ +----------------+
| cicero | | cicero | | cicero |
@@ -418,8 +416,7 @@ Thesubdomain-creation and subdomain-transfer transactions for
"cicero.res_publica.id" are broadcast by the owner of "res_publica.id".
However, any on-chain name ("jude.id" in this case) can broadcast a subdomain
update for "cicero.res_publica.id".
-
-
+
Subdomain operations are ordered by sequence number, starting at 0. Each new
subdomain operation must include:
@@ -447,7 +444,7 @@ Using the BNS API, a developer can:
Look up a subdomain’s public key and zone file (reference)
@@ -549,6 +543,71 @@ details on how to use it.
+
+
@@ -647,74 +706,6 @@ details on how to use it.
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/naming/tutorial_subdomains.html","headline":"Subdomain Design and Implementation","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/tutorial_subdomains.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Subdomain Design and Implementation","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -359,13 +359,12 @@ so we chop up the zonefile.
When the registrar wakes up to prepare a transaction, it packs the queued
registrations together and issues an UPDATE.
@@ -450,28 +445,24 @@ registrations together and issues an UPDATE
This is an API call:
-
GET /status/{subdomain}
-
-
+
GET /status/{subdomain}
+
The registrar checks if the subdomain has propagated (i.e., the
registration is completed), in which case the following is returned:
-
{"status":"Subdomain already propagated"}
-
-
+
{"status": "Subdomain already propagated"}
+
Or, if the subdomain has already been submitted in a transaction:
-
{"status":"Your subdomain was registered in transaction 09a40d6ea362608c68da6e1ebeb3210367abf7aa39ece5fd57fd63d269336399 -- it should propagate on the network once it has 6 confirmations."}
-
-
+
{"status": "Your subdomain was registered in transaction 09a40d6ea362608c68da6e1ebeb3210367abf7aa39ece5fd57fd63d269336399 -- it should propagate on the network once it has 6 confirmations."}
+
If the subdomain still hasn’t been submitted yet:
-
{"status":"Subdomain is queued for update and should be announced within the next few blocks."}
-
-
+
{"status": "Subdomain is queued for update and should be announced within the next few blocks."}
+
If an error occurred trying to submit the UPDATE transaction, this endpoint will return an error
message in the "error" key of a JSON object.
@@ -506,7 +497,7 @@ The endpoints which are subdomain aware are marked as such in
The lookups work just like normal – it returns the user’s
profile object:
Once you see Test finished; doing checks in that container’s logs, the
registrar has started and is ready to accept requests. (We recommend
@@ -574,37 +562,33 @@ correct environment variables for it to run).
Once this environment has started, you can issue a registration request from curl:
This registers baz.foo.id – you can check the registrar’s status with
-
curl http://localhost:3000/status/baz
-
-
+
curl http://localhost:3000/status/baz
+
The API endpoints /v1/users/<foo.bar.tld>,
/v1/names/<foo.bar.tld>, and /v1/addresses/bitcoin/<foo.bar.tld> all work, so if you query the core API, you’ll get a response.
+
+
@@ -723,74 +771,6 @@ correct environment variables for it to run).
-
-
-
-
-
+{"url":"https://docs.blockstack.org/core/wire-format.html","headline":"Bitcoin wire format","dateModified":"2018-10-26T14:02:20-07:00","datePublished":"2018-10-26T14:02:20-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/wire-format.html"},"author":{"@type":"Person","name":"Blockstack"},"description":"Bitcoin wire format","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -367,11 +367,10 @@ transaction of two transactions that must be sent to register a name in BNS.
0 2 3 19 39
|-----|--|-----------------------------------|-----------------------|
magic op hash128(name.ns_id,consensus hash) zone file hash
-
-
+
Note that hash128(name.ns_id, consensus hash) is the first 16 bytes of a SHA256 hash over the name concatenated to the hexadecimal string of the consensus hash (not the bytes corresponding to that hex string).
See the Method Glossary below.
@@ -195,13 +239,13 @@
-
+
Edit this page on Github
- w Oct 22, 2018
+ w Oct 26, 2018
@@ -292,10 +336,9 @@ Depending on your network connection, this can take between 15-30 minutes.
Before you begin, verify you have installed npm using the which command to
verify.
-
@@ -311,16 +354,14 @@ use libraries from the community in your project.
incapability between Cocoapods and XCode. Before starting the tutorial, confirm
you have installed CocoaPods.
-
$ pod --version
+
$ pod --version
1.6.0.beta.1
-
-
+
If you don’t have the CocoaPods beta version, install it:
-
sudo gem install cocoapods -v 1.6.0.beta.1
-
-
+
sudo gem install cocoapods -v 1.6.0.beta.1
+
Use npm to install Yeoman and the Blockstack App Generator
@@ -332,16 +373,14 @@ existing projects.
Install Yeoman.
-
npm install -g yo
-
-
+
npm install -g yo
+
Install the Blockstack application generator.
-
npm install -g generator-blockstack
-
-
+
npm install -g generator-blockstack
+
Build the Blockstack hello-world
@@ -358,27 +397,24 @@ modify the hello-world to interact with t
Create a hello-blockstack directory.
-
mkdir hello-blockstack
-
-
+
mkdir hello-blockstack
+
Change into your new directory.
-
cd hello-blockstack
-
-
+
cd hello-blockstack
+
Use Yeoman and the Blockstack application generator to create your initial hello-blockstack application.
-
yo blockstack:react
-
-
+
yo blockstack:react
+
You should see several interactive prompts.
-
$ yo blockstack:react
+
$ yo blockstack:react
==========================================================================
We are constantly looking for ways to make yo better!
May we anonymously report usage statistics to improve the tool over time?
@@ -387,8 +423,8 @@ modify the hello-world to interact with t
_-----_ ╭──────────────────────────╮
| | │ Welcome to the │
- |--(o)--| │ Blockstack app │
- `---------´ │ generator! │
+ |--(o)--| │ Blockstack app │
+ `---------´ │ generator! │
( _´U`_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
@@ -396,28 +432,26 @@ modify the hello-world to interact with t
´ ` |° ´ Y `
? Are you ready to build a Blockstack app in React? (Y/n)
-
-
+
Respond to the prompts to populate the initial app.
After the process completes successfully, you see a prompt similar to the following:
-
[fsevents] Success:
+
[fsevents] Success:
"/Users/theuser/repos/hello-blockstack/node_modules/fsevents/lib/binding/Release/node-v59-darwin-x64/fse.node"
is installed via remote npm notice created a lockfile as package-lock.json.
You should commit this file. added 1060 packages in 26.901s
-
-
+
Run the initial application.
-
npm start
+
npm start
- > hello-blockstack@0.0.0 start /Users/moxiegirl/repos/hello-blockstack
- > webpack-dev-server
+ > hello-blockstack@0.0.0 start /Users/moxiegirl/repos/hello-blockstack
+ > webpack-dev-server
Project is running at http://localhost:8080/
webpack output is served from /
@@ -434,8 +468,7 @@ modify the hello-world to interact with t
[2] (webpack)/buildin/global.js 509 bytes {0}[built]
[3] (webpack)/buildin/module.js 517 bytes {0}[built]
webpack: Compiled successfully.
-
-
+
At this point, the browser is running a Blockstack server on your local host.
@@ -480,9 +513,8 @@ application directory.
Create a public directory.
-
$ mkdir public
-
-
+
$ mkdir public
+
Use the touch command to add a redirect endpoint to your application.
@@ -490,14 +522,13 @@ application directory.
This endpoint on the web version of your app will redirect iOS users back
to your mobile app.
-
$ touch public/redirect.html
-
-
+
$ touch public/redirect.html
+
Open redirect.html and add code to the endpoint.
-
<!DOCTYPE html>
+
<!DOCTYPE html><html><head><title>Hello, Blockstack!</title>
@@ -513,8 +544,7 @@ to your mobile app.
<body></body></html>
-
-
+
Blockstack apps are identified by their domain names. The endpoint will
receive a get request with the query parameter authResponse=XXXX and
@@ -578,16 +608,14 @@ lines after.
Navigate to and change directory into the root of your project directory.
-
$cdhello-blockstack-ios
-
-
+
$cdhello-blockstack-ios
+
Create a Podfile.
-
$ pod init
-
-
+
$ pod init
+
The command creates a Podfile in the directory.
@@ -595,7 +623,7 @@ lines after.
Add a line stating the Blockstack dependency.
-
# Uncomment the next line to define a global platform for your project
+
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'hello-blockstack-ios' do
@@ -610,8 +638,7 @@ target 'hello-blockstack-ios' do
# Pods for testing
end
end
-
-
+
Save and close the Podfile.
@@ -624,7 +651,7 @@ end
Initialize the project with Cocoapods.
-
$ pod install
+
$ pod install
Analyzing dependencies
Downloading dependencies
Installing Blockstack (0.2.0)
@@ -637,20 +664,18 @@ end
Pod installation complete! There is 1 dependency from the Podfile and 2 total pods installed.
[!] Automatically assigning platform `ios` with version `11.4` on target `hello-blockstack-ios` because no platform was specified. Please specify a platform for this target in your Podfile. See `https://guides.cocoapods.org/syntax/podfile.html#platform`.
-
-
+
This command creates a number of files
Review the files that the pod installation created:
-
$ ls
-Podfile hello-blockstack-ios hello-blockstack-iosTests
+
$ ls
+Podfile hello-blockstack-ios hello-blockstack-iosTests
Podfile.lock hello-blockstack-ios.xcodeproj
Pods hello-blockstack-ios.xcworkspace
-
-
+
Start XCode and choose Open another project.
@@ -726,7 +751,7 @@ the user back to your iOS app. In this example, you use <scenes> element with the following:
-
<scenes>
+
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
@@ -760,18 +785,16 @@ the user back to your iOS app. In this example, you use
-
+
Immediately after scenes but before the close of the </document> tag add the following <resources>.
Just before the didReceiveMemoryWarning function a private updateUI() function.
This function takes care of loading the user data from Blockstack.
-
privatefuncupdateUI(){
+
privatefuncupdateUI(){DispatchQueue.main.async{ifBlockstack.shared.isSignedIn(){// Read user profile data
@@ -938,8 +957,7 @@ this application in your mobile add for now. In XCode, do the following;
}}}
-
-
+
The function uses the Blockstack.shared.isSignedIn() method to determine if
the user is already logged into Blockstack or not. It then uses the
@@ -949,13 +967,12 @@ the application display with the username.
Replace the content of the viewDidLoad() function so that it calls this private function.
-
overridefuncviewDidLoad(){
+
overridefuncviewDidLoad(){super.viewDidLoad()// Do any additional setup after loading the view, typically from a nib.self.updateUI()}
-
-
+
Create a ‘signIn()’ function that handles both sign in and out.
@@ -963,7 +980,7 @@ the application display with the username.
The function uses the Blockstack.shared.signIn() and
Blockstack.shared.signOut() methods to sign the user into the application.
-
@IBActionfuncsignIn(_sender:UIButton){
+
@IBActionfuncsignIn(_sender:UIButton){ifBlockstack.shared.isSignedIn(){print("Currently signed in so signing out.")Blockstack.shared.signOut()
@@ -986,8 +1003,7 @@ the application display with the username.
}}
-
-
+
@@ -1006,6 +1022,71 @@ the application display with the username.
+
+
@@ -1104,74 +1185,6 @@ the application display with the username.
-
-
-
-
-