欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

go語言實現(xiàn)簡易比特幣系統(tǒng)錢包的原理解析

 更新時間:2021年04月07日 10:23:06   作者:小圣.  
這篇文章主要介紹了go語言實現(xiàn)簡易比特幣系統(tǒng)錢包的原理解析,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

錢包基礎(chǔ)概念

  • 廣義上,錢包是一個應(yīng)用程序,為用戶提供交互界面。錢包控制用戶訪問權(quán)限、管理比特比地址及秘鑰、跟蹤余額、創(chuàng)建交易和簽名交易
  • 狹義上,即從程序員角度來看,“錢包”是指用于存儲和管理用戶秘鑰的數(shù)據(jù)結(jié)構(gòu)
  • 錢包是私鑰的容器,一般是通過結(jié)構(gòu)化文件或簡單數(shù)據(jù)庫來實現(xiàn)的
  • 錢包中并不包含比特幣。比特幣是被記錄在比特幣網(wǎng)絡(luò)的區(qū)塊鏈中,用戶通過錢包中的密鑰簽名交易,從而控制網(wǎng)絡(luò)中的比特幣,在某種意義上,比特幣錢包就是密鑰鏈

錢包結(jié)構(gòu)體

type Wallet struct {
	//私鑰
	Private *ecdsa.PrivateKey
	//約定,這里的PubKey不存儲原始的公鑰,而是存儲X和Y拼接的字符串,在校驗端重新拆分(參考r,s傳遞)
	PubKey []byte
}

創(chuàng)建錢包

func NewWallet() *Wallet {
	//創(chuàng)建曲線
	curve := elliptic.P256()
	//生成私鑰
	privateKey, err := ecdsa.GenerateKey(curve, rand.Reader)
	if err != nil {
		log.Panic(err)
	}

	//生成公鑰
	pubKeyOrig := privateKey.PublicKey

	//拼接X, Y
	pubKey := append(pubKeyOrig.X.Bytes(), pubKeyOrig.Y.Bytes()...)

	return &Wallet{Private: privateKey, PubKey: pubKey}
}

錢包集結(jié)構(gòu)體

//定一個 Wallets結(jié)構(gòu),它保存所有的wallet以及它的地址
type Wallets struct {
	//map[地址]錢包
	WalletsMap map[string]*Wallet
}

創(chuàng)建錢包集

func NewWallets() *Wallets {
  var ws Wallets
  ws.WalletsMap = make(map[string]*Wallet)
  //加載本地錢包,把新建的錢包保存到本地
  ws.loadFile()
  return &ws
}

創(chuàng)建錢包到錢包集

func (ws *Wallets) CreateWallet() string {
	//創(chuàng)建一個錢包
	wallet := NewWallet()
	address := wallet.NewAddress()

	//添加到錢包集
	ws.WalletsMap[address] = wallet

	//保存包本地
	ws.saveToFile()
	//返回創(chuàng)建錢包的地址
	return address
}

保存錢包到本地

func (ws *Wallets) saveToFile() {

	var buffer bytes.Buffer

	gob.Register(elliptic.P256())

	encoder := gob.NewEncoder(&buffer)
	err := encoder.Encode(ws)
	//一定要注意校驗?。。?
	if err != nil {
		log.Panic(err)
	}

	ioutil.WriteFile(walletFile, buffer.Bytes(), 0600)
}

讀取錢包集里的錢包

func (ws *Wallets) loadFile() {
	//在讀取之前,要先確認文件是否在,如果不存在,直接退出
	_, err := os.Stat(walletFile)
	if os.IsNotExist(err) {
		return
	}

	//讀取內(nèi)容
	content, err := ioutil.ReadFile(walletFile)
	if err != nil {
		log.Panic(err)
	}

	//解碼
	gob.Register(elliptic.P256())

	decoder := gob.NewDecoder(bytes.NewReader(content))

	var wsLocal Wallets

	err = decoder.Decode(&wsLocal)
	if err != nil {
		log.Panic(err)
	}

	ws.WalletsMap = wsLocal.WalletsMap
}

列出所有錢包的地址

func (ws *Wallets) ListAllAddresses() []string {
	var addresses []string
	//遍歷錢包,將所有的key取出來返回
	for address := range ws.WalletsMap {
		addresses = append(addresses, address)
	}

	return addresses
}

生成錢包地址

  • 隨機選取32byte的數(shù)字作為私鑰
  • 使用橢圓曲線加密算法(ECDSA-secp256k1)計算私鑰對應(yīng)的非壓縮公鑰
  • 計算公鑰的SHA-256哈希值
  • 取上一步結(jié)果,計算RIPEMD-160哈希值
  • 取上一步結(jié)果,前面加上版本號(比特幣主網(wǎng)版本號“0x00”)
  • 取上一步結(jié)果,計算SHA-256哈希值
  • 取上一步結(jié)果,計算SHA-256哈希值
  • 取上一步結(jié)果的前4個字節(jié)(8位十六進制)
  • 把這4個字節(jié)加在第五步的結(jié)果后面,作為校驗(這就是比特幣地址的十六進制形態(tài))
  • 用base58表示法變換一下地址(這就是常見的比特幣地址形態(tài))
//生成地址
func (w *Wallet) NewAddress() string {
	//錢包公鑰
	pubKey := w.PubKey

	//計算公鑰哈希和ripe160
	rip160HashValue := HashPubKey(pubKey)
	//主網(wǎng)版本號為0x00
	version := byte(00)
	//拼接version
	payload := append([]byte{version}, rip160HashValue...)

	//校驗碼checksum
	checkCode := CheckSum(payload)

	//拼接版本、哈希值、校驗碼、25字節(jié)數(shù)據(jù)
	payload = append(payload, checkCode...)

	//base58編碼
	address := base58.Encode(payload)

	return address
}

結(jié)束

源碼:https://gitee.com/xiaoshengdada/go_bitcoin/tree/master/v5

到此這篇關(guān)于go語言實現(xiàn)簡易比特幣系統(tǒng)錢包的原理解析的文章就介紹到這了,更多相關(guān)go實現(xiàn)比特幣錢包內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語言實現(xiàn)JSON解析的方法詳解

    Go語言實現(xiàn)JSON解析的方法詳解

    在日常項目中,使用Json格式進行數(shù)據(jù)封裝是比較常見的操作。本文將詳細講解如何利用Go語言實現(xiàn)JSON的解析,感興趣的小伙伴可以學(xué)習(xí)一下
    2022-04-04
  • go語言分布式id生成器及分布式鎖介紹

    go語言分布式id生成器及分布式鎖介紹

    這篇文章主要為大家介紹了go語言分布式id生成器及分布式鎖介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • Golang動態(tài)數(shù)組的實現(xiàn)示例

    Golang動態(tài)數(shù)組的實現(xiàn)示例

    動態(tài)數(shù)組能自動調(diào)整大小,與靜態(tài)數(shù)組不同,其大小不固定,可根據(jù)需求變化,實現(xiàn)通常依賴于數(shù)據(jù)結(jié)構(gòu)如鏈表或數(shù)組加額外信息,本文就來介紹一下Golang動態(tài)數(shù)組的實現(xiàn)示例,感興趣的可以了解一下
    2024-10-10
  • golang 實現(xiàn)兩個結(jié)構(gòu)體復(fù)制字段

    golang 實現(xiàn)兩個結(jié)構(gòu)體復(fù)制字段

    這篇文章主要介紹了golang 實現(xiàn)兩個結(jié)構(gòu)體復(fù)制字段,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • golang構(gòu)建HTTP服務(wù)的實現(xiàn)步驟

    golang構(gòu)建HTTP服務(wù)的實現(xiàn)步驟

    其實很多框架都是在 最簡單的http服務(wù)上做擴展的的,基本上都是遵循h(huán)ttp協(xié)議,本文主要介紹了golang構(gòu)建HTTP服務(wù),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • 深入探究Golang中flag標準庫的使用

    深入探究Golang中flag標準庫的使用

    在本文中,我們將深入探討 flag 標準庫的實現(xiàn)原理和使用技巧,以幫助讀者更好地理解和掌握該庫的使用方法,文中的示例代碼講解詳細,感興趣的可以了解一下
    2023-04-04
  • GoLang語法之標準庫fmt.Printf的使用

    GoLang語法之標準庫fmt.Printf的使用

    fmt包實現(xiàn)了類似C語言printf和scanf的格式化I/O,主要分為向外輸出內(nèi)容和獲取輸入內(nèi)容兩大部分,本文就來介紹一下GoLang語法之標準庫fmt.Printf的使用,感興趣的可以了解下
    2023-10-10
  • go語言如何導(dǎo)入和使用包示例詳解

    go語言如何導(dǎo)入和使用包示例詳解

    這篇文章主要為大家介紹了go語言如何導(dǎo)入和使用包示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • go內(nèi)置函數(shù)copy()的具體使用

    go內(nèi)置函數(shù)copy()的具體使用

    當(dāng)我們在Go語言中需要將一個切片的內(nèi)容復(fù)制到另一個切片時,可以使用內(nèi)置的copy()函數(shù),本文就介紹了go內(nèi)置函數(shù)copy()的具體使用,感興趣的可以了解一下
    2023-08-08
  • Golang 如何解析和生成json

    Golang 如何解析和生成json

    這篇文章主要介紹了Golang 如何解析和生成json,幫助大家更好的理解和學(xué)習(xí)golang,感興趣的朋友可以了解下
    2020-09-09

最新評論