// Copyright Fuzamei Corp. 2018 All Rights Reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package bipwallet import ( "errors" bip32 "github.com/33cn/chain33/wallet/bipwallet/go-bip32" bip39 "github.com/33cn/chain33/wallet/bipwallet/go-bip39" bip44 "github.com/33cn/chain33/wallet/bipwallet/go-bip44" "github.com/33cn/chain33/wallet/bipwallet/transformer" _ "github.com/33cn/chain33/wallet/bipwallet/transformer/btcbase" ) // https://github.com/satoshilabs/slips/blob/master/slip-0044.md const ( TypeBitcoin uint32 = 0x80000000 TypeTestnet uint32 = 0x80000001 TypeLitecoin uint32 = 0x80000002 TypeDogecoin uint32 = 0x80000003 TypeReddcoin uint32 = 0x80000004 TypeDash uint32 = 0x80000005 TypePeercoin uint32 = 0x80000006 TypeNamecoin uint32 = 0x80000007 TypeFeathercoin uint32 = 0x80000008 TypeCounterparty uint32 = 0x80000009 TypeBlackcoin uint32 = 0x8000000a TypeNuShares uint32 = 0x8000000b TypeNuBits uint32 = 0x8000000c TypeMazacoin uint32 = 0x8000000d TypeViacoin uint32 = 0x8000000e TypeClearingHouse uint32 = 0x8000000f TypeRubycoin uint32 = 0x80000010 TypeGroestlcoin uint32 = 0x80000011 TypeDigitalcoin uint32 = 0x80000012 TypeCannacoin uint32 = 0x80000013 TypeDigiByte uint32 = 0x80000014 TypeOpenAssets uint32 = 0x80000015 TypeMonacoin uint32 = 0x80000016 TypeClams uint32 = 0x80000017 TypePrimecoin uint32 = 0x80000018 TypeNeoscoin uint32 = 0x80000019 TypeJumbucks uint32 = 0x8000001a TypeziftrCOIN uint32 = 0x8000001b TypeVertcoin uint32 = 0x8000001c TypeNXT uint32 = 0x8000001d TypeBurst uint32 = 0x8000001e TypeMonetaryUnit uint32 = 0x8000001f TypeZoom uint32 = 0x80000020 TypeVpncoin uint32 = 0x80000021 TypeCanadaeCoin uint32 = 0x80000022 TypeShadowCash uint32 = 0x80000023 TypeParkByte uint32 = 0x80000024 TypePandacoin uint32 = 0x80000025 TypeStartCOIN uint32 = 0x80000026 TypeMOIN uint32 = 0x80000027 TypeArgentum uint32 = 0x8000002D TypeGlobalCurrencyReserve uint32 = 0x80000031 TypeNovacoin uint32 = 0x80000032 TypeAsiacoin uint32 = 0x80000033 TypeBitcoindark uint32 = 0x80000034 TypeDopecoin uint32 = 0x80000035 TypeTemplecoin uint32 = 0x80000036 TypeAIB uint32 = 0x80000037 TypeEDRCoin uint32 = 0x80000038 TypeSyscoin uint32 = 0x80000039 TypeSolarcoin uint32 = 0x8000003a TypeSmileycoin uint32 = 0x8000003b TypeEther uint32 = 0x8000003c TypeEtherClassic uint32 = 0x8000003d TypeOpenChain uint32 = 0x80000040 TypeOKCash uint32 = 0x80000045 TypeDogecoinDark uint32 = 0x8000004d TypeElectronicGulden uint32 = 0x8000004e TypeClubCoin uint32 = 0x8000004f TypeRichCoin uint32 = 0x80000050 TypePotcoin uint32 = 0x80000051 TypeQuarkcoin uint32 = 0x80000052 TypeTerracoin uint32 = 0x80000053 TypeGridcoin uint32 = 0x80000054 TypeAuroracoin uint32 = 0x80000055 TypeIXCoin uint32 = 0x80000056 TypeGulden uint32 = 0x80000057 TypeBitBean uint32 = 0x80000058 TypeBata uint32 = 0x80000059 TypeMyriadcoin uint32 = 0x8000005a TypeBitSend uint32 = 0x8000005b TypeUnobtanium uint32 = 0x8000005c TypeMasterTrader uint32 = 0x8000005d TypeGoldBlocks uint32 = 0x8000005e TypeSaham uint32 = 0x8000005f TypeChronos uint32 = 0x80000060 TypeUbiquoin uint32 = 0x80000061 TypeEvotion uint32 = 0x80000062 TypeSaveTheOcean uint32 = 0x80000063 TypeBigUp uint32 = 0x80000064 TypeGameCredits uint32 = 0x80000065 TypeDollarcoins uint32 = 0x80000066 TypeZayedcoin uint32 = 0x80000067 TypeDubaicoin uint32 = 0x80000068 TypeStratis uint32 = 0x80000069 TypeShilling uint32 = 0x8000006a TypePiggyCoin uint32 = 0x80000076 TypeMonero uint32 = 0x80000080 TypeNavCoin uint32 = 0x80000082 TypeFactomFactoids uint32 = 0x80000083 TypeFactomEntryCredits uint32 = 0x80000084 TypeZcash uint32 = 0x80000085 TypeLisk uint32 = 0x80000086 TypeBty uint32 = 0x80003333 TypeYcc uint32 = 0x80003334 ) // CoinName 币种名称 var CoinName = map[uint32]string{ TypeEther: "ETH", TypeEtherClassic: "ETC", TypeBitcoin: "BTC", TypeLitecoin: "LTC", TypeZayedcoin: "ZEC", TypeBty: "BTY", TypeYcc: "YCC", } // HDWallet 支持BIP-44标准的HD钱包 type HDWallet struct { CoinType uint32 RootSeed []byte MasterKey *bip32.Key } // NewKeyPair 通过索引生成新的秘钥对 func (w *HDWallet) NewKeyPair(index uint32) (priv, pub []byte, err error) { key, err := bip44.NewKeyFromMasterKey(w.MasterKey, w.CoinType, bip32.FirstHardenedChild, 0, index) if err != nil { return nil, nil, err } return key.Key, key.PublicKey().Key, err } // NewAddress 新建地址 func (w *HDWallet) NewAddress(index uint32) (string, error) { if cointype, ok := CoinName[w.CoinType]; ok { _, pub, err := w.NewKeyPair(index) if err != nil { return "", err } trans, err := transformer.New(cointype) if err != nil { return "", err } addr, err := trans.PubKeyToAddress(pub) if err != nil { return "", err } return addr, nil } return "", errors.New("cointype no support to create address") } // PrivkeyToPub 私钥转换成公钥 func PrivkeyToPub(coinType uint32, priv []byte) ([]byte, error) { if cointype, ok := CoinName[coinType]; ok { trans, err := transformer.New(cointype) if err != nil { return nil, err } pub, err := trans.PrivKeyToPub(priv) if err != nil { return nil, err } return pub, nil } return nil, errors.New("cointype no support to create address") } // PubToAddress 将公钥转换成地址 func PubToAddress(coinType uint32, pub []byte) (string, error) { if cointype, ok := CoinName[coinType]; ok { trans, err := transformer.New(cointype) if err != nil { return "", err } pub, err := trans.PubKeyToAddress(pub) if err != nil { return "", err } return pub, nil } return "", errors.New("cointype no support to create address") } //NewMnemonicString 创建助记词 lang=0 英文助记词,lang=1 中文助记词bitsize=[128,256]并且bitsize%32=0 func NewMnemonicString(lang, bitsize int) (string, error) { entropy, err := bip39.NewEntropy(bitsize) if err != nil { return "", err } mnemonic, err := bip39.NewMnemonic(entropy, int32(lang)) if err != nil { return "", err } return mnemonic, nil } // NewWalletFromMnemonic 通过助记词生成钱包对象 func NewWalletFromMnemonic(coinType uint32, mnemonic string) (wallet *HDWallet, err error) { seed, err := bip39.NewSeedWithErrorChecking(mnemonic, "") if err != nil { return nil, err } return NewWalletFromSeed(coinType, seed) } // NewWalletFromSeed 通过种子生成钱包对象 func NewWalletFromSeed(coinType uint32, seed []byte) (wallet *HDWallet, err error) { masterKey, err := bip32.NewMasterKey(seed) if err != nil { return nil, err } return &HDWallet{ CoinType: coinType, RootSeed: seed, MasterKey: masterKey}, nil }