本篇文章给大家带来的内容是关于javascript实现小型区块链的方法介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
区块链概念
狭义:区块链是一种按照时间顺序将数据区块以顺序相连的方式组合成的一种链式数据结构,并以密码方式保证的不可篡改和不可伪造的分布式账本。
一、挖矿(产生新区块)
首先,区块链是由每一个区块联系而形成的,在产生新区块之前必须先有一个最初始的区块,这个区块也叫创世区块。通过这个创世区块,不停地通过变化随机数(nonce)来计算出符合条件的区块。以下是创世区块基本信息:
const initBlock = { index: 0, data: 'hey,this is a block chain', previousHash: '0', timestamp: '1551806536961', nonce: 80490, hash: '0000352fb27dd1141fa7265833190a53e5776b1111e275db0d9a77bf840081e6' };
- index:是指每个区块的序号
- data: 这里存放着区块中所有的信息,例如转账,余额等数据
- previousHash: 指的是上一个区块的hash值,创世区块没有上一个,显示0即可
- timestamp:指的是创建这个区块的时间
- nonce:这个是随机数,挖矿就是通过不停变换这个nonce来计算出符合条件的哈希。
- hash: 本区块的hash值,通过前面5个字段的信息进行hash运算得出的值。
接着,通过不停的hash运算计算出符合条件的哈希,即挖矿。挖矿也可以调节难度的大小,例如算出的哈希值必须前3位数必须为1或者末3位数必须为1等等,这个可以自行的去定义,只要最后留一个控制的开关,方便控制即可。可以在定义一个变量
哈希的计算:
.createHash('sha256') .update(index + data + previousHash + timestamp + nonce) .digest('hex')
_that.difficulty = 3 // 即前3位或者末3位数必须为1,数量越多难度越大
生成了符合条件的hash之后,则产生了新的区块,但是还要对这个区块进行校验看看是否有效,因为可能这是一个被篡改的非法的区块,也有可能和这个链没有任何关系的区块而仅仅只是符合上述哈希的规则而已。所以,需要进行一下校验,,前后区块的有效性。
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 }
除了上面的校验之外,还需要使用上面这个函数对整一个chain进行一个每一个块的校验,以保证每一个块的信息是正确的,是没有被篡改过的是合法的。
二、构建P2P网络
区块链的网络是去中心化的,即没有中心服务器的网络,客户端不需要依赖中心服务器来获取或者处理数据。区块链网络中,有这许许多多的节点,每个节点都是一个独立的成员,他们既是客户端也是服务器,节点与节点直接都是点对点进行连接(peer-to-peer),不需要通过某一个中心服务器进行中转,所以,信息安全的角度来说,点对点的连接方式对信息私密性是非常可靠的。
虽然,区块链是通过点对点的连接方式进行数据传输,但是,在这之前还需要一个东西作为引导,这个就是种子节点。因为,两个节点之间他们可能不是处在同一个域下,他们之间想要联系,必须有一方知道对方的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.将区块链上信息同步一份都本地,同时对种子节点传来的blockchain进行每个区块的信息
三、转账交易
BTC的交易模型是使用的是UTXO
而这个小型区块链的交易模型使用的是最简单的方法。
区块链中"现金”,它是一个虚拟的东西就是一个字符串,来源于挖矿。每次挖矿成功都会有一定的奖励,得到的这些“钱”就可以在区块链网络中自由的转账交易。
在区块链中,进行记录转账交易的时候是需要一个加密的算法,把所有的信息进行加密之后再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 < 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 }
至此,区块链的最简单的功能就实现完毕。
【相关推荐:JavaScript视频教程】
Atas ialah kandungan terperinci javascript实现小型区块链的方法介绍(附代码). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Python dan JavaScript mempunyai kelebihan dan kekurangan mereka sendiri dari segi komuniti, perpustakaan dan sumber. 1) Komuniti Python mesra dan sesuai untuk pemula, tetapi sumber pembangunan depan tidak kaya dengan JavaScript. 2) Python berkuasa dalam bidang sains data dan perpustakaan pembelajaran mesin, sementara JavaScript lebih baik dalam perpustakaan pembangunan dan kerangka pembangunan depan. 3) Kedua -duanya mempunyai sumber pembelajaran yang kaya, tetapi Python sesuai untuk memulakan dengan dokumen rasmi, sementara JavaScript lebih baik dengan MDNWebDocs. Pilihan harus berdasarkan keperluan projek dan kepentingan peribadi.

Peralihan dari C/C ke JavaScript memerlukan menyesuaikan diri dengan menaip dinamik, pengumpulan sampah dan pengaturcaraan asynchronous. 1) C/C adalah bahasa yang ditaip secara statik yang memerlukan pengurusan memori manual, manakala JavaScript ditaip secara dinamik dan pengumpulan sampah diproses secara automatik. 2) C/C perlu dikumpulkan ke dalam kod mesin, manakala JavaScript adalah bahasa yang ditafsirkan. 3) JavaScript memperkenalkan konsep seperti penutupan, rantaian prototaip dan janji, yang meningkatkan keupayaan pengaturcaraan fleksibiliti dan asynchronous.

Enjin JavaScript yang berbeza mempunyai kesan yang berbeza apabila menguraikan dan melaksanakan kod JavaScript, kerana prinsip pelaksanaan dan strategi pengoptimuman setiap enjin berbeza. 1. Analisis leksikal: Menukar kod sumber ke dalam unit leksikal. 2. Analisis Tatabahasa: Menjana pokok sintaks abstrak. 3. Pengoptimuman dan Penyusunan: Menjana kod mesin melalui pengkompil JIT. 4. Jalankan: Jalankan kod mesin. Enjin V8 mengoptimumkan melalui kompilasi segera dan kelas tersembunyi, Spidermonkey menggunakan sistem kesimpulan jenis, menghasilkan prestasi prestasi yang berbeza pada kod yang sama.

Aplikasi JavaScript di dunia nyata termasuk pengaturcaraan sisi pelayan, pembangunan aplikasi mudah alih dan Internet of Things Control: 1. Pengaturcaraan sisi pelayan direalisasikan melalui node.js, sesuai untuk pemprosesan permintaan serentak yang tinggi. 2. Pembangunan aplikasi mudah alih dijalankan melalui reaktnatif dan menyokong penggunaan silang platform. 3. Digunakan untuk kawalan peranti IoT melalui Perpustakaan Johnny-Five, sesuai untuk interaksi perkakasan.

Saya membina aplikasi SaaS multi-penyewa berfungsi (aplikasi edTech) dengan alat teknologi harian anda dan anda boleh melakukan perkara yang sama. Pertama, apakah aplikasi SaaS multi-penyewa? Aplikasi SaaS Multi-penyewa membolehkan anda melayani beberapa pelanggan dari Sing

Artikel ini menunjukkan integrasi frontend dengan backend yang dijamin oleh permit, membina aplikasi edtech SaaS yang berfungsi menggunakan Next.Js. Frontend mengambil kebenaran pengguna untuk mengawal penglihatan UI dan memastikan permintaan API mematuhi dasar peranan

JavaScript adalah bahasa utama pembangunan web moden dan digunakan secara meluas untuk kepelbagaian dan fleksibiliti. 1) Pembangunan front-end: Membina laman web dinamik dan aplikasi satu halaman melalui operasi DOM dan kerangka moden (seperti React, Vue.js, sudut). 2) Pembangunan sisi pelayan: Node.js menggunakan model I/O yang tidak menyekat untuk mengendalikan aplikasi konkurensi tinggi dan masa nyata. 3) Pembangunan aplikasi mudah alih dan desktop: Pembangunan silang platform direalisasikan melalui reaktnatif dan elektron untuk meningkatkan kecekapan pembangunan.

Trend terkini dalam JavaScript termasuk kebangkitan TypeScript, populariti kerangka dan perpustakaan moden, dan penerapan webassembly. Prospek masa depan meliputi sistem jenis yang lebih berkuasa, pembangunan JavaScript, pengembangan kecerdasan buatan dan pembelajaran mesin, dan potensi pengkomputeran IoT dan kelebihan.


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

SublimeText3 versi Inggeris
Disyorkan: Versi Win, menyokong gesaan kod!

Pelayar Peperiksaan Selamat
Pelayar Peperiksaan Selamat ialah persekitaran pelayar selamat untuk mengambil peperiksaan dalam talian dengan selamat. Perisian ini menukar mana-mana komputer menjadi stesen kerja yang selamat. Ia mengawal akses kepada mana-mana utiliti dan menghalang pelajar daripada menggunakan sumber yang tidak dibenarkan.

ZendStudio 13.5.1 Mac
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver Mac版
Alat pembangunan web visual

Dreamweaver CS6
Alat pembangunan web visual