前言
本系列的目的参考比特币与以太坊的设计并加以简化,理清区块链的基本概念和设计思路,一步步实现一个最小可行性区块链产品。
最小可行性区块链设计的产品概念参考了文章《最小可行性区块链原理解析》( http://geek.csdn.net/news/detail/135684 ),建议读者先通读这篇文章了解区块链的核心设计理念以及PKI、公私钥等概念。
本文的代码地址:https://github.com/qikh/mini-block-chain/commit/6e272294d9ea6546b6a655fab4aa7113cf7a59ad (开发语言为Kotlin,更简洁的Java)
正文
区块链又被称为分布式账簿,“账户”(Account)和“交易”(Transaction)是其两大核心概念。
账户是用户在区块链网络上的唯一性标识,区块链账户由一个公钥-私钥对代表,私钥由用户秘密保管,并对所有用户发起的交易(Transaction)进行签名,公钥公布出来,让区块链节点能够验证该用户所发起的交易。账户的地址并不直接采用公钥,而是通过算法推算出来,比特币和以太坊各有不同的推算算法。(比特币地址算法:http://www.infoq.com/cn/articles/bitcoin-and-block-chain-part03,以太坊地址算法:http://ethereum.stackexchange.com/questions/3542/how-are-ethereum-addresses-generated )
比特币和以太坊的公私钥算法都遵循了一个原则:私钥可以推导公钥,公钥可以推导账户地址,并且反向可以验证。
私钥可以保存为本地文件,也可以保存到物理加密设备内(银行的U盾就是类似的道理),只有用户发起交易时才需要使用。
公钥通常会作为交易签名(signature)数据的一部分来进行公布,这样区块链的节点在验证交易合法性的时候就可以从交易数据内部得到公钥,并使用该公钥验证地址(address)和交易签名的合法性。
一个简单的账户模型Account包含了账户地址(address)和余额(balance)信息,比特币的UTXO模型没有余额信息,所以我们的账户模型更接近以太坊的实现:
class Account(val publicKey: PublicKey) {
val address: String
val balance: Long
}
交易记录模型,记录了发送方(sender)向接受方(receiver)的转账记录,包括金额(amount)和时间戳(time)。为了简化模型,没有加入费用(fee)。:
class Transaction(val senderAddress: String, val receiverAddress: String,
val amount: Long, val time: DateTime)
用户Alice和Bob各拥有一个区块链账户:
// 初始化Alice账户
val kp1 = generateKeyPair() ?: return
val alice = Account(kp1.public)
// 初始化Bob账户
val kp2 = generateKeyPair() ?: return
val bob = Account(kp2.public)
Alice和Bob的账户内各有200元:
// 初始金额为200
addAmount(alice.address, 200)
addAmount(bob.address, 200)
Alice向Bob转账100元:
// Alice向Bob转账100
val trx = Transaction(alice.address, bob.address, 100, DateTime())
区块链节点验证这笔交易并记录下来:
// 根据交易记录更新区块链状态
applyTrx(trx)
交易记录的过程会更新Alice和Bob的账户余额(balance):
/**
* 根据交易记录更新区块链的状态(state),发送方的余额会减少,接收方的余额会增加。
* 区块链的状态更新应该是原子操作,持久层是数据库可以使用事务功能。
*/
fun applyTrx(trx: Transaction) {
addAmount(trx.senderAddress, -trx.amount)
addAmount(trx.receiverAddress, +trx.amount)
}
Alice的余额应该是100元,Bob的余额应该是300元:
// 查询余额是否正确
assert(alice.balance == 100L)
assert(bob.balance == 300L)
最小可行性区块链产品的核心(core)包有4个类:
Account: 区块链账户类,记录账户地址(address)和余额(balance)信息。
AccountState: 账户状态管理。
Transaction: 交易记录类,记录了发送方(sender)向接受方(receiver)的转账记录,包括金额(amount)和时间戳(time)。
TransactionExecutor: 交易处理并更新账户状态。
密码学是区块链理论的基础,所以我们还实现了一个工具类(util):
CryptoUtil: 密码学工具类,实现了公私钥对生成和账户地址的推算功能(与以太坊的机制相同)。
这就是区块链产品的账户和交易模型雏形,Day 2我们会增加交易记录的签名功能、交易的合法性验证。