比特币地址生成过程 go语言版本

Posted Technofiend

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了比特币地址生成过程 go语言版本相关的知识,希望对你有一定的参考价值。

比特币地址结构: 【版本 + 公钥哈希 + 验证码】

版本:默认0x00, 即可空白的一字节。
公钥:由非对称加密算法得出。
公钥哈希:就是给公钥做哈希算法得出的结果。
验证码:给 [版本 + 公钥哈希],sha256两次,取头4个字符作为验证码。

package main

import (
	"bytes"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/sha256"
	"log"
	"fmt"

	"golang.org/x/crypto/ripemd160"
	"github.com/btcsuite/btcutil/base58"
)

const walletVersion = byte(0x00) // 钱包版本
const addressChecksumLen = 4 // 验证码长度

// 钱包
type Wallet struct 
	PrivateKey ecdsa.PrivateKey
	PublicKey  []byte


// 初始化钱包
func NewWallet() *Wallet 
	private, public := newKeyPair()
	wallet := Walletprivate, public

	return &wallet


// 得到比特币地址
func (w Wallet) GetAddress() string 
	pubKeyHash := HashPubKey(w.PublicKey)


	walletVersionedPayload := append([]bytewalletVersion, pubKeyHash...)
	checksum := checksum(walletVersionedPayload)

	fullPayload := append(walletVersionedPayload, checksum...)
	address := base58.Encode(fullPayload)

	// 比特币地址格式:【钱包版本 + 公钥哈希 + 验证码】
	return address


// 得到公钥哈希
func HashPubKey(pubKey []byte) []byte 
	publicSHA256 := sha256.Sum256(pubKey)

	RIPEMD160Hasher := ripemd160.New()
	_, err := RIPEMD160Hasher.Write(publicSHA256[:])
	if err != nil 
		log.Panic(err)
	
	publicRIPEMD160 := RIPEMD160Hasher.Sum(nil)

	return publicRIPEMD160


// 通过【钱包版本+公钥哈希】生成验证码
func checksum(payload []byte) []byte 
	firstSHA := sha256.Sum256(payload)
	secondSHA := sha256.Sum256(firstSHA[:])

	return secondSHA[:addressChecksumLen]


// 创建新的私钥、公钥
func newKeyPair() (ecdsa.PrivateKey, []byte) 
	curve := elliptic.P256()
	private, err := ecdsa.GenerateKey(curve, rand.Reader)
	if err != nil 
		log.Panic(err)
	
	pubKey := append(private.PublicKey.X.Bytes(), private.PublicKey.Y.Bytes()...)

	return *private, pubKey


// 验证比特币地址
func ValidateAddress(address string) bool 
	pubKeyHash := base58.Decode(address)
	actualChecksum := pubKeyHash[len(pubKeyHash)-addressChecksumLen:]
	version := pubKeyHash[0]
	pubKeyHash = pubKeyHash[1 : len(pubKeyHash)-addressChecksumLen]
	targetChecksum := checksum(append([]byteversion, pubKeyHash...))

	return bytes.Compare(actualChecksum, targetChecksum) == 0



func main() 
	for i:=0; i<100;i++  
		w := NewWallet()
		fmt.Println(w.GetAddress())
	

以上是关于比特币地址生成过程 go语言版本的主要内容,如果未能解决你的问题,请参考以下文章

比特币--通过公钥生成地址全过程

用GO把你想说的话写到比特币链上

比特币相关文档备案

GO语言区块链技术---区块链前导

生成比特币钱包地址java示例(动态生成)

从 ECDSA 公钥生成比特币地址