Signing transactions - Blockchain in Javascript (part 4)

Signing transactions – Blockchain in Javascript (part 4)



welcome back to the blockchain in JavaScript series in the previous three videos we have created a simple blockchain in JavaScript we added proof of work and we added transactions and mining rewards but there is a small problem with our current version and that is that anyone can make any transaction that he wants so effectively you can make a transaction and spend coins that aren't yours so to solve that we are going to make it mandatory for transactions to be signed with a private and public key that way you can only spend coins in a wallet if you have the private key of it before we do all that let's take our time and quickly clean up the main J's file right now this file contains a bunch of classes and it contains some test code I'm going to leave the test code in main j/s but I'm going to select all of our classes including our sha-256 import I'm gonna cut it and we're gonna put those in their own file we're gonna make a new file called blockchain CAS I'm going to paste that in there and then we're going to export our blockchain in our transaction class because we need that here in our main J's file so in blockchain is at the end of the file we're gonna say module dot export stop blockchain equals blockchain and module dot exports dot transaction equals transaction and then we're going to import these two in our main J's file we're gonna say comms blockchain and transaction equals require dot slash blockchain alright so our main dot J's file should still work next up we're going to make a new file to generate our private and public key to actually make ourselves a wallet so I'm going to go into our source directory we're gonna make a new file and we're going to call that key jas and in this file we're going to import a library called elliptic we're gonna call it EC require elliptic and this library will allow us to generate a public and private key it also has methods to sign something and also a method to verify a signature so let's install that library I'm gonna open up the terminal and we're gonna say npm install elliptic alright that's it let's hide our terminal again then we're going to make an instance of elliptic we're gonna say EC equals new UC and then in here we have to pass the elliptic curve that we want to use you can use any elliptic curve that you want but in this video I'm gonna use SEC P 256 K 1 this is the algorithm that's also the basis of Bitcoin wallets then we're going to generate a key pair we're gonna say cost key equals EC Jenna keep hair and then we're going to extract our public key which is key dot get public and we want that in a hex format and we're gonna do the same thing for our private key we're gonna say again private also as a hex string and then we're gonna show them on our console I'm gonna log an empty line just for clarity and then I'm gonna say console dot log private key is the private key and we're gonna log another empty line and then we're going to say a console above log public key equals public key all right let's save the file and let's run it to see if we now have a private and public key I'm going to open up the terminal I'm gonna change directories into SRC and then I'm gonna run node key generator yes and sure enough there is our public and our private key now we're going to need these two to sign transaction but also to verify our balance what money is in our wallets so I'm just going to copy them and I'm gonna make a new file just paste it in here and then we can use them in minutes I'm gonna hide the terminal again and now we can start changing our blockchain classes let's go to blockchain J yes and let's start at the top by changing transaction so a transaction contains right now a from address and to address and an amount and that's it but what we also need to do is we need to sign this transaction and we need a method that can check if the signature on this transaction is indeed valid so we're going to make a few new functions we're gonna make a method called calculate hash and this will return the sha-256 hash of that transaction why is this important well it's this hash that we're going to sign with our private key we're not going to sign all the data in our transaction we're just going to sign the hash of our transaction so in here we're gonna say return sha-256 and we're gonna take the from address the to address and the amounts and we're gonna hash those together and then we're also going to convert them to a string then we're gonna make a method called sign transaction and sign transaction will receive a signing key so if you want to sign a transaction we have to give it our private and public key pair now signing key will be the object that we've got from our elliptic library so if I open up the key generator it will be this object right here and this object contains cat public and get private as methods so let's go back to blockchain and let's start by creating the hash of our transaction so we're going to say hash TX equals this dot calculate hash then we're going to create a signature we're gonna say constic equals we're going to take our signing key what are we going to we're going to sign the hash of our transaction and we'll do that in base64 and then we're going to store this signature into this transaction so we're gonna say this dot signature equals signature to the R which is a special format and we want this in hex form now we can also add another check here before we sign a transaction we can check if your public key equals the from address remember that you can only spend coins from the wallet that you have the private key for and because the private key is linked to the public key that means that the from address in our transaction has to equal your public key so we're gonna say if the public key the hex version does not equal the from address of this transaction then we're going to throw a new error and we're gonna say you cannot sign transactions for other wallets which makes sense all right now let's make another method and this method is going to verify if our transaction has been correctly signed now there's one special transaction that we have to take into account and that is our mining reward remember that if I scroll down to blockchain if you mine a block you get a mining reward and this mined reward is a transaction that goes from the null address to your mind reward address so we need to take that in account because mining reward transactions aren't signed but yet they are valid so we're going to scroll up and we're going to create a small F function and we're going to say that if the from address in this transaction is null then we're just going to assume that this transaction is valid if the from address is filled in however we have to do additional checks so let's first check if there is a signature if there isn't a signature in this transaction or this signature is just empty then we're going to throw an error as well as we say throw new error no signature in this transaction now if we're still verifying that means that the transaction is not from the null address it has a signature and then we have to of course verify that the transaction was signed with the correct key so what we're going to do is we're going to make a new public key object from the from address because remember the from address is a public key so we're going to say cost public key equals we're gonna use our elliptic curve library again we're gonna say e C dot key from public we're gonna pass along the public key that we want to convert into this key object and we're going to say that it's in form hex and then we're going to use the public key dot verify function what do we want to verify but we want to verify that the hash of this block has been signed by this dot signature and now of course we're using EC here so we have to import it as well so I'm going to go to key generator I'm gonna copy these two imports paste it in here and then that is done so that's our is valid method will first check if the from address is null if it is that we assume it's valid then we'll check if there is a signature if there is a signature we are going to extract the public key from it and that we're gonna verify that this transaction has indeed been signed by that key next up we are going to change our block class so remember that in the previous video we changed our block class so that it can contain multiple transactions well in this class I want to make a method that can verify all the transactions in the current block so I'm gonna say has valid transaction and in here we're going to iterate over all the transactions in the block and we're just going to make sure that every action is valid so we're gonna say if the transaction is not valid then we're going to return false because then the block does not contain valid transactions oops and this should be an off and if you loop through all the transactions and we haven't return false that we have to return true because all the transactions in this block are indeed felt so that's just a little function that will make our lives a bit easier now we can change our blockchain class I'm going to scroll all the way down to the bottom to our is chained valid method so this method goes over all the blocks in our chain and verifies that the hashes are correct and that each block links to the previous block but we also have to verify that all the transactions in the current block are valid so I'm gonna make a new if statement here I'm gonna say if the current block has not all valid transactions now we're going to say that our blockchain isn't an invalid state we're going to return false and then we're going to change the method that adds new transactions to our blockchain that's this one right here create transaction the first thing that I'm going to do is I'm going to change it to add transaction because we're not creating a transaction here instead we're just receiving a transaction and we're pushing it into the pending transactions array then inside this function we're going to perform a few checks the first thing that we're going to check is that the from address and the to address is filled in if not that we throw an error so we're going to say if transaction does not have a from address or transaction does not have a to address then we're going to throw new error and we're going to say transaction must include from an to address another check that we're going to do is we're going to verify that the transaction that we want to add is indeed valid so we're going to say if transaction is not valid then we're also going to throw in error and we're going to say cannot add invalid transaction to the chain and when we passed these two tests that we can still push the transaction onto our pending transactions array all right that is it let me save the file let's now go to our main de Geus file to write some code to actually test all of this new functionality the first thing that I'm going to do in here is I'm going to import our eliptic library again so I'm going to copy it from key generator or I can also copy it from blockchain paste it in there and then we're going to initialize our key so we're gonna say cost my key equals we're gonna say easy dot key from private and in here we have to pass our private key so I'm going to open up the little file that I made in the beginning I'm gonna copy the private key paste it in there and then I can also extract the public key or my wallet address so I'm gonna say cost my wallet address equals my key dot get public and we want that in hex format then we're still making a new instance of our blockchain class and then we can make new transactions now I'm doing this here in one go but instead I'm going to split it up into two operations first we're gonna make a transaction so we're going to say Const tx1 equals a new transaction that transaction goes from my own wallet to someone else's wallet so here I would paste in the public key of someone else now I'm the only one was blocked in for now so I'm just gonna say public key goes here but in reality you want the actual public key and then I can define how much coins I want to send in this transaction so let's say I want to send ten coins then I have to sign my transaction so I'm going to say T X 1 dot sign transaction and we're gonna sign it with my key and after it's been signed I'm gonna add it to the blockchain I'm gonna say sad G coin dot add transaction tx1 alright so now I can remove these two right here we can start the miner and that we can check the balance of our coin I'm gonna remove the second mining start we don't really need it here now there's one more thing that we have to change when we mined pending transaction we have to tell where the mining reward should go to so in this case the mining Awards will go to the wallet with address Sophia's address but that address doesn't really exist so if we do that the coins would be sent to a wallet where no one can access them because no one has the private key of that wallet so instead we want to coins to be sent to my wallet address which is my public key and then the same thing goes for here we're checking the balance of our wallet so we have to check the balance of my wallet address all right let's save the file let's open up the terminal and let's test it I'm gonna say no main dot J yes and sure enough our balance is now ninety now why ninety well remember that if I mind a block I get a hundred coins and I've spent ten of them right here so that means that I have to 90 left so that all makes sense now let's also try to tamper with the blockchain let's do a console log and let's say is change valid and we're just gonna say Sanji coin dot is chain valid so if I rerun the example it will say my balance is still 90 because every time I run this script it resets itself basically but then it also says that our chain is valid and that's because I haven't tampered with anything but let's now try to actually tamper with something so let's add a new line here and let's go to Sanji coin let's take the chain I'm gonna take the second block on the chain remember in JavaScript we start counting from zero zero is our Genesis block so index 1 is the block that contains our transaction then we're going to say we're gonna take the first transaction in there and we're gonna try to change the amount we're gonna say well I didn't send 10 points I only sent one coin for instance let's save the file and let's see what happens is now I'm gonna rerun it and now it says is the chain valid up nope it's not valid because the signature doesn't match up anymore so that was it for this video we have made it possible for people to sign their transactions with a private key and that means that now if a person creates a new wallet creates a new key pair he is the only one who can spend the coins in that wallet now the code for this little blockchain is available on github the link will be down in the description below if you liked this video give it a thumbs up and consider getting subscribed and as always thank you very much for watching

41 thoughts on “Signing transactions – Blockchain in Javascript (part 4)

  1. How to save transation, to not lose it when de program goes down, like when u run de program, how can i save de data from a blockchain? Or the p2p network is the database, if just one is online, we will have all data save!

  2. Hey boss, are you ever planning to teach us about distribution / decentralization?
    I believe 90% of web tutorials demonstrate blockchain implementations using a server in the middle which is stupid. It's like everyone is avoiding the important work. You have the gift of God for explaining things better than everyone else. Of all the people on the internet who explain or show a decentralized blockchain implementation using distributed p2p communication, I want YOU to be the one who shows us the way.
    Regards
    -your new fan who discovered you today

  3. One of the important validation is to check if the transaction is send out an amount larger than the current balance. In blockchain, how to check this validation, could you please advise?

  4. This is very helpful. We recently switched to hyperledger fabric. I can only imagine the difficulty new people will have with no prior knowledge of blockchain, docker and linux. This would be a great starting point for both javascript and the basics of blockchain (instead of jumping from powerpoint to hyperledger)

  5. You forgot to show add rewardtx pushed in pending transaction minePendingTransactions function, result no reward at all, so my wallet is -10. But i found out abt it later.
    Great video, looking forward to see your next vid 🙂

  6. Hi always looking forward seeing your videos,
    do you mind if i ask when you will upload your next videos and how far would this tutorials would lead us to?
    Are you also going to make tutorials on building p2p networks for nodes and broadcasting system for new blocks?

  7. Been watching youtube for YEARS now, you are literally the FIRST I EVER subscribe to!
    I was able to take everything from first episode in this series to this one in 1 sitting 😀
    Short, precise and on point with an actual clean and clear code, that is scarce!

    I'm still having problems with signatures but that's because I never dealt with them before.. I never interacted with public and private keys directly before.
    I'll probably understand it as soon as I code it in myself.
    Most appreciated mate! Keep up the good work!

  8. Hello Savjee,You are really great.Your way of teaching is excellent.Still i have a doubt.I run your code and even if i don't have any balance in my wallet i am able to make a transaction and sometimes it shows negative values in balance.Can you do something to check the balance in our wallet before making transaction?

  9. What is the difference between a private key and a public key? If only the private key is unique does it mean that you can send coins to multiple wallets that share the same public key at once? And if they are both unique (the private and the public keys) why do we need both and not just the public one (considering it is longer)?

  10. You make transaction hash from from address, to address and amount. What is they are same in multiple transactions? Fox example if I send same amount of coins to same address multiple times?

  11. Great video, the signing of transactions was a missing part in the chain. Thanks!
    By the way, you forgot to re-hash the second block after you changed the amount of the transaction. Hopefully it still wouldn’t be valid due to the incorrect signature at that point.

Leave a Reply

Your email address will not be published. Required fields are marked *