package BLC
import (
"PublicBlackChain/part1/BLC"
"encoding/hex"
"fmt"
"github.com/boltdb/bolt"
"log"
"math/big"
"os"
"strconv"
)
const dbName = "block.db"
const bucketName = "blocks"
type BlockChain struct {
//加入db 持久存储
Tip []byte //最新区块的hash
DB *bolt.DB //DB
}
//创建创世区块链
func CreatBlockChainWithGenensisCLI(data string) {
db, err := bolt.Open(dbName, 0600, nil)
if err != nil {
log.Fatal(err)
}
err = db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte(bucketName))
if b == nil {
b, err = tx.CreateBucket([]byte(bucketName))
if err != nil {
log.Panic(err)
}
}
//创建一个基础交易
transaction := NewCoinBaseTransaction(data)
genensisBlock := CreateGenensisBlock([]*Transaction{transaction})
err = b.Put([]byte(genensisBlock.Hash), genensisBlock.Serialize())
if err != nil {
log.Panic(err)
}
err = b.Put([]byte("l"), genensisBlock.Hash)
if err != nil {
log.Panic(err)
}
return nil
})
if err != nil {
log.Panic(err)
}
defer db.Close()
}
//转账
func (blc *BlockChain) MineNewBlock(from []string, to []string, acount []string) {
//通过相关算法建立Transaction数组
var txs []*Transaction
value, _ := strconv.Atoi(acount[0])
//建立一笔转账
for _, address := range from {
tx := NewNormalTransaction(address, to[0], int64(value), txs)
txs = append(txs, tx)
fmt.Println(tx)
}
//添加到DB中
err := blc.DB.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte(bucketName))
if b == nil {
_, err := tx.CreateBucket([]byte(bucketName))
if err != nil {
log.Panic(err)
}
}
//取出最顶的block
blockBytes := b.Get(blc.Tip)
preBlock := BLC.DeSerializeBlock(blockBytes)
//创建新区块
block := NewBlock(preBlock.Height+1, preBlock.Hash, txs)
err := b.Put([]byte(block.Hash), block.Serialize())
if err != nil {
log.Panic(err)
}
err = b.Put([]byte("l"), block.Hash)
blc.Tip = block.Hash
if err != nil {
log.Panic(err)
}
return nil
})
if err != nil {
log.Panic(err)
}
defer blc.DB.Close()
}
//获取blockchain对象
func GetBlockChainObj() *BlockChain {
db, err := bolt.Open(dbName, 0600, nil)
if err != nil {
log.Fatal(err)
}
var tipHash []byte
db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte(bucketName))
if b != nil {
tipHash = b.Get([]byte("l"))
} else {
fmt.Println("先创建创世区块")
}
return nil
})
return &BlockChain{tipHash, db}
}
//返回该地址下所有未花费交易输出
func (blc *BlockChain) UnUTXOs(address string, txs []*Transaction) []*UTXO {
blockChainIterator := blc.Iterator()
defer blockChainIterator.DB.Close()
var unUTXOs []*UTXO
var hashInt big.Int
var genensis = big.NewInt(0)
var spentTXOutputs = make(map[string][]int64)
for _, tx := range txs {
if tx.IsConbaseTransaction() == false {
for _, in := range tx.Vins {
if in.UnLockWithAddress(address) {
key := hex.EncodeToString(in.TxHash)
spentTXOutputs[key] = append(spentTXOutputs[key], in.Vout)
}
}
}
}
for _, tx := range txs {
work1:
for index, out := range tx.Vouts {
if out.UnLockWithAddress(address) {
if len(spentTXOutputs) == 0 {
utxo := &UTXO{tx.TxHash, int64(index), out}
unUTXOs = append(unUTXOs, utxo)
} else {
for hash, indexArray := range spentTXOutputs {
txHashStr := hex.EncodeToString(tx.TxHash)
if txHashStr == hash {
var isUtxo bool
for _, outIndex := range indexArray {
if outIndex == int64(index) {
isUtxo = true
continue work1
}
if isUtxo == false {
utxo := &UTXO{tx.TxHash, int64(index), out}
unUTXOs = append(unUTXOs, utxo)
}
}
} else {
utxo := &UTXO{tx.TxHash, int64(index), out}
unUTXOs = append(unUTXOs, utxo)
}
}
}
}
}
}
for {
block := blockChainIterator.Next()
hashInt.SetBytes(block.PreHash)
fmt.Println(block)
for _, tx := range block.txs {
if tx.IsConbaseTransaction() == false {
for _, in := range tx.Vins {
if in.UnLockWithAddress(address) {
key := hex.EncodeToString(in.TxHash)
spentTXOutputs[key] = append(spentTXOutputs[key], in.Vout)
}
}
}
work2:
for index, out := range tx.Vouts {
if out.UnLockWithAddress(address) {
if spentTXOutputs != nil {
if len(spentTXOutputs) != 0 {
var isSpentUTXO bool
for txHash, indexArray := range spentTXOutputs {
for _, i := range indexArray {
if int64(index) == i && txHash == hex.EncodeToString(tx.TxHash) {
continue work2
} else {
}
}
}
if isSpentUTXO == false {
utxo := &UTXO{tx.TxHash, int64(index), out}
unUTXOs = append(unUTXOs, utxo)
}
} else {
utxo := &UTXO{tx.TxHash, int64(index), out}
unUTXOs = append(unUTXOs, utxo)
}
}
}
}
}
if genensis.Cmp(&hashInt) == 0 {
break
}
}
return unUTXOs
}
func (blc *BlockChain) FindSpendableUTXOS(from string, amount int64, txs []*Transaction) (int64, map[string][]int64) {
//获取我所以的钱UTXO
utxos := blc.UnUTXOs(from, txs)
var value int64
var unSpendableUTXOS = make(map[string][]int64)
for _, utxo := range utxos {
value = value + utxo.Output.Value
hash := hex.EncodeToString(utxo.TxHash)
unSpendableUTXOS[hash] = append(unSpendableUTXOS[hash], utxo.Index)
if value >= amount {
break
}
}
if value < amount {
fmt.Println("余额不足")
os.Exit(1)
}
return value, unSpendableUTXOS
}
//查询余额
func (blc *BlockChain) GetBalance(address string) (amount int64) {
utxos := blc.UnUTXOs(address, nil)
for _, utxo := range utxos {
amount = amount + utxo.Output.Value
}
return
}
//迭代器
func (blc *BlockChain) Iterator() *BlockChainIterator {
return &BlockChainIterator{blc.Tip, blc.DB}
}
//迭代遍历
func (blc *BlockChain) PrintChainIterator() {
blockChainIterator := blc.Iterator()
defer blockChainIterator.DB.Close()
var hashInt big.Int
var genensis = big.NewInt(0)
for {
block := blockChainIterator.Next()
hashInt.SetBytes(block.PreHash)
//fmt.Println(block)
fmt.Println("####################################################################################")
fmt.Println()
fmt.Println()
fmt.Println("------------------------------------------------------------------------------------")
fmt.Printf("Height------>| %d\n", block.Height)
fmt.Println("------------------------------------------------------------------------------------")
fmt.Printf("PreHash----->| %x\n", block.PreHash)
fmt.Println("------------------------------------------------------------------------------------")
fmt.Printf("Hash-------->| %x\n", block.Hash)
fmt.Println("------------------------------------------------------------------------------------")
fmt.Printf("Nonce------->| %d\n", block.Nonce)
fmt.Println("------------------------------------------------------------------------------------")
fmt.Printf("TimesTamp--->| %d\n", block.TimesTamp)
fmt.Println("------------------------------------------------------------------------------------")
fmt.Println("*********************************-> Txs <-**************************************")
for _, tx := range block.txs {
fmt.Printf("Hash-------->: %x\n", tx.TxHash)
for _, in := range tx.Vins {
fmt.Println(in)
}
for _, out := range tx.Vouts {
fmt.Println(out)
}
fmt.Println()
}
fmt.Println()
fmt.Println()
fmt.Println("####################################################################################")
if genensis.Cmp(&hashInt) == 0 {
break
}
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
人工智能- 项目实践-区块链-GO语言简单实现BlockChain区块链公链,POW工作量证明,UTXO未使用交易输出,P2P part1 BlockChain 存储为内存数组 简单实现 part2 BlcokChain 存储为blotdb part3 BlcokChain UTXO未使用交易输出模型
资源推荐
资源详情
资源评论
收起资源包目录
人工智能- 项目实践-区块链-GO语言简单实现BlockChain区块链公链,POW工作量证明,UTXO未使用交易输出,P2P网络模型.zip (29个子文件)
PublicBlackChain-master
part2
BLC
Block.go 2KB
ProofOfWork.go 1KB
BlockChainIterator.go 579B
BlockChain.go 4KB
CLI.go 2KB
Utlis.go 260B
cli 3.03MB
block.db 64KB
main.go 434B
part1
BLC
Block.go 2KB
ProofOfWork.go 1KB
BlockChain.go 456B
Utlis.go 260B
block.db 32KB
main.go 2KB
.idea
vcs.xml 180B
part3
BLC
Block.go 2KB
ProofOfWork.go 1KB
Transaction_TXInput.go 224B
BlockChainIterator.go 575B
Transaction.go 2KB
BlockChain.go 8KB
Transaction_TXOutput.go 223B
CLI.go 3KB
Utlis.go 471B
UTXO.go 81B
cli 3.25MB
block.db 64KB
main.go 434B
共 29 条
- 1
资源评论
博士僧小星
- 粉丝: 2268
- 资源: 5990
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- AI复活历史人物快速涨粉10w+附:不花1分钱无限使用可灵方法
- 【java毕业设计】动画门户网源码(完整前后端+说明文档+LW).zip
- Windows系统渗透工具(Windows-infiltration-tool).zip
- C#美容美发会员管理系统源码带数据库文档数据库 SQL2008源码类型 WinForm
- 贪吃蛇游戏(C++/C#)
- web渗透测试平台在docker上的搭建.zip
- JDK 22.0.2 (64-bit) for Windows 11: 步骤详述与配置指导
- Web渗透学习笔记.zip
- 数据来源于Kaggle,文件名为 cwurData.csv -预测大学得分
- 【java毕业设计】大学生户外运动管理系统源码(完整前后端+说明文档+LW).zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功