Heim  >  Artikel  >  Web-Frontend  >  Einführung in die Methode zur Implementierung einer kleinen Blockchain in Javascript (mit Code)

Einführung in die Methode zur Implementierung einer kleinen Blockchain in Javascript (mit Code)

不言
不言nach vorne
2019-04-03 09:32:353724Durchsuche

Dieser Artikel bietet Ihnen eine Einführung in die Methode zur Implementierung einer kleinen Blockchain (mit Code). Ich hoffe, dass er für Freunde hilfreich ist.

Blockchain-Konzept

Enger Sinn: Blockchain ist eine Kettendatenstruktur, die Datenblöcke sequentiell in chronologischer Reihenfolge kombiniert und kryptografisch ein unveränderliches und fälschungssicheres verteiltes Hauptbuch garantiert.

1. Mining (Generieren neuer Blöcke)

Zuerst wird die Blockchain durch die Verbindung jedes Blocks gebildet, bevor ein neuer Block generiert werden kann Es gibt einen Anfangsblock, der auch Genesis-Block genannt wird. Durch diesen Genesis-Block wird der Block, der die Bedingungen erfüllt, durch ständige Änderung der Zufallszahl (Nonce) berechnet. Das Folgende sind die grundlegenden Informationen des Genesis-Blocks:

const initBlock = {
    index: 0,
    data: 'hey,this is a block chain',
    previousHash: '0',
    timestamp: '1551806536961',
    nonce: 80490,
    hash: '0000352fb27dd1141fa7265833190a53e5776b1111e275db0d9a77bf840081e6'
};
  1. Index: bezieht sich auf die Seriennummer jedes Blocks
  2. Daten: Alle Informationen im Block werden hier gespeichert, z Überweisungen, Kontostand und andere Daten
  3. Vorheriger Hash: Bezieht sich auf den Hash-Wert des vorherigen Blocks. Der Genesis-Block hat keinen vorherigen. Zeigt einfach 0 an.
  4. Zeitstempel: Bezieht sich auf die Zeit Wann dieser Block erstellt wurde: Dies ist eine Zufallszahl. Beim Mining wird der Hash berechnet, der die Bedingungen erfüllt, indem dieser Nonce ständig geändert wird.
  5. Hash: Der Hash-Wert dieses Blocks, der Wert, der durch Hashing der Informationen in den vorherigen fünf Feldern erhalten wird.
  6. Dann wird der Hash, der die Bedingungen erfüllt, durch kontinuierliche Hash-Operationen, also Mining, berechnet. Mining kann auch den Schwierigkeitsgrad anpassen, beispielsweise müssen die ersten drei Ziffern des berechneten Hash-Werts 1 sein oder die letzten drei Ziffern müssen 1 sein usw. Dies kann von Ihnen selbst definiert werden, sofern ein Steuerschalter vorhanden ist Ende aus Bequemlichkeitsgründen. Nur Kontrolle. Sie können eine Variable

definieren, um den Hash zu berechnen:

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

Nach der Generierung eines Hashs, der die Bedingungen erfüllt, wird ein neuer Block generiert, dieser Block muss jedoch überprüft werden ist gültig, da es sich möglicherweise um einen illegalen Block handelt, der manipuliert wurde, oder um einen Block, der nichts mit der Kette zu tun hat, sondern lediglich den oben genannten Hash-Regeln entspricht. Daher ist es notwendig, die Gültigkeit der Vorher- und Nachher-Blöcke zu überprüfen.

isValidaBlock(newBlock,lastBlock) {
     if (newBlock.index !== lastBlock.index+1) return false
     if (newBlock.previousHash !== lastBlock.hash) return false
     if (newBlock.timestamp <p>Zusätzlich zur oben genannten Überprüfung müssen Sie auch die obige Funktion verwenden, um jeden Block der gesamten Kette zu überprüfen, um sicherzustellen, dass die Informationen in jedem Block korrekt sind und nicht manipuliert wurden. </p><p></p>2. Aufbau eines P2P-Netzwerks <p style="white-space: normal;"><strong></strong>Das Blockchain-Netzwerk ist dezentralisiert, das heißt, es gibt kein zentrales Servernetzwerk und der Client muss sich nicht darauf verlassen zentraler Server, um Daten zu erhalten oder zu verarbeiten. Im Blockchain-Netzwerk gibt es viele Knoten. Sie sind sowohl Clients als auch Server. Die Knoten sind direkt Punkt-zu-Punkt verbunden. Die Übertragung erfolgt nicht über eine Zentrale Daher ist eine Punkt-zu-Punkt-Verbindung aus Sicht der Informationssicherheit für den Datenschutz sehr zuverlässig. </p><p></p><p><img src="https://img.php.cn/upload/image/102/511/987/1554254785651010.png" title="1554254785651010.png" alt="Einführung in die Methode zur Implementierung einer kleinen Blockchain in Javascript (mit Code)">Obwohl die Blockchain Daten über Punkt-zu-Punkt-Verbindungen überträgt, ist vorher noch etwas als Leitfaden erforderlich, nämlich der Seed-Knoten. Da sich die beiden Knoten möglicherweise nicht in derselben Domäne befinden, muss eine Partei, wenn sie miteinander Kontakt aufnehmen möchten, die IP und den Port der anderen Partei kennen, damit sie die andere Partei kontaktieren kann. Knoten-IP und Portnummer Nachdem der Knoten erstellt wurde, sendet ihm der Seed-Knoten die IP- und Portnummer aller Knoten in der Blockchain und zeichnet die IP- und Portnummer des neuen Partners auf. Nachdem der neue Knoten dieses „Adressbuch“ erhalten hat, sendet er eine Nachricht an alle Freunde in diesem „Adressbuch“ und teilt ihnen mit, dass ein neuer Freund beigetreten ist. Danach erhalten andere Knoten diese Informationen, die des neuen Partners IP und Portnummer werden ebenfalls zu seinem „Adressbuch“ hinzugefügt, was einem Beitritt zur Whitelist gleichkommt. Auf diese Weise kann der neue Knoten dann mit jedem beliebigen Knoten kommunizieren. </p><p>Das Folgende ist eine Codedemonstration: </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. Speichern Sie die Informationen des neuen Knotens vom Seed-Knoten, einschließlich der IP- und Portnummer, da die IP- und Portnummer des neuen Knoten wird geändert werden Umstände.

2. Akzeptieren Sie die Knotenliste vom Startknoten, durchlaufen und überprüfen Sie die Knoten in der Liste und schreiben Sie sie in die Liste, wenn sie nicht identisch sind.

3. Senden Sie die Informationen des neuen Knotens an alle Knoten, und gleichzeitig aktualisieren die Knoten, die die Informationen erhalten, die Knotenliste

4. Synchronisieren Sie die Informationen lokal auf der Blockchain . Gleichzeitig werden die Informationen jedes Blocks auf der vom Seed-Knoten übertragenen Blockchain verarbeitet

3. Transaktion übertragen

Das Transaktionsmodell von BTC verwendet UTXO

Einführung in die Methode zur Implementierung einer kleinen Blockchain in Javascript (mit Code)Das Transaktionsmodell dieser kleinen Blockchain verwendet die einfachste Methode.

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

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

Das obige ist der detaillierte Inhalt vonEinführung in die Methode zur Implementierung einer kleinen Blockchain in Javascript (mit Code). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen