区块链简述
2018-05-09 本文已影响0人
vampire_64a8
区块链结构
第一步是要决定你的区块链结构当你要写自己的区块链时,为了使事情尽量简化,我把最重要的几个列举出来, 索引,数据,哈希,之前的哈希和时间戳。
1_pbyFH4U5sO27UE1EjnImoA.png
class Block{
constructor(index, previousHash, timestamp, hash){
this.index = index;
this.previousHash = previouslyHash.toString();
this.timestamp = timstamp;
this.data = data;
this.hash = hash.toString();
}
}
区块链的哈希
区块需要用哈希来保证数据的完整, SHA-256可以用来接管区块的内容, 你要知道的是这个哈希和挖矿无关, 因为他并没有相关的问题被解决。
var calculateHash = (index, previsouHash, timestamp, data) => {
return CryptoJS.SHA256(index + previsouHash + timestamp + data).toString()
};
生成一个区块
要生成一个区块我们必须知道之前的哈希然后创建一些必须的内容,比如索引,哈希,数据和时间戳。区块的内容是由最终的用户提供的。
var generateNextBlock = (blockData) => {
var previsouBlock = getLastBlock();
var nextIndex = previsouBlock.index + 1;
var nextTimestamp = new Date().getTime() / 1000;
var nextHash = calculateHash(nextIndex, previousBlock.hash, nextTimestamp, blockData);
return new Block(nextIndex, previousBlock.hash, nextTimestamp, blockData, nextHash);
}
存储区块
JS的数组可以用来存储区块链, 一个区块链的区块经常被叫做起源区块。
var getGenesisBlock = () => {
return new Block(0,"0", 1465154705, "my genesis block!!", "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7" );
};
var blockChain = [getGenesisBlock()];
证明区块的有效性
在任何情况下我们都要证明是否一个区块链是有效的在保存方面。特别是在当我们接收到一个新的区块在其他的节点, 我们必须决定要不要接受他们。
var isValidNewBlock = (newBlock, previousBlock) => {
if(previousBlock.index + 1 !== newBlock.index) {
console.log('invalid index');
return false;
}
else if (previousBlock.hash !== newBlock.previsousHash) {
console.log('invalid previsousHash');
return false;
}
else if (calculateHashForBlock(newBlock) !== newBlock.hash) {
console.log('invalid hash': calculateHashForBlock(newBlock) + '' + newBlock.hash);
return false;
}
return true;
};
选择最长的链
在指定的时间里面必须只能有一个区块在区块链内部。 为了防止冲突,我们选择有最多区块的链。
1_KM7WYPiZwxyfDL6Eb66QIg.png
var replaceChain = (newBlocks) => {
if (isValidNewBlock(newBlocks) && newBlocks.length > blockChain.length) {
console.log('Received blockChain is vaild')
blockChain = new Blocks;
broadcast(responseLatestMsg());
} else {
console.log('received blockchain invaild');
}
}
和其他节点的交流
一个节点很重要的部分就是和区块链里面其他的节点分享和同步。下面的规则就是为了使区块链网络保持同步。
-
当一个节点产生一个新的区块, 他会把信息传播到网络内部
-
当一个节点和另一个节点连接,他会询问他的最近的区块
-
当一个节点遇到一个区块他的索引大于目前已知的区块, 他会把这个区块加到目前的区块链上或者询问区块链
控制节点
用户必须要用某些方法控制区块。 这可以设置一个HTTP 服务器来实现。
var initHttpServer = () => {
var app = express();
app.use(bodyParser.json());
app.get('/block', (req, res) => res.send(JSON.stringify(blockchain)));
app.post('/mineBlock', (req,res) => {
var newBlock = generateNextBlock(req.body.data);
addBlock(newBlock);
broadcast(responseLatestMsg());
console.log('block added: ' + JSON.stringify(newBlock));
res.send();
});
app.get('/peers', (res, req) => {
res.send(socket.map(s => s._socket.remoteAddress + ':' + s._socket.remotePort
});
app.post('/addPeer', (res, req) => {
connetToPeers([req.body.peer]);
res.send();
});
app.listen(http_port, () => console.log('listening http on port: ' + http_port));
};
从上可以看出, 用户可以和其他节点进行交流用以下的几种方式“
-列出所有的区块
-用用户给出的内容创建一个新的区块
-列出或者添加其他的节点
最直接的方式来控制节点可以用Curl:
#get all blocks from the node
curl http://localhost:3001/blocks
结尾
一般来说, 节点实际上会暴露在2个服务器上, 一个是给来控制节点的也就是HTTP 服务器, 另一个是是给他们节点之间交流的也就是 Websocket HTTP 服务器。
Capture.PNG
这个博客只是简单的介绍了区块链的原则和实现,具体的挖矿算法参考 PoS or PoW.