This lesson is relative to bitcoin and general blockchain concepts.

Lesson 1 – Blockchain Basics

This are my notes on the Udacity Blockchain developer “nanodegree”.

I graduated from an engineering school with a computer science master’s degree. But I was never aiming at becoming a developer. But blockchain is such a cool topic that I am willing to get back to school and learn from scratch to code in nodeJs and solidity.

Diclaimer: This section will not be about narration and informative articles, but rather my notes on the Udacity course so I can get back to it in case of need.

First contact with Js

// in the terminal
// print version of NodeJs
node -v
// Create a new file called newFile.js
touch newFile.js
//Add in the .js file a command to print in the console : 
console.log ("Yay! I am enjoying my Blockchain Nanodegree!")
//execute the script 
node newFile.js

Blockchain basics

  • When we want to exchange something we can either do barter or base our transaction on a common standard which can be gold or money
  • Banks use a ledger to solve the double spend problem and act as a trusted third party
  • You are giving your data to third parties such as banks
  • As you try to book more complex transactions you usually involve more and more third parties

Blockchain technology can address some of those problems by providing a shared ledger

A block is a group of transactions bundled together

Resources to read :

Bitcoin : A solution to the double-spending problem using a peer-to-peer network

Hashing

SHA-256 : Secured Hashing Algorithm, 256 : output of the algo (256 bits number). Used to make an unique ID for every block.

Experiment with SHA-256 :  Anders.com

Basically f(x) = y , but impossible to retrieve x from y. But f(x) will always have y as output

Coding practice for Hashing

/**
 * Step 1: Verify 'crypto-js' module is installed for your project.
 * After verifying it is installed, move on to Step 2. No code needs to be written here.
 */

/**
 * Step 2: Import from crypto-js module the SHA256 library.
 */

// Write your code here
var SHA256 = require("crypto-js/sha256");
/**
 * Variables: Do not change variable values.
 */

const data1 = "Blockchain Rock!";
const dataObject = {
	id: 1,
  	body: "With Object Works too",
  	time: new Date().getTime().toString().slice(0,-3)
};

/**
 * Step 3: Add code to the `generate hash function
 * Function that generates the SHA256 Hash
 * @param {*} obj 
 */

function generateHash(obj) {
	return SHA256(JSON.stringify(obj));
}

console.log(`SHA256 Hash: ${generateHash(data1)}`);
console.log("************************************");
console.log(`SHA256 Hash: ${generateHash(dataObject)}`);

/**
 * Run your application using `node hashing.js`
 */

Ressource : https://www.npmjs.com/package/crypto-js#usage

In this small program we imported the crypto-js library and we used SHA256 function to hash two different inputs, one fixed (data1) and one which changes roughly every second.

  • Hash from the first call is : f9a8aa13efcf511cb7ac496943a3dd5c14de3a8188c36719aa4350f662957329
  • The second call changes all the time

Blocks

Block header : Previous blocks Hash + Time + Merkle Root + nonce

Block difficulty : how much 0 in the hash to be reached with a nounce

Block Size : Size of a block in terms of mb for instance

Go back to  Anders.com to see how a block works

Coding practice for blocks

/**
 * Import crypto-js/SHA256 library
 */
const SHA256 = require('crypto-js/sha256');

/**
 * Class with a constructor for block 
 */
class Block {

	constructor(data){
		this.id = 0;
        this.nonce = 144444;
      	this.body = data;
      	this.hash = "";
    }
    
    /**
     * Step 1. Implement `generateHash()`
     * method that return the `self` block with the hash.
     * 
     * Create a Promise that resolve with `self` after you create 
     * the hash of the object and assigned to the hash property `self.hash = ...`
     */
  	// 
  	generateHash() {
      	// Use this to create a temporary reference of the class object
      	let self = this;
        //Implement your code here
        return new Promise(function(resolve, reject) {        
    	self.hash = SHA256(JSON.stringify(self)).toString();
    	resolve(self);
    });
    }
}

// Exporting the class Block to be reuse in other files
module.exports.Block = Block;

Basically we construct a block and then we hash the information and store it into the same hash.

Blockchain

Immutable transaction history, chained blocked linked together by hashing.

If you change something in a block, the hash will not be valid anymore and as a consequence the block will not be valid anymore and all the further blocks will be invalid as well as the hash of the previous block is part of a block and needs to be valid

Distributed Peer-to-Peer Networks

Peer-to-Peer Network: A network of computers that allows information to be shared across users.

Distributed Network: A network that allows information to spread out across many users.

Before becoming a part of the network, and eventually the blockchain, transactions are held in something known as a memory pool. The memory pool (also known as the mempool) is the waiting place for transactions before they enter the blockchain. The blockchain can only handle so much information at once, and the backlog of information goes here.

Why a transaction would leave the Mempool ?

  • Transaction expired by timeout (14 days after entering – at the time of the course)
  • Trx was at the bottom of the mempool when sorted by fee per size, the mepool reached size limit and a new huigh-fee transaction was accepted, evicting the transaction at the bottom
  • Transaction was included into a block
  • Transaction or one of its unconfirmed ancestors conflicts with a transaction that was included in a block

Usually we consider a block as irrevocable after 6 confirmation (5 blocks were added on top of our block -> 6 confirmations)

Byzantine General’s problem : this challenge has been around for a while – achieving consensus in a distributed system with suboptimal communication between participants who do not necessarily trust each other isn’t new.

Proof of work Mining : Combine all the data in the block with a nonce and hash it, change the value of the nonce incrementally until you find a hash with x leading 0s depending on the difficulty, bam you solved it. the more the 0s the more the need is specific and the more it is difficult to find a nonce that fits the requirement.

PoW involves miner nodes, or miners, to solve a math puzzle that requires a lot of computation power. Whichever miner is able to solve the puzzle the fastest is able to add a block of transactions to the blockchain, and in return, they are paid the transaction fees from all the transactions included in the block as well as paid by the network with bitcoins that were newly created upon the “mining” of the block.

In bitcoin we try to stay at 10 minutes per block, so the difficulty changes based on the time it takes to mine a new block

Problems with proof of work mining:

  • Power/Energy consumption
  • Concentration/Monopoly of computing for mining pools giving them too much control over the bitcoin network

Proof of stake: The key idea behind proof of stake is that it focuses on giving votes to members, depending on how much stake they have in the success of the chain. The higher the stake a validator has, the more he is susceptible to validate blocks.

In the Proof-of-Stake Consensus Protocol, there are no more miners; instead, there are Validators. These validators, or stakeholders, determine which block makes it onto the blockchain. In order to validate transactions and create blocks, validators put up their own coins as “stake”. Think of it as placing a bet – if they validate a fraudulent transaction, they lose their holdings as well as their rights to participate as a validator in the future. In theory, this check incentivizes the system to validate only truthful transactions.

Potential issue : Nothing at stake -> Slasher solution : penalize validators if they simultanously do blocks on multiple chains. Additionally there’s the Punisher Strategy which simply punishes validators for creating blocks on the wrong chain. In this method, Validators will be motivated to be selective and conscious about the blockchain in which they put their stake.

Delegated Byzantine Fault Tolerance or DBFT for short, is yet another important consensus algorithm. Unlike proof of work or proof of stake, DBFT tries to achieve consensus by assigning roles to nodes to help coordinate consensus. (speaker, delegates, regular nodes). dBFT uses a system similar to a democracy where Ordinary Nodes the system vote on representative Delegate Nodes to decide which blocks should be added to the blockchain. When it’s time to add a block, a Speaker is randomly assigned from the group of Delegates to create a new block and propose the new block. 66.66% of delegates need to approve on the block for it to pass.

potential issues :

Dishonest Speaker : There is always a chance the Speaker, who is randomly selected from the Delegates, could be dishonest or malfunction. In this situation, the network needs to rely on honest delegates to vote the proposed block down so it doesn’t reach 66% approval. It is up to users of protocol who vote on Delegates, to find out which delegates are not trustworthy and vote on other delegates that are truthful.

Dishonest Delegate : In this case, the chosen Speaker is honest but there are Dishonest Delegates in the system meaning even if they receive a proposal for new block that is faulty, they can say it is valid. If it is a minority of delegates that are dishonest, the block will not make it and new speaker is elected.

Lesson 2 – Managing blockchain transactions

Blockchain Identity Overview

  • Private key : A secret number that allows you to spend bitcoin from your wallet
  • Wallets can hold one or multiple private keys
  • Public key : Publicly shareable key that cannot be used to spend bitcoin and is derived from the private key
  • After creating the public key from the private key, it is not possible to deduce the private key from the public key
  • Bitcoin does this with an algorithm called A one-way Elliptic Curve Digital Signature Algorithm (ECDSA)
  • Private key -> ECDSA -> Public key
  • Wallet Address: A unique ID for your wallet

Blockchain Hashing Algorithms

We create the wallet address from the public key, can’t find out the public key from the wallet Address

to do this we user SHA-256 + primitive digest (RIPEMD-160), 256 bits for the first in output, 160 bits in output for the second one

But this is difficult to use so we push also the 160 bit number into a BASE58CHECK in order to make it more usable. This in final gives the shareable wallet address.

Wallet types overview

  • Non-Deterministic Wallet : random wallets, a wallet where private keys are generated from random numbers. First implementation. Can have a use for back end services for instance
  • Deterministic Wallet: A wallet where addresses, private keys, and public keys can be traced back to their original seed words -> Easier to remember seeds words. If you have the seed you have the power and you can use this ton re-generate all the derived private keys. Easy migrations of keys.
  • Hierarchical Deterministic Wallet: An advanced type of deterministic wallet that contains keys derived from a tree structure. Came in BIP-0032 (bitcoin improvement proposal)

With HD wallets you can derive sub keys from keys, hence the tree structure. You can share branches and certain levels of it. You can separate different departments for instance and provide a branch to each department. Strong back up of the master key though ! Super risk lays on this master key as it controls the whole tree.

Private keys

Private key : A 256-bit random number between 1 and 2^256.

Can be in different formats :

Entropy : Lack of order or predictability. The degree of disorder or randomness in the system

In python you can use the random library for instance. Or online services for this like bitaddress.org

When using bitaddress.org better do it offline, you save the page locally, you disconnect from the internet and you do it offline.

In Electrum you can generate your keys and then retrieve them from the software. You could need to retrieve your private keys in case you want to restore your wallet.

To summarize :

  • What’s the purpose of a Private key : Private keys generate Public Keys and Wallet Address that allow us to interact with the blockchain
  • What makes a private key secure : A private key is a 256-bit random number between 1 and 2^256
  • How to generate a private key:
    • Paper, pencil, coin, dice
    • OS with source of entropy or library with cryptographic secure number generator
    • Bitcoin address generating websites
    • Software wallets

Installed Electrum wallet on my side

If you want to restore a wallet you can do it with :

A seed : One way to restore a wallet is using a seed. The ‘seed’ is the 12 words you were given when creating your wallet. If you can remember these words, you can use them to restore your wallet!

A Private key:

Importing a private key :

When importing a private key, you’ll have a source wallet and a destination wallet. The destination wallet is likely filled with a group of private keys already. To import the key you move the private key from the source wallet to the destination wallet. This results in you getting access to both the source wallet AND the destination wallet.

Sweep a Private key :

When you sweep a private key, you add a private key from a source wallet into the destination wallet. All the bitcoins that belong to that private key are swept from the source wallet over into the destination wallet. This is a little different than importing because it completely removes the funds from the original wallet. You’ll now only be using this new wallet to make future transactions.

Why would you import or sweep a private key?

Sweep a wallet if you’re worried about wallet security.This might happen in the case that you think someone might have access to your private key. Sweeping completely cleans out the wallet so that no one will have access to your bitcoins.

If you are certain no one has gotten access to your private key, and that no one ever will, then you can import the key instead. This is useful in cases where you need the funds to be available from multiple wallets.

When in doubt, stick with sweeping. It’s more secure this way, and it avoids some problems that are associated with importing a wallet.

Signature

  • How do we know it’s valid?
  • Who owns the transaction?

We validate transactions and assign ownership using what’s known as a digital signature. These signatures are an important piece underlying the security of the blockchain. In this video, we’ll explore this idea further to discuss how signing a transaction works

UTXO : unspent transaction output

Proof of ownership derived from private key (you sign it with the private key)

To create a transaction output you need to have the sum of the input transactions which are equal to, or, greater than the value you are sending. You also include the miner fees into the transaction (to motivate miners to integrate your transaction into a block).

TX0 + TX1 + TX2 = your inputs, what you have in your wallet

TX3 = you want to send 1 bitcoin to your friend and you include 0.003 as miner fee

TX4 = your change that is given back to you (remaining unspent position)

Lesson 3 – Bitcoin Core Testnet

Goal :

  • Set up your own bitcoin core development environment.
  • Introduce bitcoin core – its purpose, and the tools
  • Create transactions between wallets using a bitcoin core test environment.
  • Investigate the transactions made using the online block explorer to get a better idea of how transactions flow through the network.

Bitcoin core is the original solution, the basis, the CORE

Key terms

  • Bitcoin: Network of bitcoin users creating and validating transactions
  • Bitcoin Core: Implementation of bitcoin that encompasses all of the software behind bitcoin
  • Debug Console: Tool that allows you to interact with data on the bitcoin blockchain

Bitcoin core enables to :

  • Connect to the network
  • Validate the blockchain
  • Send and Receive Bitcoin

Bitcoin Core Networks :

  • Bitcoin Mainnet: Primary Network where live transactions take place
  • Bitcoin Testnet: Alternative Bitcoin blockchain that provides a test environment for applications (coins have no value, there are peers to test your thing)
  • Bitcoin Regnet: Alternative test network for testing bitcoin applications (coins have no value, no peers) Reg:regression
This image has an empty alt attribute; its file name is image-6.png

Difference between Testnet and Regression net :

This image has an empty alt attribute; its file name is image-7.png

Let’s install bitcoin core

what is bitcoin core ?

Bitcoin Full Node Wallet: A bitcoin wallet that fully validates transactions and blocks

Now to install bitcoin core and use the testnet, here is how I did it :

  • Download from here : https://bitcoincore.org/bin/bitcoin-core-0.16.3/
  • Install the software
  • Start it and let it start to sync with the mainnet
  • Stop it, exit and go to : AppData\Roaming\Bitcoin
  • Create a new file called “bitcoin.conf”
  • Open it and add “testnet=1”
  • Close it and run the bitcoin-qt.exe again
  • Voila, you are on the testnet ! let it sync
This image has an empty alt attribute; its file name is image-8.png
This image has an empty alt attribute; its file name is image-9.png

Get testnet coins

Let’s go to a public faucet to get some coins now !

First create a receiving adress :

This image has an empty alt attribute; its file name is image-10-1024x498.png

Then you have to copy the adress and find some faucets online, just enter “testnet faucet bitcoin” in google and you will find eventually website where you input your publick address and they send you free testnet bitcoins. Like :

Testnet Wallet Transactions

To create new wallets go to the appdata folder, then into the testnet3 folder and simply copy the wallet.dat and rename it, here I renamed it into receiving and sending.

This image has an empty alt attribute; its file name is image-11.png

And now to open the new wallet, specify which wallet you want to open in the bitcoin.conf :

This image has an empty alt attribute; its file name is image-12.png

Once you’re in, you can check the wallet name by going to the debug console and typing in getwalletinfo.

You can send and receive bitcoins on those wallets. If you want to check the status of the transactions you can use blockchain explorers, such as https://live.blockcypher.com/btc-testnet/

block height : Block height refers to a specific location in a blockchain, measured by how many confirmed blocks precede it. The current block height of a blockchain is an indication of its current size or time in existence.

Basically the block number

I really struggled to find a faucet with enough BTC to fund my bitcoin core wallet as most were distributing 0.0001 BTC per day, which doesn’t even pay for the transaction fee. So in the end I digged on reddit and finally found a charitable soul that sent me a full BTC on the testnet.

Lesson 4 – Blockchain Data

Block data model :

Block header:

  • Previous Block’s Hash – The hash value for the block that comes directly before a given block in the chain. This is what links blocks in the blockchain together
  • Time – The time the block was created is also held in the header
  • Merkle Root – The merkle root is a hash that represents every transaction included inside the block. To get the merkle root, pairs of transactions within a block are repeatedly hashed together. Each pair results in a single hash. Then the hash of 2 pairs of transactions are again hashed together, over and over again until you are left with a single hash value. Given that final hash value, known as the merkle root, you can now use the hash to search the original transactions or hash values that created them. This searching allows you to find the original transactions that made up the block when starting from this single hash value.
  • Nonce – A nonce (stands for “number only used once”) is a number used in bitcoin mining. The blockchain miners are solving for the nonce that when added to a hashed block, and those 2 values are rehashed, will solve the mining puzzle.

Block Body:

  • Transactions (Inputs and Outputs)

Transactions encode the transfer of value between participants in the system. In more detail, a transaction is a data structure that encodes a transfer of value from a source of funds called an “input” to a destination called an “output”.

Inputs in one transaction are just the unspent outputs from another transaction. All inputs reference back to an output. Unspent Outputs is sometimes short-handed to UTXO.

Inputs in one transaction are just the unspent outputs from another transaction.

Conceptualize the arrow as a pointer from the inputs referencing the outputs from which they came. This is similar to pointers in a linked list. You’ll find that this is standard arrow notation, inputs pointing back to their outputs.

Structure of a block :

This is the Raw Transaction we explored in the video:

0100000001f3f6a909f8521adb57d898d2985834e632374e770fd9e2b98656f1bf1fdfd427010000006b48304502203a776322ebf8eb8b58cc6ced4f2574f4c73aa664edce0b0022690f2f6f47c521022100b82353305988cb0ebd443089a173ceec93fe4dbfe98d74419ecc84a6a698e31d012103c5c1bc61f60ce3d6223a63cedbece03b12ef9f0068f2f3c4a7e7f06c523c3664ffffffff0260e31600000000001976a914977ae6e32349b99b72196cb62b5ef37329ed81b488ac063d1000000000001976a914f76bc4190f3d8e2315e5c11c59cfc8be9df747e388ac00000000

Transaction in the bitcoin blockchain are stored in a double-hashed form:

SHA256(SHA256(01000…)) = b138360800cdc72248c3ca8dfd06de85913d1aac7f41b4fa54eb1f5a4a379081

Raw Transaction with each component highlighted:

more details :

  • Version – All transactions include information about the Bitcoin Version number so we know which rules this transaction follows.
  • Input Count – Which is how many inputs were used for this transaction

Data stored in Input information:

  • Previous output hash – All inputs reference back to an output (UTXO). This points back to the transaction containing the UTXO that will be spent in this input. The hash value of this UTXO is saved in a reverse order here.
  • Previous output index – The transaction may have more than one UTXO which are referenced by their index number. The first index is 0.
  • Unlocking Script Size – This is the size of the Unlocking Script in bytes.
  • Unlocking Script – This is the hash of the Unlocking Script that fulfills the conditions of the UTXO Locking Script.
  • Sequence Number – This is a deprecated feature of bitcoin, currently set to ffffffff by default.

Output Count – which tells us how many outputs were produced from this transaction.

Data stored in Output Information:

  • Amount – The amount of Bitcoin outputted in Satoshis (the smallest bitcoin unit). 10^8 Satoshis = 1 Bitcoin.
  • Locking Script Size – This is the size of the Locking Script in bytes.
  • Locking Script – This is the hash of the Locking Script that specifies the conditions that must be met to spend this output.

Locktime – The locktime field indicates the earliest time or the earliest block a transaction can be added to the blockchain. If the locktime is non-zero and less than 500 million, it is interpreted as a block height and miners have to wait until that block height is reached before attempting to add it to a block. If the locktime is above 500 million, it is read as a UNIX timestamp which means the number of seconds since the date January 1st 1970. It is usually 0 which means confirm as soon as possible.

Bitcoin Script

  • Stack based, executes left to right
  • Not turing complete, no loops or complex flow control.
  • Remove the fear to be stuck in an infinite loop
  • It is deterministic
  • Provides security and simplicity
  • Script verified by our node would also be verified by another node (stateless verification)

example : OP_ADD, will pop two numbers and then push the sum of those 2 numbers back

example : 2 6 OP_ADD 8 OP_EQUAL

  • Push 2 on top of the stack
  • Push 6 on top of the stack
  • OP_ADD Pops the 2 layers ( 2 and 6 ) out of the stack
  • OP_ADD adds the two together and pushes the result on top of the stack (8)
  • Push 8 on top of the stack
  • OP_EQUAL pops the 2 layers ( 8 and 8 ) out of the stack
  • OP_EQUAL returns true as both are the same and pushes boolean TRUE on top of the stack

Exercise : what solves the Locking Script: OP_ADD 2 OP_MUL 1 OP_ADD 11 OP_EQUAL

2 3 solves it as 2+3=5, 5*2 = 10, 10+1 = 11 and 11 = 11

Standard Script Notation

Let’s discuss standard script notation using this example, <sig><pubKey> OP_CHECKMULTISIG

  • Bracketed values are data to be pushed to the stack.
    • For example, <sig>.
  • Non-bracketed words are opcodes.
    • For example, OP_CHECKMULTISIG
  • Sometimes you may see the OP prefix omitted.
    • For example, <sig><pubKey> OP_CHECKMULTISIG may be abbreviated to <sig><pubKey> CHECKMULTISIG

Raw transaction review

Transactions in the bitcoin blockchain are stored in a double-hashed form.

This means the raw transaction was put through SHA256 twice to get the Transaction hash we see on the blockchain.

Creating our own transactions

In bitcoin core you can check what are your UTXO by going to the debug console and submitting “

listunspent

This will give you an array with all your UTXO available :

{
    "txid": "d734dc6ea4671c59a6d8812116b2d81a5e17d52643632a42922ee12acea015ba",
    "vout": 0,
    "address": "2Mtn8V5jEVqFt4rHMPT3iz3mD9ifpbNFzpf",
    "account": "testos",
    "redeemScript": "00144da8f0da450db4d2f36e0ef806a270256f2004c3",
    "scriptPubKey": "a91410d06d30fc863d1102ecb0a21e096e8442eb6f5087",
    "amount": 1.00000000,
    "confirmations": 89,
    "spendable": true,
    "solvable": true,
    "safe": true
  }

To get the details of an unspent output we found we can use :

gettxout "txid" n

Arguments:

  1. “txid” (string, required) The transaction id
  2. “n” (numeric, required) vout number

In my case :

gettxout d734dc6ea4671c59a6d8812116b2d81a5e17d52643632a42922ee12acea015ba 1

Output from the debug console :

{
  "bestblock": "000000000000001cd2209e5c782e11817b6c89f92ade89c389d0977100b6f48b",
  "confirmations": 91,
  "value": 950.99991904,
  "scriptPubKey": {
    "asm": "OP_HASH160 785da4798d821dc5a63a49d1b1928a8eb8673f2b OP_EQUAL",
    "hex": "a914785da4798d821dc5a63a49d1b1928a8eb8673f2b87",
    "reqSigs": 1,
    "type": "scripthash",
    "addresses": [
      "2N4DfFhPVzvv6oZky1fEo7WSZFphvWucvQq"
    ]
  },
  "coinbase": false
}

Now let’s construct our very own transaction :

createrawtransaction '[{"txid":"TXID","vout": VOUT}]’’{“to_address”:amount1, “from_address”:amount2}’
txid: d734dc6ea4671c59a6d8812116b2d81a5e17d52643632a42922ee12acea015ba
it's the txid of one of our unspent outputs

vout: 0
index in the unspent output

to_address: 2MxkhhvQ6T5dtc97f8PdLDK7tZeqGLH94sf
receiving address

from_address: 2Mtn8V5jEVqFt4rHMPT3iz3mD9ifpbNFzpf
sending address

amount1: 0.01 BTC being sent to "to_address"

amount2: 0.98 BTC being sent back to the "from_address"

Sum(Inputs) - Sum(Outputs) = Transaction Fee
1 - 0.98+0.01 = 0.01

The transaction is therefore :

createrawtransaction '[{"txid": 
"d734dc6ea4671c59a6d8812116b2d81a5e17d52643632a42922ee12acea015ba", "vout":0}]'
'{"2MxkhhvQ6T5dtc97f8PdLDK7tZeqGLH94sf":0.01, 
"2Mtn8V5jEVqFt4rHMPT3iz3mD9ifpbNFzpf":0.98}'

It was a pain to make it work as the quotes and double quotes have to be in a specific format but in the end it worked ! I have my hex string :

0200000001ba15a0ce2ae12e92422a634326d5175e1ad8b2162181d8a6591c67a46edc34d70000000000ffffffff0240420f000000000017a9143c6bd45ca694f17ff66b59ab0b7b7150daa27dcf87805cd7050000000017a91410d06d30fc863d1102ecb0a21e096e8442eb6f508700000000

The transaction is not yet broadcasted to the network though

Decode Raw Transaction

You use the decoderawtransaction command in the debug console with the previous hexstring :

decoderawtransaction "0200000001ba15a0ce2ae12e92422a634326d5175e1ad8b2162181d8a6591c67a46edc34d70000000000ffffffff0240420f000000000017a9143c6bd45ca694f17ff66b59ab0b7b7150daa27dcf87805cd7050000000017a91410d06d30fc863d1102ecb0a21e096e8442eb6f508700000000"

and you get all the info you need concerning your transaction :

{
  "txid": "f64e780637243139770ed40f16487bd9d688a5967c39e97c1560622ba7a0c08f",
  "hash": "f64e780637243139770ed40f16487bd9d688a5967c39e97c1560622ba7a0c08f",
  "version": 2,
  "size": 115,
  "vsize": 115,
  "locktime": 0,
  "vin": [
    {
      "txid": "d734dc6ea4671c59a6d8812116b2d81a5e17d52643632a42922ee12acea015ba",
      "vout": 0,
      "scriptSig": {
        "asm": "",
        "hex": ""
      },
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 0.01000000,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_HASH160 3c6bd45ca694f17ff66b59ab0b7b7150daa27dcf OP_EQUAL",
        "hex": "a9143c6bd45ca694f17ff66b59ab0b7b7150daa27dcf87",
        "reqSigs": 1,
        "type": "scripthash",
        "addresses": [
          "2MxkhhvQ6T5dtc97f8PdLDK7tZeqGLH94sf"
        ]
      }
    },
    {
      "value": 0.98000000,
      "n": 1,
      "scriptPubKey": {
        "asm": "OP_HASH160 10d06d30fc863d1102ecb0a21e096e8442eb6f50 OP_EQUAL",
        "hex": "a91410d06d30fc863d1102ecb0a21e096e8442eb6f5087",
        "reqSigs": 1,
        "type": "scripthash",
        "addresses": [
          "2Mtn8V5jEVqFt4rHMPT3iz3mD9ifpbNFzpf"
        ]
      }
    }
  ]
}

We have rightfully one input and two outputs, with the sending of 0.01 BTC and the change coming back

Now we need to sign the transaction as the scriptSig is empty

Sign Raw Transaction

To sign the transaction we will use the command

signrawtransaction "hexstring"

So in our case :

signrawtransaction "0200000001ba15a0ce2ae12e92422a634326d5175e1ad8b2162181d8a6591c67a46edc34d70000000000ffffffff0240420f000000000017a9143c6bd45ca694f17ff66b59ab0b7b7150daa27dcf87805cd7050000000017a91410d06d30fc863d1102ecb0a21e096e8442eb6f508700000000" 

You get a hexstring in return, now if you decode it again you should find your signature inside :

decoderawtransaction "02000000000101ba15a0ce2ae12e92422a634326d5175e1ad8b2162181d8a6591c67a46edc34d700000000171600144da8f0da450db4d2f36e0ef806a270256f2004c3ffffffff0240420f000000000017a9143c6bd45ca694f17ff66b59ab0b7b7150daa27dcf87805cd7050000000017a91410d06d30fc863d1102ecb0a21e096e8442eb6f508702483045022100ec94c33593757d8b426f207a493cd143841ce6603afec37def4e7eea649a168002206a535c3c78e5cea0d45dea7d3d0fbd55920b2cac58f3bf445f06677824c061d1012103b668f6dd4bfedbeb776bb4478315b6efe8e6ccade6f47f569f52a7c9080e27cf00000000"

And done ! Now we need to broadcast the transaction

Broadcast signed transaction

To do so we will use the sendrawtransaction command, using the SIGNED hexstring.

sendrawtransaction "02000000000101ba15a0ce2ae12e92422a634326d5175e1ad8b2162181d8a6591c67a46edc34d700000000171600144da8f0da450db4d2f36e0ef806a270256f2004c3ffffffff0240420f000000000017a9143c6bd45ca694f17ff66b59ab0b7b7150daa27dcf87805cd7050000000017a91410d06d30fc863d1102ecb0a21e096e8442eb6f508702483045022100ec94c33593757d8b426f207a493cd143841ce6603afec37def4e7eea649a168002206a535c3c78e5cea0d45dea7d3d0fbd55920b2cac58f3bf445f06677824c061d1012103b668f6dd4bfedbeb776bb4478315b6efe8e6ccade6f47f569f52a7c9080e27cf00000000"

You could also add an additional parameter called allohighfees, but I just kept it simple and used the by default “false” by not indicating it in the command.

And Voila :

If the submission went through, we are returned the transaction hash (txid) in hex of the raw transaction that was submitted to the network. Looks good! In our case :

b70acf77e2cc345e82b0c5b27278549bcad14f908a904be2e8a6c8b484286603

Query the Transaction

You do it by using gettransaction command :

gettransaction "b70acf77e2cc345e82b0c5b27278549bcad14f908a904be2e8a6c8b484286603"

And.. you get your information :

{
  "amount": 0.00000000,
  "fee": -0.01000000,
  "confirmations": 0,
  "trusted": true,
  "txid": "b70acf77e2cc345e82b0c5b27278549bcad14f908a904be2e8a6c8b484286603",
  "walletconflicts": [
  ],
  "time": 1620756628,
  "timereceived": 1620756628,
  "bip125-replaceable": "no",
  "details": [
    {
      "account": "",
      "address": "2MxkhhvQ6T5dtc97f8PdLDK7tZeqGLH94sf",
      "category": "send",
      "amount": -0.01000000,
      "label": "Maximator",
      "vout": 0,
      "fee": -0.01000000,
      "abandoned": false
    },
    {
      "account": "",
      "address": "2Mtn8V5jEVqFt4rHMPT3iz3mD9ifpbNFzpf",
      "category": "send",
      "amount": -0.98000000,
      "label": "testos",
      "vout": 1,
      "fee": -0.01000000,
      "abandoned": false
    },
    {
      "account": "Maximator",
      "address": "2MxkhhvQ6T5dtc97f8PdLDK7tZeqGLH94sf",
      "category": "receive",
      "amount": 0.01000000,
      "label": "Maximator",
      "vout": 0
    },
    {
      "account": "testos",
      "address": "2Mtn8V5jEVqFt4rHMPT3iz3mD9ifpbNFzpf",
      "category": "receive",
      "amount": 0.98000000,
      "label": "testos",
      "vout": 1
    }
  ],
  "hex": "02000000000101ba15a0ce2ae12e92422a634326d5175e1ad8b2162181d8a6591c67a46edc34d700000000171600144da8f0da450db4d2f36e0ef806a270256f2004c3ffffffff0240420f000000000017a9143c6bd45ca694f17ff66b59ab0b7b7150daa27dcf87805cd7050000000017a91410d06d30fc863d1102ecb0a21e096e8442eb6f508702483045022100ec94c33593757d8b426f207a493cd143841ce6603afec37def4e7eea649a168002206a535c3c78e5cea0d45dea7d3d0fbd55920b2cac58f3bf445f06677824c061d1012103b668f6dd4bfedbeb776bb4478315b6efe8e6ccade6f47f569f52a7c9080e27cf00000000"
}

Steps and Commands Used

  • Step 1 – View all unspent confirmed UTXO in the wallet
    • listunspent – Show all the unspent confirmed outputs in our wallet)
  • Step 2 – View Details about a Specific UTXO
    • gettxout – Get the details of this unspent output above
  • Step 3 – Create a Raw Transaction
  • Step 4 – Decode the Raw Transaction (to double-check it went through correctly)
  • Step 5 – Sign the Raw Transaction
  • Step 6 – Submit the Raw Transaction to the Network
    • sendrawtransction – Takes the raw hex string produced by signrawtransaction and returns a transaction hash (txid) as it submits the transaction on the network.
  • Step 7 – Query the TxID of the Transaction we sent
    • gettransaction – Query the TxID and view details. Similar to online block explorer

Bonus : store a message in a transaction

createrawtransaction '[{"txid":"b70acf77e2cc345e82b0c5b27278549bcad14f908a904be2e8a6c8b484286603","vout":0}]' '{"data":"5041442065737420756e206e61766574","2Mtn8V5jEVqFt4rHMPT3iz3mD9ifpbNFzpf":0.00100000}'

So basically I selected one of my unspent outputs, and added “data” and a hex code inside that is an insult to my brother. Haha. Last part is the address where to send the change back. Sign it, broadcast and Voila. Check it out :

https://www.blockchain.com/btc-testnet/tx/726bd86675a711481e4d4807e686def2eaa8858773c95d6875d9da1b23cc577a

  • Tutorial for that part : https://medium.com/@CoinCapsAi/live-forever-on-the-blockchain-bf70368c13
  • Text to Hex : https://www.online-toolz.com/tools/text-hex-convertor.php

And here is another one :

https://www.blockchain.com/btc-testnet/tx/0917c92df9f76157204e8ea0e98e008b5f3a99f210d14510321e65a9d92d8be8

I will probably do a tutorial just for this part at some point

Lesson 5 : Private Blockchains

Creating your own Private Blockchain

//Node package manager initialisation
npm init 

//It produces a Json that you can reuse as a template in other projects 

{
  "name": "project_2",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

Now we want to create our own data model, so we will first open an “example” block from the testnet :

{
   "hash": "000000000000e198e04b0759cfecd59a95604cc551db9ad3b12a290375a95419",
   "confirmations": 1,
   "strippedsize": 35904,
   "size": 50974,
   "weight": 158686,
   "height": 1325438,
   "version": 536870912,
   "versionHex": "20000000",
   "merkleroot": "1ba2204e76ed33d9133b4edc43519efd7d6b23fd135a0b8758cc4e2caaddc789",
   "tx": [
     "c0aadcbbc4b95f0684d715cc5692e9cd4608d4f9ba646509bdd28f3201f9a98f",
     "5320c80b1e1a7059cf7c3dadef46feaa440dd913091bb068f5eb42e76ca88158",
     "9e3839f97fa4dad2ad46f25141c738928ba92b8ec220a2b91fa7bfeb3a0ab5ec",
     "48b9fc36f82052bf6a35763133ea571b81251e00f7ad551feb03d0b07f98ed1a",
     "8eea305a4da52b4b069f5ddfab08760741f800bcc7020f58b690fd2851de7b1e",
     "8704dc1b0149a84815a005c1114bfccc1d2fd0dc19d38dfdc7b896829b167227",
     "8c244f85af996d158174f46b31b2fa0178eba62fe9b87b7e22259c5e110dd129",
     "a5ce6c4e6255eba488485e8ae87d9361a61625f7a1f8a0fe9cdd42fd2774e82f",
     "fc96f7299f6a0d2bdbfaf8f90f661f35e9154b43d8006d57bd2e6de94a40e530",
     "ceaaccdb563249d9677775ce235cf270e51cea81567d5b28f4051dfc2ef34a37",
     "ed2d25ecd5c39a35d877e1633ced7bff278eba3cd4f20ed0d716188445575242",
     "d3b1ecc04e3ec816355ec3056862dd5c82cc6e5e4362111ca591ae9184dbee5a",
     "1083d2b17d0a5b3510267bfa2657e81e9afaeb741d5be0d96b89de638ba1db69",
     "ca3d6098ed9942d2253abd372e01747fe2955a2c8cfab3905f4255e31284147d",
     "13acea9095a78ba30d71660c766f2e9ebf53d2cc280f9bd160ec96b98fb60083",
     "13996f40720bbcd3472d61bf8bdbfbd7783d3020a53be8e633b94297a96d7786",
     "57b1cd7b5d1cfd3570795602fc421f07bbaace89b31d9d8e9974c112f93c0ea4",
     "34542b2aa99df77667daf5972dca5f18a8529664e863ade9729fdffc2807c5a5",
     "985dce57073c1fed90f908ff556136f8462a8e72225fda259eec508c723775a8",
     "5adddbaf00261de26ea499a07e6c9084b198209615064e558a04d65290e03aaa",
     "c467bd8272efe2836e320ebae8f1dacba6360d29685afa9a6225e65c8229acae",
     "f13e9f3be16ea2186a07492676a781b97c922e08d1aba2e150ab6586a88addae",
     "c6e6b850d63e32fc9aed2aa326b2a4ae186cfd20a3a7f98d656a4e6aa698e9c6",
     "3a5dfebf61c0125968b89e86ae72cbdcd98eb38337ed37591ae410c26a19d9ca",
     "5d4007a80af2ed82e504002c1ad7a6be2ca8844017db1b18e9e7942c7a69f0d2",
     "2dba5b95ea6fae0b6404377647556489f57e5da709f2afdd320252c7f07bcadc",
     "aa28ee73856412bb880f6f8b519a98df3f2a274c58a184c97485310597a033df",
     "ed702e8b831ee5cb77d1c6fc1e092b010ad81be29f422276177d9d252a89e9e8",
     "b3a8cf97b486690632a3889ac18d6c160574226978f84575fe73a33f980bff49",
     "fd1c98dfa98bb446c08326007d8b26864f132843808ceb10fbec25c4d5c5347f",
     "7fc87546d97d61776e6421a7d646b8e1c47bece2d10e01054eaee2e7faedae87",
     "2f87d9488d09246d52b9e9a11183819002b4e6e87f57d434f66a89157b082424",
     "2028b1a2a6b069f02ef626a13133bf104056c91c54ba1bf8d56b0fcce0e2cb1d",
     "225ca48a094a16edcac6b82c7c38b08ff845f345f3c07b990fcba21eb8d84a78",
     "fda48e5eb45a788c8df47a67732e8fcc21f0545fd7082606a540ad8b995def78",
     "b633b2a735e99d170a5c6e631ecff86c3db1c2daabd7e4186d2a6774c80753dc",
     "d10cd9b6251ebd33a818978cb2aedd370393f632f89873dfd0252ad465169ee8",
     "102fe18d681dbf5aedca0b65ade6d4fb4e2275f4cb6a09d91215e2c4c68b5f6f",
     "5bce1ce91cf9b5a9fda5fe807a0c4729bab7e32f709d9864d1c8cbecec6667e8",
     "9cb5a9f6e3d24bd58d71ecdf9ce4fcbd568e4d6facae6ac89150c8e32cebd2da",
     "a3f37cb7a16dd91b81ed13cc57ef3c6d36fecf864836c5952f5bd9d0a5c6023b",
     "0b3990891cfb3fbee7eccf1aa715fb1268d80a378d7f9feb55d84e506719b492",
     "6e29600ad19aec1e94d902bf87dc4ef06486e25dfc669c24a306c39f0ca33acc",
     "1e56daa297bad924bcc3888e95125292c35fa8a7e1bc155d4a2e2ce79e907d34",
     "69e4c1b68a8d9ff78ecc73d43e513c521f89bc7d4877b21dc844987e932e803b",
     "8db996643a6da86a839d65dc3876d712227728a768057ffc5c5c01edaed0c42f",
     "9135e09134c00d6887852e963a719b3b12486355c3ff9ba5eb00caafb1841a96",
     "0b9023c0b47db5d436fd990913271c002a0139f5fa2704f363f2e953a3bdc748",
     "34b6687d9bb7990c4d41312db93ec8f2299bb8097a3e3e0214a0191761a7532e",
     "58e57779fb981ddbc0a4f077aa7e274473ba90651330306b3ed8f8d2f69fc1a8",
     "26f10ff1318b6b40f437e216aadb250ddb82c7778b079d3d7ccac1b0df91d9d3",
     "12a6f68fd821b426732ef6219551554c18b45ec271398835986505c4ed8e92e8",
     "232e411b624aa09e04a09a29e761a385ace952115cf6ae02e8aa1c8eaba68c1e",
     "7ab379952c659e7a04bedd8c18b3d3603820690588e830080a561220a563bf4a",
     "b0727822a001936925f584a66c5211e7ebd4c03c255bc39f29f0bbc1bb737512",
     "ab7efc87165efdc8e3e2b58dfc81796b906114eb3bc67b1b2057924e3141ed35",
     "422f59e4b944601d74500e5fd8f7bd9f1869658985b5ac3953313ce4d90802c1",
     "d8fb6b45c5a2a9012ab530f8a1c940200fd1b1b6caecb05371f50d27e8050231",
     "de910d1be5dffa9a5b6d4b71a7e7246fa61a999d5a1fb6690b12b2a1f7456789",
     "398511252828e95daeae944537c19884008979172aae1e210b8ad84f8f2de039",
     "8f764c70b885c7c402f78995b85506af63a5b7d9b17e5db06a8bb81b9fb9a6aa",
     "243f71604446c2d9fcead119af8989c8340f2f1ae0cbcaaaa78beb7bb7ebcdcc",
     "7163c1903b8b70e9da6970e5777e6e7827896dc9b6bb36243a62f450efea9665",
     "1fb9e2fdb00a4e446e208f0342071ecd06c979a5d35cc17036d9aa41ca2ff205",
     "a095ad8671bcd32a21ebb4202f39a757ed572e522f10d608b6d03f4e12fb1326",
     "e82cce884bbdf9e789cda3bc90d601b7cb65ba35706175d7aefea5b30143402d",
     "e6acfaaa6f1b8237cc08a407ae81a1e6e960bdcc4c0e5a57293d61f6169ccca8",
     "983d31b1711f574dccff920b05090ab0eadc51f450b4d65562cd506b59e7d8e9",
     "337738e6ad6214f0f7a9fb198a11df09f0700757968f3a65bca8d934a7b8b518",
     "3fe05fe948c0c253d3c070c303239ab75d952472b1a3c2fd684e4bc67cb5340e",
     "6ab92b02bde97cc4933fec9161a923f01144a08ba527b2e7b49038d918f1a27b",
     "b5fb8c5e6fab18af112fdac768adbf2a66920d2da608f6b6abe5ddfea0afa6e0",
     "18e2ae545619fbe84b0d165c65c629aa7544d04eeaa4b9e178555edf99ab83fb",
     "372d3fe365045d8c5cfc3ceb4a20edbf2ccc81eabfd76e3f9c5f89c6a39e70f0",
     "6f677e257860d4f7b4b81ede0d86976fceb10b1c4565743cc8321e936e55a5ec",
     "bc15c712c4ee7e9cc21adcddf71b3583ca4d2bab0a8776d502e945df55dfafa1",
     "f415b2285f9c852666488bfc16b703f8462d273331dbe718fd492521ecfa9936",
     "73a569e7b32335447ed50e35d42d02519c68f5df261b13c9361dd2127913903e",
     "7cf5be42d07d430e5ba5f191c0257097d8971d20b92f1d67a806188d2b139b53",
     "215a5f69da67329e5f23cdfdf7300fe4488038344f803a441d7a4916b2b7d7d6",
     "76bda879782b7808de4dd2fc0ed23486957ef651a47f16a6ca34d78cb648302a",
     "c7dc07aff10c822cf178ab90888a1e6a48dd3619a4c167b1ba04f02638c3cbe9",
     "34f951c94d3d59d53e613369c0cb574eb9c01aecea91bc54ffe103a1227441f3",
     "4b28d9e3930fedd7e08d4a86691955d21fb4b3d5e67ab576ad491b8f58d869b7",
     "af9c154081c9d563e9e5de445ca9977e6cc700513ce746c8791778bc3ef82d75",
     "4cbc89a2c255163d22856b8938bc8a5c381fa1f3e7ea5542efd4879eb17aba27",
     "953a932c4a9b0635e1844aa6bde4bec2150c126f103fefe5c617048d4dc55770",
     "788fcf7932de1116d7142e1b49eed855343fb9c55fc733b772c96f2ce358fbfb",
     "8053e6cc66d8b45df7fa4732d8bfb48534553fd9d812dd8a9fc41a54f340ae34",
     "e516a61bf729fcab9f7d1f2a32f4e231dc299131759ea06185ea860c650c0bab",
     "189669a3254805acb40c7c42ef4414b6f070320b1763a6566b9ebead9e9435c7",
     "5765173d4b18bbed38a19d46285d260e64ef60fb3c3bc076ff7d1d5f24d97ac4",
     "5d18e903283d16e938a2e11b99833e18852676ade10e06189dbb4e511397592b",
     "6f400328bcab9b5a11409b9b1a6aeaced32ae013735c9c362b4ee3f293663c9c",
     "82b6a243d240fdf9997d991f42329d79a76758709fd5f61219f2a8c261ce4c9c",
     "0126442304021b20c5b45aa26b77770afae343089c0564af1271b965781794fe",
     "d990f92e986dc26ecd6f1c26d6d5da1f60882eec14b5f1a9c83b9d70ee008ea4",
     "22c7e295b135d02f1754f7fd864319575c790c994b7c15441ffee3916fb61f57",
     "8e726bfde6374be0b5ec3ff658fb8c55dab605e021e22028db914383c71737a9",
     "bc731f07e036293030244fd540f190fd3f45e58ebafcb60642cad07a71ba9efd",
     "de48ce556e34340cd90bdcd7cb297bb3d8df8c06f957adb1172c6b1c988b7711",
     "bc628b5913a3f5eff9163441bac425ca19ecf80d8486655b5d9856c9a97d4242",
     "bd13a6cb30f3f05a77b17145c046712c74034a5ab3c92393a5b054cfac2e7872",
     "249d188191b0e97f2b7352d8dceb641a420a36e381fdef1dc9fc321c2e5bc4eb",
     "d5b03241fb090e9767c929ab7658e54d83ad4fee98a078a880ab10bbb791b20e",
     "9056c1d57a6b1b90f37a4a0c0d9b03344aae23a49c81c47a4a07ad1cc5c1cc22",
     "1738b3e0814ebb77fa7200cc522ab2cc606de8d2d500b628f30eab69cbb9a392",
     "aa60b3be7a582eff8d228d4f1eb55c22b996af30c42af2b284c2b3bbf4ae59be",
     "b125e0cb3d7287e0cc408014381959258dcbee18262c9238b539f00674a275d1",
     "edd92657684da60985fc0529abf571c263dcfac46c1242d2ea7841feb073e626",
     "d39a18ba10325eeb2cbd24eda846c6684fcc9b6ee1261431bbb5d0ffc29c342d",
     "1dea88e363ce7340ec26accee247d744b2ada723df1c2674c4c28d15ceb2de38",
     "0cf792e76391aad470710014a25f344dc799e261da720b5e2c20fb9bc8902b3a",
     "72dc3c07ca4c0824832c841bdccb6d1b1b70e8912dc1c30dd37957ee5d4e5d3b",
     "a3219685fc349f5039e082524650e509b3c52ec286fd3137e69083b860c66c48",
     "68664782b3647ee46c9021cb555859610c4ec5d44a0fc7c452debd339ad7dd5a",
     "4976fed47d535d4309569e0f3a96086f1f87ca43974c223e639105d49b72b05d",
     "bcb9c0434af572f2a373c78ad380c6ace3e8e1ddecce299eda13b2ce216d7b6b",
     "a046f06b3f8f6e99c2f624be672495733336f972d25d0dcb9ee308413a0b9f8f",
     "ade7a8828ac5cbeb512ee0800641147482359e24f91fa49a3f88ee944dbda3b7",
     "d248bd5d58d675912474d9b8c5e385a8eeece73c1ed0f7e00957905e9dd2fda0",
     "726793a0aec81cdf136ded30fbee5115f763d9442fabb14d91f3b8b82ce2efc4",
     "f92e6c78e5466c89821e719fe8decaa6b0a368432fb7f165412b3031dc6015e7",
     "a027eb58357d1606ce0d29050783736c400230d757cd14d7cd743a37bca56af9"
   ],
   "time": 1529001822,
   "mediantime": 1528996432,
   "nonce": 52797352,
   "bits": "1d00ffff",
   "difficulty": 1,
   "chainwork": "00000000000000000000000000000000000000000000004fae26c297c2d2af07",
   "previousblockhash": "00000000af61e2a9b09936dad3f5f213a8f659c5845d142b71894b4d5e5e17da"
 }
//Create a new file called notes.txt 
touch notes.txt 

//we then copy the content from the example block above in our notes.txt and delete what we don't need 
//There we go : 

{
   "hash": "",
   "height": 0,
   "body": [
   ],
   "time": 0,
   "previousblockhash": ""
 }

There we go, now we need a class to create new blocks.

//Create new js file
touch simpleChain.js

//then we put inside : 

/* ===== Block Class ===================================
|  Class with a constructor for block data model       |
|  ====================================================*/

class Block{
	constructor (data){
     this.hash = "",
     this.height = 0,
     this.body = data,
     this.time = 0,
     this.previousblockhash = ""
    }
}

//now we can enter node by typing node in the terminal and test it :

> new Block("Some Data")

Block {
  hash: '',
  height: 0,
  body: 'Some Data',
  time: 0,
  previousblockhash: '' }

//It works ! 

We now create a new blockchain class with a constructor to store data within the chain array. Then, we created the addBlock function to push the newBlock to the chain.

// in the same simpleChain.js 

class Blockchain{
	constructor(){
      this.chain=[];
    }
	addBlock(newBlock){
      this.chain.push(newBlock);
  }
}

//and then in the terminal : 

> class Blockchain{
...       constructor(){
.....       this.chain=[];
.....     }
...       addBlock(newBlock){
.....       this.chain.push(newBlock);
.....   }
... }
undefined
> let blockchain = new Blockchain()
undefined
> blockchain.addBlock(new Block('test data'))
undefined
> blockchain.chain
[ Block {
    hash: '',
    height: 0,
    body: 'test data',
    time: 0,
    previousblockhash: '' } ]

Now we want to link the blocks together using hashes

To setup the crypto-js library, in the terminal we used:

npm install crypto-js --save

In simpleChain.js,

  • Configured crypto-js library
  • In Blockchain class, modified constructor to included new genesis block
  • Modified addBlock function to include generation of our block hash.
// The script 
const SHA256 = require('crypto-js/sha256')

class Block {
  constructor(data){
    this.height = '';
    this.timeStamp = '';
    this.data = data;
    this.previousHash = '0x';
    this.hash = '';
  }
}

class Blockchain{
    constructor(){
      // new chain array
      this.chain = [];
      // add first genesis block
      this.addBlock(this.createGenesisBlock());
   }

  createGenesisBlock(){
    return new Block("First block in the chain - Genesis block");
  }

// addBlock method
  addBlock(newBlock){
    if (this.chain.length>0) {
      // previous block hash
      newBlock.previousHash = this.chain[this.chain.length-1].hash;
    }
    // SHA256 requires a string of data
    newBlock.hash = SHA256(JSON.stringify(newBlock)).toString();
    // add block to chain
    this.chain.push(newBlock);
  }
}

//And in the terminal : 
> let blockchain = new Blockchain();
undefined
> blockchain.addBlock(new Block('test'));
undefined
> blockchain.chain
[ Block {
    height: '',
    timeStamp: '',
    data: 'First block in the chain - Genesis block',
    previousHash: '0x',
    hash: '2b531ce3be7127c3bc382c13fdb20c73c5f711489b75698934f789be11f78a5f' },
  Block {
    height: '',
    timeStamp: '',
    data: 'test',
    previousHash: '2b531ce3be7127c3bc382c13fdb20c73c5f711489b75698934f789be11f78a5f',
    hash: '72adeb61f9d6339e5272778bf9bfbc83770be01bb299fe6f2129b2f5e5aff407' } ]
> blockchain.addBlock(new Block('test 2'));
undefined
> blockchain.chain
[ Block {
    height: '',
    timeStamp: '',
    data: 'First block in the chain - Genesis block',
    previousHash: '0x',
    hash: '2b531ce3be7127c3bc382c13fdb20c73c5f711489b75698934f789be11f78a5f' },
  Block {
    height: '',
    timeStamp: '',
    data: 'test',
    previousHash: '2b531ce3be7127c3bc382c13fdb20c73c5f711489b75698934f789be11f78a5f',
    hash: '72adeb61f9d6339e5272778bf9bfbc83770be01bb299fe6f2129b2f5e5aff407' },
  Block {
    height: '',
    timeStamp: '',
    data: 'test 2',
    previousHash: '72adeb61f9d6339e5272778bf9bfbc83770be01bb299fe6f2129b2f5e5aff407',
    hash: 'e6c48f272db1f1b6f2df027dd16bf4852712e7e2d0c28084dab29941042530a9' } ]

It works ! Now we want to add block height and the timestamp in the addblock section. We modify our addBlock function to include block height within our newBlock object. In addition, we configure our newBlock object to include a timestamp in UTC format.

const SHA256 = require('crypto-js/sha256')

class Block {
  constructor(data){
    this.height = '';
    this.timeStamp = '';
    this.data = data;
    this.previousHash = '0x';
    this.hash = '';
  }
}

class Blockchain{
    constructor(){
      // new chain array
      this.chain = [];
      // add first genesis block
      this.addBlock(this.createGenesisBlock());
   }

  createGenesisBlock(){
    return new Block("First block in the chain - Genesis block");
  }

// addBlock method
  addBlock(newBlock){
     // block height
    newBlock.height = this.chain.length;
    // UTC timestamp
    newBlock.timeStamp = new Date().getTime().toString().slice(0,-3);
    if (this.chain.length>0) {
      // previous block hash
      newBlock.previousHash = this.chain[this.chain.length-1].hash;
    }
    // SHA256 requires a string of data
    newBlock.hash = SHA256(JSON.stringify(newBlock)).toString();
    // add block to chain
    this.chain.push(newBlock);
  }
}

And.. voila ! done, we are adding blocks with timestamp and height :

> let blockchain = new Blockchain()
undefined
> blockchain.addBlock(new Block('test'));
undefined
> blockchain.addBlock(new Block('test 2'));
undefined
> blockchain.chain
[ Block {
    height: 0,
    timeStamp: '1620828978',
    data: 'First block in the chain - Genesis block',
    previousHash: '0x',
    hash: '46c388cf0185350b060f3c28b01d011468cfb91961a55b3339971afd520ac269' },
  Block {
    height: 1,
    timeStamp: '1620829003',
    data: 'test',
    previousHash: '46c388cf0185350b060f3c28b01d011468cfb91961a55b3339971afd520ac269',
    hash: '01586ded5a1a99acdef910b586e88f86aabee3345ac9c78ad3d82d8535ae2005' },
  Block {
    height: 2,
    timeStamp: '1620829007',
    data: 'test 2',
    previousHash: '01586ded5a1a99acdef910b586e88f86aabee3345ac9c78ad3d82d8535ae2005',
    hash: '9f129fe787ca071dcb39872a38b9f196b4cef1352b48710062aac85d66104cba' } ]
> 

Lesson 6 : Digital Assets

  • Digital Asset – Digitally stored content or online account owned by an individual
  • Encode – Process of putting a sequence of characters into a specialized format for efficient transmission or storage
  • Decode – Takes encoded, raw, unreadable files and converts them back into human readable format
  • ASCII – American Standard Code for Information Interchange
  • Hexadecimal – More concise and human readable representation of binary
  • Base64 – Encoding scheme meant to represent data as numbers in a string format

Encode and Decode Text from Terminal

  • String to hex: xxd -p <<< "Blockchain Developer"
  • Hex to string: echo 426c6f636b636861696e20446576656c6f7065720a|xxd -r -p

Encode and Decode Text from Terminal Using Files

  • Create file: touch hello.txt
  • Add text to file
  • String to Hex: xxd -p hello.txt helloEncoded.txt
  • Hex to String: xxd -p -r helloEncoded.txt helloDecoded.txt

Encode and Decode Image from Terminal Using Files

  • Find image file and place in directory
  • Image to Hex: xxd -p cat.png cat.txt
  • Hex to Image: xxd -p -r cat.txt catDecoded.png

Do it yourself :

// Require file system access
fs = require('fs');

// Read file buffer 
imgReadBuffer = fs.readFileSync('test-pattern.jpg');


// Encode image buffer to hex
imgHexEncode = new Buffer(imgReadBuffer).toString('hex');


// Decode hex
var imgHexDecode = new Buffer(imgHexEncode, 'hex');


// Output encoded data to console
console.log(imgHexEncode);

// Save decoded file file system 
fs.writeFileSync('decodedHexImage.jpg', imgHexDecode);

The image used :

By running this, you should see the Hex outpout in the console + creation of a new image as well built by decoding the Hex.

Proof of Existence

Proof of Existence: The concept that publicly proving and authenticating any digital asset on the blockchain by verifying its hash.

How POEX Validates Digital Assets :

  • Step1 : Digital asset is hashed via sha256
  • Step2 : That hash is appended to an identifier (i.e : 0x444f4..)
  • Step3 : The hash + identifier is put into a generated Transaction
  • Step4 : The Tx is marked with OP_RETURN so it’s unspendable

Why do we need POE

Helps you demonstrate data ownership without revealing actual data.

  • This is useful for things like copyrighted material or patents.

Checks for the integrity of your digital asset. Any proof of existence will recognize your document FOREVER.

  • Even the slightest difference will be recognized allowing you to be sure your asset hasn’t changed.

Provides document Time stamping. You can use this to prove certain information existed at a certain time.

  • This can be useful in cases where you want to prove who was the original owner of the document.

Certifies the existence of the document without the need for a central authority.

  • Similar to many blockchain concepts this decentralized proof can’t be erased or modified by anyone.

POE Algorithms

There are a bunch of different algorithms to demonstrate Proof of Existence. The two we have chosen to focus on here are SHA256 and MD5.

They both serve the same purpose. They’re a way to hash a digital asset so it can be embedded in a transaction in the blockchain. This allows people to verify that a document existed at a certain point in time.

SHA256

This is an algorithm we’ve seen already in several different parts of the Bitcoin network. It’s used in mining as part of the proof of work algorithm.

It’s also used to create secured bitcoin addresses.

SHA256 stands for Secure Hash Algorithm. It is a one-way hashing function that takes in any piece of data and produces a unique hash.

This is the algorithm POEX uses to secure their digital documents.

MD5

Next, the MD5 algorithm is a hash function that takes in a String input and produces a 128-bit hash value. This value is usually shown as a 32-character hexadecimal number that humans can read.

Goals of POE Algorithms

While each method does things a bit differently, the important thing to remember is their purpose.

They hash digital assets to hide the actual content. Once the hashed data is embedded in a transaction in the blockchain, the existence of that transaction in the blockchain proves that the document existed at the time the transaction got included into a block.

Do you need a blockchain ?

here are some helpful questions to help determine if you really need a blockchain

Problem of Value Identification

  1. Is there a need to share information, credentials or value with others?
  2. Is trust a critical requirement to the process?
  3. Do you need to prove to others you are transacting/reporting accurately?
  4. Is there potential to monetize the data or digital asset in the value chain?
  5. Who owns the problem? Individual or industry wide challenges?

Stakeholders buy in

  1. Is there a network of stakeholders (i.e. more than 2)?
  2. Is there a dependency on others for information?
  3. Does more than one participant need to update the data?
  4. Is there scope to open up the ecosystem to ancillary parties in the future?
  5. Are you working with other industry players on any activities?

Technical considerations

  1. Is there any ongoing need or future requirements for high data throughput?
  2. Do you rely or use public data sources to make decisions?
  3. Do you need to store a particularly rich/complex data structure?
  4. Do you need to digitize assets in your value chain?
  5. Do you need transaction privacy? Do you need anonymity?

RESTful APIs with Node.js Frameworks

REST ( Representational State Transfer) Set of rules that defines guidelines based on the HTTP protocol

Framework : Set of tools and guidelines designed to support the development of web applications

it’s all about rules and guidelines. Why use a framework ?

  • Build rapidly (out of the box functionalities)
  • Access code that’s been built and tested
  • Help extend functionality to integrate with other suff

We will use :

Creating Hello World express application

Tools we’ll use

  • Expressjs.com for documentation
  • Your Local Desktop
  • A Terminal Window
  • Code Editor (I’m using VS Code)
  • Another Browser window (to view your application)

Create a folder for the project

Go to the folder in the terminal and type : npm init to create the package, accept default options

npm init

Create a new index.js file in the folder

in the terminal type : npm install express –save

npm install express --save

Copy paste into the index.js file :

//constant express that requires the express package
const express = require('express')
//
const app = express()

//Client makes a request, server makes a response
//send hello world to the application
app.get('/', (req, res) => res.send('Hello World!'))
//opens port 3000 
app.listen(3000, () => console.log('Example app listening on port 3000!'))

Run your code :

node index.js

You should now see : Example app listening on port 3000!

Open your browser and enter localhost:3000 in the address bar, there you go, the web app works :


Brax

Dude in his 30s starting his digital notepad