diff --git a/CHANGELOG.md b/CHANGELOG.md index 41092f7..421ec92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,29 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## v1.6.0 - 2017-09-01 + +### Added + +- Ability to derive signature from private key. +- CLI outputs signature from WIF using new function. + +```golang +privateKey, err := neo.NewPrivateKeyFromWIF("L1QqQJnpBwbsPGAuutuzPTac8piqvbR1HRjrY5qHup48TBCBFe4g") +if err != nil { + log.Fatal(err) +} + +signatureBytes, err := privateKey.Signature() +if err != nil { + log.Fatal(err) +} + +signature := hex.EncodeToString(signatureBytes) + +log.Println(signature) +``` + ## v1.5.0 - 2017-09-01 ### Added diff --git a/VERSION b/VERSION index bc80560..dc1e644 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.5.0 +1.6.0 diff --git a/circle.yml b/circle.yml index 37c57e6..374e50a 100644 --- a/circle.yml +++ b/circle.yml @@ -18,6 +18,7 @@ test: - cd "$APP_PATH" && make test - cd "$APP_PATH" && make vet - cd "$APP_PATH" && make build-cli + - cd "$APP_PATH" && ./neo-go-sdk --wif KxQREAjBL6Ga8dw9rPN45pwoZ5dxhAQacEajQke6qmpB7DW6nAWE deployment: feature-branch: diff --git a/main.go b/main.go index 897421f..fbef391 100644 --- a/main.go +++ b/main.go @@ -35,11 +35,18 @@ func main() { } publicKey := hex.EncodeToString(publicKeyBytes) + signatureBytes, err := privateKey.Signature() + if err != nil { + outputError("Error when creating signature from private key.") + } + signature := hex.EncodeToString(signatureBytes) + fmt.Println("Details:") fmt.Printf(" - NEO address (compressed): \t%s\n", publicAddress) fmt.Printf(" - Private key: \t\t%s\n", privateKey.Output()) fmt.Printf(" - Private key (base64): \t%s\n", privateKey.OutputBase64()) fmt.Printf(" - Public key (compressed): \t%s\n", publicKey) + fmt.Printf(" - Signature: \t\t\t%s\n", signature) fmt.Printf(" - WIF (compressed): \t\t%s\n", wif) } diff --git a/neo/fixtures_test.go b/neo/fixtures_test.go index 745a4c1..34f0cee 100644 --- a/neo/fixtures_test.go +++ b/neo/fixtures_test.go @@ -6,6 +6,7 @@ var ( privateKeyBase64 string publicAddress string publicKey string + signature string wif string }{ { @@ -13,6 +14,7 @@ var ( privateKeyBase64: "fRKKbQlvDBTDolorDEHPeWYb/LSozJWqrqKL3k1zI0Q=", publicAddress: "ALq7AWrhAueN6mJNqk6FHJjnsEoPRytLdW", publicKey: "02028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef", + signature: "3775292229eccdf904f16fff8e83e7cffdc0f0ce", wif: "L1QqQJnpBwbsPGAuutuzPTac8piqvbR1HRjrY5qHup48TBCBFe4g", }, { @@ -20,6 +22,7 @@ var ( privateKeyBase64: "3F4nPzcBEwGCF8h2BWAR2tDIl/bsoHS/dBgH817ScdI=", publicAddress: "AVzgMjviERgZSCVoerzaGYhZhKoecd9RXk", publicKey: "02c39609dc92eba0221809f0420e80728649c2515f95536288f848e324751cf738", + signature: "9bfdbeb5ac91a220742b1dac66b402e8b7cd9107", wif: "L4c5RVHp3FyG7duisGHpSCBzEqnTUqvYw4Bv6hnwCgbDTsLYgt9o", }, { @@ -27,6 +30,7 @@ var ( privateKeyBase64: "B/vuBIG7MkQen8pdUsZuJVTAZZHH90fl13vLYhfRlS0=", publicAddress: "AN2SiiLndiLsX9sYyVYmn3LYyjgozfUnb4", publicKey: "038d92ca035622f04be0c6d23a65bcad04ce638c4ebd18b87facbd101323d349f9", + signature: "44922f93bf285dfc5199f28a028e82387d869306", wif: "KwVEM6nK44RvgsohK5zxYAgRbut9mfGYaTcb7jkqBBfnApCLRJys", }, } diff --git a/neo/private_key.go b/neo/private_key.go index 73c8de5..4f0b119 100644 --- a/neo/private_key.go +++ b/neo/private_key.go @@ -71,40 +71,29 @@ func NewPrivateKeyFromWIF(wif string) (*PrivateKey, error) { // PublicAddress derives the public NEO address that is coupled with the private key, and // returns it as a string. func (p PrivateKey) PublicAddress() (string, error) { - bytes, err := p.PublicKey() + bytes, err := p.Signature() if err != nil { return "", err } - bytes = append([]byte{0x21}, bytes...) - bytes = append(bytes, 0xAC) - - sha256H := sha256.New() - sha256H.Reset() - sha256H.Write(bytes) - hashOne := sha256H.Sum(nil) - - ripemd160H := ripemd160.New() - ripemd160H.Reset() - ripemd160H.Write(hashOne) - hashTwo := ripemd160H.Sum(nil) - var ver uint8 = 0x17 - hashTwo = append([]byte{ver}, hashTwo...) + bytes = append([]byte{ver}, bytes...) + + sha256H := sha256.New() sha256H.Reset() - sha256H.Write(hashTwo) + sha256H.Write(bytes) hashThree := sha256H.Sum(nil) sha256H.Reset() sha256H.Write(hashThree) hashFour := sha256H.Sum(nil) - hashTwo = append(hashTwo, hashFour[0:4]...) + bytes = append(bytes, hashFour[0:4]...) base58 := utility.NewBase58() - address := base58.Encode(hashTwo) + address := base58.Encode(bytes) return address, nil } @@ -154,6 +143,29 @@ func (p PrivateKey) OutputBase64() string { return base64.StdEncoding.EncodeToString(p.bytes) } +// Signature creates the signature using the private key. +func (p PrivateKey) Signature() ([]byte, error) { + bytes, err := p.PublicKey() + if err != nil { + return nil, err + } + + bytes = append([]byte{0x21}, bytes...) + bytes = append(bytes, 0xAC) + + sha256H := sha256.New() + sha256H.Reset() + sha256H.Write(bytes) + hashOne := sha256H.Sum(nil) + + ripemd160H := ripemd160.New() + ripemd160H.Reset() + ripemd160H.Write(hashOne) + hashTwo := ripemd160H.Sum(nil) + + return hashTwo, nil +} + func (p PrivateKey) createEllipticCurve() utility.EllipticCurve { var ellipticCurve utility.EllipticCurve diff --git a/neo/private_key_test.go b/neo/private_key_test.go index f425ffe..5726c08 100644 --- a/neo/private_key_test.go +++ b/neo/private_key_test.go @@ -87,4 +87,23 @@ func TestPrivateKey(t *testing.T) { } }) }) + + t.Run(".Signature()", func(t *testing.T) { + t.Run("HappyCase", func(t *testing.T) { + for i, account := range testAccounts { + description := fmt.Sprintf("%d", i) + t.Run(description, func(t *testing.T) { + privateKey, err := neo.NewPrivateKeyFromWIF(account.wif) + assert.NoError(t, err) + + signatureBytes, err := privateKey.Signature() + assert.NoError(t, err) + + signature := hex.EncodeToString(signatureBytes) + + assert.Equal(t, account.signature, signature) + }) + } + }) + }) }