Home > Software design >  Implementing this Node.js blockhain on a network
Implementing this Node.js blockhain on a network

Time:03-07

I am looking at this Blockchain from firebase. https://github.com/fireship-io/node-blockchain/blob/main/index.ts

The Blockchain is simple enough. There are many similar examples of blockchain implementations, but I don't really see any that are actually used in a network. I am trying to get some footing for implementing this, at least with 2 users to start.

The thing I'm confused about at the moment is what actually gets shared between users? Is it the chain itself? Just new transactions? When a user does Wallet.sendMoney(5, satoshi.publicKey), it would update the local wallet, but then what? I'm guessing send the transaction to others on the network, but then each copy of the blockchain adds/verifies independently. This seems problematic because some of the transactions could get lost (internet outage or whatever), which makes me wonder if the whole blockchain gets sent, yet this seems unwieldy.

CodePudding user response:

The thing I'm confused about at the moment is what actually gets shared between users?

You meant between nodes not "users". All the nodes should have the same chain and transactions. So you have to implement a pub-sub system to listen for certain events and also publish the transaction and chain. Using redis, you can create a class. I explained on code:

// Note that redis stores strings.
const redis = require("redis");

// create two channels to transfer data
const CHANNELS = {
  BLOCKCHAIN: "BLOCKCHAIN",
  TRANSACTION: "TRANSACTION",
};

// unlike socket, we do not need to know the address of otehr nodes

// ---------------------------HERE IS BROADCASTING STATION---------------------
// it writes multiple processes to communicate over channels.
class PubSub {
  constructor({ blockchain, transactionPool }) {
    // it is able to broadcast its chain and replacing the valid chain
    this.blockchain = blockchain;
    this.transactionPool = transactionPool;

    this.publisher = redis.createClient();
    this.subscriber = redis.createClient();
    this.subscribeToChannels();
    // this.subscriber.on("message", (channel, message) => {
    //   return this.handleMessage(channel, message);
    // });
    this.subscriber.on("message", (channel, message) =>
      this.handleMessage(channel, message)
    );
  }

  // we are listening all channels
  subscribeToChannels() {
    Object.values(CHANNELS).forEach((channel) => {
      this.subscriber.subscribe(channel);
    });
  }

  publish({ channel, message }) {
    //we unsubscrive so we dont send message to ourselves
    // we subscribe again to receive messages
    this.subscriber.unsubscribe(channel, () => {
      this.publisher.publish(channel, message, () => {
        this.subscriber.subscribe(channel);
      });
    });
  }

  // ------THIS IS WHERE BROADCASTING DONE-------------
  handleMessage(channel, message) {
    const parsedMessage = JSON.parse(message);
    switch (channel) {
      case CHANNELS.BLOCKCHAIN:
        this.blockchain.replaceChain(parsedMessage, true, () => {
          // we need to clear local transaction pool becasue we got a new chain
          this.transactionPool.clearBlockchainTransactions({
            chain: parsedMessage,
          });
        });
        break;
      case CHANNELS.TRANSACTION:
        console.log("this in pubsusb", this.transactionPool);
        this.transactionPool.setTransaction(parsedMessage);

        break;
      default:
        return;
    }
  }

  broadcastChain() {
    this.publish({
      channel: CHANNELS.BLOCKCHAIN,
      message: JSON.stringify(this.blockchain.chain),
    });
  }

  broadcastTransaction(transaction) {
    this.publish({
      channel: CHANNELS.TRANSACTION,
      message: JSON.stringify(transaction),
    });
  }
}

export default PubSub;
  • Related