blockchain6

package module
v0.0.0-...-9a8bb3c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 9, 2022 License: GPL-3.0 Imports: 23 Imported by: 0

README

blockchain6

交易性能优化 文档地址:https://www.kancloud.cn/daleboy/blockchain/1971570

Documentation

Index

Constants

View Source
const (
	//HashLength 哈希长度
	HashLength = 32
)

Variables

View Source
var (
	ErrEmptyString   = &decError{"empty hex string"}
	ErrSyntax        = &decError{"invalid hex string"}
	ErrMissingPrefix = &decError{"hex string without 0x prefix"}
	ErrOddLength     = &decError{"hex string of odd length"}
	ErrEmptyNumber   = &decError{"hex string \"0x\""}
	ErrLeadingZero   = &decError{"hex number with leading zero digits"}
	ErrUint64Range   = &decError{"hex number > 64 bits"}
	ErrBig256Range   = &decError{"hex number > 256 bits"}
)

Errors

Functions

func Base58Decode

func Base58Decode(input []byte) []byte

Base58Decode 反编码Base58-encoded数据

func Base58Encode

func Base58Encode(input []byte) []byte

Base58Encode 将字节数组编码为Base58(人可以认识)

func Decode

func Decode(input string) ([]byte, error)

Decode 反编码一个hex字符串(包含0x前缀)

func Encode

func Encode(b []byte) string

Encode 编码字节数组为hex字符串(带0x前缀)

func HashPubKey

func HashPubKey(pubKey []byte) []byte

HashPubKey 对公钥进行哈希

func IntToHex

func IntToHex(num int64) []byte

IntToHex 将整型转为二进制数组

func ReverseBytes

func ReverseBytes(data []byte)

ReverseBytes 反转字节数组顺序

func ValidateAddress

func ValidateAddress(address string) bool

ValidateAddress 检查地址是否合法

Types

type Block

type Block struct {
	Timestamp     int64
	Transactions  []*Transaction //存储交易数据,不再是字符串数据了
	PrevBlockHash []byte
	Nonce         int
	Hash          []byte
}

Block 区块结构新版,增加了计数器nonce,主要目的是为了校验区块是否合法 即挖出的区块是否满足工作量证明要求的条件

func DeserializeBlock

func DeserializeBlock(d []byte) *Block

DeserializeBlock 反序列化,注意返回的是Block的指针(引用)

func NewBlock

func NewBlock(transactions []*Transaction, prevBlockHash []byte) *Block

NewBlock 创建普通区块 一个block里面可以包含多个交易

func NewGenesisBlock

func NewGenesisBlock(coninbase *Transaction) *Block

NewGenesisBlock 创建创始区块,包含创始交易。注意,创建创始区块也需要挖矿。

func (*Block) HashTransactions

func (b *Block) HashTransactions() []byte

HashTransactions 计算交易组合的哈希值,最后得到的是Merkle tree的根节点 获得每笔交易的哈希,将它们关联起来,然后获得一个连接后的组合哈希 此方法只会被PoW使用

func (*Block) Serialize

func (b *Block) Serialize() []byte

Serialize Block序列化 特别注意,block对象的任何不以大写字母开头命令的变量,其值都不会被序列化到[]byte中

type Blockchain

type Blockchain struct {
	Tip []byte   //区块链最后一块的哈希值
	Db  *bolt.DB //数据库
}

Blockchain 区块链结构 我们不在里面存储所有的区块了,而是仅存储区块链的 tip。 另外,我们存储了一个数据库连接。因为我们想要一旦打开它的话,就让它一直运行,直到程序运行结束。

func CreatBlockchain

func CreatBlockchain(address string) *Blockchain

CreatBlockchain 创建一个全新的区块链数据库 address用户发起创始交易,并挖矿,奖励也发给用户address 注意,创建后,数据库是open状态,需要使用者负责close数据库

func NewBlockchain

func NewBlockchain() *Blockchain

NewBlockchain 从数据库中取出最后一个区块的哈希,构建一个区块链实例

func (*Blockchain) FindSpendableOutput

func (bc *Blockchain) FindSpendableOutput(pubKeyHash []byte, amount int) (int, map[string][]int)

FindSpendableOutput 查找某个用户可以花费的输出,放到一个映射里面 从未花费交易里取出未花费的输出,直至取出输出的币总数大于或等于需要send的币数为止

func (*Blockchain) FindTransaction

func (bc *Blockchain) FindTransaction(txID []byte) (Transaction, error)

FindTransaction 迭代整个区块链,根据交易ID查询到一个交易

func (*Blockchain) FindTransactionForUTXO

func (bc *Blockchain) FindTransactionForUTXO(txID []byte) (Transaction, error)

FindTransactionForUTXO 根据交易ID查询到一个交易,仅仅查询UTXOBlock的数据库,不需要迭代整个区块链

func (*Blockchain) FindUTXO

func (bc *Blockchain) FindUTXO() (map[string]TxOutputs, map[string]common.Hash)

FindUTXO 从区块链中取得所有未花费输出及包含未花费输出的block 只会区块链新创建后调用一次,其他时候不会调用 不再需要调用者的公钥,因为我们保存到bucket的UTXO是所有的未花费输出

func (*Blockchain) FindUnspentTransaction

func (bc *Blockchain) FindUnspentTransaction(pubKeyHash []byte) []Transaction

FindUnspentTransaction 查找未花费的交易(即该交易的花费尚未花出,换句话说, 及该交易的输出尚未被其他交易作为输入包含进去)

func (*Blockchain) Iterator

func (bc *Blockchain) Iterator() *BlockchainIterator

Iterator 每当需要对链中的区块进行迭代时候,我们就通过Blockchain创建迭代器 注意,迭代器初始状态为链中的tip,因此迭代是从最新到最旧的进行获取

func (*Blockchain) MineBlock

func (bc *Blockchain) MineBlock(transactions []*Transaction) *Block

MineBlock 挖出普通区块并将新区块加入到区块链中 此方法通过区块链的指针调用,将修改区块链bc的内容

func (*Blockchain) SignTransaction

func (bc *Blockchain) SignTransaction(tx *Transaction, privKey ecdsa.PrivateKey)

SignTransaction 对一个交易的所有输入引用的输出的交易进行签名 注意,这里签名的不是参数tx(当前交易),而是tx输入所引用的输出的交易

func (*Blockchain) VerifyTransaction

func (bc *Blockchain) VerifyTransaction(tx *Transaction) bool

VerifyTransaction 验证一个交易的所有输入的签名

type BlockchainIterator

type BlockchainIterator struct {
	// contains filtered or unexported fields
}

BlockchainIterator 区块链迭代器,用于对区块链中的区块进行迭代

func (*BlockchainIterator) Next

func (i *BlockchainIterator) Next() *Block

Next 区块链迭代,返回当前区块,并更新迭代器的currentHash为当前区块的PrevBlockHash

type CLI

type CLI struct{}

CLI 响应处理命令行参数

func (*CLI) Run

func (cli *CLI) Run()

Run 读取命令行参数,执行相应的命令 使用标准库里面的 flag 包来解析命令行参数:

type Hash

type Hash [HashLength]byte

Hash 表示32字节Keccak256哈希

func BytesToHash

func BytesToHash(b []byte) Hash

BytesToHash 将b转为hash 如果b的长度大于32字节, b将从左侧截断

func (Hash) Big

func (h Hash) Big() *big.Int

Big 将哈希转为 big integer

func (Hash) Bytes

func (h Hash) Bytes() []byte

Bytes 获得字节数组切

func (Hash) Format

func (h Hash) Format(s fmt.State, c rune)

Format 实现fmt.Formatter,强制将字节切片转为指定的格式

func (Hash) Hex

func (h Hash) Hex() string

Hex 将哈希转为hex字符串

func (*Hash) SetBytes

func (h *Hash) SetBytes(b []byte)

SetBytes 将哈希转为二进制数组,并拷贝给二进制数组b. 如果b比len(h)大, b将被从左侧截断.

func (Hash) String

func (h Hash) String() string

String 实现stringer接口,也会在需要写入日志时候用到

type MerkleNode

type MerkleNode struct {
	Left  *MerkleNode
	Right *MerkleNode
	Data  []byte
}

MerkleNode Merkle树节点

func NewMerkleNode

func NewMerkleNode(left, right *MerkleNode, data []byte) *MerkleNode

NewMerkleNode 哈希计算根节点的方法,创建一个新的Merkle树节点 叶子节点的left和right参数为nil,data参数不为nil,直接生成data的哈希就是节点值(节点的Data) 其它节点的data参数为nil,left和right参数不为nil,组合right和left并哈希后生成节点的Data

type MerkleTree

type MerkleTree struct {
	RootNode *MerkleNode
}

MerkleTree Merkle树结构

func NewMerkleTree

func NewMerkleTree(data [][]byte) *MerkleTree

NewMerkleTree 从一序列字节数组数据创建一个Merkle树

type ProofOfWork

type ProofOfWork struct {
	// contains filtered or unexported fields
}

ProofOfWork POW结构体 可以看出,每一个pow实例与具体的block相关 但在确定好挖矿难度系数后,所有区块的pow的target是相同的, 除非挖矿系数随着时间推移,挖矿难度系数不断增加

func NewProofOfWork

func NewProofOfWork(b *Block) *ProofOfWork

NewProofOfWork 初始化创建一个POW的函数,以block指针为参数(将修改该block) 主要目的是确定target

func (*ProofOfWork) Run

func (pow *ProofOfWork) Run() (int, []byte)

Run POW挖矿核心算法实现,注意,这是一个方法,不是函数, 因为挖矿的完整描述是:挖出包含某个实际交易信息(或数据)的区块 挖矿是为交易上链提供服务,矿工拿到交易信息后进行挖矿,挖出的有效区块将包含交易信息 有可能挖不出符合条件的区块,所以将区块上链之前,需要对挖出的区块进行验证(验证是否符合条件)

func (*ProofOfWork) Validate

func (pow *ProofOfWork) Validate() bool

Validate 验证工作量证明POW

type Transaction

type Transaction struct {
	ID        []byte     //交易ID
	Vin       []TxInput  //交易输入,由上次交易输入(可能多个)
	Vout      []TxOutput //交易输出,由本次交易产生(可能多个)
	Timestamp int64      //时间戳,确保每一笔交易的ID完全不同
}

Transaction 交易结构,代表一个交易

func NewCoinbaseTX

func NewCoinbaseTX(to, data string) *Transaction

NewCoinbaseTX 创建一个区块链创始交易,不需要签名

func NewUTXOTransaction

func NewUTXOTransaction(from, to string, amount int, UTXOSet *UTXOSet) *Transaction

NewUTXOTransaction 创建一个资金转移交易并签名(对输入签名) from、to均为Base58的地址字符串,UTXOSet为从数据库读取的未花费输出

func (*Transaction) Hash

func (tx *Transaction) Hash() []byte

Hash 返回交易的哈希,用作交易的ID

func (Transaction) IsCoinbase

func (tx Transaction) IsCoinbase() bool

IsCoinbase 检查交易是否是创始区块交易 创始区块交易没有输入,详细见NewCoinbaseTX tx.Vin只有一个输入,数组长度为1 tx.Vin[0].Txid为[]byte{},因此长度为0 Vin[0].Vout设置为-1

func (Transaction) Serialize

func (tx Transaction) Serialize() []byte

Serialize 对交易序列化

func (*Transaction) Sign

func (tx *Transaction) Sign(privKey ecdsa.PrivateKey, prevTXs map[string]Transaction)

Sign 对交易中的每一个输入进行签名,需要把输入所引用的输出交易prevTXs作为参数进行处理

func (Transaction) String

func (tx Transaction) String() string

String 将交易转为人可读的信息

func (*Transaction) TrimmedCopy

func (tx *Transaction) TrimmedCopy() Transaction

TrimmedCopy 创建一个修剪后的交易副本(深度拷贝的副本),用于签名用 由于TrimmedCopy是在tx签名前执行,实际上修剪只是在tx基础上,将输入Vin中的每一个vin的PubKey置为nil

func (*Transaction) Verify

func (tx *Transaction) Verify(prevTXs map[string]Transaction) bool

Verify 校验所有交易输入的签名 私钥签名,公钥验证

type TxInput

type TxInput struct {
	Txid []byte //前一笔交易的ID
	Vout int    //前一笔交易在该笔交易所有输出中的索引(一笔交易可能有多个输出,需要有信息指明具体是哪一个)

	Signature []byte //输入数据签名

	//PubKey公钥,是发送者的钱包的公钥,用于解锁输出
	//如果PubKey与所引用的锁定输出的PubKey相同,那么引用的输出就会被解锁,然后被解锁的值就可以被用于产生新的输出
	//如果不正确,前一笔交易的输出就无法被引用在输入中,或者说,也就无法使用这个输出
	//这种机制,保证了用户无法花费其他人的币
	PubKey []byte
}

TxInput 交易的输入 包含的是前一笔交易的一个输出

func (*TxInput) UsesKey

func (in *TxInput) UsesKey(pubKeyHash []byte) bool

UsesKey 检查是否可以解锁引用的输出

type TxOutput

type TxOutput struct {
	Value int //输出里面存储的“币”

	//锁定输出的公钥(比特币里面是一个脚本,这里是公钥)
	PubKeyHash []byte
}

TxOutput 交易的输出

func NewTxOutput

func NewTxOutput(value int, address string) *TxOutput

NewTxOutput 创建一个新的 TXOutput 注意,这里需要将address进行反编码成实际的地址

func (*TxOutput) IsLockedWithKey

func (out *TxOutput) IsLockedWithKey(pubKeyHash []byte) bool

IsLockedWithKey 检查输出是否能够被公钥pubKeyHash拥有者使用

func (*TxOutput) Lock

func (out *TxOutput) Lock(address []byte)

Lock 对输出锁定,即反编码address后,获得实际的公钥哈希

type TxOutputs

type TxOutputs struct {
	Outputs []TxOutput
}

TxOutputs TxOutput集合

func DeserializeOutputs

func DeserializeOutputs(data []byte) TxOutputs

DeserializeOutputs 反序列化TxOutputs

func (TxOutputs) Serialize

func (outs TxOutputs) Serialize() []byte

Serialize 序列化TxOutputs

type UTXOSet

type UTXOSet struct {
	Blockchain *Blockchain
}

UTXOSet 代表UTXO集合

func (UTXOSet) CountTransactions

func (u UTXOSet) CountTransactions() int

CountTransactions 从数据库的UTXO表中查找一个UTXO集合中交易的数量

func (UTXOSet) FindSpendableOutputs

func (u UTXOSet) FindSpendableOutputs(pubkeyHash []byte, amount int) (int, map[string][]int)

FindSpendableOutputs 从数据库的UTXO表中找到输入引用的未花费输出 从未花费交易里取出未花费的输出,直至取出输出的币总数大于或等于需要send的币数为止

func (UTXOSet) FindUTXO

func (u UTXOSet) FindUTXO(pubKeyHash []byte) []TxOutput

FindUTXO 从数据库的UTXO表中查找一个公钥哈希的UTXO

func (UTXOSet) Reindex

func (u UTXOSet) Reindex()

Reindex 重建数据库的UTXO 只会在区块链新创建完毕后执行一次,其他时候不执行 在bucket中,一个交易ID,最多只有一条记录 创建两个表:utxoBucket和utxoBlockBucket

func (UTXOSet) Update

func (u UTXOSet) Update(block *Block)

Update 根据区块中的交易更新数据库的UTXO表和UTXOBlock表 该区块是区块链的Tip区块

type Wallet

type Wallet struct {
	PrivateKey ecdsa.PrivateKey
	PublicKey  []byte
}

Wallet 钱包保存公钥和私钥对

func NewWallet

func NewWallet() *Wallet

NewWallet 创建并返回一个钱包

func (Wallet) GetAddress

func (w Wallet) GetAddress() []byte

GetAddress 返回钱包地址(可为人识别的地址)

type Wallets

type Wallets struct {
	Wallets map[string]*Wallet
}

Wallets 保存钱包集合

func NewWallets

func NewWallets() (*Wallets, error)

NewWallets 从文件读取生成Wallets

func (*Wallets) CreateWallet

func (ws *Wallets) CreateWallet() string

CreateWallet 添加一个钱包到Wallets

func (*Wallets) GetAddresses

func (ws *Wallets) GetAddresses() []string

GetAddresses 从钱包文件中返回所有钱包地址

func (Wallets) GetWallet

func (ws Wallets) GetWallet(address string) Wallet

GetWallet 根据地址返回一个钱包

func (*Wallets) LoadFromFile

func (ws *Wallets) LoadFromFile() error

LoadFromFile 从文件读取wallets

func (Wallets) SaveToFile

func (ws Wallets) SaveToFile()

SaveToFile 保存wallets到文件

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL