golang共识锁实现用户地址分配

参考:https://github.com/liuchengxu/blockchain-tutorial/blob/master/content/part-5/address.md

类似于比特币实现一个用户一个地址,并分配10对ecc公私钥。

package main

import (
	"bytes"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/sha256"
	"golang.org/x/crypto/ripemd160"
	"log"
	"fmt"
	"encoding/hex"
	"math/big"
)

const version = byte(0x00)
const addressChecksumLen = 4
var b58Alphabet = []byte("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")

type userKeys struct {
	prk *ecdsa.PrivateKey
	puk ecdsa.PublicKey
}

type Address struct {
	PrivateKey ecdsa.PrivateKey
	PublicKey  []byte
	usrAddress string
	usrKeys    [10]userKeys
}

func getKey() (*ecdsa.PrivateKey, error) {
	prk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		return prk, err
	}
	return prk, nil
}

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 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 newAddress() Address {
	var address Address
	private, public := newKeyPair()
	address.PublicKey = public
	address.PrivateKey = private
	for i := 0; i < 10; i++ {
		prk, err := getKey()
		if err != nil {
			panic(err)
		}
		address.usrKeys[i].prk = prk
		address.usrKeys[i].puk = prk.PublicKey
	}
	address.usrAddress = getAddress(address)
	return address
}

func getAddress(a Address) string {
	pubKeyHash := hashPubKey(a.PublicKey)
	versionedPayload := append([]byte{version}, pubKeyHash...)
	checksum := checksum(versionedPayload)
	fullPayload := append(versionedPayload, checksum...)
	address := Base58Encode(fullPayload)
	return string(address)
}

func checksum(payload []byte) []byte {
	firstSHA := sha256.Sum256(payload)
	secondSHA := sha256.Sum256(firstSHA[:])
	return secondSHA[:addressChecksumLen]
}

func Base58Encode(input []byte) []byte {
	var result []byte
	x := big.NewInt(0).SetBytes(input)
	base := big.NewInt(int64(len(b58Alphabet)))
	zero := big.NewInt(0)
	mod := &big.Int{}
	for x.Cmp(zero) != 0 {
		x.DivMod(x, base, mod)
		result = append(result, b58Alphabet[mod.Int64()])
	}
	if input[0] == 0x00 {
		result = append(result, b58Alphabet[0])
	}
	return result
}

func Base58Decode(input []byte) []byte {
	result := big.NewInt(0)
	for _, b := range input {
		charIndex := bytes.IndexByte(b58Alphabet, b)
		result.Mul(result, big.NewInt(58))
		result.Add(result, big.NewInt(int64(charIndex)))
	}
	decoded := result.Bytes()
	if input[0] == b58Alphabet[0] {
		decoded = append([]byte{0x00}, decoded...)
	}
	return decoded
}

func main() {
	var ars Address = newAddress();
	fmt.Println("user PublicKey is :", hex.EncodeToString(ars.PublicKey))
	fmt.Println("user Address is :", ars.usrAddress)
	for i := 0; i < 10; i++ {
		fmt.Println(ars.usrKeys[i].prk)
		fmt.Println(ars.usrKeys[i].puk)
	}
}

猜你喜欢

转载自blog.csdn.net/reigns_/article/details/83088289