-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
875 additions
and
143 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
package mbc.config | ||
|
||
import com.typesafe.config.Config | ||
import com.typesafe.config.ConfigFactory | ||
import mbc.core.AccountState | ||
import mbc.core.Block | ||
import mbc.core.Transaction | ||
import mbc.serialization.AccountStateSerialize | ||
import mbc.serialization.BlockSerialize | ||
import mbc.serialization.TransactionSerialize | ||
import mbc.storage.DataSource | ||
import mbc.storage.LevelDbDataSource | ||
import mbc.storage.MemoryDataSource | ||
import mbc.storage.ObjectStore | ||
import org.spongycastle.util.encoders.Hex | ||
import java.io.File | ||
|
||
class BlockChainConfig { | ||
|
||
enum class DATABASE_TYPE { | ||
MEMORY, LEVELDB | ||
} | ||
|
||
companion object { | ||
var minerCoinBase: ByteArray = ByteArray(0) | ||
|
||
var defaultConfig: Config = ConfigFactory.empty() | ||
|
||
fun getConfig(): Config { | ||
if (defaultConfig.isEmpty) { | ||
val resourceConfig = ConfigFactory.parseResources("application.conf") | ||
val fileConfig = ConfigFactory.parseFile(File("application.conf")) | ||
|
||
defaultConfig = defaultConfig.withFallback(resourceConfig).withFallback(fileConfig) | ||
} else { | ||
return defaultConfig | ||
} | ||
return defaultConfig | ||
} | ||
|
||
/** | ||
* Account State的存储类组装。 | ||
*/ | ||
fun getAccountStateStore(): ObjectStore<AccountState> { | ||
val dbName = "accounts" | ||
var ds: DataSource<ByteArray, ByteArray> = MemoryDataSource(dbName) | ||
if (getDatabaseType().equals(DATABASE_TYPE.LEVELDB.name, true)) { | ||
ds = LevelDbDataSource(dbName) | ||
} | ||
ds.init() | ||
return ObjectStore(ds, AccountStateSerialize()) | ||
} | ||
|
||
/** | ||
* Block的存储类组装。 | ||
*/ | ||
fun getBlockStore(): ObjectStore<Block> { | ||
val dbName = "blocks" | ||
var ds: DataSource<ByteArray, ByteArray> = MemoryDataSource(dbName) | ||
if (getDatabaseType().equals(DATABASE_TYPE.LEVELDB.name, true)) { | ||
ds = LevelDbDataSource(dbName) | ||
} | ||
ds.init() | ||
return ObjectStore(ds, BlockSerialize()) | ||
} | ||
|
||
/** | ||
* Transaction的存储类组装。 | ||
*/ | ||
fun getTransactionStore(): ObjectStore<Transaction> { | ||
val dbName = "transactions" | ||
var ds: DataSource<ByteArray, ByteArray> = MemoryDataSource(dbName) | ||
if (getDatabaseType().equals(DATABASE_TYPE.LEVELDB.name, true)) { | ||
ds = LevelDbDataSource(dbName) | ||
} | ||
ds.init() | ||
return ObjectStore(ds, TransactionSerialize()) | ||
} | ||
|
||
/** | ||
* 得到矿工的Coinbase地址。 | ||
*/ | ||
fun getMinerCoinbase(): ByteArray { | ||
if (this.minerCoinBase.size > 0) { | ||
return minerCoinBase | ||
} else { | ||
if (getConfig().hasPathOrNull("miner.minerCoinBase")) { | ||
minerCoinBase = Hex.decode(getConfig().getString("miner.minerCoinBase")) | ||
return minerCoinBase; | ||
} else { | ||
throw RuntimeException("Miner Coinbase is empty") | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* 设置矿工的Coinbase地址。 | ||
*/ | ||
fun setMinerCoinbase(newCoinbase: ByteArray) { | ||
this.minerCoinBase = newCoinbase | ||
} | ||
|
||
/** | ||
* Key-Value存储的实现。 | ||
*/ | ||
fun getDatabaseType(): String { | ||
if (getConfig().hasPathOrNull("database.type")) { | ||
return getConfig().getString("database.type") | ||
} else { | ||
return DATABASE_TYPE.MEMORY.name | ||
} | ||
} | ||
|
||
/** | ||
* 数据库的存储目录。 | ||
*/ | ||
fun getDatabaseDir(): String { | ||
if (getConfig().hasPathOrNull("database.dir")) { | ||
return getConfig().getString("database.dir") | ||
} else { | ||
return "database" | ||
} | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,23 @@ | ||
package mbc.core | ||
|
||
import java.util.* | ||
import mbc.util.CodecUtil | ||
import java.math.BigInteger | ||
|
||
/** | ||
* 账户状态管理。 | ||
* 账户状态。 | ||
*/ | ||
object AccountState { | ||
/** | ||
* 账户余额存储,为了演示方便使用HashMap。 | ||
*/ | ||
val accountBalances: HashMap<String, Long> = HashMap() | ||
class AccountState(val nonce: BigInteger, val balance: BigInteger) { | ||
|
||
/** | ||
* 根据账户地址(address)读取账户余额(balance)。 | ||
*/ | ||
fun getAccountBalance(address: String): Long { | ||
return accountBalances.getOrDefault(address, 0) | ||
fun encode(): ByteArray { | ||
return CodecUtil.encodeAccountState(this) | ||
} | ||
|
||
/** | ||
* 根据账户地址(address)更新账户余额(balance)。 | ||
*/ | ||
fun setAccountBalance(address: String, amount: Long): Long? { | ||
return accountBalances.put(address, amount) | ||
fun increaseNonce(): AccountState { | ||
return AccountState(nonce + BigInteger.ONE, balance) | ||
} | ||
|
||
|
||
fun increaseBalance(amount: BigInteger): AccountState { | ||
return AccountState(nonce, balance + amount) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,24 @@ | ||
package mbc.core | ||
|
||
import mbc.util.CodecUtil | ||
import mbc.util.CryptoUtil | ||
import org.joda.time.DateTime | ||
|
||
/** | ||
* 区块(Block)类,包含了区块高度(height),上一个区块哈希值(parentHash),旷工账户地址(minerAddress),交易列表(transactions)和时间戳(time)。 | ||
* 区块(Block)类,包含了区块高度(height),上一个区块哈希值(parentHash),旷工账户地址(coinBase),交易列表(transactions)和时间戳(time)。 | ||
*/ | ||
class Block(val height: Long, val parentHash: ByteArray, val minerAddress: String, val transactions: List<Transaction>, | ||
val time: DateTime) { | ||
|
||
val version: Int = 1 | ||
|
||
val merkleRoot: ByteArray | ||
get() = CryptoUtil.merkleRoot(transactions) | ||
|
||
var difficulty: Int = 0 | ||
|
||
var nonce: Int = 0 | ||
class Block(val version: Int, val height: Long, val parentHash: ByteArray, val merkleRoot: ByteArray, | ||
val coinBase: ByteArray, val transactions: List<Transaction>, val time: DateTime, val difficulty: Int, | ||
val nonce: Int) { | ||
|
||
/** | ||
* 区块(Block)的哈希值(KECCAK-256) | ||
*/ | ||
val hash: ByteArray | ||
get() = CryptoUtil.hashBlock(this) | ||
|
||
fun encode(): ByteArray { | ||
return CodecUtil.encodeBlock(this) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.