Maison  >  Article  >  interface Web  >  Introduction à la méthode d'implémentation de petite blockchain en javascript (avec code)

Introduction à la méthode d'implémentation de petite blockchain en javascript (avec code)

不言
不言avant
2019-04-03 09:32:353792parcourir

Le contenu de cet article est une introduction à la méthode d'implémentation d'une petite blockchain en JavaScript (avec du code). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

Concept de blockchain

Sens étroit : la blockchain est une structure de données en chaîne qui combine des blocs de données de manière séquentielle dans l'ordre chronologique et un grand livre distribué cryptographiquement garanti immuable et infalsifiable.

1. Mining (génération de nouveaux blocs)

Tout d'abord, la blockchain est formée par la connexion de chaque bloc. Avant de générer un nouveau bloc, il faut d'abord qu'elle soit formée. Il existe un bloc initial, également appelé bloc de genèse. Grâce à ce bloc de genèse, le bloc qui remplit les conditions est calculé en changeant constamment le nombre aléatoire (nonce). Voici les informations de base du bloc Genesis :

const initBlock = {
    index: 0,
    data: 'hey,this is a block chain',
    previousHash: '0',
    timestamp: '1551806536961',
    nonce: 80490,
    hash: '0000352fb27dd1141fa7265833190a53e5776b1111e275db0d9a77bf840081e6'
};
  1. index : fait référence au numéro de série de chaque bloc
  2. données : Toutes les informations du bloc sont stockées ici , telles que le transfert, le solde et d'autres données
  3. previousHash : fait référence à la valeur de hachage du bloc précédent. Il n'y a pas de bloc précédent dans le bloc Genesis, affichez simplement 0.
  4. timestamp : fait référence. à la création de cette zone Block time
  5. nonce : Il s'agit d'un nombre aléatoire Le minage consiste à calculer un hachage qualifié en changeant constamment ce nonce.
  6. hash : La valeur de hachage de ce bloc, la valeur obtenue en hachant les informations dans les cinq champs précédents.

Ensuite, le hachage qui remplit les conditions est calculé par une opération de hachage continue, c'est-à-dire le minage. L'exploitation minière peut également ajuster la difficulté. Par exemple, la valeur de hachage calculée doit avoir les trois premiers chiffres égaux à 1 ou les trois derniers chiffres égaux à 1, etc. Cela peut être défini par vous-même, à condition qu'il y ait un interrupteur de commande en place. fin pour plus de commodité. Il suffit de contrôler. Vous pouvez définir une variable

Calcul du hachage :

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

Après avoir généré un hachage qui remplit les conditions, un nouveau bloc est généré, mais cette zone doit être Le bloc est vérifié pour voir s'il est valide, car il peut s'agir d'un bloc illégal qui a été falsifié, ou d'un bloc qui n'a rien à voir avec la chaîne et qui est simplement conforme aux règles de hachage ci-dessus. Il est donc nécessaire de vérifier la validité des blocs avant et après.

isValidaBlock(newBlock,lastBlock) {
     if (newBlock.index !== lastBlock.index+1) return false
     if (newBlock.previousHash !== lastBlock.hash) return false
     if (newBlock.timestamp <p>En plus de la vérification ci-dessus, vous devez également utiliser la fonction ci-dessus pour vérifier chaque bloc de toute la chaîne afin de vous assurer que les informations de chaque bloc sont correctes et n'ont pas été falsifiées. </p><p style="white-space: normal;"><strong>2. Construire un réseau P2P </strong></p><p>Le réseau blockchain est décentralisé, c'est-à-dire qu'il n'y a pas de réseau de serveurs centraux et que le client n'a pas besoin de s'appuyer sur le serveur central pour obtenir ou traiter des données. Dans le réseau blockchain, il existe de nombreux nœuds. Chaque nœud est un membre indépendant. Ce sont à la fois des clients et des serveurs qui sont directement connectés point à point (pas besoin de transfert via une centrale). serveur, donc du point de vue de la sécurité des informations, la connexion point à point est très fiable pour la confidentialité des informations. </p><p><img src="https://img.php.cn/upload/image/102/511/987/1554254785651010.png" title="1554254785651010.png" alt="Introduction à la méthode dimplémentation de petite blockchain en javascript (avec code)"></p><p>Bien que la blockchain transmette des données via des connexions point à point, il y a encore quelque chose de nécessaire comme guide avant cela, qui est le nœud de départ. Étant donné que les deux nœuds peuvent ne pas être dans le même domaine, s'ils souhaitent se contacter, une partie doit connaître l'adresse IP et le port de l'autre partie, afin de pouvoir contacter l'autre partie. IP du nœud et numéro de port. Une fois le nœud créé, le nœud de départ lui enverra l'IP et le numéro de port de tous les nœuds de la blockchain et enregistrera l'IP et le numéro de port du nouveau partenaire. Ensuite, une fois que le nouveau nœud a reçu ce « carnet d'adresses », il enverra un message à tous les amis de ce « carnet d'adresses », leur indiquant qu'un nouvel ami a rejoint. Après cela, d'autres nœuds recevront cette information, celle du nouveau partenaire. L'IP et le numéro de port seront également ajoutés à son « carnet d'adresses », ce qui équivaut à rejoindre la liste blanche. De cette manière, le nouveau nœud peut alors communiquer avec n’importe quel nœud. </p><p>Ce qui suit est une démonstration de code : </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 Enregistrez les informations du nouveau nœud du nœud de départ, y compris l'adresse IP et le numéro de port, car l'adresse IP et le numéro de port de. le nouveau nœud est Les choses vont changer.

2. Acceptez la liste de nœuds du nœud de départ, parcourez et vérifiez les nœuds de la liste, et écrivez-les dans la liste s'ils ne sont pas identiques.

3. Diffusez les informations du nouveau nœud à tous les nœuds, et en même temps, les nœuds qui reçoivent les informations mettent à jour la liste des nœuds

4. Synchronisez les informations sur la blockchain avec. tous les emplacements locaux. En même temps, les informations de chaque bloc sont traitées sur la blockchain transmise depuis le nœud de départ

3. Transaction de transfert

Le modèle de transaction de BTC utilise UTXO

Introduction à la méthode dimplémentation de petite blockchain en javascript (avec code)

Le modèle de transaction de cette petite blockchain utilise la méthode la plus simple.

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

在区块链中,进行记录转账交易的时候是需要一个加密的算法,把所有的信息进行加密之后再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视频教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer