Uploading a signed profile.json to the Blockstack Gaia hub

Hey @jude, is there a CLI or other way to upload a signed profile.json to the Gaia hub offered by Blockstack at a location like this: https://gaia.blockstack.org/hub/377L4AYUDHHnLuyNRWcvrwvhKmH5JMLNhS/profile.json ?

I read in an older article something about the set_profile CLI command, but it’s not supported by the CLI (anymore or never was, I don’t know).

Hey @jefvanbockryck,

Does your ~/.blockstack/client.ini file have a [gaia_hub] config section? Also, do you have storage_drivers = gaia_hub and storage_drivers_required_write = gaia_hub set in your [blockstack-client] section?

If you need to make a [gaia_hub] section, you can do so as follows:

  1. You will need to generate an API token for your Gaia bucket. I have a script below that does this:
$ cat ./connectGaia.js
 #!/usr/bin/node

const blockstack = require('blockstack');
const args = process.argv.slice(2)

if (args.length !== 2) {
   console.error(`Usage: ${process.argv[0]} hub_url private_key`);
   process.exit(1);
}

const hubUrl = args[0];
let privKey = args[1];

if (privKey.length == 66 && privKey.slice(64) === '01') {
   privKey = privKey.slice(0, 64);
}

blockstack.connectToGaiaHub(hubUrl, privKey).then((res) => {
   console.log('[gaia_hub]');
   console.log(`url_prefix = ${res.url_prefix}`);
   console.log(`token = ${res.token}`);
   console.log(`server = ${res.server}`);
   console.log(`address = ${res.address}`);
   return;
});
  1. You will need to get your identity private key. In the CLI, you can get this with blockstack wallet. This will be your owner_privkey

  2. Once you have your identity private key, you can generate an API token to connect to Gaia as follows

$ ./connectGaia.js "https://hub.blockstack.org" "3dea536750c97f06399e54fc8c0a5e07042f3989dc242ec0fb03d8f7de89c67501"
[gaia_hub]                                                                                                                                                                                                                                                                                                                    
url_prefix = https://gaia.blockstack.org/hub/
token = eyJwdWJsaWNrZXkiOiIwMjc5YmU2NjdlZjlkY2JiYWM1NWEwNjI5NWNlODcwYjA3MDI5YmZjZGIyZGNlMjhkOTU5ZjI4MTViMTZmODE3OTgiLCJzaWduYXR1cmUiOiIzMDQ1MDIyMTAwYjU1MzIyMDk3NDhlNGExZmU3NTYyOWNlNzJmMTYwN2IxYTM0YmJmODMwMWZhYjdjZDBjZGI1MGExNWUzYTg5NDAyMjAwNDczYjJkMDkxMjk3OTQ3Y2Q3MzE0NzM4ZTA3ODNhMmU5NzAzY2FmNjA1NGI2ZmM4ZWM4YTA3YWFmZjlmMmE2In0=
server = https://hub.blockstack.org
address = 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH

Once you put this into your ~/.blockstack/client.ini file, you should be able to call put_profile.

Hi @jude, tnx again for this great help.

One more question to get me started on this and I’m sorry if this might sound a bit stupid, but where do I have to place this script to execute it? It has dependencies so I guess this matters.

Where do I have to place this script to execute it?

You can start a new directory and then (if you have npm installed), just run npm install blockstack in that directory, and you should be able to run it from there:

$ mkdir connectGaiaScript
$ cd connectGaiaScript
$ npm install blockstack
$ ./connectGaia.js "https://hub.blockstack.org" "3dea536750c97f06399e54fc8c0a5e07042f3989dc242ec0fb03d8f7de89c67501"

Super tnx @aaron. I can manage that :);

Hi @jude ,
This works and I have added the [gaia_hub] section to my ~/.blockstack/client.ini .

I’m now signing a profile JSON using the sign_profile CLI command. When I test this with the verify_profile command I get the following error:

“error”: “No data public key in zone file, and owner is a p2sh address”

Besides that, I’m getting these deprication warnings (Python) when I’m running both commands:

Should I update something on Python level?

Are both issues related?

I’m now signing a profile JSON using the sign_profile CLI command. When I test this with the verify_profile command I get the following error:

Can you tell me which name you’re using, so I can try to reproduce it? More specifically, can you tell me what your name’s ID-address is? If your name is owned by a p2sh address (i.e. one that starts with 3), you’ll first need to transfer it to a p2pkh address (i.e. one that starts with 1) in order for the rest of the ecosystem to recognize your profile. This is due to the fact that at one point in the past the CLI would sign and verify profiles using a different key than the owner_privkey (i.e. it would use the data_privkey in your wallet). This behavior is not supported by the Browser or the explorer, and will not be present in the new CLI I’m writing.

The ID-address that I’m using in the CLI is indeed one that starts with a 3.
It lives in my CLI wallet.

I can transfer it to a an address that starts with a 1, a browser ID-address that I own. I can work on that either from the browser or using your new CLI (soon), right?

Using that new CLI, I can then transfer the ID-address to another user’s browser, right? That last bit is crucial to me.

I can transfer it to a an address that starts with a 1, a browser ID-address that I own. I can work on that either from the browser or using your new CLI (soon), right?

Yup! You can also do it with the old CLI by generating a new owner private key, transferring your name to it, and then generating a new wallet with that owner private key:

For example:

$ # make a new owner private key 
$ python -c 'import virtualchain; print virtualchain.lib.ecdsalib.ecdsa_private_key().to_hex()'                                                                                                                                                                                 
83f5b256c7781f686fe26d0b76e71525f6e9c0cd1ad95eb445da15ac87add189
$ # get its address
$ python -c 'import virtualchain, sys; print virtualchain.lib.ecdsalib.ecdsa_private_key(sys.argv[1]).public_key().address()' 83f5b256c7781f686fe26d0b76e71525f6e9c0cd1ad95eb445da15ac87add189                                                                                  
15dscDGQiUaSjofERYpdXjLqDyx4tpo599
$ # transfer your name to it 
$ blockstack transfer YOUR_NAME.id 15dscDGQiUaSjofERYpdXjLqDyx4tpo599
$ # get your payment private key 
$ blockstack wallet
$ # set your new wallet
$ blockstack import_wallet YOUR_PAYMENT_KEY 83f5b256c7781f686fe26d0b76e71525f6e9c0cd1ad95eb445da15ac87add189

(I recommend trying this in the test framework first).

Using that new CLI, I can then transfer the ID-address to another user’s browser, right? That last bit is crucial to me.

Just to clarify–you want to transfer the name, or the ID-address?

Just to clarify–you want to transfer the name, or the ID-address?

I was wrong, I meant transfer of the name (.id) not the ID-address.

Many thnx for the Python snippet, with that I can make a new wallet with an ID-address starting with 1 using the current CLI, that’s nice.

I found this docker test framework that works well (hopefully this is the correct one):

But I’m having troubles with the last step:
$ blockstack import_wallet YOUR_PAYMENT_KEY 83f5b256c7781f686fe26d0b76e71525f6e9c0cd1ad95eb445da15ac87add189

In this step, the interactive prompt asks for 3 keys: payment_privkey, owner_privkey and data_privkey.
The owner private key was generated in the first step, but what about the other two, @jude ?
I can’t just copy those from my existing wallet, because then I get the "error": "Wallet already exists!". So I guess that I have to generate those as well, no? How can I do that?

I found this docker test framework that works well (hopefully this is the correct one):

That’s the correct test framework.

In this step, the interactive prompt asks for 3 keys: payment_privkey, owner_privkey and data_privkey.

You’ll probably want to re-use your payment key from your current wallet. You can get it with blockstack wallet. Same goes for your data private key, although it won’t be used in practice.

Also, related to profile signing, you’ll want to ensure that you’re using the owner private key when signing a profile. You’ll have to do this explicitly on the CLI:

$ blockstack sign_profile YOUR_NAME /path/to/your/profile.json YOUR_OWNER_PRIVKEY

(YOUR_OWNER_PRIVKEY can be found with blockstack wallet).

You’ll want to back up your ~/.blockstack/wallet.json file before running import_wallet. Once it’s moved out of the way, import_wallet will work. Sorry I forgot to mention that!

Hi @jude. Yes by backing up the (old) wallet I could run theimport_wallet.

But I expected two things:

  • First: That the name I transferred to an address starting with 1 would show up
  • Second: That the owner_privkey would be the one I provided during the interactive dialog

Both are not true. The import wallet did nicely show the payment_privkey and data_privkey that I provided, but it created a different owner_privkey and (hence???) it also created another owner address, one starting with an m instead of an 1.

I feel I’m close, but still no cigar :). Maybe it helps if I send you a nice box of Belgian chocolates after all the help you already provided.

Second: That the owner_privkey would be the one I provided during the interactive dialog

Can you give me an example with a throw-away key, like db71cfb31d988d34bc09822924059c600ae97cf928e073b9b535b5045395212901?

Both are not true. The import wallet did nicely show the payment_privkey and data_privkey that I provided, but it created a different owner_privkey and (hence???) it also created another owner address, one starting with an m instead of an 1.

Ah, you’re doing this in the test framework. If it starts with m, then you’re fine. Bitcoin uses a different address encoding for testnet/regtest than for mainnet—the leading 1 becomes either m or n, and the leading 3 becomes 2. For example, 1LV8KGrc3vVHHCJx3oYVRMcYVxhXHa2zXe and n115cKwarwvY4JnZmNWsFGpsMxJEE4Vfe6 are the base58check-encoded hashes (i.e. addresses) of the same public key, but the former is the one you’d use in testnet/regtest and the latter is the one you use on mainnet.

You can dissect an address with keylib, for example:

$ python
Python 2.7.14 (default, Dec 14 2017, 15:51:29)
[GCC 6.4.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import keylib
>>> keylib.b58check_decode('1LV8KGrc3vVHHCJx3oYVRMcYVxhXHa2zXe').encode('hex')
'd5bc24a3d3ef41dee92608cf7cfcabb5a98ddf87'
>>> keylib.b58check_decode('n115cKwarwvY4JnZmNWsFGpsMxJEE4Vfe6').encode('hex')
'd5bc24a3d3ef41dee92608cf7cfcabb5a98ddf87'

Can you give me an example with a throw-away key, like

Yes, @jude I can and since I’m using the test framework I can share you all the keys I have used so you can replay my scenario (right?). I followed all the steps you described and these result in the following keys:

  • New owner_privkey: c484227e8d66d6f30dfd206e9ebe54dcc9302e1a06b106eeca677ba34a2036ae

  • New owner address from this owner_privkey: 1NXG7eDNSuQFACHmBVvWozQowcYTgGjM4t

  • This is the payment_privkey I reused: f4c3907cb5769c28ff603c145db7fc39d7d26f69f726f8a7f995a40d3897bb5201

  • This is the data_privkey I reused: bb68eda988e768132bc6c7ca73a87fb9b0918e9a38d3618b74099be25f7cab7d01

  • After import_wallet command this is the owner address that it generated: myaPViveUWiiZQQTb51KXCDde4iLC3Rf3K

  • Now using the Python keylib function your provided, I compared the two owner addresses and … they result in two different hashes: c6188c847771ed0bcb804d5a7dde0d1c4f232368 and ec13bcbdca6808f6eec53d7d6396d30001912593.

What to think about that?
(Again, many tnx for leading me so far and sorry for taking your precious time)

Hi @jefvanbockryck,

I tried duplicating it with the keys you gave. Here are the steps I took:

(blockstack-master) jude@cf54:~$ mkdir /tmp/wallet-test
(blockstack-master) jude@cf54:~$ cp ~/blockstack-live-test/client.ini /tmp/wallet-test/
(blockstack-master) jude@cf54:~$ blockstack -c /tmp/wallet-test/client.ini import_wallet f4c3907cb5769c28ff603c145db7fc39d7d26f69f726f8a7f995a40d3897bb5201 c484227e8d66d6f30dfd206e9ebe54dcc9302e1a06b106eeca677ba34a2036ae bb68eda988e768132bc6c7ca73a87fb9b0918e9a38d3618b74099be25f7cab7d01
Enter new password:
Confirm new password:
{
    "status": true
}
(blockstack-master) jude@cf54:~$ ls /tmp/wallet-test/
client.ini  client.uuid  wallet.json
(blockstack-master) jude@cf54:~$ cat /tmp/wallet-test/wallet.json
{"enc": "c2NyeXB0ABQAAAAIAAAAAdz9n0cuV8wlBJuUUMM8LhXXpSBrWVaBtXeWccT4nOjLatc2VGF6axqSqXxfXg6cO2BmoO5/2qFuieqzGOidseJUcLVba73G9bpFt/+6Fi7hmpTieJvDbgedjXgJLk+G+I5/yxPNQVAkwiaKt0SfwJeO0rYAemRcseSNA5wCyhbwkV0R/8D7NSkRDQkImynOAXpCmxKBzM/MKXixLTEbrh7m1IyRq3WymncC8MVmQnexkFDrKRQwOUlgzcLi+Uo77ZlpGa5bfw9ggruPVy6YkMNx0fb/9hJkjOFpA489egTPYHUzA6LffIj6raOmW+YAX4P8bpkERO48pbBQBcSSDAdUt8Giw5Rp1NOopLZMepK4ZmMFDeIR0FeRyHXbm9PX3Gi+iszl2bbOyw9AwpxZopTI4zvYF8XcW4dQbVY5+V/UteLYo6RZNXYpv8iT/p1uxci+mp8FjkA1YnxVOPmSVRFl8Mvndm0YGNviwiQghhem7177Sw==", "owner_addresses": ["1NXG7eDNSuQFACHmBVvWozQowcYTgGjM4t"], "data_pubkeys": ["03ea5d8c2a3ba84eb17625162320bb53440557c71f7977a57d61405e86be7bdcda"], "payment_addresses": ["1Fj52UvVncNa2hJ6TU8dpu8pHGs65Qxp5J"], "version": "0.18.0", "data_pubkey": "03ea5d8c2a3ba84eb17625162320bb53440557c71f7977a57d61405e86be7bdcda"}(blockstack-master) jude@cf54:~$
(blockstack-master) jude@cf54:~$
(blockstack-master) jude@cf54:~$ blockstack -c /tmp/wallet-test/client.ini wallet
Enter wallet password:
------------------------------------------------------------
Payment address:        1Fj52UvVncNa2hJ6TU8dpu8pHGs65Qxp5J
Owner address:          1NXG7eDNSuQFACHmBVvWozQowcYTgGjM4t
Data public key:        04ea5d8c2a3ba84eb17625162320bb53440557c71f7977a57d61405e86be7bdcdab63a7f1eda1e6c1670c64a9f532b9f55458019d9b80fdf41748d06cd7f60d451
------------------------------------------------------------
Balance:
1Fj52UvVncNa2hJ6TU8dpu8pHGs65Qxp5J: 0.0
------------------------------------------------------------
Names Owned:
1NXG7eDNSuQFACHmBVvWozQowcYTgGjM4t: []
------------------------------------------------------------
Payment private key info: f4c3907cb5769c28ff603c145db7fc39d7d26f69f726f8a7f995a40d3897bb5201
Owner private key info:   c484227e8d66d6f30dfd206e9ebe54dcc9302e1a06b106eeca677ba34a2036ae
Data private key info:    bb68eda988e768132bc6c7ca73a87fb9b0918e9a38d3618b74099be25f7cab7d01
------------------------------------------------------------
{
    "data_privkey": "bb68eda988e768132bc6c7ca73a87fb9b0918e9a38d3618b74099be25f7cab7d01",
    "data_pubkey": "04ea5d8c2a3ba84eb17625162320bb53440557c71f7977a57d61405e86be7bdcdab63a7f1eda1e6c1670c64a9f532b9f55458019d9b80fdf41748d06cd7f60d451",
    "owner_address": "1NXG7eDNSuQFACHmBVvWozQowcYTgGjM4t",
    "owner_privkey": "c484227e8d66d6f30dfd206e9ebe54dcc9302e1a06b106eeca677ba34a2036ae",
    "payment_address": "1Fj52UvVncNa2hJ6TU8dpu8pHGs65Qxp5J",
    "payment_privkey": "f4c3907cb5769c28ff603c145db7fc39d7d26f69f726f8a7f995a40d3897bb5201"
}

(I didn’t do this in the test framework. I just made a new Blockstack directory with a copy of one of my config files, and used it to generate a new wallet).

Does the above work for you?

It absolutely does, yes. Tnx very much.

Maybe one other (different) question:
Can I also transfer bitcoin from one CLI wallet to another CLI wallet using the CLI?
If that is possible, it seems to be the more safe way to first create a new wallet and then transfer the bitcoin from the old to the new, or am I wrong?

Part 2: It does work via blockstack -c /tmp/wallet-test/client.ini wallet to show the new wallet.
But when I copy the new wallet to ~/.blockstack where the original client.ini and all the rest is situated and when I execute blockstack wallet it keeps on showing the old wallet.

Update: After a restart of my mac, it’s solved.
But the bitcoin transfer question is still relevant :slight_smile:

Can I also transfer bitcoin from one CLI wallet to another CLI wallet using the CLI?

Yes–you can use blockstack withdraw DESTINATION_ADDRESS for that. You can optionally pass an amount to withdraw; if no amount is given, the entire balance is sent.

If that is possible, it seems to be the more safe way to first create a new wallet and then transfer the bitcoin from the old to the new, or am I wrong?

That sounds safe to me. You’d make a new wallet (in a different directory than ~/.blockstack, using the steps shown above), get its payment address, and then use your current wallet to run the blockstack withdraw command.

Hey @jude, I have no more questions (on the topics we went through), I managed to go through the whole path, except updating a profile on the Gaia Hub. I was able to generate the Gaia Hub section, but I got a "connection refused" error back trying to connect to it.
Also, the withdraw from my old to the new CLI wallet worked well.
So I went the more (slightly) costly (but certainly the more slow) route and do a blockstack update pointing to a URL of my own and that worked :smile:. You can see the proof looking up leyqi.id .

Thank you again for all the help you provided.

1 Like