[轉]區塊鏈代碼快速學習實踐


如何使用Python編寫一個簡單且安全的區塊鏈數據庫API?


GitHub項目鏈接:https://github.com/adamchinkc/blockchain_database

當我們討論區塊鏈時,我們總是把它與p2p網絡聯繫起來,認爲數據必須分散在網絡上。這也會使人們擔心區塊鏈將會破壞數據的機密性。

事實上,區塊鏈本身的數據架構已經爲保護數據免受未經授權操作提供了一個好的解決方案,並且考慮到服務器受到足夠的控制(如訪問控制、網絡和系統安全控制)的保護,最好是在內部網絡。

因此,我嘗試通過使用Python, Sqlite和RESTful API框架基於區塊鏈的數據架構創建一個數據庫。

 

區塊鏈的數據架構及其完整性

gsCt1MspoQyA

摘自於中本聰發表的比特幣白皮書《比特幣:一種點對點電子現金系統》https://bitcoin.org/bitcoin.pdf

從上圖看,每一個數據區塊都包含了上一個哈希(Prev Hash)Nonce交易(Tx)。如果你不確定什麼是哈希(Hash),你可以先閱讀這篇文章進行了解。簡而言之,哈希值是上一個區塊的一個獨一無二的ID。如果我們使用這個“獨一無二的ID“來驗證上一個區塊,我們將會知道上一個區塊是否被更改了。

這意味着什麼?這種機制允許我們確保任何人都不被允許更改先前創建的數據。如果你需要修改數據,那麼你就必須創建另一條記錄以“修改”或“刪除”它。

_g58C_aNixnw

在上面的例子中,Alice錯誤地輸入日記條目到了123.4,而正確地應該是432.1。Alice必須創建另外的記錄“刪除”推翻此前輸入的條目。

這似乎是大多數審計系統的基本職能,但是我們並不能知道這個系統在應用層上是否被控制住了,這就造成了數據可能在數據庫層被更改的可能性。

要確保從始至終沒有人能夠更改數據,我引入了一種簡單且安全的區塊鏈數據庫API。

 

基於區塊鏈數據架構的數據庫

7oDh_zLTFm-w

可審計性,保密性和完整性

當用戶創建一個交易記錄時,他將會使私鑰對交易數據進行加密並將這個數據發佈到區塊鏈數據庫API。區塊鏈數據庫API將使用該用戶的公鑰對數據進行解密。在這個過程中,用戶的身份已經被確認。這就實現了可審計性和保密性的目標。

在下一步中,這個區塊鏈數據庫API將會計算出nonce交易的哈希值,即隨機字符串和上一個哈希。區塊鏈數據庫API將把這個交易,nonce和哈希插入到這個數據庫中。

要刪除未授權的更改,區塊鏈數據庫API將基於上一個哈希,交易和nonce的信息重新計算這個哈希值。如果出現了任何更改,這個哈希值將發生變化,這個API將被通知發生了變化。從而,數據的完整性將會得到保證。

 

侷限性

 

由於處於一種中心化架構中,獲得管理權限的攻擊者有可能會通過再次重新這個哈希值來改變整個數據庫。

這個問題可以通過以下解決方案來解決:

•將此交易克隆島一個安全的日誌服務器

•以增量方式進行數據備份而不是全球備份

如何使用這個API?

1.啓動哈希API

python hash.py

2.啓動Nonce API

python nonce.py

3.啓動Main API

python main.py

4.發佈日記數據到Main API http://127.0.0.1:8000/construct,獲得帶有nonce和哈希的Response。

data1 = { 	"journal_id": "JE000001", 
	"entry_date" : "2016-11-06", 
	"create_time" : "2016-11-06 18:00:00", 
	"created_by": "Adam",
	"post_status": "P",
	"account_code" : "100000",
	"amount" : 16453.24,
	"dr_cr" : "C"
}

5.發佈Response到Main API http://127.0.0.1:8000/insert

data1 = { 	"journal_id": "JE000001", 
	"entry_date" : "2016-11-06", 
	"create_time" : "2016-11-06 18:00:00", 
	"created_by": "Adam",
	"post_status": "P",
	"account_code" : "100000",
	"amount" : 16453.24,
	"dr_cr" : "C",
  "nonue" : ".....",
  "hash" : "....."
}

6.通過Get http://127.0.0.1:8000/verify?id=1驗證您的交易。


文章來源:http://www.8btc.com/python-blockchain-database-api









200 行代碼實現一個簡單的區塊鏈


英文原文:Lauri Hartikka

區塊鏈的基礎概念很簡單:一個分佈式數據庫,存儲一個不斷加長的 list,list 中包含着許多有序的記錄。然而,在通常情況下,當我們談到區塊鏈的時候也會談起使用區塊鏈來解決的問題,這兩者很容易混淆。像流行的比特幣和以太坊這樣基於區塊鏈的項目就是這樣。“區塊鏈”這個術語通常和像交易、智能合約、加密貨幣這樣的概念緊緊聯繫在一起。

這就令理解區塊鏈變得不必要得複雜起來,特別是當你想理解源碼的時候。下面我將通過 200 行 JS 實現的超級簡單的區塊鏈來幫助大家理解它,我給這段代碼起名爲 NaiveChain。

塊結構

第一個邏輯步驟是決定塊結構。爲了保證事情儘可能的簡單,我們只選擇最必要的部分:index(下標)、timestamp(時間戳)、data(數據)、hash(哈希值)和 previous hash(前置哈希值)。

圖0:200 行代碼實現一個簡單的區塊鏈

這個塊中必須能找到前一個塊的哈希值,以此來保證整條鏈的完整性。

class Block {
    constructor(index, previousHash, timestamp, data, hash) {
        this.index = index;
        this.previousHash = previousHash.toString();
        this.timestamp = timestamp;
        this.data = data;
        this.hash = hash.toString();
    }
}

塊哈希

爲了保存完整的數據,必須哈希區塊。SHA-256會對塊的內容進行加密,記錄這個值應該和“挖礦”毫無關係,因爲這裏不需要解決工作量證明的問題。

var calculateHash = (index, previousHash, timestamp, data) => {
    return CryptoJS.SHA256(index + previousHash + timestamp + data).toString();
};

塊的生成

要生成一個塊,必須知道前一個塊的哈希值,然後創造其餘所需的內容(= index, hash, data and timestamp)。塊的data部分是由終端用戶所提供的。

var generateNextBlock = (blockData) => {
    var previousBlock = getLatestBlock();
    var nextIndex = previousBlock.index + 1;
    var nextTimestamp = new Date().getTime() / 1000;
    var nextHash = calculateHash(nextIndex, previousBlock.hash, nextTimestamp, blockData);
    return new Block(nextIndex, previousBlock.hash, nextTimestamp, blockData, nextHash);
};

塊的存儲

內存中的Javascript數組被用於存儲區塊鏈。區塊鏈的第一個塊通常被稱爲“起源塊”,是硬編碼的。

var getGenesisBlock = () => {
    return new Block(0, "0", 1465154705, "my genesis block!!", "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7");
};
 
var blockchain = [getGenesisBlock()];

確認塊的完整性

在任何時候都必須能確認一個區塊或者一整條鏈的區塊是否完整。在我們從其他節點接收到新的區塊,並需要決定接受或拒絕它們時,這一點尤爲重要。

var isValidNewBlock = (newBlock, previousBlock) => {
    if (previousBlock.index + 1 !== newBlock.index) {
        console.log('invalid index');
        return false;
    } else if (previousBlock.hash !== newBlock.previousHash) {
        console.log('invalid previoushash');
        return false;
    } else if (calculateHashForBlock(newBlock) !== newBlock.hash) {
        console.log('invalid hash: ' + calculateHashForBlock(newBlock) + ' ' + newBlock.hash);
        return false;
    }
    return true;
};

選擇最長的鏈

任何時候在鏈中都應該只有一組明確的塊。萬一衝突了(例如:兩個結點都生成了72號塊時),會選擇有最大數目的塊的鏈。

圖1:200 行代碼實現一個簡單的區塊鏈

var replaceChain = (newBlocks) => {
    if (isValidChain(newBlocks) && newBlocks.length > blockchain.length) {
        console.log('Received blockchain is valid. Replacing current blockchain with received blockchain');
        blockchain = newBlocks;
        broadcast(responseLatestMsg());
    } else {
        console.log('Received blockchain invalid');
    }
};

與其他結點的通信

結點的本質是和其他結點共享和同步區塊鏈,下面的規則能保證網絡同步。

  • 當一個結點生成一個新塊時,它會在網絡上散佈這個塊。
  • 當一個節點連接新peer時,它會查詢最新的block。
  • 當一個結點遇到一個塊,其index大於當前所有塊的index時,它會添加這個塊到它當前的鏈中,或者到整個區塊鏈中查詢這個塊。

圖2:200 行代碼實現一個簡單的區塊鏈

如圖爲當節點遵循前文所述協議時會發生的一些典型通信場景

我沒有采用自動發現peer的工具。peers的位置(URL)必須是手動添加的。

結點控制

在某種程度上用戶必須能夠控制結點。這一點通過搭建一個HTTP服務器可以實現。

var initHttpServer = () => {
    var app = express();
    app.use(bodyParser.json());
 
    app.get('/blocks', (req, res) => res.send(JSON.stringify(blockchain)));
    app.post('/mineBlock', (req, res) => {
        var newBlock = generateNextBlock(req.body.data);
        addBlock(newBlock);
        broadcast(responseLatestMsg());
        console.log('block added: ' + JSON.stringify(newBlock));
        res.send();
    });
    app.get('/peers', (req, res) => {
        res.send(sockets.map(s => s._socket.remoteAddress + ':' + s._socket.remotePort));
    });
    app.post('/addPeer', (req, res) => {
        connectToPeers([req.body.peer]);
        res.send();
    });
    app.listen(http_port, () => console.log('Listening http on port: ' + http_port));
};

用戶可以用下面的方法和結點互動:

  • 列出所有的塊
  • 用用戶提供的內容創建一個新的塊
  • 列出或者新增peers

下面這個Curl的例子就是最直接的控制結點的方法:

#get all blocks from the node
curl http://localhost:3001/blocks

體系結構

需要指出的是,節點實際上展現了兩個web服務器:一個(HTTP服務器)是讓用戶控制節點,另一個(Websocket HTTP服務器)。

圖3:200 行代碼實現一個簡單的區塊鏈

NaiveChain的主要組成部分

總結

創造 NaiveChain 的目的是爲了示範和學習,因爲它並沒有“挖礦”算法(PoS of PoW),不能被用於公用網絡,但是它實現了區塊鏈運作的基本特性。

你可以在 Github 庫中查看更多的技術細節。 https://github.com/lhartikk/naivechain


文章來源:http://blog.csdn.net/HyNeverGiveUp/article/details/70233564 








用不到200行的Python代碼實現一個區塊鏈


原文:A Python Implementation of a simple blockchain 
翻譯:無阻我飛揚

摘要:本文來自github,描述瞭如何用少量的Python代碼實現一個簡單的blockchain,以下是譯文。

描述

pysimplechain的實現完全聚焦於哈希賬本功能。它不包含任何高級功能,諸如分佈式賬本或者通過工作量證明的一致性協議。在這個項目中,還會發現“事務”的概念被抽象爲一個更通用的“消息”概念,它可以包含任何類型的數據。

因此,這個項目的目標是解釋和澄清什麼是blockchain最核心的結構。項目的意圖不是爲了重寫一個高級的blockchain,如比特幣或以太坊。

這個blockchain通過包含三個類的simple_chain.py文件實現。Message()類,Block()類和Chain()類。

message是基本的數據容器。當增加一個塊時,它被密封,塊中具有標識它的2個哈希值:有效載荷哈希和塊哈希。每個消息通過哈希指針(prev_hash屬性)鏈接到前一個消息。validate消息的方法將確保每個消息的完整性,但不會檢查哈希指針正確與否。這個工作留給在Block()類中的validate方法去完成。

block包含一個接一個地依次鏈接的1,…,n個消息。當一個block添加到chain時,它被密封和驗證,以確保消息正確排序,並且哈希指針匹配。一旦塊被密封和哈希,它將通過檢查期望值與實際值進行驗證。

chain包含一個接一個依次鏈接的1,…,m個塊。可以隨時調用validate方法來驗證鏈的完整性,它將調用每個塊的驗證方法,一旦驗證不通過,將拋出InvalidBlockchain異常。

交互性:

manager()函數,通過終端/控制檯與blockchain交互。基本動作是:

  • 添加消息到塊:允許向當前塊添加消息;
  • 添加塊到鏈:允許將當前塊添加到鏈,如果它不爲空;
  • 顯示塊:請求一個索引,如果存在具有該索引的塊,則返回一些塊屬性;
  • 顯示鏈:返回鏈中每個塊的一些屬性;
  • 驗證完整性:如果驗證是完整的,則返回True,否則終止程序,拋出適當的異常;
  • 退出:終止程序並刪除區塊鏈。

貢獻

歡迎大家有新的想法:打開/關閉issues,fork repo,通過Pull請求分享你的代碼。 
將此項目克隆到您的計算機: 
git clone https://github.com/EricAlcaide/pysimplechain


來源:http://blog.csdn.net/dev_csdn/article/details/78454542?fps=1&locationNum=2




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章