go語言實(shí)戰(zhàn)之實(shí)現(xiàn)比特幣地址校驗(yàn)步驟
由公鑰生成比特幣地址步驟
- 隨機(jī)取一個(gè)32位隨機(jī)數(shù)作為私鑰
- 利用生產(chǎn)的隨機(jī)數(shù)采用橢圓加密算法生成公鑰
- 計(jì)算公鑰的sha256哈希值
- 計(jì)算RIPEMD-160哈希值
- 第4步結(jié)果加上版本號(hào)(比特幣為0x00)
- 對(duì)第5步結(jié)果取兩次sha256哈希值
- 取上一步結(jié)果的前四個(gè)字節(jié)
- 將第7步結(jié)果加到第步的結(jié)果后面作為校驗(yàn)
- 利用base58對(duì)第8步結(jié)果進(jìn)行變化得到地址
生成地址代碼如下
func (w Wallet) GetAddress() []byte {
pubKeyHash := HashPubKey(w.PublicKey)
versionedPayload := append([]byte{version}, pubKeyHash...)
checksum := checksum(versionedPayload)
fullPayload := append(versionedPayload, checksum...)
address := Base58Encode(fullPayload)
return address
}
func HashPubKey(pubKey []byte) []byte {
publicSHA256 := sha256.Sum256(pubKey)
RIPEMD160Hasher := ripemd160.New()
_, err := RIPEMD160Hasher.Write(publicSHA256[:])
publicRIPEMD160 := RIPEMD160Hasher.Sum(nil)
return publicRIPEMD160
}
func checksum(payload []byte) []byte {
firstSHA := sha256.Sum256(payload)
secondSHA := sha256.Sum256(firstSHA[:])
return secondSHA[:addressChecksumLen]
}
校驗(yàn)比特幣
地址是否正確代碼
addressChecksumLen:=4
func ValidateAddress(address string) bool {
pubKeyHash := Base58Decode([]byte(address))
actualChecksum := pubKeyHash[len(pubKeyHash)-addressChecksumLen:]
version := pubKeyHash[0]
pubKeyHash = pubKeyHash[1 : len(pubKeyHash)-addressChecksumLen]
targetChecksum := checksum(append([]byte{version}, pubKeyHash...))
return bytes.Compare(actualChecksum, targetChecksum) == 0
}
Base58Decode是對(duì)比特幣地址進(jìn)行解碼,然后取后四位校驗(yàn)位actualChecksum,利用去掉校驗(yàn)位的pubKeyHash再次算出校驗(yàn)位與地址的校驗(yàn)位做出對(duì)比,即可驗(yàn)證地址的正確性。 其中用到的函數(shù)有:
func checksum(payload []byte) [] //利用兩次shah256求校驗(yàn)位
byte {
firstSHA := sha256.Sum256(payload)
secondSHA := sha256.Sum256(firstSHA[:])
return secondSHA[:addressChecksumLen]
}
這是解碼的函數(shù),已經(jīng)有不少現(xiàn)有的代碼支持,故不作講解
func Base58Decode(input []byte) []byte {
result := big.NewInt(0)
zeroBytes := 0
for b := range input {
if b == 0x00 {
zeroBytes++
}
}
payload := input[zeroBytes:]
for _, b := range payload {
charIndex := bytes.IndexByte(b58Alphabet, b)
result.Mul(result, big.NewInt(58))
result.Add(result, big.NewInt(int64(charIndex)))
}
decoded := result.Bytes()
decoded = append(bytes.Repeat([]byte{byte(0x00)}, zeroBytes), decoded...)
return decoded
}
以上就是go語言實(shí)戰(zhàn)之實(shí)現(xiàn)比特幣地址校驗(yàn)步驟的詳細(xì)內(nèi)容,更多關(guān)于go語言比特幣地址校驗(yàn)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
go 判斷兩個(gè) slice/struct/map 是否相等的實(shí)例
這篇文章主要介紹了go 判斷兩個(gè) slice/struct/map 是否相等的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-12-12
GO比較兩個(gè)對(duì)象是否相同實(shí)戰(zhàn)案例
我們時(shí)常有比較兩個(gè)值是否相等的需求,下面這篇文章主要給大家介紹了關(guān)于GO比較兩個(gè)對(duì)象是否相同的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12
Go來合并兩個(gè)csv的實(shí)現(xiàn)示例
本文主要介紹了Go來合并兩個(gè)csv的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
golang實(shí)現(xiàn)循環(huán)隊(duì)列的示例代碼
循環(huán)隊(duì)列是一種使用固定大小的數(shù)組來實(shí)現(xiàn)隊(duì)列的數(shù)據(jù)結(jié)構(gòu),本文主要介紹了golang實(shí)現(xiàn)循環(huán)隊(duì)列的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下2024-07-07
Go語言fmt.Sprintf格式化輸出的語法與實(shí)例
Go 可以使用 fmt.Sprintf 來格式化字符串,下面這篇文章主要給大家介紹了關(guān)于Go語言fmt.Sprintf格式化輸出的語法與實(shí)例,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
Go代碼的組織和格式化規(guī)則實(shí)戰(zhàn)示例
這篇文章主要為大家介紹了Go代碼的組織和格式化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08

