目录
面向区块链应用的Java编程
1、什么是区块链
2、如何验证区块链
3、如何挖掘区块
4、区块链的工作方式
5、区块链的应用
5.1、比特币
5.2、智能合约
5.3、医疗
5.4、制造业和供应链
5.5、物联网
6、关于区块链的一些问题
7、Java区块链实例
8、Java区块链交易示例
区块链是当前最热热门的话题之一,什么是区块链?它与比特币有什么关系?
区块链技术的最初目的是充当加密货币比特币的分布式、数字化、公开化的交易双重支付。使用公开的交易账户账本,当第二次视图使用相同的数字代币时,交易将得不到确认。如今,区块链在许多领域显示出了潜力,如智能合约、智能物业,保险、音乐、医疗保健、制造、供应链、艺术、物联网等。区块链是另一种可能会彻底改变人们生活和方式的数字技术。
简而言之,如图,区块链基本上是一条包含区块链,每个区块链都包含一些信息(数据)。对于数字货币领域的区块链,数据可以是转账金额,发送者和接收者的身份、日期和时间等。每个区块还包含索引、前一区块的哈希值、时间戳、随机数以及区块自己的哈希值,每个区块可以通过哈希值连接到前一区块,因此所有区块都像菊花链一样连接一起,只是这里还获得了区块链的名称。区块链中的第一个区块名为创世区块,没有连接前一区块,因此前一区块的哈希值为NULL。索引是每一个区块的唯一编号,第一个区块的索引为0,第二个区块的索引为1,第三个区块的索引为2,以此类推。时间戳是区块链的创建日期和时间,随机数是32位(4字节)的整数,用于控制区块的哈希计算结果。
每个区块都使用自己的索引、前一区块的哈希值、数据、时间戳和随机数以填充如SHA-256的哈希函数,从而创建自己的哈希值,如上图,(哈希函数是一个数学函数,可以用来将任何大小的数据映射到固定大小的数据。与加密不同,哈希是不可逆的。如果有人得到当前块的哈希值,它们就不可能在区块中找出信息。)
区块链是一系列信息的记录,例如一系列交易。区块链在形成之后,必须进行验证。在验证区块链时,必须验证区块链中的每一个区块,可从创世区块开始。
验证区块并不困难,只需要执行两个步骤。首先,需要测试前一区块的哈希值是否与当前区块的哈希值相同(对第一个区块的验证可以跳过此步骤)。其次,需要用区块的索引、前一区块的哈希值、数据、时间戳和随机数填充哈希函数(例如 SHA-256),以计算当前区块的哈希值,从而查看新计算的哈希值与区块中原始的哈希值是否相同。如果这两个步骤能执行成功,就说明区块有效。如果区块链中的所有区块都有效,就说明整个区块链是有效的。
现在,如果尝试在创建区块链之后更改区块链中区块2的数据,会发生什么?当更改数据时,区块将变得无效,因为新的哈希值将与现有的哈希值不匹配。可以使用新的哈希值替换现有的哈希值以使区块有效,但是这样区块3将无效,因为之前的哈希值不再匹配区块2中新的哈希值。当然,也可以使用区块2中新的哈希值替换区块3中前一区块的哈希值,但是之后需要重载计算区块3的哈希值以使用区块3再次有效。然后你必须对区块4、5、6等重复执行这个步骤,直到区块链的末端。这就是区块链中使用哈希的好处。一旦创建了区块链,就无法再更改。当你试图从区块链中删除区块或新的区块插入其中时,也会发生同样的情况。
对区块链进步更改唯一方法是在更改区块之后重新计算所有区块哈希值,但是区块链技术提供了一种共识机制防止这种情况发生,这种机制被称为工作量证明。
区块链技术中的工作量证明系统意味着当计算哈希值,哈希值需要以一定数量的 0 开始。0 越多意味着难度越大,0 越少意味着难度越小。区块链使用难度来控制区块的创建时间。如果难度值为5,那么意味着哈希值必须以 5 个 0 开头。因为区块中的所有其他信息(例如索引、前一区块的哈希值、数据和工作时间戳)都是固定的,所以唯一可以更改的就是随机数。通常尝试不同的随机数,反复计算哈希,直到获得以所需数量的 0 开始的哈希值,这称为区块挖掘。显然难度值越高,挖掘区块所需的时间就越长。平均而言,挖掘一块区块大约需要0分钟。如果区块链较长,那么挖掘所有区块的时间将更长。这还只是一条区块。如果有数百万用户,那就需要更改数百万区块链。工作量证明系统几乎不可能更改区块链中的信息。这就是区块链与其他技术有所不同的原因,也是区块链在许多应用中潜在价值的原因。
以汇款为例:传统方式下,如果 A 要向 B 汇款,A 需要通过银行进行这项操作,因为双方都信任银行。这是一种集中式汇款,在这种方式下,银行就像一本账本。这种方式存在几个问题。首先,银行会对这项服务收费,特别是,如果要汇一大笔钱,费用可能非常高。其次,交易需要时间,尤其是国际交易。最后,如果银行出现问题,就像2008年金融危机那样,A 和 B 都会遭殃。
相反,区块链使用的是分布式汇款。在这种方式下,如果A要项 B 汇款,A 只需要现有的区块链中添加一个新的区块。新的区块将将包含发送方的名称、接收方的名称以及要汇的金额之类的信息。然后后,将区块链复制给网络中的每个用户,称为peer。peer形成点对点网络,所有peer一起表现为分布式账本的一种形式。这带来如下好处:免费、快速且透明。与传统的集中式汇款不同的是,A 实际上并没有向 B 发送任何东西——没有账户,也没有余额。所有用户共享一条区块链,然后计算谁发送了什么,谁接收了什么,最后的余额是多少。因此,数字货币就是存在于一系列的交易记录中的数字。
如果B想要通过改变区块链中的信息来进行欺诈,那么B不仅需要更改自己的区块链,还需要更改网络中所有用户的区块链,由于存在工作量证明系统,这实际上不可能实现的。
下面总结区块链技术的主要特点和优点。
去中心化 这是区块链技术的核心概念,也是核心价值所在,没有使用集中的账本记录和确认交易;相反,网络中的用户
共同扮演着分布式账本的角色。因此,服务是免费的,而且速度很快,交易时间可能只有几小时,而不是几天。
不可篡改 一旦创建了区块,就无法更改。即不能在区块链中添加或删除区块,也不能更改区块中的任何信息。唯一可以
做的就是在区块链末尾添加新的区块。这种不可擅改性是区块链的另一主要优势,从而为人们带来了安全性和可
靠新。
透明性 在点对点网络中,因为所有的交易记录都是与所有用户共享的,所以一切都是透明的,没有黑盒子。
高可用性 由于交易记录在点对点网络中与所有用户共享,因此不存在单点故障问题,数据高度可用。
展示了一个虚拟的区块链演示网站(Blockchain Demo - A visual demo of blockchain technology),你可以到区块的内容,将新的区块添加到区块链中,并添加更多的peer。
区块链技术有许多应用,下面介绍一些示例。
第一也是最重要的应用是数字货币,也称为加密货币,因为数字货币是通过加密来进行保护的。有许多数字货币。最受欢迎的是比特币(BTC),符号 B 。比特币由中文聪发明,并于2009年作为开源软件发布。比特币可以转移和退换成真实货币、产品和服务。世界上有数百万比特币用户,每个月产生数百万笔交易。一枚比特币的价格已经从几美分上涨到了万美元。交易时,不需要和购买一枚完整的比特币。可以买卖的最小比特币单位为 “聪” —— 一枚比特币的一亿分之一。与可以无限供应的真实货币不同,比特币的供应有限。比特币是通过名为比特币挖矿的过程中产生的。比特币挖矿基本上是一个验证最近交易、向区块链中添加新的区块并获得奖励的过程。通过比特币挖矿,新的比特币被创造出来,但每小时只能创建少量比特币,并受底层算法严格控制。新比特币被不断创造,直到2100万枚的上限。这种有限的供应使比特币成为一种潜在资产:随着需要的增加,价值也会增加。
如图,展示了比特币区块的内部结构。每个区块都有头和主体。头部分布包前一区块的头部分的哈希值、时间戳、目标难度、随机数和Merkle根。主题包含所有交易。每给区块包含约500笔交易。每笔交易都将计算自己的哈希值,然后将所有的哈希值一起计算得到最终的哈希值。最终的哈希值存储在Merkle根或Tx_Roor中。
三层的比特币服务架构。
底层是点对点网络:这里用来将所有节点或用户连接在一起的地方。
中间层是去中心化的账本,中间层是用来实现区块链技术。
顶层是应用层:用来实现诸如比特币钱包的应用。
有几个网站可以供研究比特币区块链的结构。Bloct Explorer(Chainlink - LINK Price, Live Chart, and News | Blockchain.com)示例,可以看到比特币主链中的总块数(称为高度)在时为227594,最近的区块创建于大约6分钟之前(称为区块链的年龄),其中包含652笔交易,发送的比特币数量1686.25,区块大小为313.35KB。
通过访问如下连接,可以查看最新的比特币交易和比特币区块的结构:
BlockExplorer.com | Home 另一个有趣的网站是Learn Me a Bitcoin,通过该网站可以学习比特币方面的术语,还可以浏览比特币区块的信息:Bitcoin Technical Guide | Simple Explanations of How Bitcoin Works 但是,随着比特币的普及,出现了一些可扩展性问题:比特币使用1 MB 大小的区块,每秒只能进行7笔交易,每笔交易需要10分钟的处理时间。导致一种新的加密货币的出现:比特币现金(Bitcoin Cash,BCH),BCH是比特币的另一版本,因为比特币和BCH基于相同的技术,而BCH正作为新的分支进行发展。使用8 MB大小的区块,难度级别可调,并且交易只需要两分钟时间。
如果兴趣尝试比特币或加密货币,例如BCH,以太币、Ripple、Litecoin、Peercoin或 Dogecoin,可下载并安装以下主流的加密货币数字钱包。
Bitcoin Core 由中本聪为比特创建,又称为中本聪客户端:Bitcoin Core
Ethereum 一种开源的、公共的、基于区块链的分布式计算平台,提供了一种名为 Ether 的加密货币 Home | ethereum.org
Ripple 一种基于共享的公共XRP总账的实时支付系统,已被联合信贷银行(UniCredit)、瑞银(UBS) 和 桑坦德(Santander)等银行普遍采购。
Bitcoin Cash 比特币的另一版本,但使用起来更快、更便宜,区块大小为8 MB http://bitcoincash.org/
Electrum 轻易级的比特币客户端,同时具有硬件钱包的功能。硬件钱包允许用户在硬件设备(例如 USB 记忆棒)上存储比特币信息,例如私钥。与软件钱包不同,硬件钱包可以物理保护,并且不受病毒的侵害,病毒往往从软件中窃取信息 http://electrurn.org/
Coinbase 最知名、最值得信赖的数字货币买卖和管理应用之一 https://www.coinbase.com/
Blockchain Luxembourg 具有易于使用的精美用户界面以及许多用于加密货币的有用功能 http://www.blokchain.com/
最受欢迎的三种加密货币是 BTC(比特币)、XRP(瑞波币)和ETH(Ethereum).
https://bitcoin.org/bitcoin.pdf
https://en.bitcoin.it/witi/Main_Page
Bitcoin - Open source P2P money
智能合约是自动执行的合同,旨在执行协议中的条款。智能合约用于在特定条件下控制各方之间数字货币或资产的转移。使用智能合约,无需中间人即可交换金钱、财产、股份或任何有价物品。智能合约不仅定义了所有规则和所有处罚,而且会自动执行这些义务。
例如,购买房屋通常涉及买方、卖方和多个第三方,例如房地产经纪人和律师。有了智能合约和数字货币,就可以在买卖双方之间完成交易。一旦满足所有条件,智能合约在本质上就是软件程序,它将使用数字货币自动完成交易,具体过程如下:
1、买卖双方就以数字货币衡量的房屋价格达成一致,将合同写入区块链。合同包括买方和卖方的所有信息,条款和条件。因为合同在公共总账上,所有不能更改。
2、当满足所有条件并发触发事件(如日子到期)时,合同将按照约定的条款执行。
3、卖方获得数字货币形式的付款,买方获得房屋,包括所有法律文件,例如土地契约。所有清算和结算都是自动化的,所有权无可争议。
个人健康数据也可以存储在受加密保护的区块链中,只允许特定用户(例如医生和保险提供商)访问。医生将拥有患者完整的病史,因此可以提供更好的诊断。病历将自动与保险公司共享,以支持索赔。区块链也可以用于验证药物的真实性,防止假冒药物和医疗器械,以及提高临床试验数据的质量和可靠性。
区块链技术还可以用于制造业和供应链,以及任何交换、协议/合同、跟踪和尾款。由于每笔交易都记录在严格区块中,并且记录在分布于用于之间的多个账本的副本中,因此这种记录方法是透明的,也是高度安全的,非常有效并且可扩展。你将能够查看产品或组件的完整记录,包括来源和去向,这叫作可塑性。区块链技术可以提高供应链的效率和透明度。
有了物联网(loT),数十亿台设备相互连接。安全地存储物联网系统产生的海量数据是人们将要面临的一项巨大挑战。借助区块链技术的分布式账本,物联网数据能够以一种不可信任的方式进行分布式存储,并且可以更好地进行组合分析,从而产生有价值的见解。区块链非常适合于公共和私营的物联网系统,因为它具有识别、验证和数据传输能力。区块链可以在双方和设备之间建立信任,通过消除中间人来价格低成本,还可以通过缩短结算时间加速交易。
就像其他技术一样,区块链也存在一些局限性。
安全性 因为区块链依赖用户存储记录,所以如果大多数用户决定更改记录,那么对记录做的更改将接受,这被称为51%攻击。总本聪在比特币问世时就强调了这一安全漏洞。为了将这种51%攻击的可能性降到最低,网络必须大小一定的大小,以使任何人或团队都不能拥有超过51%的控制权。黑客攻击也是数字货币面临的一种常见威胁。
复杂性 区块链基于庞大、复杂的技术,涉及复杂的数学和大量的软件编程。区块链的复杂性使得任何人都很难理解它的工作原理以及带来的好处,从而阻碍了应用。
缺乏监管 因为区块链技术太新了,所以几乎没有法规。缺乏法规会造成危险的环境,在这种环境中,欺诈、欺骗和市场操纵司空见惯。
量子准备 区块链建立在加密的基础上,对于当今的计算机而言是安全的。但随着量子计算等技术的出现,计算机的运行速度可能比现在快1亿倍,这将对当今使用的所有形式的加密构成严重威胁。为了面对这一挑战,需要开发一种抗量子密码系统。
可伸缩性 随着网络的增长,由于存在复杂性、加密性和分布式特性,区块链中的交易处理可能会变得非常缓慢和烦锁。
简单的Java区块链演示程序,它由两个Java文件Block.java 和 BlockChainMain.java组成。
Block.java的任务创建但各区块。每个区块中有6个属性和3个方法。这6个属性与前面所讲的属性相同:index、timestamp、currentHash、previousHash、data、nonce。这3个方法分别速度calculateHash()、mineBlock() 和 toString()。calculateHase()用于计算区块的当前哈希值,mineBlock()用于根据指定的难度(前导0的数量)挖掘区块,toString()用于显示区块的信息。为了创建区块,需要提供有关index、previousHash 和 data 的信息。
public class Block {
public int index;
public long timestamp;
public String currentHash;
public String previousHash;
public String data;
public int nonce;
public Block(int index ,String previousHash,String data) {
this.index = index;
this.timestamp = System.currentTimeMillis();
this.previousHash = previousHash;
this.data = data;
nonce = 0;
currentHash = calculateHash();
}
public String calculateHash() {
try {
String input = index + timestamp + previousHash + data + nonce;
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(input.getBytes("UTF-8"));
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < hash.length; i++) {
String hex = Integer.toString(0xff & hash[i]);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void minBlock(int difficulty){
nonce = 0;
String target = new String(new char[difficulty]).replace('\0','0');
while(!currentHash.substring(0,difficulty).equals(target)) {
nonce++;
currentHash = calculateHash();
}
}
public String toString(){
String s = "Block # :" + index + "\r\n";
s = s + "PreviousHash : " + previousHash + "\r\n";
s = s + "Timestamp : " + timestamp + "\r\n";
s = s + "Data" + data + "\r\n";
s = s + "Nonce : " + nonce + "\r\n";
s = s + "CurrentHash : " + currentHash + "\r\n";
return s;
}
}
BlockChainMain.java是主程序,用于创建区块链并将两个区块添加到区块链中
import java.util.ArrayList;
public class BlockChainMain {
public static ArrayList blockchain = new ArrayList();
public static int difficulty = 5;
public static void main(String[] args) {
Block b = new Block(0,null,"My First Block");
b.minBlock(difficulty);
blockchain.add(b);
System.out.println(b.toString());
Block b2 = new Block(1,b.currentHash, "My Second Block");
b2.minBlock(difficulty);
blockchain.add(b2);
System.out.println(b2.toString());
}
}
运行结果:
可以修改BlockChainMain.java 程序以验证这些区块,可以根据区块的索引、前一区块的哈希值和当前区块的哈希值来验证区块。
如何使用区块链记录交易:ArrayList
import java.security.MessageDigest;
import java.util.ArrayList;
public class Block2 {
public int index;
public long timestamp;
public String currentHash;
public String previousHash;
public String data;
public ArrayList transactions = new ArrayList();
public int nonce;
public Block2(int index , String previousHash, ArrayList transactions) {
this.index = index;
this.timestamp = System.currentTimeMillis();
this.previousHash = previousHash;
nonce = 0;
currentHash = calculateHash();
}
public String calculateHash() {
try {
data = "";
for (int i = 0; i < transactions.size(); i++) {
Transaction tr = transactions.get(i);
data = data + tr.sender + tr.recipient + tr.value;
}
String input = index + timestamp + previousHash + data + nonce;
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(input.getBytes("UTF-8"));
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < hash.length; i++) {
String hex = Integer.toString(0xff & hash[i]);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void minBlock(int difficulty){
nonce = 0;
String target = new String(new char[difficulty]).replace('\0','0');
while(!currentHash.substring(0,difficulty).equals(target)) {
nonce++;
currentHash = calculateHash();
}
}
public String toString(){
String s = "Block # :" + index + "\r\n";
s = s + "PreviousHash : " + previousHash + "\r\n";
s = s + "Timestamp : " + timestamp + "\r\n";
s = s + "Data" + data + "\r\n";
s = s + "Nonce : " + nonce + "\r\n";
s = s + "CurrentHash : " + currentHash + "\r\n";
return s;
}
}
import java.util.ArrayList;
public class BlockChainMain4 {
public static ArrayList blockchain = new ArrayList();
public static ArrayList transactions = new ArrayList();
public static int difficulty = 5;
public static void main(String[] args) {
Wallet A = new Wallet(blockchain);
Wallet B = new Wallet(blockchain);
System.out.println("Wallet A Balance:" + A.getBalance());
System.out.println("Wallet B Balance:" + B.getBalance());
}
}
Transaction.java 仅记录一笔交易,其中包括发送方、接收方和值。
public class Transaction {
public String sender;
public String recipient;
public float value;
public Transaction(String from,String to,float value) {
this.sender = from;
this.recipient = to;
this.value = value;
}
}
Wallet.java 用于为用户创建数字钱包。可首先使用 generateKeyPair() 为用户生成一对公钥/私钥,然后使用 getBalance()获取用户的余额,最后使用send()以及发送方和接收方的公钥向另一个用户发送一些数字硬币。getBalance()会遍历整个区块链,为用户搜索交易:如果发送交易,就从余额中扣除交易额:如果收到交易,就将交易额加到余额中。为了简单期见,每个数字钱包都包含100枚数字硬币。
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.ArrayList;
public class Wallet {
public String privateKey;
public String publicKey;
private float balance = 100.0f;
private ArrayList blockchain = new ArrayList();
public Wallet(ArrayList blockchain) {
generateKeyPair();
this.blockchain = blockchain;
}
public void generateKeyPair() {
try {
KeyPair keyPair;
String algorithm = "RSA";
keyPair = KeyPairGenerator.getInstance(algorithm).generateKeyPair();
privateKey = keyPair.getPrivate().toString();
publicKey = keyPair.getPublic().toString();
}catch (Exception e){
throw new RuntimeException(e);
}
}
public float getBalance(){
float total = balance;
for (int i = 0; i < blockchain.size(); i++) {
Block2 currentBloct = blockchain.get(i);
for (int j = 0; j < currentBloct.transactions.size(); j++) {
Transaction tr = currentBloct.transactions.get(j);
if (tr.recipient.equals(publicKey)) {
total += tr.value;
}
if (tr.sender.equals(publicKey)) {
total -= tr.value;
}
}
}
return total;
}
public Transaction Send(String recipient,float value) {
if (getBalance() < value) {
System.out.println("!!!Not Enough funds. TransactionDiscarded.");
return null;
}
Transaction newTransaction = new Transaction(publicKey,recipient,value);
return newTransaction;
}
}
BlockChainMain4.java 是使用 Wallet.java 进行区块链交易的主程序,它仅创建两个数字钱包并显示它们的余额:
import java.util.ArrayList;
public class BlockChainMain4 {
public static ArrayList blockchain = new ArrayList();
public static ArrayList transactions = new ArrayList();
public static int difficulty = 5;
public static void main(String[] args) {
Wallet A = new Wallet(blockchain);
Wallet B = new Wallet(blockchain);
System.out.println("Wallet A Balance:" + A.getBalance());
System.out.println("Wallet B Balance:" + B.getBalance());
}
}
运行结果:
接下来可以添加一些交易。添加了两笔交易:A 首先向 B发送了 10枚数字硬币,然后又向 B 发生了 20枚数字硬币。可以使用前面的validateChain()来验证整个区块链:
import java.util.ArrayList;
public class BlockChainMain5 {
public static ArrayList blockchain = new ArrayList();
public static ArrayList transactions = new ArrayList();
public static int difficulty = 5;
public static void main(String[] args) {
Wallet A = new Wallet(blockchain);
Wallet B = new Wallet(blockchain);
System.out.println("Wallet A Balance:" + A.getBalance());
System.out.println("Wallet B Balance:" + B.getBalance());
System.out.println("Add two transations...");
Transaction tran1 = A.Send(B.publicKey,10);
if (tran1 != null){
transactions.add(tran1);
}
Transaction tran2 = A.Send(B.publicKey,20);
if (tran2 != null) {
transactions.add(tran2);
}
Block2 b = new Block2(0,null,transactions);
b.minBlock(difficulty);
blockchain.add(b);
System.out.println("Wallet A Balance:" + A.getBalance());
System.out.println("wallet B Balance:" + B.getBalance());
System.out.println("Blockchain Valid:" + validateChain(blockchain));
}
public static boolean validateChain(ArrayList blockchain) {
if (!validateBlock(blockchain.get(0),null)) {
return false;
}
for (int i = 0; i < blockchain.size(); i++) {
Block2 currentBlock = blockchain.get(i);
Block2 previousBlock = blockchain.get(i - 1);
if (!validateBlock(currentBlock,previousBlock)) {
return false;
}
}
return true;
}
private static boolean validateBlock(Block2 newBlock,Block2 previousBlock) {
//The same as before
}
}
对于Java开发人员来说,一些十分流行的区块链库如下:
BitcoinJ:https://github.com/bitcoinj/bitcoinj
Web3j: https://github.com/web3j/web3j
EthereumJ : https://github.com/ethereum/etheremj
HyperLedger Fabric: https://giyhb.com/hyperledger/fabric-sdk-java