最全 比特币区块链结构+代码

版权声明:转载请注明出处 https://blog.csdn.net/Booboochen/article/details/82017085
  • 1. 区块链书籍和有用链接

    首先,本人也是一周后在学习区块链的路上,学习中将自己看过的有用的信息就放在自己的GitHub上,方便自己复习好找

    本人首页:www.github.com/cancerts/study-blockchain-referrence 【点击】

    里面有我25本(写博客时)区块链领域比较热门的书籍,有PDF、mobi三种格式的,懂区块链的自己取

  • 2. 区块链结构和代码(JavaScript
     
  • 3. 区块链
    区块链是一种分布式账本,运用了许多密码学的技术来保证写入账本的数据安全,不被篡改,我们知道最初是没有区块链这个概念的,是从比特币底层组织数据的形式中提出来的
     
  • 4. 区块
    第一个区块称为创世区块(Genesis block),区块链中包含
    Index Timestamp Hash Previous Hash Data Nonce
    区块号 时间戳 sh256 前一个区块的hash 输入的内容 随机值

    代码:
     

    class Block {
      constructor (index, previousHash, timestamp, data, hash, nonce) {
        this.index = index;
        this.previousHash = previousHash;
        this.timestamp = timestamp;
        this.data = data;
        this.hash = hash;
        this.nonce = nonce;
      }
    
      get genesis() {
        new Block(
          0,
          "0",
          1508270000000,
          "Welcome to Blockchain",
          "000dc75a315c77a1f9c98fb6247d03dd18ac52632d7dc6a9920261d8109b37cf",
          604
        );
      }
    }
    
    module.exports = Block;
  • 5. 索引
    创世区块区块索引为0,下一个区块为1,每增加一个区块增加一,每一个区块链的所以唯一代表一个区块,可以更具索引查询到相应的区块信息
     
  • 6. 时间戳
    区块被创建的时间,用的是Linux时间表示方法,区块根据时间戳进行排序
     
  • 7. 哈希
    哈希就是一段随机值:000dc75a315c77a1f9c98fb6247d03dd18ac52632d7dc6a9920261d8109b37cf,根据输入内容计算出
    &&:相同的数据得到的hash值相同
    &&:不同的数据得到完全不同的hash值
    &&:hash很容易计算
    &&:不能有hash值递推出源数据
    &&:一个数据很小的变化导致hash值的变化很大
     
  • 8. 有效哈希
    有效哈希指规定计算后hash值的最前面0的数量达到要求,0越多,那么要找到正确的随机值(nonce)计算出有效的hash就会越困难
    代码:
     
    // cosnt Block = reuqire("./Block.js");
    
    // class Blockchain {
      // constructor() {
        // this.blockchain = [Block.genesis()];
        this.difficulty = 20;
      // }
      
      // get() { ... }
      // get latestBlock() { ... }
    
      isValidHashDifficulty(hash) {
        for (var i = 0; i < hash.length; i++) {
          if (hash[i] !== "0") {
            break;
          };
        }
        return i >= this.difficulty;
      }
    // };
    
    // module.exports = Blockchain;
  • 9. 计算区块哈希值
    计算哈希值就是输入一段内容然后输出一段固定长度的hash值来,用公式表示为:hash=f(data)
     
    // const Block = require("./Block.js");
    const crypto = require("crypto");
    
    // class Blockchain {
      // constructor() { ... }
      // get() { ... }
      // get latestBlock() { ... }
      // isValidHashDifficulty(hash) { ... }
    
      calculateHashForBlock(block) {
        const { index, previousHash, timestamp, transactions, nonce } = block;
        return this.calculateHash(
          index,
          previousHash,
          timestamp,
          transactions,
          nonce
        );
      }
    
      calculateHash(index, previousHash, timestamp, data, nonce) {
        return crypto
          .createHash("sha256") // SHA256 Hash Function
          .update(index + previousHash + timestamp + data + nonce)
          .digest("hex");
      }
    // };
    
    // module.exports = Blockchain;
  • 10. 前一个区块的哈希
    前一个区块的哈希就是前一个区块计算出来的hash值,创世区块hash值为0,因为没有前一个区块了
     
  • 11. 数据
    数据就是存储在每一个区块中的数据,可以值比特币中的交易
     
  • 12. 改变数据
    区块链中改变任何一个数据都会导致计算结果不一致,计算结果不一样的内容是不会被记录在区块链的有效账本中
     
  • 13. 改变数据的影响
    例如:当你创建了100和区块了,当你改变第55个区块链的内容后,将导致计算的哈希值与后面的不一样就会导致hash冲突,而且不能链接起来
     
  • 14. 开采一个区块
    开采一个区块就是将一段时间的交易信息打包后,计算随机值,找到后计算出的hash值小于给定的hash值
    代码:
     
    // const Block = require("./Block.js");
    // const crypto = require("crypto");
    
    // class Blockchain {
      // constructor() { ... }
      // get() { ... }
      // get latestBlock() { ... }
      // isValidHashDifficulty(hash) { ... }
      // calculateHashForBlock(block) { ... }
      // calculateHash(...) { ... }
    
      mine(data) {
        const newBlock = this.generateNextBlock(data);
        try {
          this.addBlock(newBlock);
        } catch (err) {
          throw err;
        };
      }
    // };
    
    // module.exports = Blockchain;
  • 15. 随机值
    随机值就是一个运用密码学技术保证安全的一种做法,计算出的随机值在比特币网络中作为工作量证明,意思就是你计算出有效的随机值,就说明你经过了很大的运算量,那么你也会获得相应的奖励,随着全网计算力的增加,寻找随机值的难度也会相应的增加
    代码:
     
    // const Block = require("./Block.js");
    // const crypto = require("crypto");
    
    // class Blockchain {
      // constructor() { ... }
      // get() { ... }
      // get latestBlock() { ... }
      // isValidHashDifficulty(hash) { ... }
      // calculateHashForBlock(block) { ... }
      // calculateHash(...) { ... }
      // mine(data) { ... }
    
      generateNextBlock(data) {
        const nextIndex = this.latestBlock.index + 1;
        const previousHash = this.latestBlock.hash;
        let timestamp = new Date().getTime();
        let nonce = 0;
        let nextHash = this.calculateHash(
          nextIndex,
          previousHash,
          timestamp,
          data,
          nonce
        );
    
        while (!this.isValidHashDifficulty(nextHash)) {
          nonce = nonce + 1;
          timestamp = new Date().getTime();
          nextHash = this.calculateHash(
            nextIndex,
            previousHash,
            timestamp,
            data,
            nonce
          );
        }
    
        const nextBlock = new Block(
          nextIndex,
          previousBlock.hash,
          nextTimestamp,
          data,
          nextHash,
          nonce
        );
    
        return nextBlock;
      }
    // };
    
    // module.exports = Blockchain;
  • 16. 开采一个新的区块
    开发一个新的区块,就是找到满足要求的随机值,然后将找出的区块添加在上一个区块的后面,比特币网络控制了每10分钟出一个新的区块,每挖出一个区块,现在是奖励:12.5+交易费用,用一个简单的例子来解释一下为什么开采一个新的区块称为挖矿呢?我们都知道传统的挖矿,就是从矿山里挖出一些矿石,然后卖了就可以赚取很多的money,你只要挖到了矿,人家就会给你发很多钱,其实那个钱是中央银行给你印的,在我们比特币中,很多矿机在那么计算随机值,计算出就相当于挖到了一车的金子,以现在6-8千美金一枚比特币,挖到一个区块,就自动发行12.5个比特币,一下子就可以为所欲为了,是不是很爽啊,人家说,70年代挖矿的人现在都成为百万富翁了,那么现在你还不挖矿,是不是家里还有座金山呢?哈哈
     
  • 17. 增加有效区块
    当你挖出一个有效的区块来时,你就要将这个区块加入到区块链中去,在所有节点同步数据之前,还要进行数据的验证,验证一下你广播的随机值是不是真的,会不会骗我啊,我可是很老实的呀,要是发现,你很诚实没有骗我,那么我就在我的小本本上记上一个区块,好,合作愉快
    代码:
     
    // const Block = require("./Block.js");
    // const crypto = require("crypto");
    
    // class Blockchain {
      // constructor() { ... }
      // get() { ... }
      // get latestBlock() { ... }
      // isValidHashDifficulty(hash) { ... }
      // calculateHashForBlock(block) { ... }
      // calculateHash(...) { ... }
      // mine(data) { ... }
      // generateNextBlock(data) { ... }
      // addBlock(newBlock) { ... }
    
      isValidNextBlock(nextBlock, previousBlock) {
        const nextBlockHash = this.calculateHashForBlock(nextBlock);
    
        if (previousBlock.index + 1 !== nextBlock.index) {
          return false;
        } else if (previousBlock.hash !== nextBlock.previousHash) {
          return false;
        } else if (nextBlockHash !== nextBlock.hash) {
          return false;
        } else if (!this.isValidHashDifficulty(nextBlockHash)) {
          return false;
        } else {
          return true;
        }
      }
    // };
    
    // module.exports = Blockchain;
  • 18. 点对点网络
    点对点网络就是加入到区块链网络中的每一个节点都要是平等的,可以进行通讯,保持相同的账本数据
    代码:
     
    const wrtc = require('wrtc');
    const Exchange = require('peer-exchange');
    const p2p = new Exchange("Blockchain Demo 2.0", { wrtc: wrtc });
    const net = require("net");
    
    class PeerToPeer {
      constructor(blockchain) {
        this.peers = [];
        this.blockchain = blockchain;
      }
    
      startServer(port) {
        const server = net
          .createServer(socket =>
            p2p.accept(socket, (err, conn) => {
              if (err) {
                throw err;
              } else {
                this.initConnection.call(this, conn);
              }
            })
          )
          .listen(port);
      }
    }
      
    module.exports = PeerToPeer;
  • 19. 增加一个节点
    比特币网络是一个共有网络,任何人都可以加入并成其为节点
    代码
     
    // const wrtc = require('wrtc');
    // const Exchange = require('peer-exchange');
    // const p2p = new Exchange(...);
    // const net = require("net");
    
    // class PeerToPeer {
      // constructor(blockchain) { ... }
      // startServer(port) { ... }
      
      discoverPeers() {
        p2p.getNewPeer((err, conn) => {
          if (err) {
            throw err;
          } else {
            this.initConnection.call(this, conn);
          }
        });
      }
    // }
      
    // module.exports = PeerToPeer;
  • 20. 节点的状态
    节点的状态就是看看,这个节点有没偷懒呀,新开采出来的区块有没有拿小本本把他记下来呀,当然,加入的节点都是很诚实的,你去看都记得可认真了
    代码:
     
    // const wrtc = require('wrtc');
    // const Exchange = require('peer-exchange');
    // const p2p = new Exchange(...);
    // const net = require("net");
    
    // class PeerToPeer {
      // constructor(blockchain) { ... }
      // startServer(port) { ... }
      // discoverPeers() { ... }
    
      connectToPeer(host, port) {
        const socket = net.connect(port, host, () =>
          p2p.connect(socket, (err, conn) => {
            if (err) {
              throw err;
            } else {
              this.initConnection.call(this, conn);
            }
          })
        );
      }
    
      closeConnection() {
        p2p.close(err => {
          throw err;
        })
      }
    // }
    
    // module.exports = PeerToPeer;
  • 21. 节点的信息
    加入到到网络中的节点,不是加入就没有事情做了,还要检查那个几点有最新的数据,有的话自己也要记一下奥
    代码:
     
    // const wrtc = require('wrtc');
    // const Exchange = require('peer-exchange');
    // const p2p = new Exchange(...);
    // const net = require("net");
    const messageType = {
      REQUEST_LATEST_BLOCK: 0,
      RECEIVE_LATEST_BLOCK: 1,
      REQUEST_BLOCKCHAIN: 2,
      RECEIVE_BLOCKCHAIN: 3,
    };
    const {
      REQUEST_LATEST_BLOCK,
      RECEIVE_LATEST_BLOCK,
      REQUEST_BLOCKCHAIN,
      RECEIVE_BLOCKCHAIN,
      REQUEST_TRANSACTIONS,
      RECEIVE_TRANSACTIONS
    } = messageType;
    
    // class PeerToPeer { ... }
    // module.exports = PeerToPeer;
    
    class Messages {
      static getLatestBlock() {
        return {
          type: REQUEST_LATEST_BLOCK
        };
      }
    
      static sendLatestBlock(block) {
        return {
          type: RECEIVE_LATEST_BLOCK,
          data: block
        };
      }
    
      static getBlockchain() {
        return {
          type: REQUEST_BLOCKCHAIN
        };
      }
    
      static sendBlockchain(blockchain) {
        return {
          type: RECEIVE_BLOCKCHAIN,
          data: blockchain
        };
      }
    }
  • 22. 节点之间的通信
    代码:
     
    // const wrtc = require('wrtc');
    // const Exchange = require('peer-exchange');
    // const p2p = new Exchange(...);
    // const net = require("net");
    // const messageType = { ... };
    // const { ... } = messageType;
    
    // class PeerToPeer {
      // constructor(blockchain) { ... }
      // startServer(port) { ... }
      // discoverPeers() { ... }
      // connectToPeer(host, port) { ... }
      // closeConnection() { ... }
    
      broadcastLatest() {
        this.broadcast(Messages.sendLatestBlock(this.blockchain.latestBlock));
      }
    
      broadcast(message) {
        this.peers.forEach(peer => this.write(peer, message));
      }
    
      write(peer, message) {
        peer.write(JSON.stringify(message));
      }
    
      initConnection(connection) {
        this.peers.push(connection);
        this.initMessageHandler(connection);
        this.initErrorHandler(connection);
        this.write(connection, Messages.getLatestBlock());
      }
    
      initMessageHandler(connection) {
        connection.on("data", data => {
          const message = JSON.parse(data.toString("utf8"));
          this.handleMessage(connection, message);
        });
      }
    
      initErrorHandler(connection) {
        connection.on("error", err => {
          throw err;
        });
      }
    
      handleMessage(peer, message) {
        switch (message.type) {
          case REQUEST_LATEST_BLOCK:
            this.write(peer, Messages.sendLatestBlock(this.blockchain.latestBlock));
            break;
          case REQUEST_BLOCKCHAIN:
            this.write(peer, Messages.sendBlockchain(this.blockchain.get()));
            break;
          case RECEIVE_LATEST_BLOCK:
            this.handleReceivedLatestBlock(message, peer);
            break;
          case RECEIVE_BLOCKCHAIN:
            this.handleReceivedBlockchain(message);
            break;
          default:
            throw "Received invalid message.";
        }
      }
    // }
    
    // module.exports = PeerToPeer;
    // class Messages { ... }
  • 23. 增加一个节点和添加一个区块
    代码:
     
    // const wrtc = require('wrtc');
    // const Exchange = require('peer-exchange');
    // const p2p = new Exchange(...);
    // const net = require("net");
    // const messageType = { ... };
    // const { ... } = messageType;
    
    // class PeerToPeer {
      // constructor(blockchain) { ... }
      // startServer(port) { ... }
      // discoverPeers() { ... }
      // connectToPeer(host, port) { ... }
      // closeConnection() { ... }
      // broadcastLatest() { ... }
      // broadcast(message) { ... }
      // write(peer, message) { ... }
      // initConnection(connection) { ... }
      // initMessageHandler(connection) { ... }
      // initErrorHandler(connection) { ... }
      // handleMessage(peer, message) { ... }
    
      handleReceivedLatestBlock(message, peer) {
        const receivedBlock = message.data;
        const latestBlock = this.blockchain.latestBlock;
    
        if (latestBlock.hash === receivedBlock.previousHash) {
          try {
            this.blockchain.addBlock(receivedBlock);
          } catch(err) {
            throw err;
          }
        } else if (receivedBlock.index > latestBlock.index) {
          this.write(peer, Messages.getBlockchain());
        } else {
          // Do nothing.
        }
      }
    // }
    
    // module.exports = PeerToPeer;
    // class Messages { ... }
  • 24. 增加一个节点和添加两个区块
    代码:
     
    // const wrtc = require('wrtc');
    // const Exchange = require('peer-exchange');
    // const p2p = new Exchange(...);
    // const net = require("net");
    // const messageType = { ... };
    // const { ... } = messageType;
    
    // class PeerToPeer {
      // constructor(blockchain) { ... }
      // startServer(port) { ... }
      // discoverPeers() { ... }
      // connectToPeer(host, port) { ... }
      // closeConnection() { ... }
      // broadcastLatest() { ... }
      // broadcast(message) { ... }
      // write(peer, message) { ... }
      // initConnection(connection) { ... }
      // initMessageHandler(connection) { ... }
      // initErrorHandler(connection) { ... }
      // handleMessage(peer, message) { ... }
    
      handleReceivedLatestBlock(message, peer) {
        // if (latestBlock.hash === receivedBlock.previousHash) {
        // ...
        } else if (receivedBlock.index > latestBlock.index) {
          this.write(peer, Messages.getBlockchain());
        } else {
          // Do nothing.
        }
      }
    
      handleReceivedBlockchain(message) {
        const receivedChain = message.data;
        
        try {
          this.blockchain.replaceChain(receivedChain);
        } catch(err) {
          throw err;
        }
      }
    // }
    
    // module.exports = PeerToPeer;
    // class Messages { ... }
  • 25. 最后讲一下51%攻击
    51%攻击指的是当每个人掌握了全网51%的算力后,他就可以更改账本,变成最长链,但是掌握51%算力是一件很问难的事,况且我也相信,比特币网络也不会允许任何一个节点达到这样的能力的

好了就说这么多吧,

猜你喜欢

转载自blog.csdn.net/Booboochen/article/details/82017085