主页 > 最新imtoken官方下载链接 > 使用 Javascript 的小型区块链

使用 Javascript 的小型区块链

最新imtoken官方下载链接 2023-03-12 06:16:47

区块链概念

狭义的定义:区块链是一种链式数据结构,将数据块按照时间顺序依次组合起来,是加密保证不可篡改、不可伪造的分布式账本。

一、挖矿(生成新区块)

首先,区块链是由每个区块的连接形成的。在生成新块之前,必须有一个初始块,也称为创世块。通过这个创世块,通过不断改变随机数来计算合格块。以下是创世区块的基本信息:

const initBlock = {  
    index: 0,  
    data: 'hey,this is a block chain',  
    previousHash: '0',  
    timestamp: '1551806536961',  
    nonce: 80490,  
    hash: '0000352fb27dd1141fa7265833190a53e5776b1111e275db0d9a77bf840081e6'  
}; 

index:指每个区块的序号 data:这里存储了区块中的所有信息,如转账、余额等数据 previousHash:指上一个区块的哈希值,创世区块中没有上一个区块,显示0可以是timestamp:指的是创建区块的时间nonce:这是一个随机数,挖矿就是通过不断改变这个nonce来计算一个合格的hash。hash:这个区块的hash值,对前5个字段的信息进行hash得到的值。

然后,通过不间断的哈希运算,计算出合格的哈希,即挖矿。挖矿还可以调整难度。比如计算出来的hash值的前3位一定是1或者后3位一定是1等等,这个可以自己定义,只要最后有一个控制开关,方便控制它. 你可以定义一个变量

哈希计算:

.createHash('sha256')  
 .update(index + data + previousHash + timestamp + nonce)  
 .digest('hex')  

区块链怎么查询账户余额

1:_that.difficulty = 3 // 即前3位或者末3位数必须为1,数量越多难度越大 

生成合格的哈希后,会生成一个新的区块,但必须检查该区块是否有效,因为它可能是被篡改的非法区块区块链怎么查询账户余额,也可能与这条链无关。任何关系的块都符合上述哈希规则。因此,有必要检查前后块的有效性。

isValidaBlock(newBlock,lastBlock) {  
     if (newBlock.index !== lastBlock.index+1) return false  
     if (newBlock.previousHash !== lastBlock.hash) return false  
     if (newBlock.timestamp <= lastBlock.timestamp) return false  
     if (newBlock.hash.slice(1 ,_that.difficulty) !== '1'.repeat(_that.difficulty)) return false  
     if (newBlock.hash !== this.computeHashForBlock(newBlock)) return false  //确保随机数正确  
        // 都满足则返回true  
        return true  
    } 

除了上述验证之外,还需要使用上述功能对整个链上的每一个区块进行验证,以确保每一个区块的信息在没有被篡改的情况下都是正确合法的。

二、搭建P2P网络

区块链网络是去中心化的,即没有中心服务器的网络,客户端不需要依赖中心服务器来获取或处理数据。在区块链网络中,有很多节点。每个节点都是一个独立的成员。它们既是客户端又是服务器。节点和节点直接对等连接。转移是通过某个中央服务器进行的。因此,从信息安全的角度来看,点对点的连接方式对于信息隐私来说是非常可靠的。

虽然区块链通过点对点的连接来传输数据,但在此之前还有一件事需要作为指导,那就是种子节点。因为,它们可能不在两个节点之间的同一个域中。如果要联系对方,一方必须知道对方的IP和端口,才能联系对方。节点 ip 和端口号。节点创建后,种子节点会将区块链中所有节点的ip和端口号发送给它,并记录新伙伴的ip和端口号。然后,新节点得到这个“通讯录”后,会向这个“通讯录”中的所有朋友发送消息,告诉他们有新的伙伴加入,然后其他节点收到这个信息,也会添加新伙伴的 ip 和端口号到您的“

区块链怎么查询账户余额

我们用代码来演示一下:

(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.从种子节点保存新节点的信息,包括ip和端口号,因为新节点的ip和端口号会改变。

2.从种子节点接受节点列表,遍历并检查列表的节点,如果不相同则写入列表。

3.将新节点的信息广播给所有节点,同时接收到信息的节点更新节点列表

4.在本地同步一份区块链上信息的副本,同时进行从种子节点传来的区块链上各个区块的信息

三、转账交易

BTC的交易模型是使用UTXO

区块链怎么查询账户余额

而这个小区块链的交易模型使用了最简单的方法。

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

在区块链中,需要一种加密算法来记录转账交易。将所有信息加密后,推送到新区块中的数据,从而完成新交易的记录。以BTC为例,BTC的加密算法采用椭圆加密算法。椭圆是一种非对称加密算法。非对称加密算法的特点是私钥是唯一的,只有拥有者才能与他的私钥进行通信。验证相应的公钥。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个步骤,分别是验证转账账户是否有足够的金额,转账账户是本地公钥。如果有,将使用两个地址、金额、时间和签名加密进行计费和打包,然后广播到所有节点。其他节点收到这个信息后第一件事就是检查新区块的有效性,检查通过后写入数据。

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 < amount)) { //_that.blance 当前账户余额  
            //全节点广播  
            _that.send('trans', sigTrans)  
        }else{  
            console.log('not enough blance')  
            return  
        }  
    }  
    this.data.push(sigTrans)  
    return sigTrans  
} 

其他节点收到消息后,首先进行去重验证,然后更新数据。

四、查看余额

这条链的查询方式比较简单,就是对区块中每笔交易的信息进行校验匹配,满足条件就增减,而忽略了准确性的问题。

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  
   } 

至此,区块链最简单的功能已经实现。

如果觉得不错区块链怎么查询账户余额,请点赞和支持,欢迎留言或进入我的个人群855801563领取【架构资料收集90期】、【BATJTMD工厂JAVA面试题1000+】,本群致力于学习交流技巧和分享面试机会。如果我拒绝广告,我会不定期在群里回答问题和讨论。