package main
import (
"blockTest/tool"
"bytes"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"fmt"
"golang.org/x/crypto/ripemd160"
"log"
)
var b58Alphabet = []byte("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
const VERSION = byte(0x00)
const CHECKSUM_LENGTH = 4
type BitcoinKeys struct {
PrivateKey *ecdsa.PrivateKey
PublicKey []byte
}
func (b BitcoinKeys) newKeyPair() {
curve := elliptic.P256()
var err error
b.PrivateKey, err = ecdsa.GenerateKey(curve, rand.Reader)
if err != nil {
log.Panic(err)
}
b.PublicKey = append(b.PrivateKey.PublicKey.X.Bytes(), b.PrivateKey.PublicKey.Y.Bytes()...)
}
func GetBitcoinKeys() BitcoinKeys {
b := &BitcoinKeys{nil, nil}
b.newKeyPair()
return b
}
func GeneratePublicKeyHash(publicKey []byte) []byte {
sha256PubKey := sha256.Sum256(publicKey)
r := ripemd160.New()
r.Write(sha256PubKey[:])
ripPubKey := r.Sum(nil)
return ripPubKey
}
func CheckSumHash(versionPublickeyHash []byte) []byte {
versionPublickeyHashSha1 := sha256.Sum256(versionPublickeyHash)
versionPublickeyHashSha2 := sha256.Sum256(versionPublickeyHashSha1[:])
tailHash := versionPublickeyHashSha2[:CHECKSUM_LENGTH]
return tailHash
}
//获取地址
func (b *BitcoinKeys) GetAddress() []byte{
//1.ripemd160(sha256(publickey))
ripPubKey := GeneratePublicKeyHash(b.PublicKey)
//2.最前面添加一个字节的版本信息获得 versionPublickeyHash
versionPublickeyHash := append([]byte{VERSION}, ripPubKey[:]...)
//3.sha256(sha256(versionPublickeyHash)) 取最后四个字节的值
tailHash := CheckSumHash(versionPublickeyHash)
//4.拼接最终hash versionPublickeyHash + checksumHash
finalHash := append(versionPublickeyHash, tailHash...)
//进行base58加密
address := tool.Base58Encode(finalHash)
return address
}
//检测比特币地址是否有效
func IsVaildBitcoinAddress(address string) bool {
adddressByte := []byte(address)
fullHash := tool.Base58Decode(adddressByte)
//version(1字节)+publicHash(20个字节)+checksum(4个字节)
if len(fullHash) != 25 {
return false
}
prefixHash := fullHash[:len(fullHash)-CHECKSUM_LENGTH]
tailHash := fullHash[len(fullHash)-CHECKSUM_LENGTH:]
tailHash2 := CheckSumHash(prefixHash)
if bytes.Compare(tailHash, tailHash2[:]) == 0 {
return true
} else {
return false
}
}
//通过地址获得公钥
func GetPublicKeyHashFromAddress(address string) []byte {
addressBytes := []byte(address)
fullHash := tool.Base58Decode(addressBytes)
publicKeyHash := fullHash[1 : len(fullHash)-CHECKSUM_LENGTH]
return publicKeyHash
}
func main(){
b:=GetBitcoinKeys()
fmt.Printf("私钥:%x\n",b.PrivateKey.D.Bytes()) //打印私钥
fmt.Printf("公钥:%x\n",b.PublicKey) //打印公钥
//ripPubKey:=GeneratePublicKeyHash(b.PublicKey)
//fmt.Printf("ripemd160公钥hash为:%x\n",ripPubKey)
bitAddress:=b.GetAddress() //接口操作
fmt.Printf("生成的比特币地址16进制为为:%x\n",bitAddress)
fmt.Printf("生成的比特币地址为:%s\n",bitAddress)
//bool:=IsVaildBitcoinAddress(string(bitAddress))
//fmt.Println(bool)
//bool2:=IsVaildBitcoinAddress("12JDwb7UAURbY5iLBXkXJeKHssg6oDxvua")
//fmt.Println(bool2)
}
有疑问加站长微信联系(非本文作者)