github.com/turingchain2020/turingchain@v1.1.21/wallet/bipwallet/bipwallet.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package bipwallet 比特币改进协议钱包相关定义
     6  package bipwallet
     7  
     8  import (
     9  	"errors"
    10  	"strings"
    11  
    12  	"github.com/turingchain2020/turingchain/common/address"
    13  	"github.com/turingchain2020/turingchain/common/crypto"
    14  	log "github.com/turingchain2020/turingchain/common/log/log15"
    15  	"github.com/turingchain2020/turingchain/types"
    16  	bip32 "github.com/turingchain2020/turingchain/wallet/bipwallet/go-bip32"
    17  	bip39 "github.com/turingchain2020/turingchain/wallet/bipwallet/go-bip39"
    18  	bip44 "github.com/turingchain2020/turingchain/wallet/bipwallet/go-bip44"
    19  	"github.com/turingchain2020/turingchain/wallet/bipwallet/transformer"
    20  	_ "github.com/turingchain2020/turingchain/wallet/bipwallet/transformer/btcbase" //register
    21  )
    22  
    23  // https://github.com/satoshilabs/slips/blob/master/slip-0044.md
    24  const (
    25  	TypeBitcoin            uint32 = 0x80000000
    26  	TypeLitecoin           uint32 = 0x80000002
    27  	TypeEther              uint32 = 0x8000003c
    28  	TypeEtherClassic       uint32 = 0x8000003d
    29  	TypeFactomFactoids     uint32 = 0x80000083
    30  	TypeFactomEntryCredits uint32 = 0x80000084
    31  	TypeZcash              uint32 = 0x80000085
    32  	TypeTrc                uint32 = 0x80003333
    33  	TypeYcc                uint32 = 0x80003334
    34  )
    35  
    36  // CoinName 币种名称
    37  var CoinName = map[uint32]string{
    38  	TypeEther:        "ETH",
    39  	TypeEtherClassic: "ETC",
    40  	TypeBitcoin:      "BTC",
    41  	TypeLitecoin:     "LTC",
    42  	TypeZcash:        "ZEC",
    43  	TypeTrc:          "TRC",
    44  	TypeYcc:          "YCC",
    45  }
    46  
    47  // coinNameType 映射关系
    48  var coinNameType = map[string]uint32{
    49  	"ETH": TypeEther,
    50  	"ETC": TypeEtherClassic,
    51  	"BTC": TypeBitcoin,
    52  	"LTC": TypeLitecoin,
    53  	"ZEC": TypeZcash,
    54  	"TRC": TypeTrc,
    55  	"YCC": TypeYcc,
    56  }
    57  
    58  //GetSLIP0044CoinType 获取货币的 CoinType 值
    59  func GetSLIP0044CoinType(name string) uint32 {
    60  	name = strings.ToUpper(name)
    61  	if ty, ok := coinNameType[name]; ok {
    62  		return ty
    63  	}
    64  	log.Error("GetSLIP0044CoinType: " + name + " not exist.")
    65  	return TypeTrc
    66  }
    67  
    68  // HDWallet 支持BIP-44标准的HD钱包
    69  type HDWallet struct {
    70  	CoinType  uint32
    71  	RootSeed  []byte
    72  	MasterKey *bip32.Key
    73  	KeyType   uint32
    74  }
    75  
    76  // NewKeyPair 通过索引生成新的秘钥对
    77  func (w *HDWallet) NewKeyPair(index uint32) (priv, pub []byte, err error) {
    78  	//bip44 标准 32字节私钥
    79  	key, err := bip44.NewKeyFromMasterKey(w.MasterKey, w.CoinType, bip32.FirstHardenedChild, 0, index)
    80  	if err != nil {
    81  		return nil, nil, err
    82  	}
    83  	if w.KeyType == types.SECP256K1 {
    84  		return key.Key, key.PublicKey().Key, err
    85  	}
    86  
    87  	edcrypto, err := crypto.New(crypto.GetName(int(w.KeyType)))
    88  	if err != nil {
    89  		return nil, nil, err
    90  	}
    91  	edkey, err := edcrypto.PrivKeyFromBytes(key.Key[:])
    92  	if err != nil {
    93  		return nil, nil, err
    94  	}
    95  
    96  	priv = edkey.Bytes()
    97  	pub = edkey.PubKey().Bytes()
    98  
    99  	return
   100  }
   101  
   102  // NewAddress 新建地址
   103  func (w *HDWallet) NewAddress(index uint32) (string, error) {
   104  	if cointype, ok := CoinName[w.CoinType]; ok {
   105  		_, pub, err := w.NewKeyPair(index)
   106  		if err != nil {
   107  			return "", err
   108  		}
   109  
   110  		trans, err := transformer.New(cointype)
   111  		if err != nil {
   112  			return "", err
   113  		}
   114  		addr, err := trans.PubKeyToAddress(pub)
   115  		if err != nil {
   116  			return "", err
   117  		}
   118  		return addr, nil
   119  	}
   120  
   121  	return "", errors.New("cointype no support to create address")
   122  
   123  }
   124  
   125  // PrivkeyToPub 私钥转换成公钥
   126  func PrivkeyToPub(coinType, keyTy uint32, priv []byte) ([]byte, error) {
   127  	if cointype, ok := CoinName[coinType]; ok {
   128  		trans, err := transformer.New(cointype)
   129  		if err != nil {
   130  			return nil, err
   131  		}
   132  		pub, err := trans.PrivKeyToPub(keyTy, priv)
   133  		if err != nil {
   134  			return nil, err
   135  		}
   136  
   137  		return pub, nil
   138  
   139  	}
   140  	return nil, errors.New("cointype no support to create address")
   141  }
   142  
   143  // PubToAddress 将公钥转换成地址
   144  func PubToAddress(pub []byte) (string, error) {
   145  	return address.PubKeyToAddr(pub), nil
   146  }
   147  
   148  //NewMnemonicString 创建助记词 lang=0 英文助记词,lang=1 中文助记词bitsize=[128,256]并且bitsize%32=0
   149  func NewMnemonicString(lang, bitsize int) (string, error) {
   150  	entropy, err := bip39.NewEntropy(bitsize)
   151  	if err != nil {
   152  		return "", err
   153  	}
   154  
   155  	mnemonic, err := bip39.NewMnemonic(entropy, int32(lang))
   156  	if err != nil {
   157  		return "", err
   158  	}
   159  	return mnemonic, nil
   160  }
   161  
   162  // NewWalletFromMnemonic 通过助记词生成钱包对象
   163  func NewWalletFromMnemonic(coinType, keyType uint32, mnemonic string) (wallet *HDWallet, err error) {
   164  	seed, err := bip39.NewSeedWithErrorChecking(mnemonic, "")
   165  	if err != nil {
   166  		return nil, err
   167  	}
   168  
   169  	return NewWalletFromSeed(coinType, keyType, seed)
   170  }
   171  
   172  // NewWalletFromSeed 通过种子生成钱包对象
   173  func NewWalletFromSeed(coinType, keyType uint32, seed []byte) (wallet *HDWallet, err error) {
   174  	masterKey, err := bip32.NewMasterKey(seed)
   175  	if err != nil {
   176  		return nil, err
   177  	}
   178  	return &HDWallet{
   179  		CoinType:  coinType,
   180  		KeyType:   keyType,
   181  		RootSeed:  seed,
   182  		MasterKey: masterKey}, nil
   183  }