一、比特币的基础知识
1.1 比特币
一个软件系统,每个人都可以下载使用,使用者之间不断进行交易,产生数据
1.2 区块
比特币系统使用者之间交易的数据以数据块的形式存储,最终存储在数据库中,这个包含交易数据的数据块我们称之为区块。
1.3 区块链
保存上述所有区块的数据库我们称之为区块链。
1.4 记账
将系统中的交易数据写到数据库中我们称之为记账
1. 5 钱包
- 创建私钥公钥,保存公钥,相当于钱包,可以存放多个地址
- 地址类似银行卡,私钥类似银行卡密码
- 钱包会便利账本的交易信息,来得知有没有钱
- 一个地址对应一个私钥
1.6 节点
每一个运行区块链挖矿软件的人都会便成为一个区块链网络的节点。
1.7 挖矿
节点之间竞争记账的权利就称之为挖矿。
1.8出块时间
大约10分钟出一个比特币
1.9 出块奖励
1.10 比特币总量
1.11 区块容量
1M大约容纳4000笔交易
1.12 每秒成交量
1.13 单位
sat(聪)
二、其他基础知识
2.1 挖矿(工作量证明)
sha256(区块数据+随机数据)<目标的哈希值
2.2 go演示挖矿
import (
"crypto/sha256"
"fmt"
)
func main(){
data := "helloWord"
for i:=0; i < 100; i++{
res := sha256.Sum256([]byte(data + string(i)))
fmt.Printf("%x", res[:])
fmt.Println()
}
}
2.3 地址生成规则
私钥经过椭圆曲线相乘生成公钥,在通过哈希算法得到比特币地址。
2.4 base64
0-9,a-z,A-Z,+,-
2.5 交易
三、模拟简单的区块链
3.1 创建简单的区块
type Block struct{
PreBlockHash []byte
Hash []byte
Data []byte
}
func createBlock(preBlockHash []byte, data string) *Block{
block := Block{
PreBlockHash: preBlockHash,
Data: []byte(data),
Hash: []byte{},
}
block.SetHash()
return &block
}
func (block *Block)SetHash(){
blockInfo := append(block.PreBlockHash,block.Data...)
Hash := sha256.Sum256(blockInfo)
block.Hash = Hash[:]
}
func main() {
var block *Block = createBlock([]byte{}, "第一个区块")
fmt.Printf("上一区块的hash值%x:",block.PreBlockHash)
fmt.Println()
fmt.Printf("当前区块的hash值%x:",block.Hash)
fmt.Println()
fmt.Println("当前区块的数据",string(block.Data))
}
结果:
前面区块的hash值 []
当前区块的hash值328fffe02f9e57c15508352cb145aa68abcf83da69a059e975d2171b1e7f8f92
当前区块的数据 第一个区块
3.2 创建简单的区块链
type BlockChain struct {
blockChain []*Block
}
func CreateBlockChain() *BlockChain{
blockChain := BlockChain{
blockChain: []*Block{GenesisBlock()},
}
return &blockChain
}
3.3 创建创世块
func GenesisBlock() *Block{
genesisBlock := CreateBlock([]byte{},"第一个创世块,牛逼")
return genesisBlock
}
3.4 向区块链中添加区块
func (bc *BlockChain)AddBlock(data string){
preHash := bc.blockChain[len(bc.blockChain)-1].Hash
block := CreateBlock(preHash, data)
bc.blockChain = append(bc.blockChain, block)
}
四、模拟复杂的区块链
4.1 将unit64转换成byte类型
func Uint64ConvertByte(data uint64)[]byte{
var buffer bytes.Buffer
err := binary.Write(&buffer, binary.BigEndian,data)
if err != nil {
log.Panicln(err)
}
return buffer.Bytes()
}
4.2 bytes.Join()
func (block *Block)SetHash(){
var blockInfo []byte
tem := [][]byte{
Uint64ConvertByte(block.Version),
block.PreBlockHash,
block.MerkelRoot,
Uint64ConvertByte(block.TimeStamp),
Uint64ConvertByte(block.Difficulty),
Uint64ConvertByte(block.Nonce),
block.Data,
}
bytes.Join(tem, []byte{})
Hash := sha256.Sum256(blockInfo)
block.Hash = Hash[:]
}
4.3 挖矿演示
type ProofOfWork struct {
block *Block
target *big.Int
}
func CreatePOW(block *Block) *ProofOfWork{
pow := ProofOfWork{
block: block,
}
target := "0000100000000000000000000000000000000000000000000000000000000000"
bigNum := big.Int{}
res, _ := bigNum.SetString(target, 16)
pow.target = res
return &pow
}
func (pow *ProofOfWork) Run()([]byte, uint64){
tmpBigInt := &big.Int{}
var nonce uint64 = 0
var hash [32]byte
for{
block := pow.block
tem := [][]byte{
Uint64ConvertByte(block.Version),
block.PreBlockHash,
block.MerkelRoot,
Uint64ConvertByte(block.TimeStamp),
Uint64ConvertByte(block.Difficulty),
Uint64ConvertByte(nonce),
block.Data,
}
blockInfo := bytes.Join(tem, []byte(""))
hash = sha256.Sum256(blockInfo)
tmpBigInt.SetBytes(hash[:])
res := tmpBigInt.Cmp(pow.target)
if res == -1{
break
}
nonce ++
}
return hash[:],nonce
}
五、git命令
5.1 git pull
将远程主机 origin 的 master 分支拉取过来,与本地的 brantest 分支合并。
git pull origin master:brantest
5.2 git push
git push 命用于从将本地的分支版本上传到远程并合并。
命令格式如下:
git push <远程主机名> <本地分支名>:<远程分支名>
如果本地分支名与远程分支名相同,则可以省略冒号:
git push <远程主机名> <本地分支名>
5.3 git push --set-upstream origin v2
|