Key signature and wallet address get functions added to Public key (#144)

* small fixes

* gofmt

* fix in raw tx build

* fixes after review

* balance getter interface

* moved address and signature calculation to public key

* errors handling

* PublicKey() returns PublicKey instead of bytes slice

* fixes after review

* fixes after review
This commit is contained in:
Anastasia Prasolova 2019-02-19 21:37:35 +03:00 committed by decentralisedkev
parent cdba88b9f2
commit 2fd2866f7f
4 changed files with 60 additions and 39 deletions

View file

@ -2,12 +2,14 @@ package crypto
import ( import (
"bytes" "bytes"
"crypto/sha256"
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
"io" "io"
"math/big" "math/big"
"github.com/pkg/errors" "github.com/pkg/errors"
"golang.org/x/crypto/ripemd160"
) )
// PublicKeys is a list of public keys. // PublicKeys is a list of public keys.
@ -43,7 +45,7 @@ func NewPublicKeyFromString(s string) (*PublicKey, error) {
return nil, err return nil, err
} }
pubKey := &PublicKey{} pubKey := new(PublicKey)
if err := pubKey.DecodeBinary(bytes.NewReader(b)); err != nil { if err := pubKey.DecodeBinary(bytes.NewReader(b)); err != nil {
return nil, err return nil, err
} }
@ -140,3 +142,45 @@ func (p *PublicKey) DecodeBinary(r io.Reader) error {
func (p *PublicKey) EncodeBinary(w io.Writer) error { func (p *PublicKey) EncodeBinary(w io.Writer) error {
return binary.Write(w, binary.LittleEndian, p.Bytes()) return binary.Write(w, binary.LittleEndian, p.Bytes())
} }
func (p *PublicKey) Signature() ([]byte, error) {
b := p.Bytes()
b = append([]byte{0x21}, b...)
b = append(b, 0xAC)
sha := sha256.New()
sha.Write(b)
hash := sha.Sum(nil)
ripemd := ripemd160.New()
ripemd.Reset()
ripemd.Write(hash)
hash = ripemd.Sum(nil)
return hash, nil
}
func (p *PublicKey) Address() (string, error) {
var (
err error
b []byte
)
if b, err = p.Signature(); err != nil {
return "", err
}
b = append([]byte{0x17}, b...)
sha := sha256.New()
sha.Write(b)
hash := sha.Sum(nil)
sha.Reset()
sha.Write(hash)
hash = sha.Sum(nil)
b = append(b, hash[0:4]...)
address := Base58Encode(b)
return address, nil
}

View file

@ -103,7 +103,7 @@ func newAccountFromPrivateKey(p *PrivateKey) (*Account, error) {
} }
a := &Account{ a := &Account{
publicKey: pubKey, publicKey: pubKey.Bytes(),
privateKey: p, privateKey: p,
Address: pubAddr, Address: pubAddr,
wif: wif, wif: wif,

View file

@ -15,7 +15,6 @@ import (
"github.com/CityOfZion/neo-go/pkg/crypto" "github.com/CityOfZion/neo-go/pkg/crypto"
"github.com/anthdm/rfc6979" "github.com/anthdm/rfc6979"
"golang.org/x/crypto/ripemd160"
) )
// PrivateKey represents a NEO private key. // PrivateKey represents a NEO private key.
@ -68,8 +67,10 @@ func NewPrivateKeyFromRawBytes(b []byte) (*PrivateKey, error) {
} }
// PublicKey derives the public key from the private key. // PublicKey derives the public key from the private key.
func (p *PrivateKey) PublicKey() ([]byte, error) { func (p *PrivateKey) PublicKey() (*crypto.PublicKey, error) {
var ( var (
err error
pk crypto.PublicKey
c = crypto.NewEllipticCurve() c = crypto.NewEllipticCurve()
q = new(big.Int).SetBytes(p.b) q = new(big.Int).SetBytes(p.b)
) )
@ -94,7 +95,10 @@ func (p *PrivateKey) PublicKey() ([]byte, error) {
} }
b := append(prefix, padded...) b := append(prefix, padded...)
return b, nil if err = pk.DecodeBytes(b); err != nil {
return nil, err
}
return &pk, nil
} }
// NewPrivateKeyFromWIF returns a NEO PrivateKey from the given // NewPrivateKeyFromWIF returns a NEO PrivateKey from the given
@ -117,48 +121,20 @@ func (p *PrivateKey) WIF() (string, error) {
// Address derives the public NEO address that is coupled with the private key, and // Address derives the public NEO address that is coupled with the private key, and
// returns it as a string. // returns it as a string.
func (p *PrivateKey) Address() (string, error) { func (p *PrivateKey) Address() (string, error) {
b, err := p.Signature() pk, err := p.PublicKey()
if err != nil { if err != nil {
return "", err return "", err
} }
return pk.Address()
b = append([]byte{0x17}, b...)
sha := sha256.New()
sha.Write(b)
hash := sha.Sum(nil)
sha.Reset()
sha.Write(hash)
hash = sha.Sum(nil)
b = append(b, hash[0:4]...)
address := crypto.Base58Encode(b)
return address, nil
} }
// Signature creates the signature using the private key. // Signature creates the signature using the private key.
func (p *PrivateKey) Signature() ([]byte, error) { func (p *PrivateKey) Signature() ([]byte, error) {
b, err := p.PublicKey() pk, err := p.PublicKey()
if err != nil { if err != nil {
return nil, err return nil, err
} }
return pk.Signature()
b = append([]byte{0x21}, b...)
b = append(b, 0xAC)
sha := sha256.New()
sha.Write(b)
hash := sha.Sum(nil)
ripemd := ripemd160.New()
ripemd.Reset()
ripemd.Write(hash)
hash = ripemd.Sum(nil)
return hash, nil
} }
// Sign signs arbitrary length data using the private key. // Sign signs arbitrary length data using the private key.

View file

@ -97,13 +97,14 @@ func (wif WIF) GetVerificationScript() ([]byte, error) {
checksig = 0xac checksig = 0xac
) )
var ( var (
pubkey, vScript []byte vScript []byte
pubkey *crypto.PublicKey
) )
pubkey, err := wif.PrivateKey.PublicKey() pubkey, err := wif.PrivateKey.PublicKey()
if err != nil { if err != nil {
return nil, err return nil, err
} }
vScript = append([]byte{pushbytes33}, pubkey...) vScript = append([]byte{pushbytes33}, pubkey.Bytes()...)
vScript = append(vScript, checksig) vScript = append(vScript, checksig)
return vScript, nil return vScript, nil
} }