os-list-addblock 项目代码

目录

2.block.go文件

3.blockChain.go文件

4.commands.go文件

5.osCli.go文件

6.utils.go文件


1.main.go文件

package main

func main() {
	/*
	todo 4、对osCli 结构体,实例化
	*/

	// 实例化
	osCli := OsCli{}
	// 调用
	osCli.Init()
}

2.block.go文件

package main

import (
	"bytes"
	"crypto/sha256"
	"math/rand"
	"time"
)

/*
todo 13、新建block文件
新建
*/

/*Block
todo 14、创建Block结构体
*/
type Block struct {
	Version       uint64 // 区块版本号
	blockHeight   int    // 区块高度
	PrevBlockHash []byte // 前hash
	MerKleRoot    []byte // 默克尔根
	TimeStamp     uint64 // 时间戳
	Difficulty    uint64 // 难度值
	Nonce         uint64 // 随机数,挖矿找的就是它
	Data          []byte // 数据
	Hash          []byte // 当前区块hash
}

const VERSION = 1

/*NewBlock
todo 18新建区块方法
参数:
返回 区块
*/
func NewBlock(data string, blockHeight int, prevBlockHash []byte) *Block {
	block := Block{
		Version:       VERSION,
		blockHeight:   blockHeight,
		PrevBlockHash: prevBlockHash,
		MerKleRoot:    []byte{},
		TimeStamp:     uint64(time.Now().Unix()),
		Difficulty:    1,
		Nonce:         uint64(rand.Intn(1000)),
		Hash:          []byte{},
		Data:          []byte(data),
	}
	block.setBlockHash()
	return &block
}

/*setBlockHash
todo 19、设置区块hash
*/
func (block *Block) setBlockHash() {
	bts := [][]byte{
		uintToByte(block.Version),
		block.PrevBlockHash,
		block.MerKleRoot,
		uintToByte(block.Difficulty),
		uintToByte(block.TimeStamp),
		uintToByte(block.Nonce),
		block.Data,
	}

	data := bytes.Join(bts, []byte{})
	hash := sha256.Sum256(data)
	block.Hash = hash[:]

}

3.blockChain.go文件

package main

import (
	"bytes"
	"crypto/elliptic"
	"encoding/gob"
	"fmt"
	"io/ioutil"
)

/*todo 15 新建blockChain.go 文件

 */

/*
BlockChain
todo 16、新建区块链结构体
区块数组切片
*/
type BlockChain struct {
	Blocks []*Block
}

const INFO = "知链区块链人才培养摇篮"
const BlockChainName = "blockChain.dat"

/*NewBlockChain
todo 17、创建区块链方法
返回值 BlockChain
*/
func NewBlockChain() *BlockChain {

	/*todo 25、加载区块链文件
	 */
	var bc BlockChain
	var isSaveFile = bc.LoadBlockChainFile()
	if !isSaveFile { // 未保存文件
		// 创建创世区块
		firstBlock := NewBlock(INFO, 0, []byte{})

		// 把创世区块放到区块列表中
		bc = BlockChain{
			Blocks: []*Block{
				firstBlock,
			},
		}
	}
	// 把区块列表返回
	return &bc
}

/*saveBlockChainFile
todo 20、存储区块链文件
返回 bool
*/
func (bc *BlockChain) saveBlockChainFile() bool {
	var buffer bytes.Buffer
	gob.Register(elliptic.P256())
	encoder := gob.NewEncoder(&buffer)

	err := encoder.Encode(bc.Blocks)

	fmt.Printf("存储列表结构\n")
	if err != nil {
		fmt.Printf("钱包序列化失败")
		return false
	}

	content := buffer.Bytes()
	// 保存到本地文件
	err = ioutil.WriteFile(BlockChainName, content, 0600)
	if err != nil {
		fmt.Printf("钱包创建失败")
		return false
	}
	return true
}

/*LoadBlockChainFile
todo 23、读取区块链文件
*/
func (bc *BlockChain) LoadBlockChainFile() bool {
	// 判断文件是否存在
	if !IsFileExist(BlockChainName) {
		fmt.Printf("钱包文件不存在,请创建\n")
		return false
	}

	// 1、读取文件
	contet, err := ioutil.ReadFile(BlockChainName)
	if err != nil {
		fmt.Printf("读取文件不成功\n")
		return false
	}

	// 2、gob解密
	gob.Register(elliptic.P256())
	decoder := gob.NewDecoder(bytes.NewBuffer(contet))

	// 3、读取文件内容-赋值给区块链列表中
	var bclist []*Block

	err = decoder.Decode(&bclist)
	bc.Blocks = bclist
	if err != nil {
		fmt.Printf("转义不成功\n")
		return false
	}
	return true
}

/*PrintBlockChainList
todo 24、打印区块链列表
*/
func (bc *BlockChain) PrintBlockChainList() {
	for i, block := range bc.Blocks {
		fmt.Printf("I: %d\n", i)
		fmt.Printf("PrevBlockHash: %x\n", block.PrevBlockHash)
		fmt.Printf("Hash: %x\n", block.Hash)
		fmt.Printf("Data: %s\n", block.Data)
		fmt.Printf("blockHeight: %d\n", block.blockHeight)
		fmt.Println("====================")
	}
}

/*addBlock
todo 28、添加区块
*/
func (bc *BlockChain) addBlock(data string) {
	// 取出最后一个区块
	lastBlock := bc.Blocks[len(bc.Blocks)-1]
	// 最后的区块的hash ,作为当前区块的前置hash
	prevHash := lastBlock.Hash
	newBlock := NewBlock(data, len(bc.Blocks), prevHash)
	bc.Blocks = append(bc.Blocks, newBlock)

	// 保存到区块文件中
	bc.saveBlockChainFile()
}

4.commands.go文件

package main

import "fmt"

/*
todo 8、新建commands 文件
*/

/*
todo 9、通过命令行新建区块链
*/
func (OsCli *OsCli) osCreatBlock() {
	fmt.Println("通过命令行新建区块链")

	/*todo 21、调用区块链方法,存储文件
	 */
	bc := NewBlockChain()
	bc.saveBlockChainFile()

	/*todo 22、运行打包
	 */
}

/* todo 10、通过命令行添加区块
 */

func (OsCli *OsCli) osAddBlock(data string) {
	fmt.Printf("通过命令行新建添加区块 %s", data)

	/*todo 29、调用区块链方法,添加区块
	 */
	bc := NewBlockChain()
	bc.addBlock(data)
	bc.PrintBlockChainList()

	/*todo 30、运行打包
	 */
}

/* todo 11、通过命令行打印区块列表
 */
func (OsCli *OsCli) osPrintBlockList() {
	fmt.Println("通过命令行打印区块列表")

	/*todo 26、调用区块链方法,打印区块列表
	 */
	bc := NewBlockChain()
	bc.PrintBlockChainList()

	/*todo 27、运行打包
	 */
}

5.osCli.go文件

package main

import (
	"fmt"
	"os"
)

/*
todo 1、新建 osCli.go 文件
*/

/*
OsCli
todo 2、声明os结构体
*/
type OsCli struct {
}

/*
todo 3、对于os结构体的封装
*/

func (OsCli *OsCli) Init() {
	// s1 接受命令行参数
	cads := os.Args

	if len(cads) < 2 {
		fmt.Printf("无效的命令")
		os.Exit(1)
	}

	switch cads[1] {
	// todo 1====区块相关======
	case "CreatBlockChain":
		fmt.Printf("创建区块链命令被调用\n")
		OsCli.osCreatBlock()
	case "addBlock":
		if len(cads) != 3 {
			fmt.Printf("无效的命令,请输入需要添加的内容")
			os.Exit(1)
		}
		fmt.Printf("添加区块AddBlock命令被调用\n")
		OsCli.osAddBlock(cads[2])
	case "BlockChainList":
		fmt.Printf("打印区块链列表BlockChainList被调用\n")
		OsCli.osPrintBlockList()
	default:
		fmt.Printf("打印错误")
	}
}

6.utils.go文件

package main

import (
	"bytes"
	"encoding/binary"
	"log"
	"os"
)

// 工具函数文件
func uintToByte(num uint64) []byte {
	//TODO uint 转 byte
	// 使用binary.Write 来进行编码
	var buffer bytes.Buffer
	err := binary.Write(&buffer, binary.BigEndian, num)
	if err != nil {
		log.Panic(err)
	}
	return buffer.Bytes()
}

func IsFileExist(fileName string) bool {
	_, err := os.Stat(fileName)
	if os.IsNotExist(err) {
		return  false
	}
	return  true
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值