1

It seems that eosjs examples do not use keosd to retrieve the private keys or to sign a transaction.

https://eosio.github.io/eosjs/

It says "Using the default JsSignatureProvider in the browser is not secure and should only be used for development purposes. Use a secure vault outside of the context of the webpage to ensure security when signing transactions in production"

So what is the typical practice to implement "a secure vault" when we develop a web page to access eos chain?

Is it using keosd or a local DB or else?

3
  • do you want to access private keys in the wallet ? or you want to use RPC calls related to the keosd? Commented Nov 22, 2018 at 9:19
  • 1
    I want to use RPC calls to keosd. Basically, I want to let keosd sign the transaction and return the signature only. I do not want to expose the private key in any communication.. Commented Nov 23, 2018 at 0:33
  • One way of doing that is running keosd in the server where the blockchain is running and perform your operations or the other way is to use online wallets or scatter. I recommend using scatter is a good way Commented Nov 23, 2018 at 6:40

3 Answers 3

2

Traditionally most websites that implement an EOSIO smart contract do not offer a key storage service, instead, they integrate with a web wallet. The wallet then stores the keys locally for the user and encrypted. It will decrypt the keys locally only to sign transactions so the web app is never exposed to the private keys.

I would recommend Scatter (https://get-scatter.com/), but there are many good wallets out there to use. Scatter has a Google Chrome extensions that is easy to use.

I integrate Scatter in my simple chess application if you'd like a code example.

https://github.com/NatPDeveloper/eos-chess/blob/master/js/lib/scatter-js/scatter.js

0
1

I captured the http message exchanges for the following cleos command by using TCPDUMP.

cleos --wallet-url http://172.18.0.1:8899 -u http://172.18.0.1:8888 push action shlee create '["shlee", 7, "feed dragon"]' -p shlee

It takes 6 http request/response message exchanges.

Step 1. to nodeos

POST /v1/chain/get_abi HTTP/1.0
Host: 172.18.0.1:8888
content-length: 24
Accept: */*
Connection: close

{"account_name":"shlee"}

HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Connection: close
Content-Length: 928
Content-type: application/json
Server: WebSocket++/0.7.0

{"account_name":"shlee","abi":{"version":"eosio::abi/1.0","types":[],"structs":[{"name":"todo","base":"","fields":[{"name":"id","type":"uint64"},{"name":"description","type":"string"},{"name":"completed","type":"uint64"}]},{"name":"create","base":"","fields":[{"name":"author","type":"name"},{"name":"id","type":"uint32"},{"name":"description","type":"string"}]},{"name":"destroy","base":"","fields":[{"name":"author","type":"name"},{"name":"id","type":"uint32"}]},{"name":"complete","base":"","fields":[{"name":"author","type":"name"},{"name":"id","type":"uint32"}]}],"actions":[{"name":"create","type":"create","ricardian_contract":""},{"name":"destroy","type":"destroy","ricardian_contract":""},{"name":"complete","type":"complete","ricardian_contract":""}],"tables":[{"name":"todos","index_type":"i64","key_names":["id"],"key_types":["uint64"],"type":"todo"}],"ricardian_clauses":[],"error_messages":[],"abi_extensions":[]}}

Step 2. to nodeos to get the chain id.

POST /v1/chain/get_info HTTP/1.0
Host: 172.18.0.1:8888
content-length: 0
Accept: */*
Connection: close



HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Connection: close
Content-Length: 578
Content-type: application/json
Server: WebSocket++/0.7.0

{"server_version":"cc9decff","chain_id":"cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f","head_block_num":746976,"last_irreversible_block_num":746975,"last_irreversible_block_id":"000b65df039e8ccbf66084ebb2e3a5582bd89d908f300e866969746caee92930","head_block_id":"000b65e08ca87bbd0dd67f75ad9b381cbd2249e76c3bfec063e11213669398d4","head_block_time":"2018-11-22T01:59:19.000","head_block_producer":"eosio","virtual_block_cpu_limit":200000000,"virtual_block_net_limit":1048576000,"block_cpu_limit":199900,"block_net_limit":1048576,"server_version_string":"v1.2.4"}

Step 3. to keosd to get all the public keys.

POST /v1/wallet/get_public_keys HTTP/1.0
Host: 172.18.0.1:8899
content-length: 0
Accept: */*
Connection: close



HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Connection: close
Content-Length: 393
Content-type: application/json
Server: WebSocket++/0.7.0

["EOS5Cm2ntfRafTjYD2SNejTN3ARRneBXTKBnVn9KGUYsfdsvgFVjK","EOS5ES24U95W9nkfTr9iL2Xk6yC366RZxBit4RzXX7ffia9BJnWmb","EOS5TPrAUwRK6CXrYhmwDC3xXAaEAaG2uiCuZzuNyMcMwD7EciZLv","EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV","EOS6gYNENaNqx9zeUUgy87uxgvWYiU2FUwJr3YsQHMrk8hscbu2Eu","EOS77WKReas8f2sAiS8rbU6iacvnhGaYGJ6bPxGqgqoKVQTvEXf56","EOS8PVjQLubNH9cAyZNoPGNRPFoUa716Q3jRzStefqaqV3JH4aYJm"]

Step 4. to nodeos to get the required public key to submit the transaction. Basically, it is the "active" public key of the user "shlee"

POST /v1/chain/get_required_keys HTTP/1.0
Host: 172.18.0.1:8888
content-length: 792
Accept: */*
Connection: close

{"transaction":{"expiration":"2018-11-22T01:59:49","ref_block_num":26079,"ref_block_prefix":3951321334,"max_net_usage_words":0,"max_cpu_usage_ms":0,"delay_sec":0,"context_free_actions":[],"actions":[{"account":"shlee","name":"create","authorization":[{"actor":"shlee","permission":"active"}],"data":"0000000000a562c3070000000b6665656420647261676f6e"}],"transaction_extensions":[]},"available_keys":["EOS5Cm2ntfRafTjYD2SNejTN3ARRneBXTKBnVn9KGUYsfdsvgFVjK","EOS5ES24U95W9nkfTr9iL2Xk6yC366RZxBit4RzXX7ffia9BJnWmb","EOS5TPrAUwRK6CXrYhmwDC3xXAaEAaG2uiCuZzuNyMcMwD7EciZLv","EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV","EOS6gYNENaNqx9zeUUgy87uxgvWYiU2FUwJr3YsQHMrk8hscbu2Eu","EOS77WKReas8f2sAiS8rbU6iacvnhGaYGJ6bPxGqgqoKVQTvEXf56","EOS8PVjQLubNH9cAyZNoPGNRPFoUa716Q3jRzStefqaqV3JH4aYJm"]}


HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Connection: close
Content-Length: 75
Content-type: application/json
Server: WebSocket++/0.7.0

{"required_keys":["EOS6gYNENaNqx9zeUUgy87uxgvWYiU2FUwJr3YsQHMrk8hscbu2Eu"]}

Step 5. to keosd to sign the transaction. keosd returns the signatures starting with "SIG_K1_...."

POST /v1/wallet/sign_transaction HTTP/1.0
Host: 172.18.0.1:8899
content-length: 531
Accept: */*
Connection: close

[{"expiration":"2018-11-22T01:59:49","ref_block_num":26079,"ref_block_prefix":3951321334,"max_net_usage_words":0,"max_cpu_usage_ms":0,"delay_sec":0,"context_free_actions":[],"actions":[{"account":"shlee","name":"create","authorization":[{"actor":"shlee","permission":"active"}],"data":"0000000000a562c3070000000b6665656420647261676f6e"}],"transaction_extensions":[],"signatures":[],"context_free_data":[]},["EOS6gYNENaNqx9zeUUgy87uxgvWYiU2FUwJr3YsQHMrk8hscbu2Eu"],"cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f"]


HTTP/1.1 201 Created
Access-Control-Allow-Origin: *
Connection: close
Content-Length: 507
Content-type: application/json
Server: WebSocket++/0.7.0

{"expiration":"2018-11-22T01:59:49","ref_block_num":26079,"ref_block_prefix":3951321334,"max_net_usage_words":0,"max_cpu_usage_ms":0,"delay_sec":0,"context_free_actions":[],"actions":[{"account":"shlee","name":"create","authorization":[{"actor":"shlee","permission":"active"}],"data":"0000000000a562c3070000000b6665656420647261676f6e"}],"transaction_extensions":[],"signatures":["SIG_K1_Ka4ebw48DQkmTUoCcHx6eCS8M2UG9Gyz3xzcX77njvYXmYbiLQ1UjNXriZBQ1zGMNAxaP76mDKSBSt7fEk6Yv4GKMaHhK6"],"context_free_data":[]}

Step 6. to nodes to push the transaction.

POST /v1/chain/push_transaction HTTP/1.0
Host: 172.18.0.1:8888
content-length: 335
Accept: */*
Connection: close

{"signatures":["SIG_K1_Ka4ebw48DQkmTUoCcHx6eCS8M2UG9Gyz3xzcX77njvYXmYbiLQ1UjNXriZBQ1zGMNAxaP76mDKSBSt7fEk6Yv4GKMaHhK6"],"compression":"none","packed_context_free_data":"","packed_trx":"950df65bdf65f66084eb00000000010000000000a562c300000000a86cd445010000000000a562c300000000a8ed3232180000000000a562c3070000000b6665656420647261676f6e00"}


HTTP/1.1 202 Accepted
Access-Control-Allow-Origin: *
Connection: close
Content-Length: 923
Content-type: application/json
Server: WebSocket++/0.7.0

{"transaction_id":"de9b775c4cb19f94dc07e9ad177d2b74d29304d7ba641c80be91aac45348a995","processed":{"id":"de9b775c4cb19f94dc07e9ad177d2b74d29304d7ba641c80be91aac45348a995","receipt":{"status":"executed","cpu_usage_us":757,"net_usage_words":15},"elapsed":757,"net_usage":120,"scheduled":false,"action_traces":[{"receipt":{"receiver":"shlee","act_digest":"896371bd40154bb3f5ff3d2d8065d174da32d1316113e490af15b9121ef482f3","global_sequence":746987,"recv_sequence":6,"auth_sequence":[["shlee",7]],"code_sequence":1,"abi_sequence":1},"act":{"account":"shlee","name":"create","authorization":[{"actor":"shlee","permission":"active"}],"data":{"author":"shlee","id":7,"description":"feed dragon"},"hex_data":"0000000000a562c3070000000b6665656420647261676f6e"},"elapsed":527,"cpu_usage":0,"console":"","total_cpu_usage":0,"trx_id":"de9b775c4cb19f94dc07e9ad177d2b74d29304d7ba641c80be91aac45348a995","inline_traces":[]}],"except":null}}

In this 6 steps, the private key of the user shlee has never been transferred through the HTTP request/response messages.

I just want to mimic the behavior of cleos command by using node.js RPC.

But it seems that developers do not use keosd for the wallets. Instead they use different mechanisms to manage the keys. I'd like to know the key managing practices in real systems.

0

eosjs-keos: JavaScript API for using keos as Signature Provider to replace the JsSignatureProvider.

https://github.com/Leask/eosjs-keos

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.