欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

利用Java代碼實(shí)現(xiàn)區(qū)塊鏈技術(shù)

 更新時(shí)間:2022年04月14日 14:42:09   作者:Java博客  
這篇文章主要介紹了利用Java代碼實(shí)現(xiàn)區(qū)塊鏈技術(shù),區(qū)塊鏈的應(yīng)用范圍幾乎無(wú)窮無(wú)盡,關(guān)于區(qū)塊鏈?zhǔn)侨绾芜\(yùn)作的,下文來(lái)看看具體的內(nèi)容介紹吧,需要的朋友可以參考一下

前言:

比特幣很熱門(mén)——這是多么輕描淡寫(xiě)的說(shuō)法啊。雖然加密貨幣的未來(lái)有些不確定,但用于驅(qū)動(dòng)比特幣的區(qū)塊鏈技術(shù)也非常流行。

區(qū)塊鏈的應(yīng)用范圍幾乎無(wú)窮無(wú)盡??梢哉f(shuō),它還有可能破壞企業(yè)自動(dòng)化。

本文將重點(diǎn)關(guān)注區(qū)塊鏈體系結(jié)構(gòu),特別是演示“不可變、僅附加”分布式賬本如何與簡(jiǎn)化的代碼示例一起工作。

作為開(kāi)發(fā)人員,與簡(jiǎn)單地閱讀技術(shù)文章相比,在理解代碼的工作原理時(shí),從代碼中看到東西要有用得多。至少對(duì)我來(lái)說(shuō)是這樣。那么,讓我們開(kāi)始吧!

簡(jiǎn)言之,區(qū)塊鏈

首先讓我們快速總結(jié)一下區(qū)塊鏈。一個(gè)塊包含一些標(biāo)題信息和一組或一塊任何類(lèi)型數(shù)據(jù)的事務(wù)。鏈從第一個(gè)(起源)塊開(kāi)始。在添加/追加事務(wù)時(shí),將根據(jù)一個(gè)塊中可以存儲(chǔ)的事務(wù)數(shù)量創(chuàng)建新的塊。

當(dāng)超過(guò)塊閾值大小時(shí),將創(chuàng)建一個(gè)新的事務(wù)塊。新區(qū)塊與前一區(qū)塊相連,因此稱(chēng)為區(qū)塊鏈。

不變性

區(qū)塊鏈?zhǔn)遣豢勺兊?,因?yàn)闉榻灰子?jì)算SHA-256哈希。塊的內(nèi)容也會(huì)被散列,從而提供唯一的標(biāo)識(shí)符。此外,來(lái)自鏈接的前一個(gè)塊的散列也被存儲(chǔ)并散列在塊頭中。

這就是為什么試圖篡改區(qū)塊鏈區(qū)塊基本上是不可能的,至少在目前的計(jì)算能力下是如此。下面是一個(gè)顯示塊屬性的部分Java類(lèi)定義。

...
public class Block<T extends Tx> {
	public long timeStamp;
	private int index;
	private List<T> transactions = new ArrayList<T>();
	private String hash;
	private String previousHash;
	private String merkleRoot;
	private String nonce = "0000";
	
	// caches Transaction SHA256 hashes
    public Map<String,T> map = new HashMap<String,T>();
...

請(qǐng)注意,注入的泛型類(lèi)型是Tx類(lèi)型。這允許事務(wù)數(shù)據(jù)發(fā)生變化。此外,previousHash屬性將引用前一個(gè)塊的哈希。merkleRootnonce屬性將在稍后進(jìn)行描述。

塊散列

每個(gè)塊可以計(jì)算一個(gè)塊散列。這本質(zhì)上是連接在一起的所有塊屬性的散列,包括前一個(gè)塊的散列和由此計(jì)算出的SHA-256散列。

下面是塊中定義的方法。計(jì)算散列的java類(lèi)。

...
public void computeHash() {
     Gson parser = new Gson(); // probably should cache this instance
     String serializedData = parser.toJson(transactions);	  
     setHash(SHA256.generateHash(timeStamp + index + merkleRoot + serializedData + nonce + previousHash));
     }
...

塊事務(wù)被序列化為JSON字符串,以便在散列之前將其附加到塊屬性中。

Chain 鏈

區(qū)塊鏈通過(guò)接受交易來(lái)管理區(qū)塊。當(dāng)達(dá)到預(yù)定閾值時(shí),創(chuàng)建塊。這是一個(gè)簡(jiǎn)單的Chain鏈。java部分實(shí)現(xiàn):

...
public class SimpleBlockchain<T extends Tx> {
	public static final int BLOCK_SIZE = 10;
	public List<Block<T>> chain = new ArrayList<Block<T>>();

	public SimpleBlockchain() {
		// create genesis block
		chain.add(newBlock());
	}

...

注意,chain屬性包含使用Tx類(lèi)型鍵入的塊的列表。此外,在創(chuàng)建鏈時(shí),無(wú)參數(shù)構(gòu)造函數(shù)會(huì)創(chuàng)建一個(gè)初始的“genesis”塊。下面是newBlock()方法的源代碼。

public Block<T> newBlock() {
		int count = chain.size();
		String previousHash = "root";

		if (count > 0)
			previousHash = blockChainHash();

		Block<T> block = new Block<T>();

		block.setTimeStamp(System.currentTimeMillis());
		block.setIndex(count);
		block.setPreviousHash(previousHash);
		return block;
	}

這個(gè)新的block方法將創(chuàng)建一個(gè)新的block實(shí)例,為適當(dāng)?shù)闹翟O(shè)定種子,并分配前一個(gè)block的hash(即鏈頭的hash)。然后它將返回塊。

在將塊添加到鏈之前,可以通過(guò)將新塊的上一個(gè)哈希與鏈的最后一個(gè)塊(頭)進(jìn)行比較來(lái)驗(yàn)證塊,以確保它們匹配。這是一個(gè)簡(jiǎn)單的鎖鏈。java方法描述了這一點(diǎn)。

public void addAndValidateBlock(Block<T> block) {

		// compare previous block hash, add if valid
		Block<T> current = block;
		for (int i = chain.size() - 1; i >= 0; i--) {
			Block<T> b = chain.get(i);
			if (b.getHash().equals(current.getPreviousHash())) {
				current = b;
			} else {

				throw new RuntimeException("Block Invalid");
			}

		}

		this.chain.add(block);
}

整個(gè)區(qū)塊鏈通過(guò)鏈的循環(huán)進(jìn)行驗(yàn)證,以確保一個(gè)區(qū)塊的哈希仍然與前一個(gè)區(qū)塊的哈希匹配。

這是SimpleBlockChain.java的 validate()方法實(shí)現(xiàn)。

public boolean validate() {

		String previousHash = null;
		for (Block<T> block : chain) {
			String currentHash = block.getHash();
			if (!currentHash.equals(previousHash)) {
				return false;
			}

			previousHash = currentHash;

		}

		return true;

	}

你可以看到,試圖以任何方式偽造交易數(shù)據(jù)或任何其他財(cái)產(chǎn)都是非常困難的。而且,隨著鏈條的增長(zhǎng),它繼續(xù)變得非常、非常、非常困難,基本上是不可能的。直到量子計(jì)算機(jī)問(wèn)世

添加事務(wù)

區(qū)塊鏈技術(shù)的另一個(gè)重要技術(shù)點(diǎn)是它是分布式的。它們是附加的這一事實(shí)只會(huì)有助于在參與區(qū)塊鏈網(wǎng)絡(luò)的節(jié)點(diǎn)之間復(fù)制區(qū)塊鏈。節(jié)點(diǎn)通常以點(diǎn)對(duì)點(diǎn)的方式進(jìn)行通信,比特幣就是這樣,但不一定要這樣。其他區(qū)塊鏈實(shí)施使用分散的方法,比如通過(guò)HTTP使用API。然而,這是另一個(gè)博客的主題。

事務(wù)幾乎可以代表任何東西。事務(wù)可以包含要執(zhí)行的代碼(即智能合約),或者存儲(chǔ)和附加有關(guān)某種業(yè)務(wù)事務(wù)的信息。

智能合同:旨在以數(shù)字方式促進(jìn)、驗(yàn)證或強(qiáng)制執(zhí)行合同談判或履行的計(jì)算機(jī)協(xié)議。

就比特幣而言,交易包含從所有者賬戶(hù)到其他賬戶(hù)的金額(即在賬戶(hù)之間轉(zhuǎn)移比特幣金額)。交易中還包括公鑰和帳戶(hù)ID,因此傳輸是安全的。但這是比特幣特有的。

將交易添加到網(wǎng)絡(luò)并合并;它們不在一個(gè)區(qū)塊或鏈條中。

這就是區(qū)塊鏈共識(shí)機(jī)制發(fā)揮作用的地方。這里有許多經(jīng)過(guò)驗(yàn)證的共識(shí)算法和模式,超出了本博客的范圍。

挖掘是比特幣區(qū)塊鏈?zhǔn)褂玫墓沧R(shí)機(jī)制。這就是本博客進(jìn)一步討論的共識(shí)類(lèi)型。共識(shí)機(jī)制收集事務(wù),用它們構(gòu)建塊,然后將塊添加到鏈中。然后,鏈在添加到鏈之前驗(yàn)證新的事務(wù)塊。

Merkle樹(shù)

事務(wù)被散列并添加到塊中。創(chuàng)建Merkle樹(shù)數(shù)據(jù)結(jié)構(gòu)來(lái)計(jì)算Merkle根哈希。每個(gè)塊將存儲(chǔ)Merkle樹(shù)的根,這是一個(gè)平衡的哈希二叉樹(shù),其中內(nèi)部節(jié)點(diǎn)是兩個(gè)子哈希的哈希,一直到根哈希,即Merkle根。

用Java代碼實(shí)現(xiàn)區(qū)塊鏈技術(shù)

此樹(shù)用于驗(yàn)證塊事務(wù),如果在任何事務(wù)中更改了單個(gè)信息位,Merkle根將無(wú)效。此外,它們還可以幫助以分布式方式傳輸塊,因?yàn)樵摻Y(jié)構(gòu)只允許添加和驗(yàn)證整個(gè)事務(wù)塊所需的事務(wù)哈希的單個(gè)分支。

下面是模塊中的方法。從事務(wù)列表中創(chuàng)建Merkle樹(shù)的java類(lèi)。

public List<String> merkleTree() {		
		ArrayList<String> tree = new ArrayList<>();
		// Start by adding all the hashes of the transactions as leaves of the
		// tree.
		for (T t : transactions) {
			tree.add(t.hash());
		}
		int levelOffset = 0; // Offset in the list where the currently processed
								// level starts.
		// Step through each level, stopping when we reach the root (levelSize
		// == 1).
	for (int levelSize = transactions.size(); levelSize > 1; levelSize = (levelSize + 1) / 2) {
			// For each pair of nodes on that level:
			for (int left = 0; left < levelSize; left += 2) {
				// The right hand node can be the same as the left hand, in the
				// case where we don't have enough
				// transactions.
				int right = Math.min(left + 1, levelSize - 1);
				String tleft = tree.get(levelOffset + left);
				String tright = tree.get(levelOffset + right);
				tree.add(SHA256.generateHash(tleft + tright));
			}
			// Move to the next level.
			levelOffset += levelSize;
		}
		return tree;
	}

該方法用于計(jì)算塊的Merkle樹(shù)根。配套項(xiàng)目有一個(gè)Merkle樹(shù)單元測(cè)試,它試圖將事務(wù)添加到塊中,并驗(yàn)證Merkle根是否已更改。下面是單元測(cè)試的源代碼。

@Test
	public void merkleTreeTest() {

		// create chain, add transaction

		SimpleBlockchain<Transaction> chain1 = new SimpleBlockchain<Transaction>();

		chain1.add(new Transaction("A")).add(new Transaction("B")).add(new Transaction("C")).add(new Transaction("D"));

		// get a block in chain
		Block<Transaction> block = chain1.getHead();

		System.out.println("Merkle Hash tree :" + block.merkleTree());

		// get a transaction from block
		Transaction tx = block.getTransactions().get(0);

		// see if block transactions are valid, they should be
		block.transasctionsValid();
		assertTrue(block.transasctionsValid());

		// mutate the data of a transaction
		tx.setValue("Z");

		// block should no longer be valid, blocks MerkleRoot does not match computed merkle tree of transactions
		assertFalse(block.transasctionsValid());

	}

此單元測(cè)試模擬驗(yàn)證事務(wù),然后在一致性機(jī)制之外的塊中更改事務(wù),即如果有人試圖更改事務(wù)數(shù)據(jù)。

記住,區(qū)塊鏈只是附加的,由于區(qū)塊鏈數(shù)據(jù)結(jié)構(gòu)在節(jié)點(diǎn)之間共享,塊數(shù)據(jù)結(jié)構(gòu)(包括Merkle根)被散列并連接到其他塊。所有節(jié)點(diǎn)都可以驗(yàn)證新塊,現(xiàn)有塊可以很容易地被證明是有效的。因此,一個(gè)礦工試圖添加一個(gè)虛假的區(qū)塊,或者一個(gè)節(jié)點(diǎn)試圖調(diào)整舊的交易,實(shí)際上是不可能的,在太陽(yáng)長(zhǎng)成超新星并給所有人一個(gè)非常好的棕褐色之前。

采礦工作證明

將交易組合成一個(gè)區(qū)塊,然后提交給鏈成員驗(yàn)證的過(guò)程在比特幣領(lǐng)域被稱(chēng)為“挖掘”。

更一般地說(shuō),在區(qū)塊鏈中,這被稱(chēng)為共識(shí)。有不同類(lèi)型的經(jīng)驗(yàn)證的分布式一致性算法。使用哪種機(jī)制取決于您是否擁有公共區(qū)塊鏈或許可區(qū)塊鏈。我們的白皮書(shū)對(duì)此進(jìn)行了更深入的描述,但本博客的重點(diǎn)是區(qū)塊鏈機(jī)制,因此本例我們將應(yīng)用一種工作證明共識(shí)機(jī)制。

因此,挖掘節(jié)點(diǎn)將監(jiān)聽(tīng)區(qū)塊鏈正在執(zhí)行的交易,并執(zhí)行一個(gè)簡(jiǎn)單的數(shù)學(xué)謎題。這個(gè)謎題使用一個(gè)在每次迭代中都會(huì)更改的nonce值生成具有一組預(yù)先確定的前導(dǎo)零的塊散列,直到找到前導(dǎo)零散列為止。

示例Java項(xiàng)目有一個(gè)Miner.java類(lèi),帶有一個(gè)proofwork(Block)方法實(shí)現(xiàn),如下所示。

private String proofOfWork(Block block) {

		String nonceKey = block.getNonce();
		long nonce = 0;
		boolean nonceFound = false;
		String nonceHash = "";

		Gson parser = new Gson();
		String serializedData = parser.toJson(transactionPool);
		String message = block.getTimeStamp() + block.getIndex() + block.getMerkleRoot() + serializedData
				+ block.getPreviousHash();

		while (!nonceFound) {

			nonceHash = SHA256.generateHash(message + nonce);
			nonceFound = nonceHash.substring(0, nonceKey.length()).equals(nonceKey);
			nonce++;

		}

		return nonceHash;

	}

同樣,這是簡(jiǎn)化的,但是一旦收到一定數(shù)量的事務(wù),miner實(shí)現(xiàn)將對(duì)塊執(zhí)行工作證明哈希。該算法只是循環(huán)并創(chuàng)建塊的SHA-256散列,直到產(chǎn)生前導(dǎo)數(shù)散列。

這可能需要很多時(shí)間,這就是為什么要實(shí)現(xiàn)特定的GPU微處理器來(lái)盡可能快地執(zhí)行和解決這個(gè)問(wèn)題。

單元測(cè)試

您可以在GitHub上看到所有這些概念與Java示例項(xiàng)目的JUnit測(cè)試結(jié)合在一起。

用Java代碼實(shí)現(xiàn)區(qū)塊鏈技術(shù)

最后的想法

希望這篇文章能給你帶來(lái)足夠的興趣和洞察力,讓你繼續(xù)研究區(qū)塊鏈技術(shù)。

到此這篇關(guān)于利用Java代碼實(shí)現(xiàn)區(qū)塊鏈技術(shù)的文章就介紹到這了,更多相關(guān)Java實(shí)現(xiàn)區(qū)塊鏈內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論