import * as express from 'express' ; import * as bodyParser from 'body-parser' ; import * as parseArgs from 'minimist' ; import Block from './blockchain/Block' ; import Transaction from './blockchain/Transaction' ; import Blockchain from './blockchain/Blockchain' ; const app = express ( ) ; const router = express . Router ( ) ; app . use ( bodyParser . urlencoded ( { extended : true } ) ) ; app . use ( bodyParser . json ( ) ) ; const args = parseArgs ( process . argv . slice ( 2 ) ) ; const port = args . port || 3000 ; const miner = new Blockchain ( ) ; const nodes = args . nodes ? args . nodes . split ( ',' ) : [ ] ; nodes . forEach ( node => miner . registerNode ( node ) ) ; app . post ( '/transactions/new' , ( req , res ) => { const newTransaction = miner . createTransaction ( miner . publicKey , req . body . recipient , req . body . amount ) ; const signedTransaction = miner . signTransaction ( newTransaction ) ; console . log ( `Created new transaction ${ signedTransaction . signature }` ) ; console . log ( 'It will be added to the list and broadcast\n' ) ; miner . addTransaction ( signedTransaction ) ; miner . broadcastTransaction ( signedTransaction ) . catch ( e => console . error ( e . message ) ) ; res . status ( 200 ) . send ( { message : 'Transaction created successfully' , transaction : signedTransaction , } ) ; } ) ; app . post ( '/transactions' , ( req , res ) => { const recievedTransaction = req . body ; const isValid = miner . validateTransaction ( recievedTransaction ) ; const isDuplicate = Boolean ( miner . pendingTransactions . find ( transaction => transaction . signature === recievedTransaction . signature ) ) ; console . log ( `Recieved transaction ${ recievedTransaction . signature }` ) ; if ( isValid && ! isDuplicate ) { console . log ( 'Transaction is valid, it will be added to the list and broadcast\n' ) ; miner . addTransaction ( recievedTransaction ) ; miner . broadcastTransaction ( recievedTransaction ) . catch ( e => console . error ( e . message ) ) ; } else { console . error ( 'Transaction is invalid or duplicate and it will be discarded\n' ) ; } res . status ( 200 ) . send ( ) ; } ) ; app . get ( '/mine' , ( req , res ) => { if ( miner . pendingTransactions . length ) { console . log ( 'Mining started...' ) ; const newBlock = miner . mine ( ) ; console . log ( 'Mining complete, new block forged\n' ) ; miner . broadcastBlock ( newBlock ) . catch ( e => console . error ( e . message ) ) ; res . status ( 200 ) . send ( { message : 'New Block Forged' , block : newBlock , } ) ; } else { res . status ( 400 ) . send ( { message : 'No Pending Transactions!' , } ) ; } } ) ; app . post ( '/blocks' , ( req , res ) => { const recievedBlock = req . body ; const isValid = miner . validateBlock ( recievedBlock ) ; const isDuplicate = Boolean ( miner . chain . find ( block => block . timestamp === recievedBlock . timestamp ) ) ; console . log ( 'Received new block' ) ; if ( isValid && ! isDuplicate ) { console . log ( 'Block is valid, it will be added to the chain and broadcast\n' ) ; miner . addBlock ( recievedBlock ) ; miner . broadcastBlock ( recievedBlock ) . catch ( e => console . error ( e . message ) ) ; } else { console . error ( 'Block is invalid or duplicate and it will be discarded\n' ) ; } res . status ( 200 ) . send ( ) ; } ) ; app . get ( '/chain' , ( req , res ) => { res . status ( 200 ) . send ( { chain : miner . chain , length : miner . chain . length , isValid : miner . validateChain ( ) , } ) ; } ) ; app . listen ( port ) ; console . log ( 'Hello from the Miner started on ' + port ) ; console . log ( 'My public address is: ' + miner . publicKey + '\n' ) ;