JavaScript开发区块链只需200行代码
ranbluer
post on 2023-1-2 10:25:45
33
0
0
然而,在通常情况下,当我们谈到区块链的时候也会谈起使用区块链来解决的问题,这两者很容易混淆。
像流行的比特币和以太坊这样基于区块链的项目就是这样。“区块链”这个术语通常和像交易、智能合约、加密货币这样的概念紧紧联系在一起。
这就令理解区块链变得不必要得复杂起来,特别是当你想理解源码的时候。下面我将通过 200 行 JS 实现的超级简单的区块链来帮助大家理解它,我给这段代码起名为 NaiveChain。你可以在Github(https://github.com/lhartikk/naivechain)查看更多的技术细节。
块结构
第一个逻辑步骤是决定块结构。为了保证事情尽可能的简单,我们只选择最必要的部分:index(下标)、timestamp(时间戳)、data(数据)、hash(哈希值)和 previous hash(前置哈希值)。
这个块中必须能找到前一个块的哈希值,以此来保证整条链的完整性,JavaScript代码如下:
class Block {
constructor(index, previousHash, timestamp, data, hash) {
this.index = index;
this.previousHash = previousHash.toString();
this.timestamp = timestamp;
this.data = data;
this.hash = hash.toString();
}
}
块哈希
为了保存完整的数据,必须哈希区块。SHA-256会对块的内容进行加密,记录这个值应该和“挖矿”毫无关系,因为这里不需要解决工作量证明的问题。JavaScript代码如下:
var calculateHash = (index, previousHash, timestamp, data) => {
return CryptoJS.SHA256(index + previousHash + timestamp + data).toString();
};
块的生成
要生成一个块,必须知道前一个块的哈希值,然后创造其余所需的内容(= index, hash, data and timestamp)。
块的data部分是由终端用户所提供的。JavaScript代码如下:
var generateNextBlock = (blockData) => {
var previousBlock = getLatestBlock();
var nextIndex = previousBlock.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);
};
块的存储
内存中的Javascript数组被用于存储区块链。区块链的第一个块通常被称为“起源块”,是硬编码的。JavaScript代码如下:
var getGenesisBlock = () => {
return new Block(0, "0", 1465154705, "my genesis block!!", "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7");
};
var blockchain = [getGenesisBlock()];
确认块的完整性
在任何时候都必须能确认一个区块或者一整条链的区块是否完整。在我们从其他节点接收到新的区块,并需要决定接受或拒绝它们时,这一点尤为重要。JavaScript代码如下:
var isValidNewBlock = (newBlock, previousBlock) => {
if (previousBlock.index + 1 !== newBlock.index) {
console.log('invalid index');
return false;
} else if (previousBlock.hash !== newBlock.previousHash) {
console.log('invalid previoushash');
return false;
} else if (calculateHashForBlock(newBlock) !== newBlock.hash) {
console.log('invalid hash: ' + calculateHashForBlock(newBlock) + ' ' + newBlock.hash);
return false;
}
return true;
};
选择最长的区块链
任何时候在链中都应该只有一组明确的块。万一冲突了(例如:两个结点都生成了72号块时),会选择有最大数目的块的链。JavaScript代码如下:
var replaceChain = (newBlocks) => {
if (isValidChain(newBlocks) && newBlocks.length > blockchain.length) {
console.log('Received blockchain is valid. Replacing current blockchain with received blockchain');
blockchain = newBlocks;
broadcast(responseLatestMsg());
} else {
console.log('Received blockchain invalid');
}
};
与其他结点的通信
结点的本质是和其他结点共享和同步区块链,下面的规则能保证网络同步。
当一个结点生成一个新块时,它会在网络上散布这个块。
当一个节点连接新peer时,它会查询最新的block。
当一个结点遇到一个块,其index大于当前所有块的index时,它会添加这个块到它当前的链中, 或者到整个区块链中查询这个块。
我没有采用自动发现peer的工具。peers的位置(URL)必须是手动添加的。
节点控制
在某种程度上用户必须能够控制节点。这一点通过搭建一个HTTP服务器可以实现。JavaScript代码如下:
var initHttpServer = () => {
var app = express();
app.use(bodyParser.json());
app.get('/blocks', (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', (req, res) => {
res.send(sockets.map(s => s._socket.remoteAddress + ':' + s._socket.remotePort));
});
app.post('/addPeer', (req, res) => {
connectToPeers([req.body.peer]);
res.send();
});
app.listen(http_port, () => console.log('Listening http on port: ' + http_port));
};
用户可以用下面的方法和节点互动:
列出所有的块用户提供的内容创建一个新的块列出或者新增peers
下面这个Curl的例子就是最直接的控制节点的方法:
#get all blocks from the node
curl http://localhost:3001/blocks
系统架构
需要指出的是,节点实际上展现了两个web服务器:一个(HTTP服务器)是让用户控制节点,另一个(Websocket HTTP服务器)。
总结
创造 NaiveChain 的目的是为了示范和学习,因为它并没有“挖矿”算法(PoS或PoW),不能被用于公用网络,但是它实现了区块链运作的基本特性。
BitMere.com is Information release platform,just provides information storage space services.
The opinions expressed are solely those of the author,Does not constitute advice, please treat with caution.
The opinions expressed are solely those of the author,Does not constitute advice, please treat with caution.
Write the first review