# SYD - TP Blockchain - Build Your Blockchain [Github](https://github.com/dreimert/BuildYourBlockChain/tree/etape-3) ###### tags: `SYD` `TP` ## Lancement Pour lancer un noeud, il faut au préalable créer un wallet à l'aide du CLI. ```bash node cli.js create ``` On rentre ensuite le nom du wallet ``` Nom du wallet ? (default) NomDuWallet Nom du wallet : NomDuWallet ``` On peut alors lancer un noeud et l'associer au wallet qui va le contrôler. On peut éventuellement préciser le numéro de port si un autre noeud est ouvert sur la même machine sur le port 3000. ```bash node noeud.js -w NomDuWallet ``` ## A deux (ou plus), c'est mieux ! Pour synchroniser les noeuds, il faut les lancer en leur donnant le même timestamp. On lance aussi le minage ```bash node noeud.js -w NomDuWallet -b 1 -m ``` Avec le CLI, on les ajoute mutuellement comme peers avec la commande addPeers ```bash node cli.js addPeer http://localhost:3001 ``` Le noeuds sont alors synchronisés. *NB: Les noeuds doivent être contrôlés par le même wallet* Modifications de ```noeud.js``` pour que la commande ```node cli.js mine <state>``` fonctionne. ```javascript= // # gestion des commandes authentifiées network.on('cmd', function (socket, cmd, callback) { cmd = Command.fromObject(cmd) if (cmd.user !== publicKey || !cmd.verify()) { const error = new Error('cmd error : vous n\'avez pas les droits') log.info(error) callback(error.message) } else if (cmd.type === 'set') { log.info('cmd::set', cmd.params.key, cmd.params.value) const transaction = Transaction.fromCommand(cmd) if (blockchain.addTransaction(transaction)) { network.notifyNeighbors('transaction', transaction) callback() } else { const error = new Error('cmd error : cette transaction existe déjà') log.info(error) callback(error.message) } } else if (cmd.type === 'addPeer') { log.info('cmd::addPeer', cmd.params.url, cmd.params.port) const s = network.addPeer(cmd.params.url, cmd.params.port, callback) if (s) { s.emit('last', (error, last) => { if (error) { log.error('addPeer::last fail:', error) } setBlock(Block.fromObject(last), s, callback) }) } /***** Début modifications *****/ } else if (cmd.type === 'mine'){ log.info('cmd::mine', cmd.params.state) if(cmd.params.state == "start"){ log.info('Minage activé') miner.findPow(blockchain.buildNextBlock()) argv.mine = true callback() } else if (cmd.params.state == "stop") { log.info('Minage désactivé') argv.mine = false callback() } else { const error = new Error(`State ${state} n'existe pas`) } /***** Fin modifications *****/ } else { const error = new Error('cmd error : type inconnue') log.info(error) callback(error.message) } }) ``` ## Connectons-nous ! Pour être synchronisés, il faut que notre noeud ait le même timestamp que celui qui tourne sur https://syd.reimert.fr Pour cela, on récupère le timestamp du bloc 0 grâce à la commande ```blockByIndex``` ```bash node cli.js -u https://syd.reimert.fr -p 443 blockByIndex 0 ``` On lance ensuite notre noeud avec le timestamp obtenu ```bash node noeud.js -b timestamp ``` On ajoute ensuite le noeud public comme peer de notre noeud ```bash node cli.js addPeer https://syd.reimert.fr:443 ``` Notre noeud est alors synchronisé au noeud public. ## Laisser une trace dans ce monde Modification de ```noeud.js``` pour que la commande ```node cli.js identity <name>``` fonctionne. ```javascript= // # gestion des commandes authentifiées network.on('cmd', function (socket, cmd, callback) { cmd = Command.fromObject(cmd) if (cmd.user !== publicKey || !cmd.verify()) { const error = new Error('cmd error : vous n\'avez pas les droits') log.info(error) callback(error.message) } else if (cmd.type === 'set') { log.info('cmd::set', cmd.params.key, cmd.params.value) const transaction = Transaction.fromCommand(cmd) if (blockchain.addTransaction(transaction)) { network.notifyNeighbors('transaction', transaction) callback() } else { const error = new Error('cmd error : cette transaction existe déjà') log.info(error) callback(error.message) } } else if (cmd.type === 'addPeer') { log.info('cmd::addPeer', cmd.params.url, cmd.params.port) const s = network.addPeer(cmd.params.url, cmd.params.port, callback) if (s) { s.emit('last', (error, last) => { if (error) { log.error('addPeer::last fail:', error) } setBlock(Block.fromObject(last), s, callback) }) } } else if (cmd.type === 'mine'){ log.info('cmd::mine', cmd.params.state) if(cmd.params.state == "start"){ log.info('Minage activé') miner.findPow(blockchain.buildNextBlock()) argv.mine = true callback() } else if (cmd.params.state == "stop") { log.info('Minage désactivé') argv.mine = false callback() } else { const error = new Error(`State ${state} n'existe pas`) } /***** Début modifications *****/ } else if (cmd.type === 'identity') { log.info('cmd::identity', cmd.params.name) const transaction = Transaction.fromCommand(cmd) if (blockchain.addTransaction(transaction)) { network.notifyNeighbors('transaction', transaction) callback() } else { const error = new Error('cmd error : cette transaction existe déjà') log.info(error) callback(error.message) } /***** Fin modifications *****/ } else { const error = new Error('cmd error : type inconnue') log.info(error) callback(error.message) } }) ``` ## Contribuer au réseau Modification de ```noeud.js``` pour ajouter une transaction de type ```reward``` aux blocs minés ```javascript= async function setBlock (block, socket, callback = () => {}) { if (!block.isValid()) { const error = new Error('block error : block invalid') log.warn(error, block) callback(error.message) } else { if (await blockchain.addBlock(block, socket)) { network.notifyNeighbors('block', block) if (argv.mine) { const nextBlock = blockchain.buildNextBlock() /***** Ajout d'une transaction reward *****/ const publicKey = fs.readFileSync(`./wallets/${argv.wallet}/pub`, 'utf8') const privateKey = fs.readFileSync(`./wallets/${argv.wallet}/priv`, 'utf8') const params = null const transaction = new Transaction('reward', params, publicKey) transaction.sign(privateKey) nextBlock.transactions.unshift(transaction) /******************************************/ // reward here ;) // indice : https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift // indice : pour créer une transaction, vous pouvez regarder comment cli.js crée une command log.info(`Search for the hash of block ${nextBlock.index}`) miner.findPow(nextBlock) } } callback() } } ```