Sign in Javascript validate in Beem!

in #steemdev6 years ago (edited)

July 11th, 2020
sign-in-javascript-verify-in-beem.png

Validation of Signatures from Javascript in Beem

Make your signatures in javascript, and validate them in Python. This can be used as a login system for a website. Use it in conjunction with Hive-Signer or Hive Keychain extensions.

Even though transactions are a source of complexity, a user will have more confidence using a CDN of the standard steem-js rather than my custom fork
and as part of the sign transaction routine signatures are formatted as strings which is what Beem expects. So in this tutorial, we will create a custom transaction. The transaction will be used as a message for the server. The server will be able to verify the message came from someone who signed it with their Hive, Golos, or Steem key.

Starting with an old transaction and removing its signature from the blockchain, I made up a key by combining my id with a trivial password. I then wrote both Javascript and Python files together.

<!DOCTYPE HTML>
<html>

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js" defer></script>
<script src='steem.min.js'></script>
<script>
        let body_el = null;
        function writeln(s) {
            if (typeof(s) == 'string')
                body_el.innerHTML += s + '<br>';
            else
                body_el.innerHTML += JSON.stringify(s) + '<br>';
        }

        document.addEventListener('DOMContentLoaded', function(ev) {
            body_el = document.getElementById('body');
            const session_id = 'ABCDEFGHIJK';
            const fictional_key = "5KJjbBMmT8ShhP5sRztfeeuQkeAvsFXWp3ZbXBiNVDYRyvSEBEB";
            writeln(fictional_key);
            const pubKey = steem.auth.wifToPublic(fictional_key);
            writeln(pubKey);
            const unsigned_tx = {'ref_block_num': 27941, 'ref_block_prefix': 4110594407, 
        'expiration': '2018-07-20T13:14:18', 
        'operations': [
          [
          'vote', 
          {'voter': 'bottomses', 'author': 'jayinr', 
          'permlink': 'free-steem-doller-btc-on-your-steem-reputation', 'weight': 3000}
          ]
          ], 
        'extensions': [], 'signatures': [], 'id': 'f3b2da2a6f9cab5e62a6e26fa1c0709dce83ff37', 
        'block_id': '01736d3794c5b3314ab3d822b31fde4ce1d781fe'};
            trx = unsigned_tx;
            writeln(unsigned_tx);
            const signed_tx = steem.auth.signTransaction(unsigned_tx, [fictional_key]);
            writeln(signed_tx);
                        
        }, false);
</script>
<body id='body'>
   

</body>

</html>

You can open that HTML in a browser locally and it will generate a signature.

from beem import Steem
from beembase.signedtransactions import Signed_Transaction
from beemgraphenebase.account import PublicKey

pubKey = "STM7YduFiCDafYsM3EFN1y2jZEsSrCQC93GGHAdLnaSkkT9zxvkFF"

no_broadcast_steem = Steem()
# The following parameters to TransactionBuilder was pasted from the output of X.html.
signed_tx = Signed_Transaction(**{"ref_block_num":27941,
"ref_block_prefix":4110594407,
"expiration":"2018-07-20T13:14:18",
"operations":[["vote",
    {"voter":"bottomses",
    "author":"jayinr",
    "permlink":"free-steem-doller-btc-on-your-steem-reputation",
    "weight":3000}]],
"extensions":[],
"signatures":["207e68c7236ab708e2aed5190c2f4625ce28d65ef4d068512" +
"6f59c891d27ecc9c649a66010059c5c3a8cddcf33906c356248de006d35f0276fe1a1600a5612a7f0"]},
 steem_instance=no_broadcast_steem)
possible_pubkeys =  [format(PublicKey(x), 'STM') for x in signed_tx.verify()]
if pubKey not in possible_pubkeys:
    print("Could not recover the public key with the signed transaction (in Javascript) (along with an incorrect one")

So there is your minimal verification only on Python and signing only in Javascript. Can we sign in Python?

from beem import Steem
from beem.transactionbuilder import TransactionBuilder
from beembase.signedtransactions import Signed_Transaction
from beemgraphenebase.account import PublicKey


fictional_key = "5KJjbBMmT8ShhP5sRztfeeuQkeAvsFXWp3ZbXBiNVDYRyvSEBEB"
pubKey = "STM7YduFiCDafYsM3EFN1y2jZEsSrCQC93GGHAdLnaSkkT9zxvkFF"
#memo_Pubkey = "STM5RiyL2vUj3FqLNSZWAsvqvQirJKd1CM1jTsxeihsUZiGo3otnc" #steem.auth.wifToPublic(fictional_key)
unsigned_tx = {'ref_block_num': 27941, 'ref_block_prefix': 4110594407,
  'expiration': '2018-07-20T13:14:18', 
  'operations': [
  {'type': 'vote_operation', 
    'value': {'voter': 'bottomses', 
    'author': 'jayinr', 
    'permlink': 'free-steem-doller-btc-on-your-steem-reputation', 
    'weight': 3000}}
  ], 
  'extensions': [], 'signatures': [], 
  'id': 'f3b2da2a6f9cab5e62a6e26fa1c0709dce83ff37', 
  'block_id': '01736d3794c5b3314ab3d822b31fde4ce1d781fe'
  }

no_broadcast_steem = Steem()
tx = TransactionBuilder(unsigned_tx, steem_instance=no_broadcast_steem)
default_prefix = tx.steem.chain_params['prefix']
signed_tx = Signed_Transaction(**tx.json(with_prefix=True))
signed_tx.add_custom_chains(tx.steem.custom_chains)
signed_tx.sign([fictional_key], chain=tx.steem.chain_params)

possible_pubkeys = signed_tx.verify([PublicKey(pubKey)])
#print( [format(PublicKey(x), 'STM') for x in possible_pubkeys] )
if pubKey not in [format(PublicKey(x), 'STM') for x in possible_pubkeys]:
    print("Verification Failed")

Journal Entry List

Dash XjzjT4mr4f7T3E8G9jQQzozTgA2J1ehMkV
LTC LLXj1ZPQPaBA1LFtoU1Gkvu5ZrxYzeLGKt
BitcoinCash 1KVqnW7wZwn2cWbrXmSxsrzqYVC5Wj836u
Bitcoin 1Q1WX5gVPKxJKoQXF6pNNZmstWLR87ityw (too expensive to use for tips)

See also


sign-in-javascript-verify-in-beem.png

Coin Marketplace

STEEM 0.18
TRX 0.14
JST 0.030
BTC 58613.96
ETH 3153.58
USDT 1.00
SBD 2.43