版权声明:转载请注明出处 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%算力是一件很问难的事,况且我也相信,比特币网络也不会允许任何一个节点达到这样的能力的
好了就说这么多吧,