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:
parent
cdba88b9f2
commit
2fd2866f7f
4 changed files with 60 additions and 39 deletions
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue