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

释放双眼,带上耳机,听听看~!

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

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
1package main
2
3import (
4   "bytes"
5   "crypto/ecdsa"
6   "crypto/elliptic"
7   "crypto/rand"
8   "crypto/sha256"
9   "log"
10  "fmt"
11
12  "golang.org/x/crypto/ripemd160"
13  "github.com/btcsuite/btcutil/base58"
14)
15
16const walletVersion = byte(0x00) // 钱包版本
17const addressChecksumLen = 4 // 验证码长度
18
19// 钱包
20type Wallet struct {
21  PrivateKey ecdsa.PrivateKey
22  PublicKey  []byte
23}
24
25// 初始化钱包
26func NewWallet() *Wallet {
27  private, public := newKeyPair()
28  wallet := Wallet{private, public}
29
30  return &wallet
31}
32
33// 得到比特币地址
34func (w Wallet) GetAddress() string {
35  pubKeyHash := HashPubKey(w.PublicKey)
36
37
38  walletVersionedPayload := append([]byte{walletVersion}, pubKeyHash...)
39  checksum := checksum(walletVersionedPayload)
40
41  fullPayload := append(walletVersionedPayload, checksum...)
42  address := base58.Encode(fullPayload)
43
44  // 比特币地址格式:【钱包版本 + 公钥哈希 + 验证码】
45  return address
46}
47
48// 得到公钥哈希
49func HashPubKey(pubKey []byte) []byte {
50  publicSHA256 := sha256.Sum256(pubKey)
51
52  RIPEMD160Hasher := ripemd160.New()
53  _, err := RIPEMD160Hasher.Write(publicSHA256[:])
54  if err != nil {
55      log.Panic(err)
56  }
57  publicRIPEMD160 := RIPEMD160Hasher.Sum(nil)
58
59  return publicRIPEMD160
60}
61
62// 通过【钱包版本+公钥哈希】生成验证码
63func checksum(payload []byte) []byte {
64  firstSHA := sha256.Sum256(payload)
65  secondSHA := sha256.Sum256(firstSHA[:])
66
67  return secondSHA[:addressChecksumLen]
68}
69
70// 创建新的私钥、公钥
71func newKeyPair() (ecdsa.PrivateKey, []byte) {
72  curve := elliptic.P256()
73  private, err := ecdsa.GenerateKey(curve, rand.Reader)
74  if err != nil {
75      log.Panic(err)
76  }
77  pubKey := append(private.PublicKey.X.Bytes(), private.PublicKey.Y.Bytes()...)
78
79  return *private, pubKey
80}
81
82// 验证比特币地址
83func ValidateAddress(address string) bool {
84  pubKeyHash := base58.Decode(address)
85  actualChecksum := pubKeyHash[len(pubKeyHash)-addressChecksumLen:]
86  version := pubKeyHash[0]
87  pubKeyHash = pubKeyHash[1 : len(pubKeyHash)-addressChecksumLen]
88  targetChecksum := checksum(append([]byte{version}, pubKeyHash...))
89
90  return bytes.Compare(actualChecksum, targetChecksum) == 0
91}
92
93
94func main() {
95  for i:=0; i<100;i++  {
96      w := NewWallet()
97      fmt.Println(w.GetAddress())
98  }
99}
100
101

给TA打赏
共{{data.count}}人
人已打赏
安全技术

Java虚拟机性能管理神器 - VisualVM(7) 排查JAVA应用程序线程泄漏

2022-1-11 12:36:11

卫生健康病毒疫情

全科医生队伍建设新闻发布会文字实录

2019-11-12 10:58:00

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索