Home >Web Front-end >JS Tutorial >Introduction to the method of implementing small blockchain in javascript (with code)

Introduction to the method of implementing small blockchain in javascript (with code)

不言
不言forward
2019-04-03 09:32:353844browse

This article brings you an introduction to the method of implementing a small blockchain in JavaScript (with code). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

Blockchain concept

Narrow sense: Blockchain is a chain data structure that combines data blocks in a sequential manner in chronological order, and cryptographically Guaranteed immutable and unforgeable distributed ledger.

1. Mining (generating new blocks)

First of all, the blockchain is formed by the connection of each block. Before generating a new block, it must first There is an initial block, which is also called the genesis block. Through this genesis block, the block that meets the conditions is calculated by constantly changing the random number (nonce). The following is the basic information of the genesis block:

const initBlock = {
    index: 0,
    data: 'hey,this is a block chain',
    previousHash: '0',
    timestamp: '1551806536961',
    nonce: 80490,
    hash: '0000352fb27dd1141fa7265833190a53e5776b1111e275db0d9a77bf840081e6'
};
  1. index: refers to the serial number of each block
  2. data: All information in the block is stored here, such as transfers, Balance and other data
  3. previousHash: refers to the hash value of the previous block. The genesis block does not have a previous one, just display 0
  4. timestamp: refers to the creation of this block Time
  5. nonce: This is a random number. Mining is to calculate the hash that meets the conditions by constantly changing this nonce.
  6. hash: The hash value of this block is the value obtained by hashing the information in the first five fields.

Then, the hash that meets the conditions is calculated through continuous hash operations, that is, mining. Mining can also adjust the difficulty. For example, the calculated hash value must have the first three digits be 1 or the last three digits must be 1, etc. This can be defined by yourself, as long as there is a control switch at the end for convenience Just control. You can define a variable

Hash calculation:

 .createHash('sha256')
 .update(index + data + previousHash + timestamp + nonce)
 .digest('hex')
_that.difficulty = 3   // 即前3位或者末3位数必须为1,数量越多难度越大

After a hash that meets the conditions is generated, a new block is generated, but this block must be verified. Check to see if it is valid, because it may be an illegal block that has been tampered with, or it may be a block that has nothing to do with the chain and just conforms to the above hash rules. Therefore, it is necessary to verify the validity of the before and after blocks.

isValidaBlock(newBlock,lastBlock) {
     if (newBlock.index !== lastBlock.index+1) return false
     if (newBlock.previousHash !== lastBlock.hash) return false
     if (newBlock.timestamp <p>In addition to the above verification, you also need to use the above function to verify each block of the entire chain to ensure that the information in each block is correct and has not been tampered with. is legal. </p><p style="white-space: normal;"><strong>2. Building a P2P network</strong></p><p>The blockchain network is decentralized, that is, there is no central server network, and the client does not need to rely on the central server to obtain or process data. In the blockchain network, there are many nodes. Each node is an independent member. They are both clients and servers. Nodes are directly connected point-to-point (peer-to-peer). No need for It is transferred through a central server, so from the perspective of information security, point-to-point connection is very reliable for information privacy. </p><p><img src="https://img.php.cn/upload/image/102/511/987/1554254785651010.png" title="1554254785651010.png" alt="Introduction to the method of implementing small blockchain in javascript (with code)"></p><p>Although the blockchain transmits data through point-to-point connections, there is something that needs to be used as a guide before that, which is the seed node. Because the two nodes may not be in the same domain, if they want to contact each other, one party must know the other party's IP and port, so that they can contact the other party. Node IP and port number. After the node is created, the seed node will send it the IP and port number of all nodes in the blockchain and record the IP and port number of the new partner. Then, after the new node gets this "address book", it will send a message to all the friends in this "address book", telling them that a new friend has joined. After that, other nodes receive this Information, the new partner's IP and port number will also be added to his "address book", which is equivalent to joining the whitelist. In this way, the new node can then communicate with any node. </p><p>The following is a code demonstration: </p><pre class="brush:php;toolbar:false">(res)=>{
  _that.remotePeerInfo = res.data.data   //1
  _that.addPeersList(res.peersList)             //2
  _that.boardCast(_that.remotePeerInfo)    //3
  _that.blockChainUpdate(blockChain,blockData)     //4
}

addPeersList(peers) {
    peers.forEach(peer => {
        if (!_that.peers.find(v => _that.isEqualPeer(peer, v))) {
            _that.peers.push(peer)
        }
    })
}

boardCast(remotePeerInfo) {
    this.peers.forEach(v => {
        this.send(action, v.port, v.address)
    })
}

blockChainUpdate(blockChain,blockData){
  if(newChain.length === 1 ){
    return
    }

    if(_that.isValidaChain(newChain) && newChain.length>_that.blockchain.length){
    _that.blockchain = Object.assign({}, newChain)
    }else{
    console.log('error')
    return
    }

    if (trans.every(v => _that.isValidTransfer(v))) {
    _that.data = trans
    }
}

1. Save the information of the new node sent from the seed node, including the ip and port number, because the ip and port number of the new node will be changed circumstances.

2. Accept the node list from the seed node, traverse and check the nodes in the list, and write them into the list if they are not the same.

3. Broadcast the information of the new node to all nodes, and at the same time, the nodes that receive the information update the node list

4. Synchronize a copy of the information on the blockchain locally. At the same time, the information of each block is processed on the blockchain transmitted from the seed node

3. Transfer transaction

The transaction model of BTC uses UTXO

Introduction to the method of implementing small blockchain in javascript (with code)

The transaction model of this small blockchain uses the simplest method.

区块链中"现金”,它是一个虚拟的东西就是一个字符串,来源于挖矿。每次挖矿成功都会有一定的奖励,得到的这些“钱”就可以在区块链网络中自由的转账交易。

在区块链中,进行记录转账交易的时候是需要一个加密的算法,把所有的信息进行加密之后再push到新区块中的data中,从而完成一笔新交易的记录。以BTC为例,BTC的加密算法是使用elliptic这个加密算法,elliptic是一个非对称性的加密算法,非对称的加密算法的特点就是,私钥是惟一的,只有拥有者才可以和他私钥对应的公钥进行校验 。 nodejs也有对应的库在github上搜索elliptic即可。

{
  "privateKey": "34a425df3eb1f22fb6cb74b0e7298b16ffd7f3fb",
  "publicKey": "ac208623a38d2906b090dbcf3a09378dfe79b77bf39c2b753ef98ea94fe08dc3995a1bd05c917"
}

上面是一个生成好的密钥对格式,仅作为展示,我删减了一部分长度。

使用银行卡进行转账交易的时候,会有一个转出的账号和一个转入的账号,在区块链中的记账也会有这个账号,这个账号就是上面使用生成的密钥对中的公钥,公钥就是地址,或者说公钥代表的就是自己的钱包。

校验的方法,首先使用字段“from”,“to”,“amount”的参数进行sign签名,然后在每次挖矿(记账)的时候,则使用verify(),通过前面的三个参数,和sig进行校验

verify(type,data){
    swtich(type){
        case 'sign':
            const bufferMsg = Buffer.from(`${data.from}-${data.to}-${data.amount}`)
            let signature = Buffer.from(keypair.sign(bufferMsg).toDER()).toString('hex')
               this.signature =  signature
        break;
        case 'verify':
             const keypairTemp = ec.keyFromPublic(pub, 'hex')
                const bufferMsg = Buffer.from(`${data.from}-${data.to}-${data.amount}`)
             this.keypair = keypairTemp.verify(bufferMsg, sig)
        break;
        default;
    }
}

转帐的时候需要3步,分别是校验转出账户是否有足够的金额,转出账户就是本地公钥。如有则进行记账并且使用两个地址、金额、时间,还有签名加密打包,之后进行全节点广播。其他节点收到这个信息之后第一件事也是对新区块的有效性做一个校验,通过校验之后就会写入data中。

transfer(data)  {
    const timestamp = new Date().getTime()
    const sig = rsa.sign({data.from, data.to, data.amount , timestamp})
    const sigTrans = {data.from, data.to, data.amount ,timestamp, sig }

        // 非创世区块
    if (trans.from !== '0') {
            // 检验余额
        if (!(_that.blance <p>其他节点收到消息之后,先进行去重校验,然后再更新数据。</p><h3>四、查询余额</h3><p>这个链的查询方法比较简单,就是将区块中的每一条交易的信息进行校验和匹配,满足条件的就进行增减,同时忽略精度上的问题。</p><pre class="brush:php;toolbar:false"> this.blance = blance(address)
 blance(address) {
        let blance = 0;
        this.blockchain.forEach(block => {
            block.data.forEach(trans => {
                if (address == trans.from) {
                    blance -= trans.amount
                }

                if (address == trans.to) {
                    blance += trans.amount
                }

            })

        });
        return blance
    }

至此,区块链的最简单的功能就实现完毕。

【相关推荐:JavaScript视频教程

The above is the detailed content of Introduction to the method of implementing small blockchain in javascript (with code). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete