亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

javascript實現(xiàn)小型區(qū)塊鏈功能

 更新時間:2019年04月03日 11:27:05   作者:TiMiGerry  
這篇文章主要介紹了javascript實現(xiàn)小型區(qū)塊鏈功能,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
區(qū)塊鏈概念
狹義:區(qū)塊鏈?zhǔn)且环N按照時間順序?qū)?shù)據(jù)區(qū)塊以順序相連的方式組合成的一種鏈?zhǔn)綌?shù)據(jù)結(jié)構(gòu),并以密碼方式保證的不可篡改和不可偽造的分布式賬本。
一、挖礦(產(chǎn)生新區(qū)塊)

首先,區(qū)塊鏈?zhǔn)怯擅恳粋€區(qū)塊聯(lián)系而形成的,在產(chǎn)生新區(qū)塊之前必須先有一個最初始的區(qū)塊,這個區(qū)塊也叫創(chuàng)世區(qū)塊。通過這個創(chuàng)世區(qū)塊,不停地通過變化隨機數(shù)(nonce)來計算出符合條件的區(qū)塊。以下是創(chuàng)世區(qū)塊基本信息:

const initBlock = {
 index: 0,
 data: 'hey,this is a block chain',
 previousHash: '0',
 timestamp: '1551806536961',
 nonce: 80490,
 hash: '0000352fb27dd1141fa7265833190a53e5776b1111e275db0d9a77bf840081e6'
};
  1. index:是指每個區(qū)塊的序號
  2. data: 這里存放著區(qū)塊中所有的信息,例如轉(zhuǎn)賬,余額等數(shù)據(jù)
  3. previousHash: 指的是上一個區(qū)塊的hash值,創(chuàng)世區(qū)塊沒有上一個,顯示0即可
  4. timestamp:指的是創(chuàng)建這個區(qū)塊的時間
  5. nonce:這個是隨機數(shù),挖礦就是通過不停變換這個nonce來計算出符合條件的哈希。
  6. hash: 本區(qū)塊的hash值,通過前面5個字段的信息進行hash運算得出的值。

接著,通過不停的hash運算計算出符合條件的哈希,即挖礦。挖礦也可以調(diào)節(jié)難度的大小,例如算出的哈希值必須前3位數(shù)必須為1或者末3位數(shù)必須為1等等,這個可以自行的去定義,只要最后留一個控制的開關(guān),方便控制即可??梢栽诙x一個變量

哈希的計算:

.createHash('sha256')
 .update(index + data + previousHash + timestamp + nonce)
 .digest('hex')
_that.difficulty = 3 // 即前3位或者末3位數(shù)必須為1,數(shù)量越多難度越大

生成了符合條件的hash之后,則產(chǎn)生了新的區(qū)塊,但是還要對這個區(qū)塊進行校驗看看是否有效,因為可能這是一個被篡改的非法的區(qū)塊,也有可能和這個鏈沒有任何關(guān)系的區(qū)塊而僅僅只是符合上述哈希的規(guī)則而已。所以,需要進行一下校驗,,前后區(qū)塊的有效性。

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 //確保隨機數(shù)正確
  // 都滿足則返回true
  return true
 }

除了上面的校驗之外,還需要使用上面這個函數(shù)對整一個chain進行一個每一個塊的校驗,以保證每一個塊的信息是正確的,是沒有被篡改過的是合法的。

二、構(gòu)建P2P網(wǎng)絡(luò)

區(qū)塊鏈的網(wǎng)絡(luò)是去中心化的,即沒有中心服務(wù)器的網(wǎng)絡(luò),客戶端不需要依賴中心服務(wù)器來獲取或者處理數(shù)據(jù)。區(qū)塊鏈網(wǎng)絡(luò)中,有這許許多多的節(jié)點,每個節(jié)點都是一個獨立的成員,他們既是客戶端也是服務(wù)器,節(jié)點與節(jié)點直接都是點對點進行連接(peer-to-peer),不需要通過某一個中心服務(wù)器進行中轉(zhuǎn),所以,信息安全的角度來說,點對點的連接方式對信息私密性是非??煽康?。

雖然,區(qū)塊鏈?zhǔn)峭ㄟ^點對點的連接方式進行數(shù)據(jù)傳輸,但是,在這之前還需要一個東西作為引導(dǎo),這個就是種子節(jié)點。因為,兩個節(jié)點之間他們可能不是處在同一個域下,他們之間想要聯(lián)系,必須有一方知道對方的ip和端口,這樣才能和對方聯(lián)系上。節(jié)點ip和端口號,在這個節(jié)點創(chuàng)建出來之后,種子節(jié)點就會發(fā)給它在這個區(qū)塊鏈中所有節(jié)點的ip和端口號同時記錄下這個新伙伴的ip和端口號。

那么,新的節(jié)點拿到了這一份"通訊錄"之后,就會給這個"通訊錄"中的所有小伙伴發(fā)個消息,告訴他們有一位新的小伙伴加入,之后,其他節(jié)點收到了這個信息,也會在自己的"通訊錄"中加上新伙伴的ip和端口號,相當(dāng)于加入了白名單。這樣新的節(jié)點接下來就可以和任意的的節(jié)點進行通信了。

下面用代碼演示一下:

(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.保存種子節(jié)點傳來的此新節(jié)點的信息包括ip和端口號,因為,新節(jié)點的ip和端口號是會有改變的情況。

2.接受種子節(jié)點傳來的節(jié)點列表,將列表的節(jié)點遍歷檢查一下,沒有相同的就寫進列表中。

3.將新節(jié)點的信息廣播到所有的節(jié)點上,同時接受到信息的節(jié)點更新一下節(jié)點列表

4.將區(qū)塊鏈上信息同步一份都本地,同時對種子節(jié)點傳來的blockchain進行每個區(qū)塊的信息

三、轉(zhuǎn)賬交易

BTC的交易模型是使用的是UTXO

而這個小型區(qū)塊鏈的交易模型使用的是最簡單的方法。

區(qū)塊鏈中"現(xiàn)金”,它是一個虛擬的東西就是一個字符串,來源于挖礦。每次挖礦成功都會有一定的獎勵,得到的這些“錢”就可以在區(qū)塊鏈網(wǎng)絡(luò)中自由的轉(zhuǎn)賬交易。

在區(qū)塊鏈中,進行記錄轉(zhuǎn)賬交易的時候是需要一個加密的算法,把所有的信息進行加密之后再push到新區(qū)塊中的data中,從而完成一筆新交易的記錄。以BTC為例,BTC的加密算法是使用elliptic這個加密算法,elliptic是一個非對稱性的加密算法,非對稱的加密算法的特點就是,私鑰是惟一的,只有擁有者才可以和他私鑰對應(yīng)的公鑰進行校驗 。 nodejs也有對應(yīng)的庫在github上搜索elliptic即可。

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

上面是一個生成好的密鑰對格式,僅作為展示,我刪減了一部分長度。

使用銀行卡進行轉(zhuǎn)賬交易的時候,會有一個轉(zhuǎn)出的賬號和一個轉(zhuǎn)入的賬號,在區(qū)塊鏈中的記賬也會有這個賬號,這個賬號就是上面使用生成的密鑰對中的公鑰,公鑰就是地址,或者說公鑰代表的就是自己的錢包。

校驗的方法,首先使用字段“from”,“to”,“amount”的參數(shù)進行sign簽名,然后在每次挖礦(記賬)的時候,則使用verify(),通過前面的三個參數(shù),和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;
 }
}

轉(zhuǎn)帳的時候需要3步,分別是校驗轉(zhuǎn)出賬戶是否有足夠的金額,轉(zhuǎn)出賬戶就是本地公鑰。如有則進行記賬并且使用兩個地址、金額、時間,還有簽名加密打包,之后進行全節(jié)點廣播。其他節(jié)點收到這個信息之后第一件事也是對新區(qū)塊的有效性做一個校驗,通過校驗之后就會寫入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 }

  // 非創(chuàng)世區(qū)塊
 if (trans.from !== '0') {
   // 檢驗余額
  if (!(_that.blance < amount)) { //_that.blance 當(dāng)前賬戶余額
   //全節(jié)點廣播
   _that.send('trans', sigTrans)
  }else{
   console.log('not enough blance')
   return
  }
 }
 this.data.push(sigTrans)
 return sigTrans
}

其他節(jié)點收到消息之后,先進行去重校驗,然后再更新數(shù)據(jù)。

四、查詢余額

這個鏈的查詢方法比較簡單,就是將區(qū)塊中的每一條交易的信息進行校驗和匹配,滿足條件的就進行增減,同時忽略精度上的問題。

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
 }

至此,區(qū)塊鏈的最簡單的功能就實現(xiàn)完畢。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。

您可能感興趣的文章:

相關(guān)文章

  • JS實現(xiàn)從對象獲取對象中單個鍵值的方法示例

    JS實現(xiàn)從對象獲取對象中單個鍵值的方法示例

    這篇文章主要介紹了JS實現(xiàn)從對象獲取對象中單個鍵值的方法,涉及javascript數(shù)組對象遍歷、事件監(jiān)聽、處理等相關(guān)操作技巧,需要的朋友可以參考下
    2019-06-06
  • JavaScript遍歷求解數(shù)獨問題的主要思路小結(jié)

    JavaScript遍歷求解數(shù)獨問題的主要思路小結(jié)

    數(shù)獨游戲非常流行,其規(guī)則就是1到9數(shù)字填入9*9宮格并要求每一行、每一列、每一個粗線(小型)宮內(nèi)的數(shù)字不重復(fù),對此我們來看一下JavaScript遍歷求解數(shù)獨問題的主要思路小結(jié)
    2016-06-06
  • 基于JS實現(xiàn)類似支付寶支付密碼輸入框

    基于JS實現(xiàn)類似支付寶支付密碼輸入框

    這篇文章主要介紹了基于JS實現(xiàn)類似支付寶支付密碼輸入框功能,密碼框只準(zhǔn)輸入數(shù)字且只可以輸入6位數(shù)字,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-09-09
  • JS中對象與字符串的互相轉(zhuǎn)換詳解

    JS中對象與字符串的互相轉(zhuǎn)換詳解

    下面小編就為大家?guī)硪黄狫S中對象與字符串的互相轉(zhuǎn)換詳解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-05-05
  • Bootstarp基本模版學(xué)習(xí)教程

    Bootstarp基本模版學(xué)習(xí)教程

    這篇文章主要為大家詳細介紹了Bootstarp基本模版學(xué)習(xí)教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • 利用Three.js制作一個新聞聯(lián)播開頭動畫

    利用Three.js制作一個新聞聯(lián)播開頭動畫

    這篇文章主要為大家介紹了如何利用Three.js制作一個新聞聯(lián)播開頭動畫,文中的實現(xiàn)步驟講解詳細,對我們學(xué)習(xí)有一定幫助,需要的可以參考一下
    2022-05-05
  • JS遠程獲取網(wǎng)頁源代碼實例

    JS遠程獲取網(wǎng)頁源代碼實例

    獲取網(wǎng)頁源代碼的方法有很多,本文為大家介紹下使用JS是如何做到的,感興趣的朋友可以學(xué)習(xí)下哦
    2013-09-09
  • 有關(guān)json_decode亂碼及NULL的問題

    有關(guān)json_decode亂碼及NULL的問題

    json decode出現(xiàn)中文亂碼,返回null,很多朋友都遇到過吧,該怎么解決呢?下面小編把解決辦法分享在腳本之家網(wǎng)站上,供大家學(xué)習(xí)
    2015-10-10
  • js 字符串操作函數(shù)

    js 字符串操作函數(shù)

    js 字符串操作函數(shù)小結(jié)。
    2009-07-07
  • canvas繪制的直線動畫

    canvas繪制的直線動畫

    本文主要分享了canvas繪制的直線動畫的示例代碼。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-01-01

最新評論