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 +356,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 +382,8 @@ modify the hello-world to interact with t
_-----_ ╭──────────────────────────╮
| | │ Welcome to the │
- |--(o)--| │ Blockstack app │
- --------- │ generator! │
+ |--(o)--| │ Blockstack app │
+ --------- │ generator! │
( _U_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
@@ -397,28 +391,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 +427,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 +472,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
@@ -539,7 +528,7 @@ iniatial state by creating an emulator to run it in. Open Android Studio and do
Enter these fields in the Create Android Project page.
-
+
Application Name
hello-android
@@ -784,7 +773,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,29 +784,27 @@ 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.
overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)
@@ -842,7 +829,7 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
})
- signInButton.setOnClickListener{view:View->
+ signInButton.setOnClickListener{view:View->blockstackSession().redirectUserToSignIn{userData->if(userData.hasValue){runOnUiThread{
@@ -852,12 +839,11 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
}}if(intent?.action==Intent.ACTION_VIEW){
- // handle the redirect from sign in
-handleAuthResponse(intent)
+ // handle the redirect from sign in
+ handleAuthResponse(intent)}}
-
-
+
This new onCreate does several things:
@@ -877,14 +863,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 +877,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(':')
@@ -915,8 +899,8 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
blockstackSession().handlePendingSignIn(authResponse,{userData->if(userData.hasValue){
- // The user is now signed in!
-runOnUiThread{
+ // The user is now signed in!
+ runOnUiThread{onSignIn(userData.value!!)}}
@@ -924,13 +908,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,18 +921,17 @@ 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
- overridefunonCreate(savedInstanceState:Bundle?){
+ overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)
@@ -965,7 +947,7 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
})
- signInButton.setOnClickListener{view:View->
+ signInButton.setOnClickListener{view:View->blockstackSession().redirectUserToSignIn{userData->if(userData.hasValue){runOnUiThread{
@@ -979,14 +961,14 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
}}
- privatefunonSignIn(userData:UserData){
+ privatefunonSignIn(userData:UserData){userDataTextView.text="Signed in as ${userData.decentralizedID}"signInButton.isEnabled=false}
- overridefunonNewIntent(intent:Intent?){
+ overridefunonNewIntent(intent:Intent?){super.onNewIntent(intent)if(intent?.action==Intent.ACTION_VIEW){
@@ -994,7 +976,7 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
}}
- privatefunhandleAuthResponse(intent:Intent){
+ privatefunhandleAuthResponse(intent:Intent){valresponse=intent.dataStringif(response!=null){valauthResponseTokens=response.split(':')
@@ -1004,8 +986,8 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
blockstackSession().handlePendingSignIn(authResponse,{userData->if(userData.hasValue){
- // The user is now signed in!
-runOnUiThread{
+ // The user is now signed in!
+ runOnUiThread{onSignIn(userData.value!!)}}
@@ -1014,7 +996,7 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
}}
- funblockstackSession():BlockstackSession{
+ funblockstackSession():BlockstackSession{valsession=_blockstackSessionif(session!=null){returnsession
@@ -1025,8 +1007,7 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
}
-
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 +334,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 +395,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 +443,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 +492,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 +529,7 @@ or remove a grocery list; updating a list has no impact.
isLoading:false};}
-
-
+
Locate the render() method.
@@ -553,10 +538,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 +554,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 +575,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 +592,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 +604,18 @@ user profile data.
You’ll use the Blockstack loadUserData() method to access the username.
@@ -694,7 +675,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 +684,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 +708,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 +736,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 +771,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 +803,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 +917,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 +931,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 +943,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 +958,7 @@ process URL paths that contain the . (dot
.finally(()=>{this.setState({isLoading:false})})
-
-
+
This fetches the user statuses.
@@ -1001,10 +967,10 @@ process URL paths that contain the . (dot
@@ -209,7 +209,7 @@ For developers, Blockstack develops an ecosystem of software and services that d
Blockstack through its
-
How do Dapps differ from applications I typically use?
+
How do Dapps differ applications I typically use?
Dapps differ from Web applications in two ways:
@@ -235,7 +235,7 @@ private key. As long as no one gets access to your private key, no one can
control your data or ID. When you use Blockstack, by design, your private keys
are never sent to any remote servers.
-
Do Dapps work with a regular browser?
+
Do Dapps uwork with a regular browser?
Yes! Dapps run in the web browsers (Chrome, Safari, Internet Explorer, etc.) you know and love.
diff --git a/_site/browser/hello-blockstack.html b/_site/browser/hello-blockstack.html
index 7002a77f..18eabd4f 100644
--- a/_site/browser/hello-blockstack.html
+++ b/_site/browser/hello-blockstack.html
@@ -7,7 +7,7 @@
Hello, Blockstack Tutorial | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/browser/hello-blockstack.html","author":{"@type":"Person","name":"Blockstack"},"headline":"Hello, Blockstack Tutorial","dateModified":"2018-10-17T09:26:44-07:00","description":"Hello, Blockstack Tutorial","datePublished":"2018-10-17T09:26:44-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/browser/hello-blockstack.html"},"@type":"BlogPosting","@context":"http://schema.org"}
@@ -195,13 +195,13 @@
-
+
Edit this page on Github
- w Sep 27, 2018
+ w Oct 17, 2018
@@ -258,10 +258,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 +326,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 +341,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.
-
-
+
@@ -370,27 +362,27 @@ structure of this generic application structure:
-
.editorconfig
+
.editorconfig
Sets universal values for editor.
-
.gitignore
+
.gitignore
Git configuration file.
-
firebase.json
+
firebase.json
Configuragion for mobile application.
-
package.json
+
package.json
Specifies required packages.
-
requires.js
+
requires.js
A Javascript module loader.
-
server.js
+
server.js
Simple static server configuration.
@@ -407,31 +399,31 @@ structure of this generic application structure:
-
app.css
+
app.css
Contains application styles.
-
app.js
+
app.js
Main application file.
-
boostrap.min.css
+
boostrap.min.css
Minifield css for production.
-
icon-192x192.png
+
icon-192x192.png
Application icon
-
index.html
+
index.html
Single page.
-
manifest.json
+
manifest.json
Tells the browser about the application and how it should behave.
-
robots.txt
+
robots.txt
Configures crawling and indexing.
@@ -451,9 +443,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 +505,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 +550,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 +558,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 +571,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
+
diff --git a/_site/browser/ids-introduction.html b/_site/browser/ids-introduction.html
index d5464fd2..acc3917d 100644
--- a/_site/browser/ids-introduction.html
+++ b/_site/browser/ids-introduction.html
@@ -7,7 +7,7 @@
Get and use a Blockstack ID | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/browser/ids-introduction.html","author":{"@type":"Person","name":"Blockstack"},"headline":"Get and use a Blockstack ID","dateModified":"2018-10-17T09:26:44-07:00","description":"Get and use a Blockstack ID","datePublished":"2018-10-17T09:26:44-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/browser/ids-introduction.html"},"@type":"BlogPosting","@context":"http://schema.org"}
@@ -126,7 +126,7 @@
-
@@ -159,13 +159,13 @@
-
+
Edit this page on Github
- w Sep 27, 2018
+ w Oct 17, 2018
diff --git a/_site/browser/multi-player-storage.html b/_site/browser/multi-player-storage.html
index 6088798d..35bb324e 100644
--- a/_site/browser/multi-player-storage.html
+++ b/_site/browser/multi-player-storage.html
@@ -7,7 +7,7 @@
Manage Data with Gaia | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/browser/multi-player-storage.html","author":{"@type":"Person","name":"Blockstack"},"headline":"Manage Data with Gaia","dateModified":"2018-10-17T09:26:44-07:00","description":"Manage Data with Gaia","datePublished":"2018-10-17T09:26:44-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/browser/multi-player-storage.html"},"@type":"BlogPosting","@context":"http://schema.org"}
@@ -195,13 +195,13 @@
-
+
Edit this page on Github
- w Sep 27, 2018
+ w Oct 17, 2018
@@ -259,10 +259,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 +334,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 +395,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 +443,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 +492,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 +529,7 @@ or remove a grocery list; updating a list has no impact.
isLoading:false};}
-
-
+
Locate the render() method.
@@ -553,10 +538,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 +554,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 +575,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 +592,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 +604,18 @@ user profile data.
You’ll use the Blockstack loadUserData() method to access the username.
@@ -694,7 +675,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 +684,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 +708,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 +736,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 +771,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 +803,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 +917,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 +931,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 +943,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 +958,7 @@ process URL paths that contain the . (dot
.finally(()=>{this.setState({isLoading:false})})
-
-
+
This fetches the user statuses.
@@ -1001,10 +967,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 +983,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 +1006,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 +1032,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 +1045,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.
diff --git a/_site/browser/todo-list.html b/_site/browser/todo-list.html
index c4d5de91..ac811398 100644
--- a/_site/browser/todo-list.html
+++ b/_site/browser/todo-list.html
@@ -7,7 +7,7 @@
Todo List Application Tutorial | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/browser/todo-list.html","author":{"@type":"Person","name":"Blockstack"},"headline":"Todo List Application Tutorial","dateModified":"2018-10-17T09:26:44-07:00","description":"Todo List Application Tutorial","datePublished":"2018-10-17T09:26:44-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/browser/todo-list.html"},"@type":"BlogPosting","@context":"http://schema.org"}
@@ -195,13 +195,13 @@
-
+
Edit this page on Github
- w Sep 27, 2018
+ w Oct 17, 2018
@@ -215,66 +215,74 @@ authentiation using a Blockstack ID and how it stores information associated
with that ID using Blockstack Storage (Gaia).
browserify to compile node code into browser-ready code
+
blockstack.js to authenticate the user and work with the user’s identity/profile information
+
-
The applicaton code relies on both the npm and the yarn package managers.
-Before you begin, verify you have these tools npm using the which command to
-verify.
+
At minimum, Blockstack requires macOS High Sierra. This tutorial was written for a user running macOS High Sierra 10.13.4. The application you build is a React.js application that is completely decentralized and server-less. While not strictly required to follow along, basic familiarity with React.js is helpful.
-
$ which npm
-/usr/local/bin/npm
-$ which yarn
-/usr/local/bin/yarn
-
-
+
When complete, the app is capable of the following:
While it stands alone, this tour relies on the information from the Hello
-Blockstack tutorial. If you haven’t worked through the hello-world
-tutorial, you may want to do that before continuing.
$ yarn install
yarn install v1.9.2
info No lockfile found.
...
@@ -282,14 +290,11 @@ These instructions assume you are cloning.
[5/5] 📃 Building fresh packages...
success Saved lockfile.
✨ Done in 19.90s.
-
-
+
-
The Todo application has a basic Vue.js structure. There are several
-configuration files but the crucial implementation files are in the src
-directory:
+
The Todo application has a basic Vue.js structure. There are several configuration files but the central programming files are in the src directory:
@@ -320,23 +325,21 @@ directory:
Sign into the application
-
The example application runs in a core node on your local host. In the next
-section, you start the application and interact with it.
+
The example application runs in a node server on your local host. In the this section, you start the application and interact with it.
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.
+
Start the application.
-
$ npm run start
-
-
+
$ npm run start
+
You should see a simple application:
@@ -357,17 +360,17 @@ section, you start the application and interact with it.
Understand the sign in process
-
Clicking the Sign In With Blockstack button brings up a modal that prompts
-you to sign in with an existing ID or create a new ID. When Blockstack is
-provided an ID, it generates an ephemeral key within the application. An
-ephemeral key is generated for each execution of a key establishment process.
-This key is just used for the particular instance of the application, in this
-case to sign a Sign In request.
-
-
A Blockstack Core node also generates a public key token which is sent to the browser
-as an authRequest from the browser to your core node.
-The signed authentication request is sent to Blockstack through a JSON Web
-Token (JWT). Blocktack passes the token in via a URL query string in the authRequest
+
Clicking the Sign In With Blockstack button brings up a modal that prompts you
+to sign in with an existing ID or create a new ID. When Blockstack is provided
+an ID, it generates an ephemeral key within the application. An ephemeral key is
+generated for each execution of a key establishment process. This key is just
+used for the particular instance of the application, in this case to sign a Sign
+In request.
+
+
A Blockstack Core node also generates a public key token which is sent to the
+browser as an authRequest from the browser to your core node. The signed
+authentication request is sent to Blockstack through a JSON Web Token (JWT).
+Blocktack passes the token in via a URL query string in the authRequest
parameter:
The iss property is a decentralized identifier or did. This identifies you and your name to the application. The specific did is a btc-addr.
+
The Blockstack JWT implementation is different from other implementations because of the underlying cryptography we employ. There are libraries in Javascript and Ruby available on the Blockstack Github to allow you to work with these tokens.
+
+
-
-
Notes:
-
-
The iss property is a decentralized identifier or did. This identifies you and your name to the application. The specific did is a btc-addr.
-
The Blockstack JWT implementation is different from other implementations because of the underlying cryptography. There are libraries in Javascript and Ruby available on the Blockstack Github to allow you to work with these tokens.
-
-
-
-
When the Blockstack node receives the authRequest, it generates a
-session token and returns an authentication response to the application. This
-response is similar to the authRequest above in that the authResponse
-includes a private key intended only for the application. This allows the
-application to encrypt data on your personal Blockstack storage.
+
When the Blockstack node receives the authRequest, it generates a session token
+and returns an authentication response to the application. This response is
+similar to the authRequest above in that the authResponse includes a private key
+intended only for the application. This allows the application to encrypt data
+on your personal Blockstack storage.
-
After the completion of this process, the user is loggged in.
+
After the completion of this process, the user is logged in.
-
Under the covers in the sign in code
+
Undder the covers in the sign in code
-
Go to the underlying blockstack-todo code you cloned or downloaded. Sign
+
Now, go to the underlying blockstack-todo code you cloned or downloaded. Sign
in and sign out is handled in each of these files:
@@ -449,18 +451,17 @@ 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 browser:
+
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()
@@ -468,26 +469,22 @@ 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 the 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.
+
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.
-
Sign out is handled in the src/components/Dashboard.vue code.
+
Signout is handled in src/components/Dashboard.vue.
The method allows the application creator to decide where to redirect the user
-after sign out.
+
The method allows the application creator to decide where to redirect the user upon Sign Out:
Working with the application
-
Now, try adding a few items to the todo list. For example, try listing the
-applications you want to see built on top of Blockstack:
+
Now, trying adding a few itmes to the todo list. For example, try making a list of applications you want to see built on top of Blockstack:
@@ -502,44 +499,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 it will reflect the change look for "completed":true:
+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.
@@ -548,30 +543,27 @@ using the Javascript console it will reflect the change look for blockstack-todo code you cloned or downloaded. The
application interactions with your Gaia Hub originate in the
src/components/Dashboard.vue file. First, examine where the changes to the
-list entries are processed:
+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()
-method to store it in our Gaia Hub.
+method to store it in a Gaia Hub.
-
The code reads the items from storage with the
-blockstack.getFile()
-method which returns a promise:
+
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||'[]')
@@ -582,14 +574,13 @@ method which returns a promise:
this.todos=todos})},
-
-
+
The todos data is retrieved from the promise.
Summary
-
You now have everything you need to construct complex applications complete with authentication and storage on the Decentralized Internet. Why not try coding a sample application that accesses multiple profiles.
+
You now have everything you need to construct complex applications complete with authentication and storage on the Decentralized Internet. Why not try coding a sample application that accesses multiple profiles.
@@ -269,13 +274,13 @@
-
+
Edit this page on Github
- w Sep 27, 2018
+ w Oct 17, 2018
@@ -424,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
+-------------------+
@@ -452,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
diff --git a/_site/core/atlas/howtouse.html b/_site/core/atlas/howtouse.html
index 4f441bec..494873b3 100644
--- a/_site/core/atlas/howtouse.html
+++ b/_site/core/atlas/howtouse.html
@@ -7,7 +7,7 @@
How to Use the Atlas Network | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/atlas/howtouse.html","author":{"@type":"Person","name":"Blockstack"},"headline":"How to Use the Atlas Network","dateModified":"2018-10-17T09:26:44-07:00","description":"How to Use the Atlas Network","datePublished":"2018-10-17T09:26:44-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/atlas/howtouse.html"},"@type":"BlogPosting","@context":"http://schema.org"}
@@ -239,6 +239,11 @@
@@ -269,13 +274,13 @@
-
+
Edit this page on Github
- w Sep 27, 2018
+ w Oct 17, 2018
@@ -316,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
@@ -324,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).
@@ -351,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)
+>>>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.
@@ -387,23 +390,22 @@ 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)
+>>>data="..."# this is the chunk you will replicate widely
+>>>data_b64=base64.b64encode(data)>>>>>>result=blockstack.lib.client.get_atlas_peers('https://node.blockstack.org:6263')>>>neighbors=result['peers']>>>print", ".join(neighbors)
-13.65.207.163:6264,52.225.128.191:6264,node.blockstack.org:6264,23.102.162.7:6264,52.167.230.235:6264,23.102.162.124:6264,52.151.59.26:6264,13.92.134.106:6264
+13.65.207.163:6264,52.225.128.191:6264,node.blockstack.org:6264,23.102.162.7:6264,52.167.230.235:6264,23.102.162.124:6264,52.151.59.26:6264,13.92.134.106:6264>>>>>>forneighborinneighbors:...result=blockstack.lib.client.put_zonefiles(neighbor,[data_b64])...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
diff --git a/_site/core/atlas/overview.html b/_site/core/atlas/overview.html
index c8de1db4..1b1630dd 100644
--- a/_site/core/atlas/overview.html
+++ b/_site/core/atlas/overview.html
@@ -7,7 +7,7 @@
Overview of the Atlas network | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/atlas/overview.html","author":{"@type":"Person","name":"Blockstack"},"headline":"Overview of the Atlas network","dateModified":"2018-10-17T09:26:44-07:00","description":"Overview of the Atlas network","datePublished":"2018-10-17T09:26:44-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/atlas/overview.html"},"@type":"BlogPosting","@context":"http://schema.org"}
@@ -239,6 +239,11 @@
@@ -269,13 +274,13 @@
-
+
Edit this page on Github
- w Sep 27, 2018
+ w Oct 17, 2018
@@ -323,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 | | | | |
+--------------+ +---------------+ +----------------+
@@ -358,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
diff --git a/_site/core/faq_developer.html b/_site/core/faq_developer.html
index 6ae557ca..c6136f6f 100644
--- a/_site/core/faq_developer.html
+++ b/_site/core/faq_developer.html
@@ -7,7 +7,7 @@
Developer FAQs | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/faq_developer.html","author":{"@type":"Person","name":"Blockstack"},"headline":"Developer FAQs","dateModified":"2018-10-17T09:26:44-07:00","description":"Developer FAQs","datePublished":"2018-10-17T09:26:44-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/faq_developer.html"},"@type":"BlogPosting","@context":"http://schema.org"}
@@ -195,13 +195,13 @@
-
+
Edit this page on Github
- w Sep 27, 2018
+ w Oct 17, 2018
@@ -296,17 +296,15 @@ profile. For example, here’s how you would get public data from the
+-------------------------------------------------------+
RESTful | +----------------+ +--------------------+ |
+--------+ API | | | private API | | |
| client |<------------>| BNS API module |<----------->| BNS indexer module | |
@@ -334,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
diff --git a/_site/core/naming/comparison.html b/_site/core/naming/comparison.html
index 8574976d..122a4dfb 100644
--- a/_site/core/naming/comparison.html
+++ b/_site/core/naming/comparison.html
@@ -7,7 +7,7 @@
Naming system feature comparison | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/naming/comparison.html","author":{"@type":"Person","name":"Blockstack"},"headline":"Naming system feature comparison","dateModified":"2018-10-17T09:26:44-07:00","description":"Naming system feature comparison","datePublished":"2018-10-17T09:26:44-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/comparison.html"},"@type":"BlogPosting","@context":"http://schema.org"}
@@ -239,6 +239,11 @@
@@ -269,13 +274,13 @@
-
+
Edit this page on Github
- w Sep 27, 2018
+ w Oct 17, 2018
@@ -288,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
@@ -345,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.
@@ -372,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
@@ -380,8 +384,7 @@ 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'}
-
A recent consensus hash is required to create a NAMESPACE_PREORDER transaction. The reference
BNS clients do this automatically. See the transaction format
diff --git a/_site/core/naming/register.html b/_site/core/naming/register.html
index 12d5323c..cb475748 100644
--- a/_site/core/naming/register.html
+++ b/_site/core/naming/register.html
@@ -7,7 +7,7 @@
Register a name | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/naming/register.html","author":{"@type":"Person","name":"Blockstack"},"headline":"Register a name","dateModified":"2018-10-17T09:26:44-07:00","description":"Register a name","datePublished":"2018-10-17T09:26:44-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/register.html"},"@type":"BlogPosting","@context":"http://schema.org"}
@@ -239,6 +239,11 @@
Note the use of jq -r to select the "name_price" field. This API
endpoint may return other ancilliary data regarding transaction fee estimation,
@@ -376,12 +380,11 @@ but this is the only field guaranteed by this specification to be present.
$ curl https://core.blockstack.org/v1/names?page=0
["judecn.id",
"3.id",
@@ -415,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
@@ -424,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": [{
@@ -527,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.
@@ -552,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",
@@ -564,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.
diff --git a/_site/core/naming/search.html b/_site/core/naming/search.html
index 1f256e25..be66b3d2 100644
--- a/_site/core/naming/search.html
+++ b/_site/core/naming/search.html
@@ -7,7 +7,7 @@
How to build a Profile Search Index | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/naming/search.html","author":{"@type":"Person","name":"Blockstack"},"headline":"How to build a Profile Search Index","dateModified":"2018-10-17T09:26:44-07:00","description":"How to build a Profile Search Index","datePublished":"2018-10-17T09:26:44-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/search.html"},"@type":"BlogPosting","@context":"http://schema.org"}
@@ -239,6 +239,11 @@
Step 2: Make sure you have Blockstack Core running locally (see instructions). We highly
@@ -329,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.
@@ -269,13 +274,13 @@
-
+
Edit this page on Github
- w Sep 27, 2018
+ w Oct 17, 2018
@@ -337,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",
@@ -365,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.
@@ -381,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 |
@@ -413,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:
@@ -442,7 +444,7 @@ Using the BNS API, a developer can:
Look up a subdomain’s public key and zone file (reference)
When the registrar wakes up to prepare a transaction, it packs the queued
registrations together and issues an UPDATE.
@@ -445,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.
@@ -501,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
@@ -569,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.
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.
Some hashing primitives are used to construct the wire-format representation of each name operation. They are enumerated here:
-
B40_REGEX = '^[a-z0-9\-_.+]*$'
+
B40_REGEX = '^[a-z0-9\-_.+]*$'
def is_b40(s):
return isinstance(s, str) and re.match(B40_REGEX, s) is not None
@@ -875,8 +869,7 @@ def hash128(data):
first 16 bytes
"""
return hexlify(bin_sha256(data)[0:16])
-
-
+
diff --git a/_site/feed.xml b/_site/feed.xml
index c400958a..5e3cab86 100644
--- a/_site/feed.xml
+++ b/_site/feed.xml
@@ -1,4 +1,4 @@
-Jekyll2018-09-27T16:58:29-07:00https://docs.blockstack.org/BlockstackDocsBlockstackSite tags2017-05-25T00:00:00-07:002017-05-25T00:00:00-07:00https://docs.blockstack.org/2017/05/25/post63<p>https://docs.blockstack.org/assets/posts/</p>
+Jekyll2018-10-17T09:26:44-07:00https://docs.blockstack.org/BlockstackDocsBlockstackSite tags2017-05-25T00:00:00-07:002017-05-25T00:00:00-07:00https://docs.blockstack.org/2017/05/25/post63<p>https://docs.blockstack.org/assets/posts/</p>
<p>/2017/05/25/post63.html</p>
@@ -26,7 +26,7 @@
<h2 id="example-of-code-block">Example Of Code Block</h2>
<p>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;</p>
-<div class="language-html highlighter-rouge"><pre class="highlight"><code><span class="nt"><head></span>
+<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><head></span>
<span class="nt"><meta</span> <span class="na">charset=</span><span class="s">"utf-8"</span><span class="nt">></span>
<span class="nt"><meta</span> <span class="na">http-equiv=</span><span class="s">"X-UA-Compatible"</span> <span class="na">content=</span><span class="s">"IE=edge"</span><span class="nt">></span>
<span class="nt"><meta</span> <span class="na">name=</span><span class="s">"viewport"</span> <span class="na">content=</span><span class="s">"width=device-width, initial-scale=1"</span><span class="nt">></span>
@@ -34,8 +34,7 @@
<span class="nt"><link</span> <span class="na">rel=</span><span class="s">"shortcut icon"</span> <span class="na">type=</span><span class="s">"image/png"</span> <span class="na">href=</span><span class="s">"/assets/img/favicon.png"</span> <span class="nt">></span>
<span class="nt"><script </span><span class="na">src=</span><span class="s">"/assets/js/main.js"</span><span class="nt">></script></span>
<span class="nt"></head></span>
-</code></pre>
-</div>
+</code></pre></div></div>
<h2 id="text-and-quote">Text and Quote</h2>
<p>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.</p>
diff --git a/_site/index.html b/_site/index.html
index 32bc4d00..677e7348 100644
--- a/_site/index.html
+++ b/_site/index.html
@@ -7,7 +7,7 @@
Blockstack | Docs
-
+
@@ -17,7 +17,7 @@
+{"url":"https://docs.blockstack.org/","author":{"@type":"Person","name":"Blockstack"},"headline":"Blockstack","description":"Docs","name":"Blockstack","@type":"WebSite","@context":"http://schema.org"}
diff --git a/_site/ios/tutorial.html b/_site/ios/tutorial.html
index 82110730..859b5742 100644
--- a/_site/ios/tutorial.html
+++ b/_site/ios/tutorial.html
@@ -7,7 +7,7 @@
iOS SDK Tutorial (Pre-release) | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/ios/tutorial.html","author":{"@type":"Person","name":"Blockstack"},"headline":"iOS SDK Tutorial (Pre-release)","dateModified":"2018-10-17T09:26:44-07:00","description":"iOS SDK Tutorial (Pre-release)","datePublished":"2018-10-17T09:26:44-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/ios/tutorial.html"},"@type":"BlogPosting","@context":"http://schema.org"}
@@ -195,13 +195,13 @@
-
+
Edit this page on Github
- w Sep 27, 2018
+ w Oct 17, 2018
@@ -269,7 +269,7 @@ application by doing the following:
Set up your environment
-
This sample application requires two code bases, a Blockstack hello-blockstack web
+
This sample application requires two code bases, a BlockStack hello-blockstack web
application and a hello-ios iOS application. You use the iOS application to run the
web application on an iOS device.
@@ -292,10 +292,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 +310,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 +329,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 +353,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 +379,8 @@ modify the hello-world to interact with t
_-----_ ╭──────────────────────────╮
| | │ Welcome to the │
- |--(o)--| │ Blockstack app │
- `---------´ │ generator! │
+ |--(o)--| │ Blockstack app │
+ `---------´ │ generator! │
( _´U`_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
@@ -396,28 +388,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 +424,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 +469,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 +478,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 +500,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 +564,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 +579,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 +594,7 @@ target 'hello-blockstack-ios' do
# Pods for testing
end
end
-
-
+
Save and close the Podfile.
@@ -624,7 +607,7 @@ end
Initialize the project with Cocoapods.
-
$ pod install
+
$ pod install
Analyzing dependencies
Downloading dependencies
Installing Blockstack (0.2.0)
@@ -637,20 +620,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 +707,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 +741,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 +913,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 +923,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 +936,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 +959,7 @@ the application display with the username.
}}
-