Fetch the repository succeeded.
package keygen
import (
"encoding/hex"
"errors"
"fmt"
"gitee.com/teacherming/keygen/dogecoin"
"gitee.com/teacherming/keygen/zcash"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/txscript"
dashutil "github.com/dashpay/dashd-go/btcutil"
dashchaincfg "github.com/dashpay/dashd-go/chaincfg"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
"github.com/fbsobreira/gotron-sdk/pkg/address"
"github.com/gcash/bchd/bchec"
bchchaincfg "github.com/gcash/bchd/chaincfg"
"github.com/gcash/bchutil"
ltcbtcec "github.com/ltcsuite/ltcd/btcec/v2"
ltcchaincfg "github.com/ltcsuite/ltcd/chaincfg"
"github.com/ltcsuite/ltcd/ltcutil"
"github.com/tyler-smith/go-bip32"
"github.com/tyler-smith/go-bip39"
)
// Purpose BIP43 - Purpose Field for Deterministic Wallets
// https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki
//
// Purpose is a constant set to 44' (or 0x8000002C) following the BIP43 recommendation.
// It indicates that the subtree of this node is used according to this specification.
//
// What does 44' mean in BIP44?
// https://bitcoin.stackexchange.com/questions/74368/what-does-44-mean-in-bip44
//
// 44' means that hardened keys should be used. The distinguisher for whether
// a key a given index is hardened is that the index is greater than 2^31,
// which is 2147483648. In hex, that is 0x80000000. That is what the apostrophe (') means.
// The 44 comes from adding it to 2^31 to get the final hardened key index.
// In hex, 44 is 2C, so 0x80000000 + 0x2C = 0x8000002C.
type Purpose = uint32
const (
PurposeBIP44 Purpose = 0x8000002C // 44' BIP44
PurposeBIP49 Purpose = 0x80000031 // 49' BIP49
PurposeBIP84 Purpose = 0x80000054 // 84' BIP84
PurposeBIP86 Purpose = 0x80000056 // 86' BIP86
PurposeCIP1852 Purpose = 0x8000073c // 1852' CIP1852
)
// CoinType SLIP-0044 : Registered coin types for BIP-0044
// https://github.com/satoshilabs/slips/blob/master/slip-0044.md
type CoinType = uint32
const (
CoinTypeBTC CoinType = 0x80000000
CoinTypeTestnet CoinType = 0x80000001
CoinTypeLTC CoinType = 0x80000002
CoinTypeDOGE CoinType = 0x80000003
CoinTypeDASH CoinType = 0x80000005
CoinTypeETH CoinType = 0x8000003c
CoinTypeZEC CoinType = 0x80000085
CoinTypeBCH CoinType = 0x80000091
CoinTypeEOS CoinType = 0x800000c2
CoinTypeTRX CoinType = 0x800000c3
CoinTypeNEAR CoinType = 0x8000018d
CoinTypeSOL CoinType = 0x800001f5
CoinTypeFLOW CoinType = 0x8000021b
CoinTypeMATIC CoinType = 0x800003c6
CoinTypeOKT CoinType = 0x800003e4
CoinTypeADA CoinType = 0x80000717
CoinTypeAVAXC CoinType = 0x8000232d
CoinTypeBSC CoinType = 0x8000232e
)
const (
Apostrophe uint32 = 0x80000000 // 0'
)
var NotSuppportCoin = errors.New("not support coin")
type Key struct {
purpose Purpose
coinType CoinType
path string
bip32Key *bip32.Key
}
func (k *Key) B58Serialize() string {
return k.bip32Key.B58Serialize()
}
// https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
// bip44 define the following 5 levels in BIP32 path:
// m / purpose' / coin_type' / account' / change / address_index
func (k *Key) GetPath() string {
return k.path
}
func (k *Key) Address() (string, error) {
switch k.coinType {
case CoinTypeBTC:
_, pubKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
addressPubKey, err := btcutil.NewAddressPubKey(pubKey.SerializeCompressed(), &chaincfg.MainNetParams)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
case CoinTypeTestnet:
_, pubKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
addressPubKey, err := btcutil.NewAddressPubKey(pubKey.SerializeCompressed(), &chaincfg.TestNet3Params)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
case CoinTypeDOGE:
_, pubKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
addressPubKey, err := btcutil.NewAddressPubKey(pubKey.SerializeCompressed(), &dogecoin.MainNetParams)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
case CoinTypeLTC:
_, pubKey := ltcbtcec.PrivKeyFromBytes(k.bip32Key.Key)
addressPubKey, err := ltcutil.NewAddressPubKey(pubKey.SerializeCompressed(), <cchaincfg.MainNetParams)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
case CoinTypeDASH:
_, pubKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
addressPubKey, err := dashutil.NewAddressPubKey(pubKey.SerializeCompressed(), &dashchaincfg.MainNetParams)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
case CoinTypeETH:
_, publicKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
publicKeyECDSA := publicKey.ToECDSA()
return crypto.PubkeyToAddress(*publicKeyECDSA).Hex(), nil
case CoinTypeZEC:
_, pubKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
addrPubKeyHash, err := zcash.NewAddressPubKeyHash(btcutil.Hash160(pubKey.SerializeUncompressed()), &zcash.MainNetParams)
if err != nil {
return "", err
}
return addrPubKeyHash.EncodeAddress(), nil
case CoinTypeBCH:
_, pubKey := bchec.PrivKeyFromBytes(bchec.S256(), k.bip32Key.Key)
addressPubKey, err := bchutil.NewAddressPubKey(pubKey.SerializeCompressed(), &bchchaincfg.MainNetParams)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
case CoinTypeNEAR:
return "", nil
case CoinTypeSOL:
return "", nil
case CoinTypeTRX:
_, publicKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
publicKeyECDSA := publicKey.ToECDSA()
return address.PubkeyToAddress(*publicKeyECDSA).Hex(), nil
case CoinTypeMATIC:
_, publicKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
publicKeyECDSA := publicKey.ToECDSA()
return crypto.PubkeyToAddress(*publicKeyECDSA).Hex(), nil
case CoinTypeOKT:
_, publicKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
publicKeyECDSA := publicKey.ToECDSA()
return crypto.PubkeyToAddress(*publicKeyECDSA).Hex(), nil
case CoinTypeADA:
_, publicKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
publicKeyECDSA := publicKey.ToECDSA()
return crypto.PubkeyToAddress(*publicKeyECDSA).Hex(), nil
case CoinTypeAVAXC:
_, publicKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
publicKeyECDSA := publicKey.ToECDSA()
return crypto.PubkeyToAddress(*publicKeyECDSA).Hex(), nil
case CoinTypeBSC:
_, publicKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
publicKeyECDSA := publicKey.ToECDSA()
return crypto.PubkeyToAddress(*publicKeyECDSA).Hex(), nil
default:
return "", NotSuppportCoin
}
}
func (k *Key) AddressPubKeyHash() (string, error) {
switch k.coinType {
case CoinTypeBTC:
_, pubKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
pubKeyHash := btcutil.Hash160(pubKey.SerializeCompressed())
addressPubKey, err := btcutil.NewAddressPubKeyHash(pubKeyHash, &chaincfg.MainNetParams)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
case CoinTypeTestnet:
_, pubKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
pubKeyHash := btcutil.Hash160(pubKey.SerializeCompressed())
addressPubKey, err := btcutil.NewAddressPubKeyHash(pubKeyHash, &chaincfg.TestNet3Params)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
case CoinTypeLTC:
_, pubKey := ltcbtcec.PrivKeyFromBytes(k.bip32Key.Key)
pubKeyHash := btcutil.Hash160(pubKey.SerializeCompressed())
addressPubKey, err := ltcutil.NewAddressPubKeyHash(pubKeyHash, <cchaincfg.MainNetParams)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
case CoinTypeDASH:
_, pubKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
pubKeyHash := btcutil.Hash160(pubKey.SerializeCompressed())
addressPubKey, err := dashutil.NewAddressPubKeyHash(pubKeyHash, &dashchaincfg.MainNetParams)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
default:
return "", NotSuppportCoin
}
}
func (k *Key) AddressWitnessPubKeyHash() (string, error) {
switch k.coinType {
case CoinTypeBTC:
_, pubKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
pubKeyHash := btcutil.Hash160(pubKey.SerializeCompressed())
addressPubKey, err := btcutil.NewAddressWitnessPubKeyHash(pubKeyHash, &chaincfg.MainNetParams)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
case CoinTypeTestnet:
_, pubKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
pubKeyHash := btcutil.Hash160(pubKey.SerializeCompressed())
addressPubKey, err := btcutil.NewAddressWitnessPubKeyHash(pubKeyHash, &chaincfg.TestNet3Params)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
case CoinTypeLTC:
_, pubKey := ltcbtcec.PrivKeyFromBytes(k.bip32Key.Key)
pubKeyHash := btcutil.Hash160(pubKey.SerializeCompressed())
addressPubKey, err := ltcutil.NewAddressWitnessPubKeyHash(pubKeyHash, <cchaincfg.MainNetParams)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
case CoinTypeDASH:
_, pubKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
pubKeyHash := btcutil.Hash160(pubKey.SerializeCompressed())
addressPubKey, err := dashutil.NewAddressWitnessPubKeyHash(pubKeyHash, &dashchaincfg.MainNetParams)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
default:
return "", NotSuppportCoin
}
}
func getScript(pubKey []byte) ([]byte, error) {
pubKeyHash160 := btcutil.Hash160(pubKey)
// 1.0
//return txscript.NewScriptBuilder().
// //AddOp(txscript.OP_DUP).
// AddOp(txscript.OP_HASH160).
// AddData(pubKeyHash160).
// AddOp(txscript.OP_EQUAL).
// //AddOp(txscript.OP_EQUALVERIFY).
// //AddOp(txscript.OP_CHECKSIG).
// Script()
// 2.0
return txscript.NewScriptBuilder().AddOp(txscript.OP_0).AddData(pubKeyHash160).Script()
// 3.0
//return pubKeyHash160, nil
}
func (k *Key) AddressScriptHash() (string, error) {
switch k.coinType {
case CoinTypeBTC:
_, pubKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
script, err := getScript(pubKey.SerializeCompressed())
if err != nil {
return "", err
}
addressPubKey, err := btcutil.NewAddressScriptHash(script, &chaincfg.MainNetParams)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
case CoinTypeTestnet:
_, pubKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
script, err := getScript(pubKey.SerializeCompressed())
if err != nil {
return "", err
}
addressPubKey, err := btcutil.NewAddressScriptHash(script, &chaincfg.TestNet3Params)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
case CoinTypeLTC:
_, pubKey := ltcbtcec.PrivKeyFromBytes(k.bip32Key.Key)
script, err := getScript(pubKey.SerializeCompressed())
if err != nil {
return "", err
}
addressPubKey, err := ltcutil.NewAddressScriptHash(script, <cchaincfg.MainNetParams)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
default:
return "", NotSuppportCoin
}
}
// 多签脚本太难了
func (k *Key) AddressWitnessScriptHash() (string, error) {
switch k.coinType {
case CoinTypeBTC:
_, pubKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
script, err := getScript(pubKey.SerializeCompressed())
if err != nil {
return "", err
}
addressPubKey, err := btcutil.NewAddressWitnessScriptHash(script, &chaincfg.MainNetParams)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
case CoinTypeTestnet:
_, pubKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
script, err := getScript(pubKey.SerializeCompressed())
if err != nil {
return "", err
}
addressPubKey, err := btcutil.NewAddressWitnessScriptHash(script, &chaincfg.TestNet3Params)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
case CoinTypeLTC:
_, pubKey := ltcbtcec.PrivKeyFromBytes(k.bip32Key.Key)
script, err := getScript(pubKey.SerializeCompressed())
if err != nil {
return "", err
}
addressPubKey, err := ltcutil.NewAddressWitnessScriptHash(script, <cchaincfg.MainNetParams)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
default:
return "", NotSuppportCoin
}
}
func (k *Key) AddressTaproot() (string, error) {
switch k.coinType {
case CoinTypeBTC:
_, pubKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
tapKey := txscript.ComputeTaprootKeyNoScript(pubKey)
addressPubKey, err := btcutil.NewAddressTaproot(schnorr.SerializePubKey(tapKey), &chaincfg.MainNetParams)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
case CoinTypeTestnet:
_, pubKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
tapKey := txscript.ComputeTaprootKeyNoScript(pubKey)
addressPubKey, err := btcutil.NewAddressTaproot(schnorr.SerializePubKey(tapKey), &chaincfg.TestNet3Params)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
case CoinTypeLTC:
_, pubKey := ltcbtcec.PrivKeyFromBytes(k.bip32Key.Key)
tapKey := txscript.ComputeTaprootKeyNoScript(pubKey)
addressPubKey, err := ltcutil.NewAddressTaproot(schnorr.SerializePubKey(tapKey), <cchaincfg.MainNetParams)
if err != nil {
return "", err
}
return addressPubKey.EncodeAddress(), nil
default:
return "", NotSuppportCoin
}
}
func (k *Key) PublicKey() string {
switch k.coinType {
case CoinTypeBTC:
_, publicKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
return hex.EncodeToString(publicKey.SerializeCompressed())
case CoinTypeTestnet:
_, publicKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
return hex.EncodeToString(publicKey.SerializeCompressed())
case CoinTypeDOGE:
_, publicKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
return hex.EncodeToString(publicKey.SerializeCompressed())
case CoinTypeLTC:
_, publicKey := ltcbtcec.PrivKeyFromBytes(k.bip32Key.Key)
return hex.EncodeToString(publicKey.SerializeCompressed())
case CoinTypeDASH:
_, publicKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
return hex.EncodeToString(publicKey.SerializeCompressed())
case CoinTypeETH:
_, publicKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
publicKeyECDSA := publicKey.ToECDSA()
publicKeyECDSABytes := crypto.FromECDSAPub(publicKeyECDSA)
return hexutil.Encode(publicKeyECDSABytes)
case CoinTypeBCH:
_, publicKey := bchec.PrivKeyFromBytes(bchec.S256(), k.bip32Key.Key)
return hex.EncodeToString(publicKey.SerializeCompressed())
case CoinTypeTRX:
case CoinTypeMATIC:
_, publicKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
publicKeyECDSA := publicKey.ToECDSA()
publicKeyECDSABytes := crypto.FromECDSAPub(publicKeyECDSA)
return hexutil.Encode(crypto.Keccak256(publicKeyECDSABytes))
case CoinTypeOKT:
_, publicKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
publicKeyECDSA := publicKey.ToECDSA()
publicKeyECDSABytes := crypto.FromECDSAPub(publicKeyECDSA)
return hexutil.Encode(crypto.Keccak256(publicKeyECDSABytes))
case CoinTypeADA:
return ""
case CoinTypeAVAXC:
_, publicKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
publicKeyECDSA := publicKey.ToECDSA()
publicKeyECDSABytes := crypto.FromECDSAPub(publicKeyECDSA)
return hexutil.Encode(crypto.Keccak256(publicKeyECDSABytes))
case CoinTypeBSC:
_, publicKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
publicKeyECDSA := publicKey.ToECDSA()
publicKeyECDSABytes := crypto.FromECDSAPub(publicKeyECDSA)
return hexutil.Encode(crypto.Keccak256(publicKeyECDSABytes))
}
return ""
}
func (k *Key) PrivateKey() (string, error) {
switch k.coinType {
case CoinTypeBTC:
privateKey, _ := btcec.PrivKeyFromBytes(k.bip32Key.Key)
wif, err := btcutil.NewWIF(privateKey, &chaincfg.MainNetParams, true)
if err != nil {
return "", err
}
return wif.String(), nil
case CoinTypeTestnet:
privateKey, _ := btcec.PrivKeyFromBytes(k.bip32Key.Key)
wif, err := btcutil.NewWIF(privateKey, &chaincfg.TestNet3Params, true)
if err != nil {
return "", err
}
return wif.String(), nil
case CoinTypeDOGE:
privateKey, _ := btcec.PrivKeyFromBytes(k.bip32Key.Key)
wif, err := btcutil.NewWIF(privateKey, &dogecoin.MainNetParams, true)
if err != nil {
return "", err
}
return wif.String(), nil
case CoinTypeLTC:
privateKey, _ := ltcbtcec.PrivKeyFromBytes(k.bip32Key.Key)
wif, err := ltcutil.NewWIF(privateKey, <cchaincfg.MainNetParams, true)
if err != nil {
return "", err
}
return wif.String(), nil
case CoinTypeDASH:
privateKey, _ := btcec.PrivKeyFromBytes(k.bip32Key.Key)
wif, err := dashutil.NewWIF(privateKey, &dashchaincfg.MainNetParams, true)
if err != nil {
return "", err
}
return wif.String(), nil
case CoinTypeETH:
privKey, _ := btcec.PrivKeyFromBytes(k.bip32Key.Key)
privKeyECDSA := privKey.ToECDSA()
return hexutil.Encode(crypto.FromECDSA(privKeyECDSA)), nil
case CoinTypeBCH:
privateKey, _ := bchec.PrivKeyFromBytes(bchec.S256(), k.bip32Key.Key)
wif, err := bchutil.NewWIF(privateKey, &bchchaincfg.MainNetParams, true)
if err != nil {
return "", err
}
return wif.String(), nil
case CoinTypeTRX:
case CoinTypeMATIC:
privKey, _ := btcec.PrivKeyFromBytes(k.bip32Key.Key)
privKeyECDSA := privKey.ToECDSA()
return hexutil.Encode(crypto.FromECDSA(privKeyECDSA)), nil
case CoinTypeOKT:
privKey, _ := btcec.PrivKeyFromBytes(k.bip32Key.Key)
privKeyECDSA := privKey.ToECDSA()
return hexutil.Encode(crypto.FromECDSA(privKeyECDSA)), nil
case CoinTypeADA:
_, publicKey := btcec.PrivKeyFromBytes(k.bip32Key.Key)
publicKeyECDSA := publicKey.ToECDSA()
return crypto.PubkeyToAddress(*publicKeyECDSA).Hex(), nil
case CoinTypeAVAXC:
privKey, _ := btcec.PrivKeyFromBytes(k.bip32Key.Key)
privKeyECDSA := privKey.ToECDSA()
return hexutil.Encode(crypto.FromECDSA(privKeyECDSA)), nil
case CoinTypeBSC:
privKey, _ := btcec.PrivKeyFromBytes(k.bip32Key.Key)
privKeyECDSA := privKey.ToECDSA()
return hexutil.Encode(crypto.FromECDSA(privKeyECDSA)), nil
}
return "", NotSuppportCoin
}
type KeyManager struct {
mnemonic string
passphrase string
}
// NewKeyManager return new key manager
// bitSize has to be a multiple 32 and be within the inclusive range of {128, 256}
// 128: 12 phrases
// 256: 24 phrases
func NewKeyManager(bitSize int, passphrase, mnemonic string) (*KeyManager, error) {
if mnemonic == "" {
entropy, err := bip39.NewEntropy(bitSize)
if err != nil {
return nil, err
}
mnemonic, err = bip39.NewMnemonic(entropy)
if err != nil {
return nil, err
}
}
km := &KeyManager{
mnemonic: mnemonic,
passphrase: passphrase,
}
return km, nil
}
func (km *KeyManager) GetMnemonic() string {
return km.mnemonic
}
func (km *KeyManager) GetPassphrase() string {
return km.passphrase
}
func (km *KeyManager) GetSeed() []byte {
return bip39.NewSeed(km.GetMnemonic(), km.GetPassphrase())
}
func (km *KeyManager) GetMasterKey() (*Key, error) {
path := "m"
bip32Key, err := bip32.NewMasterKey(km.GetSeed())
if err != nil {
return nil, err
}
key := &Key{
path: path,
bip32Key: bip32Key,
}
return key, nil
}
func (km *KeyManager) GetPurposeKey(purpose uint32) (*Key, error) {
path := fmt.Sprintf(`m/%d'`, purpose-Apostrophe)
parent, err := km.GetMasterKey()
if err != nil {
return nil, err
}
bip32Key, err := parent.bip32Key.NewChildKey(purpose)
if err != nil {
return nil, err
}
key := &Key{
path: path,
purpose: purpose,
bip32Key: bip32Key,
}
return key, nil
}
func (km *KeyManager) GetCoinTypeKey(purpose, coinType uint32) (*Key, error) {
path := fmt.Sprintf(`m/%d'/%d'`, purpose-Apostrophe, coinType-Apostrophe)
parent, err := km.GetPurposeKey(purpose)
if err != nil {
return nil, err
}
bip32Key, err := parent.bip32Key.NewChildKey(coinType)
if err != nil {
return nil, err
}
key := &Key{
path: path,
purpose: purpose,
coinType: coinType,
bip32Key: bip32Key,
}
return key, nil
}
func (km *KeyManager) GetAccountKey(purpose, coinType, account uint32) (*Key, error) {
path := fmt.Sprintf(`m/%d'/%d'/%d'`, purpose-Apostrophe, coinType-Apostrophe, account)
parent, err := km.GetCoinTypeKey(purpose, coinType)
if err != nil {
return nil, err
}
bip32Key, err := parent.bip32Key.NewChildKey(account + Apostrophe)
if err != nil {
return nil, err
}
key := &Key{
path: path,
purpose: purpose,
coinType: coinType,
bip32Key: bip32Key,
}
return key, nil
}
// GetChangeKey ...
// https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#change
// change constant 0 is used for external chain
// change constant 1 is used for internal chain (also known as change addresses)
func (km *KeyManager) GetChangeKey(purpose, coinType, account, change uint32) (*Key, error) {
path := fmt.Sprintf(`m/%d'/%d'/%d'/%d`, purpose-Apostrophe, coinType-Apostrophe, account, change)
parent, err := km.GetAccountKey(purpose, coinType, account)
if err != nil {
return nil, err
}
bip32Key, err := parent.bip32Key.NewChildKey(change)
if err != nil {
return nil, err
}
key := &Key{
path: path,
purpose: purpose,
coinType: coinType,
bip32Key: bip32Key,
}
return key, nil
}
func (km *KeyManager) GetKey(purpose, coinType, account, change, index uint32) (*Key, error) {
path := fmt.Sprintf(`m/%d'/%d'/%d'/%d/%d`, purpose-Apostrophe, coinType-Apostrophe, account, change, index)
parent, err := km.GetChangeKey(purpose, coinType, account, change)
if err != nil {
return nil, err
}
bip32Key, err := parent.bip32Key.NewChildKey(index)
if err != nil {
return nil, err
}
key := &Key{
path: path,
purpose: purpose,
coinType: coinType,
bip32Key: bip32Key,
}
return key, nil
}
func Generate(compress bool) (wif, address, segwitBech32, segwitNested string, err error) {
prvKey, err := btcec.NewPrivateKey()
if err != nil {
return "", "", "", "", err
}
return GenerateFromBytes(prvKey, compress)
}
func GenerateFromBytes(prvKey *btcec.PrivateKey, compress bool) (wif, address, segwitBech32, segwitNested string, err error) {
// generate the wif(wallet import format) string
btcwif, err := btcutil.NewWIF(prvKey, &chaincfg.MainNetParams, compress)
if err != nil {
return "", "", "", "", err
}
wif = btcwif.String()
// generate a normal p2pkh address
serializedPubKey := btcwif.SerializePubKey()
addressPubKey, err := btcutil.NewAddressPubKey(serializedPubKey, &chaincfg.MainNetParams)
if err != nil {
return "", "", "", "", err
}
address = addressPubKey.EncodeAddress()
// generate a normal p2wkh address from the pubkey hash
witnessProg := btcutil.Hash160(serializedPubKey)
addressWitnessPubKeyHash, err := btcutil.NewAddressWitnessPubKeyHash(witnessProg, &chaincfg.MainNetParams)
if err != nil {
return "", "", "", "", err
}
segwitBech32 = addressWitnessPubKeyHash.EncodeAddress()
// generate an address which is
// backwards compatible to Bitcoin nodes running 0.6.0 onwards, but
// allows us to take advantage of segwit's scripting improvments,
// and malleability fixes.
serializedScript, err := txscript.PayToAddrScript(addressWitnessPubKeyHash)
if err != nil {
return "", "", "", "", err
}
addressScriptHash, err := btcutil.NewAddressScriptHash(serializedScript, &chaincfg.MainNetParams)
if err != nil {
return "", "", "", "", err
}
segwitNested = addressScriptHash.EncodeAddress()
return wif, address, segwitBech32, segwitNested, nil
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。