Example #1
0
//GenerateKey generates random PublicKey and PrivateKey.
func GenerateKey(flagTestnet bool) (*Key, error) {
	seed := make([]byte, 32)
	_, err := rand.Read(seed)
	if err != nil {
		return nil, err
	}
	s256 := btcec.S256()

	private := PrivateKey{}
	private.isTestnet = flagTestnet
	public := PublicKey{}
	public.isTestnet = flagTestnet
	private.key, public.key = btcec.PrivKeyFromBytes(s256, seed)
	key := Key{
		Pub:  &public,
		Priv: &private,
	}

	//Print the keys
	logging.Println("Your private key in WIF is")
	logging.Println(private.GetWIFAddress())

	logging.Println("Your address is")
	logging.Println(public.GetAddress())

	return &key, nil
}
Example #2
0
//GetKeyFromWIF gets PublicKey and PrivateKey from private key of WIF format.
func GetKeyFromWIF(wif string) (*Key, error) {
	secp256k1 := btcec.S256()
	privateKeyBytes, isCmpressed, err := base58check.Decode(wif)
	if err != nil {
		return nil, err
	}

	pub := PublicKey{}
	priv := PrivateKey{}
	key := Key{
		Pub:  &pub,
		Priv: &priv,
	}
	switch privateKeyBytes[0] {
	case 0xef:
		pub.isTestnet = true
		priv.isTestnet = true
	case 0x80:
		pub.isTestnet = false
		priv.isTestnet = false
	default:
		return nil, errors.New("cannot determin net param from private key")
	}
	pub.isCompressed = isCmpressed

	//Get the raw public
	priv.key, pub.key = btcec.PrivKeyFromBytes(secp256k1, privateKeyBytes[1:])

	return &key, nil

}
Example #3
0
//GetPublicKey returns PublicKey struct using public key hex string.
func GetPublicKey(pubKeyByte []byte, isTestnet bool) (*PublicKey, error) {
	secp256k1 := btcec.S256()
	key, err := btcec.ParsePubKey(pubKeyByte, secp256k1)
	if err != nil {
		return nil, err
	}
	return &PublicKey{key: key, isTestnet: isTestnet}, nil
}
Example #4
0
// CreateScriptSig signs a raw transaction with keys.
func (rs *RedeemScript) createScriptSig(rawTransactionHashed []byte, signs [][]byte) ([]byte, error) {

	//Verify that it worked.
	secp256k1 := btcec.S256()
	count := 0
	for i, signature := range signs {
		if signature == nil {
			continue
		}
		count++
		sig, err := btcec.ParseSignature(signature, secp256k1)
		if err != nil {
			return nil, err
		}
		valid := sig.Verify(rawTransactionHashed, rs.PublicKeys[i].key)
		if !valid {
			return nil, fmt.Errorf("number %d of signature is invalid", i)
		}
	}

	if count != rs.M {
		return nil, fmt.Errorf("number of signatures %d must be %d", count, rs.M)
	}

	//redeemScript length. To allow redeemScript > 255 bytes, we use OP_PUSHDATA2 and use two bytes to specify length
	var redeemScriptLengthBytes []byte
	var requiredPUSHDATA byte
	if len(rs.Script) < 255 {
		requiredPUSHDATA = opPUSHDATA1 //OP_PUSHDATA1 specifies next *one byte* will be length to be pushed to stack
		redeemScriptLengthBytes = []byte{byte(len(rs.Script))}
	} else {
		requiredPUSHDATA = opPUSHDATA2 //OP_PUSHDATA2 specifies next *two bytes* will be length to be pushed to stack
		redeemScriptLengthBytes = make([]byte, 2)
		binary.LittleEndian.PutUint16(redeemScriptLengthBytes, uint16(len(rs.Script)))
	}
	//Create scriptSig
	var buffer bytes.Buffer
	buffer.WriteByte(op0) //OP_0 for Multisig off-by-one error
	for _, signature := range signs {
		if signature == nil {
			continue
		}
		buffer.WriteByte(byte(len(signature) + 1)) //PUSH each signature. Add one for hash type byte
		buffer.Write(signature)                    // Signature bytes
		buffer.WriteByte(0x1)                      //hash type
	}
	buffer.WriteByte(requiredPUSHDATA)    //OP_PUSHDATA1 or OP_PUSHDATA2 depending on size of redeemScript
	buffer.Write(redeemScriptLengthBytes) //PUSH redeemScript
	buffer.Write(rs.Script)               //redeemScript
	return buffer.Bytes(), nil
}
Example #5
0
//SignMessage sign using bitcoin sign struct
func (key *Key) SignMessage(hash []byte) ([]byte, error) {
	msg := make([]byte, 0)
	msg = append(msg, []byte("\x18Bitcoin Signed Message:\n")...)
	msg = append(msg, []byte{byte(len(hash))}...)
	msg = append(msg, hash...)
	h := sha256.Sum256(msg)
	hh := sha256.Sum256(h[:])
	s256 := btcec.S256()

	sig, err := btcec.SignCompact(s256, key.Priv.key, hh[:], key.Pub.isCompressed)
	if err != nil {
		return nil, err
	}
	return sig, nil
}