国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

從零到一用go語言造一個小型區(qū)塊鏈(一)

這篇具有很好參考價值的文章主要介紹了從零到一用go語言造一個小型區(qū)塊鏈(一)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

學了兩個月左右的區(qū)塊鏈理論知識,學來學去總是不深入,總是覺得迷迷糊糊,于是我打算自己造一個小型私有的區(qū)塊鏈。當然這一個項目我也是有借鑒前人視頻的,因為項目這個東西其實單靠一個人的力量根本搞不動的,只好借鑒前人的視頻來深化自己的基礎內(nèi)容,同時也增加自己的項目經(jīng)驗。

環(huán)境

編程語言:go語言
測試環(huán)境以及運行環(huán)境:windows11

理論知識

golang 區(qū)塊鏈項目,golang,區(qū)塊鏈,開發(fā)語言
區(qū)塊鏈:存數(shù)據(jù)的塊+hash指針鏈。
hash:哈希,類似于一個數(shù)學函數(shù)f(x),其輸出空間f(x)為2^256次方,而輸入空間x是無限的。所以有一定幾率會有hash碰撞。
hash碰撞:就是兩個不同的輸入,卻有兩個相同的輸出。但是專家說這個幾率比bigbang還小,專家把它稱為collision resistance。此外專家還提出了其余兩個hash的性質(zhì):hiding , puzzle friendly。
collision resistance:耐撞,就是hash可以盡量避免碰撞的意思。
hiding:單向的,不可逆轉的,即知道x可以推f(x),但是知道f(x)不可以推x。
puzzle friendly:謎一般的存在,就是這玩意很難快速通過x找出f(x),只能一個個不同的x嘗試,所以這也成為了pow!
pow:proof of work,工作量證明,說白了:你家電腦開著挖礦計算f(x),電表轉了多少w(或者 嘗試x的次數(shù)),這就是你的工作量證明。進而v神提出了某太坊(也是區(qū)塊鏈),想要改變某特幣中pow為pos。
pos:proof of state,權益證明,說白了:有錢就有權!
UTXO:未花費的交易輸出,就是一個數(shù)據(jù)結構存放了未花費的交易,這樣就不用從當前區(qū)塊往前查找自己獲得的比特幣以及自己花費的比特幣來計算自己余額。
golang 區(qū)塊鏈項目,golang,區(qū)塊鏈,開發(fā)語言
全節(jié)點:保存區(qū)塊鏈一切的信息
輕節(jié)點:只保留與自身相關的交易信息,等到需要驗證的時候,去全節(jié)點進行驗證交易信息是否偽造篡改。
交易信息:transaction,它是礦工將區(qū)塊鏈上相關的轉賬交易等進行打包,生成merkle tree,然后通過merkle tree獲得根值的hash值。
merkle tree:默克爾樹,哈希樹,葉節(jié)點鏈接交易信息,并且逐層取hash,直到獲得根hash,將其存儲block header(區(qū)塊頭),如下圖所示。
golang 區(qū)塊鏈項目,golang,區(qū)塊鏈,開發(fā)語言
挖礦:用電獲得算力,用算力計算hash值,查看hash是否小于區(qū)塊鏈系統(tǒng)指定的target區(qū)間。這個hash值是block header中的信息進行concat(鏈接)的字節(jié),然后將這些字節(jié)進行計算獲得hash(當然nonce是可變的,所以可以使得每次輸出的hash不同,從而找到符合的hash值)

初步實現(xiàn)pow的框架

初步實現(xiàn):能算hash,讓其達到target區(qū)間內(nèi)的hash。

1.實現(xiàn)單個的block(區(qū)塊)

package block

import (
	"bytes"
	"crypto/sha256"
	"strconv"
	"time"
)

type Block struct {
	//區(qū)塊 包含 高度 prevhash thishash merkleTree(交易數(shù)據(jù)) timestamp nonce
	Height        int64
	PrevBlockHash []byte
	Data          []byte
	thisBlockHash []byte
	Timestamp     int64
	Nonce         int64
}

// 創(chuàng)建新的區(qū)塊
func CreateBlock(data string, height int64, prevBlockHash []byte) *Block {
	block := new(Block)
	block.Height = height
	block.Data = []byte(data)
	block.Timestamp = time.Now().Unix()
	block.PrevBlockHash = prevBlockHash
	block.thisBlockHash = nil
	block.Nonce = 0
	//pow:proof of work,工作量的證明,返回hash和nonce
	pow := NewProofOfWork(block)
	//開始挖礦
	hash, nonce := pow.Start()
	//更新兩者
	block.thisBlockHash = hash[:]
	block.Nonce = nonce
	return block
}

// 形成hash值
func (block *Block) SetHash() {
	//高度字節(jié)化
	height := Int64ToByte(block.Height)
	//timeStamp := Int64ToByte(block.Timestamp)
	//時間戳字節(jié)化
	timeString := strconv.FormatInt(block.Timestamp, 2)
	timeStamp := []byte(timeString)
	//拼接所有屬性
	blockBytes := bytes.Join([][]byte{height, block.PrevBlockHash, block.Data, timeStamp, block.thisBlockHash}, []byte{})
	//形成hash
	hash := sha256.Sum256(blockBytes)
	//類型轉換
	block.thisBlockHash = hash[:]
}

// 生成創(chuàng)世塊
func CreateGenesisBlock(data string) *Block {
	genesisBlock := new(Block)
	//創(chuàng)世區(qū)塊的長度為1,無前hash指針
	genesisBlock.PrevBlockHash = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
	genesisBlock.Data = []byte(data)
	genesisBlock.Height = 1
	genesisBlock.Timestamp = time.Now().Unix()
	genesisBlock.SetHash()
	return genesisBlock
}

2.實現(xiàn)一整條blockchain(區(qū)塊鏈)

package block

type BlockChain struct {
	//存儲區(qū)塊
	Blocks []*Block
}

// 創(chuàng)建帶有創(chuàng)世區(qū)塊的區(qū)塊鏈
func CreateBCWithGB() *BlockChain {
	genesisBlock := CreateGenesisBlock("創(chuàng)世區(qū)塊")
	return &BlockChain{[]*Block{genesisBlock}}
}

// 往區(qū)塊鏈添加新的區(qū)塊
func (bc *BlockChain) AppendBlock(data string, height int64, preHash []byte) {
	newBC := CreateBlock(data, height, preHash)
	bc.Blocks = append(bc.Blocks, newBC)
	//newBC := block.CreateBlock(data, int64(len(bc.Blocks)), bc.Blocks[len(bc.Blocks)-1].thisBlockHash)

}

3.實現(xiàn)proof of work(工作量證明)

package block

import (
	"bytes"
	"crypto/sha256"
	"fmt"
	"math/big"
)

// 代表該目標區(qū)域的hash中前16位為0
const targetZeroBits = 30

type ProofOfWork struct {
	block  *Block   //當前要驗證的區(qū)塊
	target *big.Int //挖礦難度(目標區(qū)域)
}

// 拼接數(shù)據(jù),返回字節(jié)數(shù)組,以便形成hash
func (pow *ProofOfWork) prepData(nonce int64) []byte {
	data := bytes.Join(
		[][]byte{
			pow.block.PrevBlockHash,
			pow.block.Data,
			Int64ToByte(pow.block.Timestamp),
			Int64ToByte(int64(targetZeroBits)),
			Int64ToByte(int64(nonce)),
			Int64ToByte(int64(pow.block.Height))}, []byte{})
	return data
}

// 啟動工作量證明(挖礦!)
func (pow *ProofOfWork) Start() ([]byte, int64) {
	//1.block屬性拼接成字節(jié)數(shù)組
	//2.生成hash
	//3.判斷hash有效性
	nonce := 0
	var hashInt big.Int //用于存儲當前所生成的hash值
	var hash [32]byte
	for {
		prep := pow.prepData(int64(nonce))
		hash = sha256.Sum256(prep)
		fmt.Println(hash)
		hashInt.SetBytes(hash[:])
		fmt.Println(hash)
		if pow.target.Cmp(&hashInt) == 1 {
			break
		}
		nonce = nonce + 1
	}
	return hash[:], int64(nonce)
}

// 判斷hash是否有效
func (pow *ProofOfWork) isValid() bool {
	var hashInt big.Int
	hashInt.SetBytes(pow.block.thisBlockHash)
	if pow.target.Cmp(&hashInt) == -1 {
		return false
	}
	return true
}

// 創(chuàng)建工作量證明的對象(礦工)
func NewProofOfWork(block *Block) *ProofOfWork {
	pow := new(ProofOfWork)
	//創(chuàng)建一個初始值為1的target
	target := big.NewInt(1)
	//左移256-targetZeroBits,這樣就可以得到它的目標區(qū)域target
	target = target.Lsh(target, 256-targetZeroBits)
	pow.target = target
	pow.block = block
	return pow
}

大致的流程如下:
golang 區(qū)塊鏈項目,golang,區(qū)塊鏈,開發(fā)語言文章來源地址http://www.zghlxwxcb.cn/news/detail-777602.html

到了這里,關于從零到一用go語言造一個小型區(qū)塊鏈(一)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 用go語言擼一個簡易版的區(qū)塊鏈

    用go語言擼一個簡易版的區(qū)塊鏈

    用go擼一個簡易版的區(qū)塊鏈 這個最初的版本時多年以前學習go的時候,自己擼的一個簡易版本的區(qū)塊鏈。不過麻雀雖小,五臟俱全。通過這個代碼你了解區(qū)塊鏈內(nèi)部的大概運行機制時沒有問題的。 比特幣底層區(qū)塊鏈的代碼非常復雜,但是我們可以從中梳理幾個核心的概念,然

    2024年01月16日
    瀏覽(19)
  • 從零實現(xiàn)一個數(shù)據(jù)庫(DataBase) Go語言實現(xiàn)版 0.介紹

    英文源地址 我們?yōu)槭裁葱枰獢?shù)據(jù)庫?為什么不是直接把數(shù)據(jù)dump進文件中. 第一個話題就是持久化. 我們將討論如果寫入文件的過程中程序崩潰了, 或者電源斷電了, 文件的狀態(tài)會是什么樣的呢? 文件是否只是丟失了最后一次寫操作? 或者以寫了一半的文件結束 或者是以更差的狀態(tài)

    2024年02月06日
    瀏覽(21)
  • 開發(fā)一個Android應用:從零到一的實踐指南

    在這篇博文中,我們將逐步探討如何從頭開始構建一個Android應用。我們將從最基本的環(huán)境搭建開始,然后深入討論組件、布局和其他核心概念。在完成整個過程后,你將會掌握一個簡單但完整的Android應用開發(fā)流程。讓我們開始吧! 準備開發(fā)環(huán)境 創(chuàng)建項目 理解項目結構 設計

    2024年02月08日
    瀏覽(57)
  • go腳手架,可快速構建一個go小型項目

    1、項目技術使用 gin+sqlx+redis ,后續(xù)會引入需要的技術 2、項目目的 當我們有一個新的 idea 需要馬上付出實踐,用于構建小型項目,直接上手寫接口即可,主要為了大學生可以快速完成作業(yè),不需要搭建環(huán)境,本項目暫時完成不了復雜的業(yè)務哦~ 3、項目介紹 腳手架架構分為

    2024年02月09日
    瀏覽(36)
  • 【別再做XX外賣啦!和我從零到1編寫Mini版Easy-ES】完成一個Mapper模型

    【別再做XX外賣啦!和我從零到1編寫Mini版Easy-ES】完成一個Mapper模型

    作者:沈自在 代碼倉庫:https://gitee.com/tian-haoran/mini-easy-es 本節(jié)教程分支:https://gitee.com/tian-haoran/mini-easy-es/tree/course_02_create_mapper/ ??注意:本項目會持續(xù)更新,直到功能完善 1.1.1 什么是 FactoryBean接口? 很多同學都知道 BeanFactory 接口,這個是大名鼎鼎的Spring中的核心接口,

    2024年02月04日
    瀏覽(45)
  • 使用golang從零開始搭建基于UTXO模型的區(qū)塊鏈(一、實現(xiàn)最簡易的區(qū)塊鏈)

    使用golang從零開始搭建基于UTXO模型的區(qū)塊鏈(一、實現(xiàn)最簡易的區(qū)塊鏈)

    真正理解區(qū)塊鏈底層原理的方法就是寫一個底層,UTXO模型區(qū)塊鏈的開發(fā)難度還是比較簡單的,等開發(fā)完后再去嘗試一下基于account模型的。 什么是區(qū)塊鏈以及UTXO模型和account模型等問題我就不在這里寫了,網(wǎng)上的資料有很多,跟著寫之前可以先去了解一下區(qū)塊鏈的基礎知識。

    2024年02月10日
    瀏覽(22)
  • Golang:Go語言結構

    在我們開始學習 Go 編程語言的基礎構建模塊前,讓我們先來了解 Go 語言最簡單程序的結構。 Go 語言的基礎組成有以下幾個部分: 包聲明 引入包 函數(shù) 變量 語句 表達式 注釋 接下來讓我們來看下簡單的代碼,該代碼輸出了\\\"Hello World!\\\": 讓我們來看下以上程序的各個部分: 第一

    2024年02月10日
    瀏覽(21)
  • 學習如何在VS Code中創(chuàng)建一個Golang/Go項目,并運行一個簡單的Golang程序

    ?學習如何在VS Code中創(chuàng)建一個Golang項目,并運行一個簡單的Golang程序。 在VS Code 手動輸入命令創(chuàng)建一個Golang項目 在VS Code 不輸入命令創(chuàng)建一個Golang項目 1.?在VS Code 手動輸入命令創(chuàng)建一個Golang項目 步驟1:在VS Code中創(chuàng)建一個新文件夾,用于存放Golang項目文件。 步驟2:打開VS

    2024年02月14日
    瀏覽(28)
  • 66.Go從零搭建一個orm框架【簡版】

    66.Go從零搭建一個orm框架【簡版】

    代碼地址:https://gitee.com/lymgoforIT/golang-trick/tree/master/39-go-orm 我們在使用各種語言去做需求的時候,不管是 Java , Golang 還是 C++ 等語言,應該都接觸過使用 ORM 去鏈接數(shù)據(jù)庫,這些 ORM 有些是項目組自己整合實現(xiàn)的,也有些是用的開源的組件。特別在 1 個全新的項目中,我們都

    2024年01月18日
    瀏覽(28)
  • Go語言(Golang)數(shù)據(jù)庫編程

    要想連接到 SQL 數(shù)據(jù)庫,首先需要加載目標數(shù)據(jù)庫的驅(qū)動,驅(qū)動里面包含著于該數(shù)據(jù)庫交互的邏輯。 sql.Open() 數(shù)據(jù)庫驅(qū)動的名稱 數(shù)據(jù)源名稱 得到一個指向 sql.DB 這個 struct 的指針 sql.DB 是用來操作數(shù)據(jù)庫的,它代表了0個或者多個底層連接的池,這些連接由sql 包來維護,sql 包會

    2024年02月03日
    瀏覽(93)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包