Code Monkey home page Code Monkey logo

btcutil's Introduction

This package is now a sub-package in the btcutil directory of the btcd repository.

btcutil's People

Contributors

aakselrod avatar adiabat avatar afk11 avatar benma avatar bob201203 avatar cfromknecht avatar cpacia avatar crypt-iq avatar dajohi avatar davecgh avatar devrandom avatar egonelbre avatar flammit avatar gipsy86147 avatar guggero avatar halseth avatar jcvernaleo avatar jimpo avatar johnta0 avatar josharian avatar jrick avatar kallerosenbaum avatar michael1011 avatar onyb avatar pascaldekloe avatar roasbeef avatar stevenroose avatar waldyrious avatar wallclockbuilder avatar wpaulino avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

btcutil's Issues

BIP49 (SegWit) Address Generation Support

After spending a few hours on this, it seems to me that something is missing so I can't generate proper BIP49 addresses. Unless I missed something. I use hdkeychain.NewKeyFromString to generate (derived) addresses. Works fine for BIP44. But now I'm trying to generate SegWit addresses.

It seems I need to be able to set the BIP32 Derivation path to: m/49'/1'/0'/0, or, well m/49' something at least as currently m/44' seems to be hard-coded somewhere. I have the proper "Account Extended Public Key", but since I can't change the "Purpose", the generated addresses ends up different from what I expect to get.

Anyone here that can help me out here?

Thanks!

Remove PkScript method from coinset.Coin interface

The pubkey script is not necessary for coin selection, at least for none of the algorithms in the coinset package. I think it should be removed, since a type may not necessarly need this method to be usable by a coin selector.

cc @flammit as he was the original author of the package.

Please avoid circular dependencies with btcsuite/btcd

It looks like this repository has circular dependencies with btcsuite/btcd.

Maybe the two repositories should be merged? Is there something we can do? This makes it hard for downstream projects like Debian to build them as separate packages.

Cheers,

Is the algorithm testing the derived child point is at infinity right?

if ilx.Sign() == 0 || ily.Sign() == 0 {

According to the BIP32, should we test the childX and childY instead of the above code?
I don't know much about the secp256k1 curve, I am confused about how to testing whether or not the point is at finity, in btcec pkg, it's tested by X.Sign() == 0 && Y.Sign() == 0, but here, it's tested by X.Sign() == 0 || Y.Sign() ==0, why the OR logic not AND?

Add support for the bech32m encoding defined in BIP-350

Taproot is just around the corner with a new encoding format for addresses. I already have a working version of btcutil with Bech32m, but it breaks the signature of bech32.Encode and bech32.EncodeFromBase256 with an additional encoding parameter and also returns an additional encoding value in the bech32.Decode and bech32.DecodeFromBase256, which is used to make sure that addresses use the correct encoding depending on the witness version.

If we can't break the current API, then we need to find a new name for these functions or create a new bech32m package. Any comments or suggestions welcome.

Ecdsa public key 88 byte to bitcoin format

Hi,

I don't have access to the ECDSA private key (it's in an HSM), but I have an api to generate the public key from private key. I'm trying to use the btcsuite util package to create a newaddresspubkey eg:

addrPubKey, err := btcutil.NewAddressPubKey(wif.PrivKey.PubKey().SerializeUncompressed(), &chaincfg.TestNet3Params)

I can't seem to find any function in the library that supports using 88 byte public keys and converting them to the bitcoin format. Is this something the util library can be enhanced to do?

Thanks,
Pete.

btcutil.NewAmount can overflow

Multiplying the float64 input by 1e8 can result in the value overflowing the maximum value representable by an int64, causing truncation during the type conversion. This needs to be detected and an error should be returned.

Consequences of removing net.InterfaceAddrs from NewTLSCertPair

I forked your code to get some parts to run on Google App Engine. Being a sandboxed environment, some method calls are not allowed within its runtime. For example I ended up removing references to the conformal/fastsha256 package due to its dependence on some assembly. That's beside the point though.

The btcutil.NewTLSCertPair function uses net.InterfaceAddrs which is not allowed in Google App Engine. If I just remove it as so, does this make btcutil.NewTLSCertPair a completely useless function? Would it be cleaner to completely remove the function from my fork?

Requesting New Release (v1.0.2 seems outdated)

Using this package in my code gives this error:

masterKey.Derive undefined (type *hdkeychain.ExtendedKey has no field or method Derive)

Seems like go modules refer to https://pkg.go.dev/github.com/btcsuite/btcutil -> github.com/btcsuite/btcutil v1.0.2 which don't include the commits after Apr 14, 2020. Looks like I need to refer to the commit: - hdkeychain: correct BIP-32 derivation issue on Oct 21, 2020 for my code to work properly.

Any help on this matter would be appreciated.

Add convenience method to Amount type.

The Amount type provides a .ToUnit function which allows conversion to various units such as BTC, mBTC, and kBTC. This is a useful function and I think it should definitely remain, but since it is a bit verbose to type and the the most common conversion is by far to BTC, I think a convenience method named ToBTC should be added to it. This would allow callers that already have a btcutil.Amount to simply do:

amount.ToBTC()

Instead of:

amount.ToUnit(btcutil.AmountBTC)

Test packages

You use:

package <pkg>_test

But note that:

To write a new test suite, create a file whose name ends _test.go that contains the TestXxx functions as described here. Put the file in the same package as the one being tested. The file will be excluded from regular package builds but will be included when the “go test” command is run. For more detail, run “go help test” and “go help testflag”.

http://golang.org/pkg/testing/

Could DecodeAddress be used with other bitcoin like chains?

Hey, thanks for the library!

I have a questions: Have the DecodeAddress function were designed to be used with other bitcoin-like chains also? If so, it seems like at this moment it couldn't be used like this because of:

address.go, 190: case ripemd160.Size: // P2PKH or P2SH
address.go, 191:	isP2PKH := chaincfg.IsPubKeyHashAddrID(netID)
address.go, 192:	isP2SH := chaincfg.IsScriptHashAddrID(netID)
address.go, 193:	switch hash160 := decoded; 

chaincfg.IsPubKeyHashAddrID function uses pubKeyHashAddrIDs map which is initialised with default main bitcoin net parameters, rather than defaultNet DecodeAddress field.

[Question] How do you use a existing public master key to generate multiple bitcoin addresses?

Hello!

Let's say that this is my public master key that I generated from a private key that was generated by a BIP39 seed:

xpub661MyMwAqRbcGNVENt2tgk3uebENbktcaKroxgwa9T5W3btQ18PL2f7vp78LNoioGhZcgSH1i2cH48YcQttiEaAh86TuJpsUu2J7jQWnmbC

So far, I have this code:

package main

import (
    "os"

    "github.com/btcsuite/btcd/chaincfg"
    "github.com/btcsuite/btcutil/hdkeychain"
)

var xpubmkeydummy = "xpub661MyMwAqRbcGNVENt2tgk3uebENbktcaKroxgwa9T5W3bt" +
    "Q18PL2f7vp78LNoioGhZcgSH1i2cH48YcQttiEaAh86TuJpsUu2J7jQWnmbC"

func GetNewAddress(i int) (string, error) {
    xpubmkey := os.Getenv("xpubmkey")
    if xpubmkey == "" {
        xpubmkey = xpubmkeydummy
    }
    masterkey, err := hdkeychain.NewKeyFromString(xpubmkey)
    if err != nil {
        return "", err
    }
    acct, err := masterkey.Child(0)
    if err != nil {
        return "", err
    }
    acctext, err := acct.Child(0)
    if err != nil {
        return "", err
    }
    acctn, err := acctext.Child(uint32(i))
    if err != nil {
        return "", err
    }
    addr, err := acctn.Address(&chaincfg.MainNetParams)
    if err != nil {
        return "", err
    }
    return addr.String(), nil
}

My main concern is if I'm doing everything as specified in the use case of Unsecure money receiver: N(m/iH/0) from the BIP32 document, I fear doing something dumb or wrong that could cost me Bitcoins.

Thanks!

Do invalid keys in BIP44 path matter?

I understand not all private keys are usable as they fall outside of Secp256k1, but do they really matter when the master node or path being derived in BIP44 generates a private key which isn't usable as those nodes (keys at that node) are not supposed to hold funds?

Or is it just the actual address (external/internal chain of addresses under an account) that matters as those are the ones supposed to hold funds?

Or hitting a private key outside of Secp256k1 somehow translate into child keys being outside of Secp256k1 as well?

Last couple of commits are only compatible with Roasbeef fork?

# github.com/btcsuite/btcutil
./block.go:82: b.msgBlock.SerializeNoWitness undefined (type *wire.MsgBlock has no field or method SerializeNoWitness)
./tx.go:63: t.msgTx.WitnessHash undefined (type *wire.MsgTx has no field or method WitnessHash)
./tx.go:77: t.msgTx.HasWitness undefined (type *wire.MsgTx has no field or method HasWitness)

Hash160 from Compressed address

Hello, i Have a question. I m trying to convert a public address (like "1EWVYro91c1rnCBb8ZVKXVasfWGW45VMKT") to hash160 using btcutil.

But I don't finder any helper to do this. Coul you help ?

Fix NewAddress* methods to handle regtest network

Need to match bitcoind behavior and use the TestNet IDs when in regtest. Currently these methods fail in checkBitcoinNet resulting in getrawtransaction verbose=true not showing the address array in regtest mode, whereas bitcoind does.

As per @davecgh, we could change to use a new method IsForNet(net btcwire.BitcoinNet) and update the encodes to include btcwire.TestNet fallthrough to btcwire.TestNet3

Decoding failure

I have noticed that decoding done with bech32.Decode returns different result than https://github.com/nym-zone/bech32

The below diff is adding a test that proves that

diff --git a/bech32/bech32_test.go b/bech32/bech32_test.go
index 1322386..9583a1c 100644
--- a/bech32/bech32_test.go
+++ b/bech32/bech32_test.go
@@ -5,6 +5,8 @@
 package bech32_test
 
 import (
+       "bytes"
+       "encoding/hex"
        "strings"
        "testing"
 
@@ -67,3 +69,25 @@ func TestBech32(t *testing.T) {
                }
        }
 }
+
+func TestBench32Encoding(t *testing.T) {
+       // bech32  -e -h tiov 746573742d7061796c6f6164
+       const enc = `tiov1w3jhxapdwpshjmr0v9jqymqq4y`
+
+       want, err := hex.DecodeString("746573742d7061796c6f6164")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       _, payload, err := bech32.Decode(enc)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       if !bytes.Equal(want, payload) {
+               t.Logf("want %d", want)
+               t.Logf("got  %d", payload)
+               t.Fatal("invalid decode")
+       }
+
+}

How to validate bech32 signed message?

Hello,

I've been trying to validate a signed bech32 message (from Electrum, BIP-0137) but I keep running into walls, since my knowledge related to ECDSA, addresses and signatures is pretty limited.

I was able to extract PublicKey using the code below, but it doesn't match address and signature, err := btcec.ParseSignature(signatureEncoded, btcec.S256()) errors out with malformed signature: no header magic. I have a feeling that it's because the signature isn't provided in the proper format, not sure how to get there though.

If anyone could help me out that would be greatly appreciated. I tried to find a Slack/Mattermost/Gitter channel but haven't found any otherwise I would've asked there.

package main

import (
	"encoding/base64"
	"fmt"

	"github.com/btcsuite/btcd/btcec"
	"github.com/btcsuite/btcd/chaincfg/chainhash"
)

const (
	message           = "Hello"
	address           = "bc1qsdjne3y6ljndzvg9z9qrhje8k7p2m5yas704hn"
	electrumSignature = "H0wOFGpArXjGOdT57eb902p9SsZ4ELAtMLL8hATpeQerCdheTSHf6qP8y+x83nhV30MEXsa9Gji8+Z9OZKdSs2E="
)

func main() {
	signatureEncoded, err := base64.StdEncoding.DecodeString(electrumSignature)
	if err != nil {
		fmt.Println(err)
		return
	}

	pubKey, _, err := btcec.RecoverCompact(btcec.S256(), signatureEncoded, []byte(message))
	if err != nil {
		fmt.Println(err)
		return
	}

	signature, err := btcec.ParseSignature(signatureEncoded, btcec.S256())
	if err != nil {
		fmt.Println(err)
		return
	}

	// Verify the signature for the message using the public key.
	messageHash := chainhash.DoubleHashB([]byte(message))
	verified := signature.Verify(messageHash, pubKey)
	fmt.Println("Signature Verified?", verified)
}

bech32: Encode accepts invalid uppercase HRP

bech32.Encode will accept an uppercase HRP and generate an invalid bech32 encoding instead of normalizing it or returning an error.

BIP 0173 is clear that mixed case encodings are invalid, and that the lowercase encoding should be used for checksum purposes. This means there are two ways to handle an uppercase HRP in Encode:

  1. treat it as lowercase, and ideally return a lowercase encoding
  2. return an error

Instead, this library will use the uppercase values for the checksum and return a mixed case encoding. Decode will correctly reject the mixed case encoding, and will fail the checksum of the lowercase version.

https://play.golang.org/p/h0ekj8VmiPV

Create multiple example for btcutil

I was wondering if I can contribute by creating example directory with multiple example on how to use btcsuite to get address balance, create and sign transactions e.t.c

thanks in advance

Error when installing

I install package using command go get -u github.com/btcsuite/btcutil. It returns error:

# github.com/btcsuite/btcutil btcsuite/btcutil/block.go:82: b.msgBlock.SerializeNoWitness undefined (type *wire.MsgBlock has no field or method SerializeNoWitness) btcsuite/btcutil/tx.go:63: t.msgTx.WitnessHash undefined (type *wire.MsgTx has no field or method WitnessHash) btcsuite/btcutil/tx.go:77: t.msgTx.HasWitness undefined (type *wire.MsgTx has no field or method HasWitness)

I using golang 1.8.3 (in both ubuntu 14.04 TS 32 bit and 64bit).

Cannot test because functions of internal_test are not used

I'm relatively new to go and don't know much about standards and practices, I just needed assistance/support with the following behaviour.

I tried to test the package with go test, gocov and the provided cov_report.sh but all of them show the same errors:
./address_test.go:56:12: undefined: btcutil.TstAddressPubKeyHash ./address_test.go:74:12: undefined: btcutil.TstAddressPubKeyHash ...

Upon inspection I see that the tests are in package btcutil_test whereas the code is in package btcutil. A detailed explanation for this decision is dicussed in #7.

Returning to the undefined function – it turns out that the function(s) invoked by btcutil_test are indeed declared in btcutil's internal_test.go. Nevertheless, my IDE reports that the Tst... functions are not being used, leading to the compiler not including them (right?).

My goal is to test, and help improve the code coverage. How can I proceed to have the tests running and passing?

About my setup:
go version go1.13 darwin/amd64
GoLand 2019.2.2

Exported ExtendedKey

The ExtendedKey struct in the hdkeychain package has all private fields. This is a bit problematic as my use case requires using a custom chaincode.

Would you accept a PR changing newExtendedKey to exported so that people can create custom extended keys outside the package?

Can't deserialize partial transaction

A simple test case:

tx := wire.MsgTx{}
err = tx.Deserialize(hexToBytes("02000000000100e1f5050000000017a914ba4bdb0b07d67bc60f59c1f4fe541705652549748700000000"))

err == "unexpected EOF"

while I can decode it with core:

$ bitcoin-cli decoderawtransaction 02000000000100e1f5050000000017a914ba4bdb0b07d67bc60f59c1f4fe541705652549748700000000
{
  "txid": "06fe61025e1e7911445cdc6128fa4447e85131c46bc49a97ea637c6ae024fa17",
  "hash": "06fe61025e1e7911445cdc6128fa4447e85131c46bc49a97ea637c6ae024fa17",
  "version": 2,
  "size": 42,
  "vsize": 42,
  "weight": 168,
  "locktime": 0,
  "vin": [
  ],
  "vout": [
    {
      "value": 1.00000000,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_HASH160 ba4bdb0b07d67bc60f59c1f4fe54170565254974 OP_EQUAL",
        "hex": "a914ba4bdb0b07d67bc60f59c1f4fe5417056525497487",
        "reqSigs": 1,
        "type": "scripthash",
        "addresses": [
          "2NAEGYWL2VhiXjvXjhe3QoGY8vo8zLumEAt"
        ]
      }
    }
  ]
}

(note how the transaction has no inputs).

This seems to be causing issues as i'm trying to an rpc call to createrawtransaction (without inputs) and then push it through fundrawtransaction. But it seems to have trouble parsing the result of createrawtransaction :(

Derived Addresses not matching bip-44

I'm trying to generate bip-44 addresses. The address looks valid but when I use the same seed and path (m/49'/0'/0'/0/0) with different wallets they generate a different set of addresses which makes me believe I'm doing something wrong. E.g. The same mnemonic/seed used with https://iancoleman.io/bip39/ returns
m/44'/0'/0'/0/0 | 17s47s1bFG6qG8bqPxwkCpnDHWEc3z2KFn as first address while my code returns 15oRMZN7rFEjp2EiRyoMXJ5GiLXQkGj8yq

package main

import (
	"fmt"
	"github.com/btcsuite/btcd/chaincfg"
	"github.com/btcsuite/btcutil/hdkeychain"
	bip39 "github.com/tyler-smith/go-bip39"
)

func main() {
	const mnemonic = "attract immense unknown voice prosper result since soul toast talent much need"
	seed := bip39.NewSeed(mnemonic, "")
	// Generate a new master node using the seed.
	master, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)
	if err != nil {
		panic(err)
		return
	}

	// m/49'
	purpose, err := master.Child(49 + hdkeychain.HardenedKeyStart)
	if err != nil {
		panic(err)
	}

	// m/49'/0'
	coinType, err := purpose.Child(0 + hdkeychain.HardenedKeyStart)
	if err != nil {
		panic(err)
	}

	// m/49'/0'/0'
	acct0, err := coinType.Child(0 + hdkeychain.HardenedKeyStart)
	if err != nil {
		panic(err)
	}

	// m/49'/0'/0'/0
	acct0External, err := acct0.Child(0)
	if err != nil {
		panic(err)
	}

	acct0ExternalPub, err := acct0External.Neuter()
	if err != nil {
		panic(err)
	}


	// m/49'/0'/0'/0/0
	acct0External0Pub, err := acct0ExternalPub.Child(0)
	if err != nil {
		panic(err)
	}
	addr, err := acct0External0Pub.Address(&chaincfg.MainNetParams)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%s", addr)
	return

}

btcutil.DecodeAddress is call err

btcAdd, err := btcutil.DecodeAddress("12MzCDwodF9G1e7jfwLXfR164RNtx4BRVG", &chaincfg.MainNetParams)

address_test.go
addr: "1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gX",
all addr test
all return is decoded address is of unknown size
why?

Private key doesn't match public address

I'm trying to generate pairs of bitcoin private keys and public addresses. To test it I sent a small amount of BTC to the child BTC address from an external wallet. The BTC was sent but the issue is that the corresponding private key from path/chain is not recognised by any wallet software(i.e. they error out saying that the private key doesn't match the address) so I can't use the coins sent anymore. Any idea if this is a bug in hdkeychain/btcutil package or am I doing something wrong ?
The code below prints:

master wif 5JKsPX7gkeARgrWjp8N1w5A4sS36GaUZ8j84T25xwGz5TgnkuRW
 btc child private 5J1HZKEP9YBd4apoBKyJLgZ6uUsxDuJ9ap4ncWSeFd3DpFuPkf1
 btc child Public 3HAkEb9NTC4jJCUBevuB2VrFoucc5vdzz4

I used btc child public (3HAkEb9NTC4jJCUBevuB2VrFoucc5vdzz4) as receiving address but it doesn't seem to match the generated private key 5J1HZKEP9YBd4apoBKyJLgZ6uUsxDuJ9ap4ncWSeFd3DpFuPkf1


package main

import (
	"github.com/bartekn/go-bip39"
	"github.com/btcsuite/btcd/chaincfg"
	"github.com/btcsuite/btcd/txscript"
	"github.com/btcsuite/btcutil"
	"github.com/btcsuite/btcutil/hdkeychain"

	"crypto/ecdsa"
	"fmt"
	log "github.com/golang/glog"
)

func main() {
	pass := "somepass"
	mnemonic := "glide west cross blue animal salmon mind sell guess vote crazy fashion language report wrap lounge fence soft strategy voice scout merit gate buyer"
	priv, pub, err := NewFromMnemonic(mnemonic, pass)
	// master key/wallet
	masterWIF, err := priv.MasterWIF()
	if err != nil {
		panic(err)
	}
	account := uint32(0)
	index := uint32(1)
	cointTyp := BTC

	btcPublic, err := pub.PublicAddr(cointTyp, account, index)
	if err != nil {
		panic(err)
	}
	btcPrivate, err := priv.WIF(cointTyp, account, index)
	if err != nil {
		panic(err)
	}

	fmt.Printf("mn %s \n, master wif %s\n, btc child private %s\n btc child Public %s\n\n",
		mnemonic, masterWIF, btcPrivate, btcPublic)

}


// returns a new masterkey along with its base58encoded form
func NewMaster(passw string) (private, public *Key, err error) {
	entropy, err := bip39.NewEntropy(256)
	if err != nil {
		log.Error(err)
		return nil, nil, err
	}
	mnemonic, err := bip39.NewMnemonic(entropy)
	if err != nil {
		log.Error(err)
		return nil, nil, err
	}
	return NewFromMnemonic(mnemonic, passw)

}

func NewFromMnemonic(mnemonic, passw string) (private, public *Key, err error) {
	// Generate a Bip32 HD wallet for the mnemonic and a user supplied password
	seed := bip39.NewSeed(mnemonic, passw)
	// Create master private key from seed
	master, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)
	if err != nil {
		return nil, nil, err
	}
	private = &Key{k: master, mnemonic: mnemonic, private: true}
	neut, err := master.Neuter()
	if err != nil {
		return nil, nil, err
	}
	public = &Key{k: neut}
	return private, public, nil
}

func (k *Key) Mnemonic() (string, error) {
	if k.mnemonic == "" {
		return "", fmt.Errorf("no mnemonic available")
	}
	return k.mnemonic, nil
}


func (k *Key) MasterWIF() (string, error) {
	compress := false //?
	priv, err := k.k.ECPrivKey()
	if err != nil {
		return "", err
	}
	wf, err := btcutil.NewWIF(priv, &chaincfg.MainNetParams, compress)
	if err != nil {
		return "", err
	}
	return wf.String(), nil
}

// creates the Wallet Import Format string encoding of a WIF structure.
func (k *Key) WIF(coinTyp CoinType, account, index uint32) (string, error) {
	acctXExternalX, err := k.deriveKey(coinTyp, account, index)
	if err != nil {
		return "", err
	}
	compress := false //?
	priv, err := acctXExternalX.k.ECPrivKey()
	if err != nil {
		return "", err
	}
	wf, err := btcutil.NewWIF(priv, &chaincfg.MainNetParams, compress)
	if err != nil {
		return "", err
	}
	return wf.String(), nil
}

type CoinType uint32

const (
	BTC CoinType = 1
)

func (k *Key) deriveKey(coinTyp CoinType, account, index uint32) (*Key, error) {
	// m/49'
	purpose, err := k.k.Child(49)
	if err != nil {
		return nil, err
	}

	// m/49'/1'
	coinType, err := purpose.Child(uint32(coinTyp))
	if err != nil {
		return nil, err
	}

	// m/49'/1'/0'
	acctX, err := coinType.Child(account)
	if err != nil {
		return nil, err
	}
	// Derive the extended key for the account 0 external chain.  This
	// gives the path:
	//   m/0H/0
	// 0 is external, 1 is internal address (used for change, wallet software)
	acctXExt, err := acctX.Child(0)
	if err != nil {
		return nil, err
	}
	// Derive the Indexth extended key for the account X external chain.
	// m/49'/1'/0'/0
	acctXExternalX, err := acctXExt.Child(index)
	if err != nil {
		return nil, err
	}
	return &Key{private: k.private, k: acctXExternalX}, nil
}

func (k *Key) PublicAddr(coinTyp CoinType, account, index uint32) (string, error) {
	if k.private {
		// prevent insecure behaviour
		return "", fmt.Errorf("Don't use the private key to gen btc addresses, use the extended public key instead")
	}
	acctXExternalX, err := k.deriveKey(coinTyp, account, index)
	if err != nil {
		return "", err
	}
	// BIP49 segwit pay-to-script-hash style address.
	pubKey, err := acctXExternalX.k.ECPubKey()
	if err != nil {
		return "", err
	}

	keyHash := btcutil.Hash160(pubKey.SerializeCompressed())
	scriptSig, err := txscript.NewScriptBuilder().AddOp(txscript.OP_0).AddData(keyHash).Script()
	if err != nil {
		return "", err
	}
	addr, err := btcutil.NewAddressScriptHash(scriptSig, &chaincfg.MainNetParams)
	if err != nil {
		return "", err
	}
	return addr.String(), nil
}

type Key struct {
	private  bool
	k        *hdkeychain.ExtendedKey
	mnemonic string
}

// receives the master public key (Neuster) and returns a list of addresses ?
func (masterPublicKey *Key) DeriveAddress(coin CoinType, account, startIndex, limit uint32) ([]string, error) {
	var keys []string
	for i := startIndex; i <= startIndex+limit; i++ {
		k, err := masterPublicKey.PublicAddr(coin, account, i)
		if err != nil {
			log.Error(err)
			continue
		}
		keys = append(keys, k)
	}
	return keys, nil
}



func (k *Key) PrivateECDSA() (*ecdsa.PrivateKey, error) {
	if k.private == false {
		return nil, fmt.Errorf("key is not private")
	}
	ecPriv, err := k.k.ECPrivKey()
	if err != nil {
		return nil, err
	}
	return ecPriv.ToECDSA(), nil
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.