From 8f5176dbc7ec87980076d1dc7235e734d6662850 Mon Sep 17 00:00:00 2001 From: Emyrk Date: Thu, 14 Nov 2019 17:41:50 -0600 Subject: [PATCH 1/6] initial work on rcd-e --- address.go | 137 +++++++++++++++++++++++++++++++++++++++++++++++- address_test.go | 28 ++++++++++ go.mod | 1 + go.sum | 78 +++++++++++++++++++++++++++ rcdsigner.go | 2 + 5 files changed, 245 insertions(+), 1 deletion(-) diff --git a/address.go b/address.go index f41963b..5bea888 100644 --- a/address.go +++ b/address.go @@ -24,10 +24,14 @@ package factom import ( "context" + "crypto/ecdsa" "crypto/rand" "crypto/sha256" - "crypto/ed25519" + "encoding/hex" + "fmt" + + "github.com/ethereum/go-ethereum/crypto" ) // Notes: This file contains all types, interfaces, and methods related to @@ -45,6 +49,12 @@ type FAAddress [sha256.Size]byte // FsAddress is the secret key to a FAAddress. type FsAddress [sha256.Size]byte +// EthSecret is the secret key to a FAAddress +// It uses rcd type 0x0e with ecdsa signing. +// TODO: To get the bitsize, you need to do `priv.Params().Bitsize`. +// It is not in a constant. +type EthSecret [32]byte + // ECAddress is a Public Entry Credit Address. type ECAddress [sha256.Size]byte @@ -152,6 +162,12 @@ func (adr FsAddress) String() string { return adr.payload().StringWithPrefix(adr.PrefixBytes()) } +// String encodes adr into its human readable form: base58check with +// adr.PrefixBytes(). +func (adr EthSecret) String() string { + return "0x" + hex.EncodeToString(adr[:]) +} + // String encodes adr into its human readable form: base58check with // adr.PrefixBytes(). func (adr ECAddress) String() string { @@ -174,6 +190,11 @@ func (adr FsAddress) MarshalText() ([]byte, error) { return adr.payload().MarshalTextWithPrefix(adr.PrefixBytes()) } +// MarshalText encodes adr as a string using adr.String(). +func (adr EthSecret) MarshalText() ([]byte, error) { + return []byte(adr.String()), nil +} + // MarshalText encodes adr as a string using adr.String(). func (adr ECAddress) MarshalText() ([]byte, error) { return adr.payload().MarshalTextWithPrefix(adr.PrefixBytes()) @@ -192,6 +213,12 @@ func GenerateFsAddress() (FsAddress, error) { return generatePrivKey() } +// GenerateEthSecret generates a secure random private Etheruem address using +// crypto/rand.Random as the source of randomness. +func GenerateEthSecret() (EthSecret, error) { + return generatePrivKey() +} + // GenerateEsAddress generates a secure random private Entry Credit address // using crypto/rand.Random as the source of randomness. func GenerateEsAddress() (EsAddress, error) { @@ -218,6 +245,12 @@ func NewFsAddress(adrStr string) (adr FsAddress, err error) { return } +// NewEthSecret attempts to parse adrStr into a new EthSecret. +func NewEthSecret(adrStr string) (adr EthSecret, err error) { + err = adr.Set(adrStr) + return +} + // NewECAddress attempts to parse adrStr into a new ECAddress. func NewECAddress(adrStr string) (adr ECAddress, err error) { err = adr.Set(adrStr) @@ -240,6 +273,25 @@ func (adr *FsAddress) Set(adrStr string) error { return adr.payload().SetWithPrefix(adrStr, adr.PrefixString()) } +// Set attempts to parse adrStr into adr. +// adrStr is in format 0x[64 character hex] +func (e *EthSecret) Set(adrStr string) error { + // TODO: Payload code expects base 58. So this address type cannot + // use those generic functions + if !has0xPrefix(adrStr) { + return fmt.Errorf("exp 0x prefix") + } + if len(adrStr) != 66 { // 66 is 64 hex + 2 character prefix + return fmt.Errorf("exp 64 hex characters") + } + secret, err := hex.DecodeString(adrStr[2:]) + if err != nil { + return err + } + copy(e[:], secret) + return nil +} + // Set attempts to parse adrStr into adr. func (adr *ECAddress) Set(adrStr string) error { return adr.payload().SetWithPrefix(adrStr, adr.PrefixString()) @@ -262,6 +314,12 @@ func (adr *FsAddress) UnmarshalText(text []byte) error { return adr.payload().UnmarshalTextWithPrefix(text, adr.PrefixString()) } +// UnmarshalText decodes a string with a human readable secret Factoid address +// into adr. +func (adr *EthSecret) UnmarshalText(text []byte) error { + return adr.Set(string(text)) +} + // UnmarshalText decodes a string with a human readable public Entry Credit // address into adr. func (adr *ECAddress) UnmarshalText(text []byte) error { @@ -281,6 +339,11 @@ func (adr FAAddress) GetFsAddress(ctx context.Context, c *Client) (FsAddress, er return privAdr, err } +func (adr EthSecret) GetEthSecret(ctx context.Context, c *Client) (EthSecret, error) { + panic("Not yet implemented") // TODO: Implement + return EthSecret{}, nil +} + // GetEsAddress queries factom-walletd for the EsAddress corresponding to adr. func (adr ECAddress) GetEsAddress(ctx context.Context, c *Client) (EsAddress, error) { var privAdr EsAddress @@ -331,6 +394,11 @@ func (adr FsAddress) Save(ctx context.Context, c *Client) error { return c.SavePrivateAddresses(ctx, adr.String()) } +func (adr EthSecret) Save(ctx context.Context, c *Client) error { + panic("Not yet implemented") // TODO: Implement + return nil +} + // Save adr with factom-walletd. func (adr EsAddress) Save(ctx context.Context, c *Client) error { return c.SavePrivateAddresses(ctx, adr.String()) @@ -359,6 +427,11 @@ func (adr FsAddress) GetBalance(ctx context.Context, c *Client) (uint64, error) return adr.FAAddress().GetBalance(ctx, c) } +// GetBalance queries factomd for the Factoid Balance for adr. +func (adr EthSecret) GetBalance(ctx context.Context, c *Client) (uint64, error) { + return adr.FAAddress().GetBalance(ctx, c) +} + // GetBalance queries factomd for the Entry Credit Balance for adr. func (adr ECAddress) GetBalance(ctx context.Context, c *Client) (uint64, error) { return c.getBalance(ctx, "entry-credit-balance", adr.String()) @@ -390,6 +463,12 @@ func (adr FsAddress) Remove(ctx context.Context, c *Client) error { return adr.FAAddress().Remove(ctx, c) } +// Remove adr from factom-walletd. WARNING: THIS IS DESTRUCTIVE. +func (adr EthSecret) Remove(ctx context.Context, c *Client) error { + panic("Not yet implemented") // TODO: Implement + return nil +} + // Remove adr from factom-walletd. WARNING: THIS IS DESTRUCTIVE. func (adr ECAddress) Remove(ctx context.Context, c *Client) error { return c.removeAddress(ctx, adr.String()) @@ -414,6 +493,11 @@ func (adr FsAddress) FAAddress() FAAddress { return sha256d(adr.RCD()) } +// FAAddress returns the FAAddress corresponding to adr. +func (e EthSecret) FAAddress() FAAddress { + return sha256d(e.RCD()) +} + // ECAddress returns the ECAddress corresponding to adr. func (adr EsAddress) ECAddress() (ec ECAddress) { copy(ec[:], adr.PublicKey()) @@ -431,11 +515,24 @@ func (adr FsAddress) RCD() []byte { return append([]byte{RCDType01}, adr.PublicKey()[:]...) } +func (s EthSecret) RCD() []byte { + return append([]byte{RCDType0e}, s.PublicKeyBytes()...) +} + // Sign the msg. func (adr FsAddress) Sign(msg []byte) []byte { return ed25519.Sign(adr.PrivateKey(), msg) } +// Sign the msg. +func (adr EthSecret) Sign(msg []byte) []byte { + sig, err := crypto.Sign(msg, adr.PrivateKey()) + if err != nil { + return nil + } + return sig +} + // PublicKey returns the ed25519.PublicKey for adr. func (adr ECAddress) PublicKey() ed25519.PublicKey { return adr[:] @@ -451,12 +548,50 @@ func (adr FsAddress) PublicKey() ed25519.PublicKey { return adr.PrivateKey().Public().(ed25519.PublicKey) } +func (s EthSecret) PublicKey() ecdsa.PublicKey { + secret := s.PrivateKey() + if secret == nil { + return ecdsa.PublicKey{} + } + return secret.PublicKey +} + +// PublicKeyBytes returns the byte representation of the public key +func (s EthSecret) PublicKeyBytes() []byte { + pub := s.PublicKey() + bytes := crypto.FromECDSAPub(&pub) + // Strip off the 0x04 prefix to indicate an uncompressed key. + // You can find the prefix list here: + // https://www.oreilly.com/library/view/mastering-ethereum/9781491971932/ch04.html + return bytes[1:] +} + // PrivateKey returns the ed25519.PrivateKey for adr. func (adr FsAddress) PrivateKey() ed25519.PrivateKey { return ed25519.NewKeyFromSeed(adr[:]) } +func (s EthSecret) PrivateKey() *ecdsa.PrivateKey { + secret, err := crypto.ToECDSA(s[:]) + if err != nil { + return nil + } + return secret +} + // PrivateKey returns the ed25519.PrivateKey for adr. func (adr EsAddress) PrivateKey() ed25519.PrivateKey { return ed25519.NewKeyFromSeed(adr[:]) } + +// Extra EthSecret functions + +// EthAddress returns the linked eth address +func (adr EthSecret) EthAddress() string { + return crypto.PubkeyToAddress(adr.PublicKey()).String() +} + +// has0xPrefix validates str begins with '0x' or '0X'. +func has0xPrefix(str string) bool { + return len(str) >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X') +} diff --git a/address_test.go b/address_test.go index cdddc12..ba8f381 100644 --- a/address_test.go +++ b/address_test.go @@ -24,8 +24,10 @@ package factom import ( "context" + "encoding/hex" "encoding/json" "fmt" + "strings" "testing" "github.com/stretchr/testify/assert" @@ -259,3 +261,29 @@ func TestAddress(t *testing.T) { assert.NoError(t, err) }) } + +func TestNewEthSecret(t *testing.T) { + // Eth Vector from + // https://www.oreilly.com/library/view/mastering-ethereum/9781491971932/ch04.html + + secret := "0xf8f8a2f43c8376ccb0871305060d7b27b0554d2cc72bccf41b2705608452f315" + public := "0x6e145ccef1033dea239875dd00dfb4fee6e3348b84985c92f103444683bae07b83b5c38e5e2b0" + + "c8529d7fa3f64d46daa1ece2d9ac14cab9477d042c84c32ccd0" + ethAddress := "0x001d3f1ef827552ae1114027bd3ecf1f086ba0f9" + faAddress := "FA2M6ddTAgewAiU7Cm5T6wffXsteuqrYkDAtUtbBjcurf3LKH9Eo" + + assert := assert.New(t) + + addr, err := NewEthSecret(secret) + assert.NoError(err) + + // Check eth address + assert.True(strings.EqualFold(addr.EthAddress(), ethAddress)) + + // Check the public key + exp, _ := hex.DecodeString(public[2:]) + assert.Equal(exp, addr.PublicKeyBytes()) + + // Check the FA address + assert.Equal(faAddress, addr.FAAddress().String()) +} diff --git a/go.mod b/go.mod index e5e192c..5ba1468 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/AdamSLevy/retry v0.0.0-20191017184328-cce921f261f4 github.com/Factom-Asset-Tokens/base58 v0.0.0-20181227014902-61655c4dd885 github.com/kr/pretty v0.1.0 // indirect + github.com/ethereum/go-ethereum v1.9.7 github.com/stretchr/testify v1.4.0 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect diff --git a/go.sum b/go.sum index 15d4b1b..ae3bf3e 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,7 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +crawshaw.io/iox v0.0.0-20181124134642-c51c3df30797/go.mod h1:sXBiorCo8c46JlQV3oXPKINnZ8mcqnye1EkVkqsectk= +crawshaw.io/sqlite v0.1.2/go.mod h1:BZaitnE9BVpocOuCdi/y5XReJMUelG53e/rDSLwSFzY= +crawshaw.io/sqlite v0.1.3-0.20190520153332-66f853b01dfb/go.mod h1:igAO5JulrQ1DbdZdtVq48mnZUBAPOeFzer7VhDWNtW4= github.com/AdamSLevy/go-merkle v0.0.0-20190611101253-ca33344a884d h1:FWutTJGVqBnL4rLgeNaspUYnmnvkXcmDA3QO3rHBGgU= github.com/AdamSLevy/go-merkle v0.0.0-20190611101253-ca33344a884d/go.mod h1:Nw3sh5L40Xs1wno7ndbD/dYWg+vARpBvpX9Zz1YSxbo= github.com/AdamSLevy/jsonrpc2/v12 v12.0.1 h1:cVyqoBa4Qgw8bQj3vCBnZHOX/E+uvPM8TbQPobGwY8Q= @@ -15,15 +19,85 @@ github.com/JohnCGriffin/overflow v0.0.0-20170615021017-4d914c927216/go.mod h1:X0 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/ethereum/go-ethereum v1.9.7 h1:p4O+z0MGzB7xxngHbplcYNloxkFwGkeComhkzWnq0ig= +github.com/ethereum/go-ethereum v1.9.7/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nightlyone/lockfile v0.0.0-20180618180623-0ad87eef1443/go.mod h1:JbxfV1Iifij2yhRjXai0oFrbpxszXHRx1E5RuM26o4Y= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.2.1/go.mod h1:6gapUrK/U1TAN7ciCoNRIdVC5sbdBTUh1DKN0g6uH7E= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= @@ -31,5 +105,9 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/rcdsigner.go b/rcdsigner.go index ddafc9e..c8885db 100644 --- a/rcdsigner.go +++ b/rcdsigner.go @@ -58,6 +58,8 @@ const ( RCDType01Size = ed25519.PublicKeySize + 1 // SignatureSize is the size of the ed25519 signatures. RCDType01SigSize = ed25519.SignatureSize + + RCDType0e byte = 0x0e ) func ValidateRCD01(rcd, sig, msg []byte) (Bytes32, error) { From 05e1106a4bc6e610338534b589917059a933b9f8 Mon Sep 17 00:00:00 2001 From: Emyrk Date: Fri, 15 Nov 2019 08:52:33 -0600 Subject: [PATCH 2/6] Implement validate rcde --- rcdsigner.go | 30 +++++++++++++++++++++++++++- rcdsigner_test.go | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 rcdsigner_test.go diff --git a/rcdsigner.go b/rcdsigner.go index c8885db..cd1f3e6 100644 --- a/rcdsigner.go +++ b/rcdsigner.go @@ -25,6 +25,8 @@ package factom import ( "crypto/ed25519" "fmt" + + "github.com/ethereum/go-ethereum/crypto" ) // RCDSigner is the interface implemented by types that can generate Redeem @@ -45,6 +47,8 @@ func ValidateRCD(rcd, sig, msg []byte) (Bytes32, error) { switch rcd[0] { case RCDType01: validateRCD = ValidateRCD01 + case RCDType0e: + validateRCD = ValidateRCD0e default: return Bytes32{}, fmt.Errorf("unsupported RCD") } @@ -59,7 +63,11 @@ const ( // SignatureSize is the size of the ed25519 signatures. RCDType01SigSize = ed25519.SignatureSize - RCDType0e byte = 0x0e + RCDType0e byte = 0x0e + RCDType0eSize = 64 + 1 // Excluding uncompressed 0x04 prefix + // The recover byte allows the public key to be recovered from the + // signature + msg. + RCDType0eSigSize = 65 // 64 byte sig + recovery byte ) func ValidateRCD01(rcd, sig, msg []byte) (Bytes32, error) { @@ -80,3 +88,23 @@ func ValidateRCD01(rcd, sig, msg []byte) (Bytes32, error) { return sha256d(rcd), nil } + +func ValidateRCD0e(rcd []byte, sig []byte, msg []byte) (Bytes32, error) { + if len(rcd) != RCDType0eSize { + return Bytes32{}, fmt.Errorf("invalid RCD size") + } + if rcd[0] != RCDType0e { + return Bytes32{}, fmt.Errorf("invalid RCD type") + } + if len(sig) != RCDType0eSigSize { + return Bytes32{}, fmt.Errorf("invalid signature size") + } + + pubKey := []byte(rcd[1:]) // Omit RCD Type byte + pubKey = append([]byte{0x04}, pubKey...) // Uncompressed prefix + if !crypto.VerifySignature(pubKey, msg, sig[:64]) { // Ignore recovery byte + return Bytes32{}, fmt.Errorf("invalid signature") + } + + return sha256d(rcd), nil +} diff --git a/rcdsigner_test.go b/rcdsigner_test.go new file mode 100644 index 0000000..4cf230a --- /dev/null +++ b/rcdsigner_test.go @@ -0,0 +1,50 @@ +package factom_test + +import ( + crand "crypto/rand" + "testing" + + "github.com/stretchr/testify/assert" + + . "github.com/Factom-Asset-Tokens/factom" +) + +func TestValidateRCD(t *testing.T) { + // Tests random created addresses creates signatures that pass + // validation and generate the expected rcdhash + + t.Run("rcd1", func(t *testing.T) { + for i := 0; i < 100; i++ { + assert := assert.New(t) + adr, err := GenerateFsAddress() + assert.NoError(err) + + valid, err := ValidateRCD(rcdFields(adr)) + assert.NoError(err) + rcdHash := adr.FAAddress() + assert.Equal(rcdHash[:], valid[:]) + } + }) + + t.Run("rcd-e", func(t *testing.T) { + for i := 0; i < 100; i++ { + assert := assert.New(t) + adr, err := GenerateEthSecret() + assert.NoError(err) + + valid, err := ValidateRCD(rcdFields(adr)) + assert.NoError(err) + rcdHash := adr.FAAddress() + assert.Equal(rcdHash[:], valid[:]) + } + }) +} + +func rcdFields(adr RCDSigner) (rcd []byte, sig []byte, digest []byte) { + digest = make([]byte, 32) + _, _ = crand.Read(digest) + + sig = adr.Sign(digest) + rcd = adr.RCD() + return +} From bc38da9dd2fdde69c3107802b06c149a3786eefc Mon Sep 17 00:00:00 2001 From: Emyrk Date: Fri, 15 Nov 2019 09:19:44 -0600 Subject: [PATCH 3/6] Add more test vectors --- rcdsigner_test.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/rcdsigner_test.go b/rcdsigner_test.go index 4cf230a..c3ec425 100644 --- a/rcdsigner_test.go +++ b/rcdsigner_test.go @@ -2,13 +2,24 @@ package factom_test import ( crand "crypto/rand" + "encoding/hex" + "fmt" "testing" + "github.com/ethereum/go-ethereum/crypto" + + "github.com/Factom-Asset-Tokens/factom/varintf" + "github.com/stretchr/testify/assert" . "github.com/Factom-Asset-Tokens/factom" ) +func TestValidateRCD0e(t *testing.T) { + fmt.Printf("%x\n", varintf.Encode(14)) + fmt.Println(varintf.Decode([]byte{0x0e})) +} + func TestValidateRCD(t *testing.T) { // Tests random created addresses creates signatures that pass // validation and generate the expected rcdhash @@ -40,6 +51,41 @@ func TestValidateRCD(t *testing.T) { }) } +// These are vectors taken from the etheruem repo +func TestValidateRCD0eVectors(t *testing.T) { + assert := assert.New(t) + + // Vector from + // https://github.com/ethereum/go-ethereum/blob/f03b2db7db123a569672b0caed5c1cd735c72ba7/crypto/signature_test.go#L31-L34 + testmsg, _ := hex.DecodeString("ce0677bb30baa8cf067c88db9811f4333d131bf8bcf12fe7065d211dce971008") + testsig, _ := hex.DecodeString("90f27b8b488db00b00606796d2987f6a5f59ae62ea05effe84fef5b8b0e549984a691139ad57a3f0b906637673aa2f63d1f55cb1a69199d4009eea23ceaddc9301") + testpubkey, _ := hex.DecodeString("04e32df42865e97135acfb65f3bae71bdc86f4d49150ad6a440b6f15878109880a0a2b2667f7e725ceea70c673093bf67663e0312623c8e091b13cf2c0f11ef652") + + valid, err := ValidateRCD0e(append([]byte{0x0e}, testpubkey[1:]...), testsig, testmsg) + assert.NoError(err) + assert.False(valid.IsZero()) + + // TestVerifySignatureMalleable Vector from + // https://github.com/ethereum/go-ethereum/blob/f03b2db7db123a569672b0caed5c1cd735c72ba7/crypto/signature_test.go#L80-L82 + testsig, _ = hex.DecodeString("638a54215d80a6713c8d523a6adc4e6e73652d859103a36b700851cb0e61b66b8ebfc1a610c57d732ec6e0a8f06a9a7a28df5051ece514702ff9cdff0b11f454") + testsig = append(testsig, 0) // Make it 65 bytes + + testpubkeyC, _ := hex.DecodeString("03ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd3138") + ecdsaPub, err := crypto.DecompressPubkey(testpubkeyC) + assert.NoError(err) + testpubkey = crypto.FromECDSAPub(ecdsaPub) + + testmsg, _ = hex.DecodeString("d301ce462d3e639518f482c7f03821fec1e602018630ce621e1e7851c12343a6") + valid, err = ValidateRCD0e(append([]byte{0x0e}, testpubkey[1:]...), testsig, testmsg) + if err == nil { + t.Errorf("VerifySignature returned true for malleable signature") + } +} + +func generateVector() { + +} + func rcdFields(adr RCDSigner) (rcd []byte, sig []byte, digest []byte) { digest = make([]byte, 32) _, _ = crand.Read(digest) From 1cbf14dc6181f4c1f9a9979a32c8ae9daa8048f6 Mon Sep 17 00:00:00 2001 From: Emyrk Date: Fri, 15 Nov 2019 09:26:15 -0600 Subject: [PATCH 4/6] Add small function to generate vectors --- rcdsigner_test.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/rcdsigner_test.go b/rcdsigner_test.go index c3ec425..1f0ad3e 100644 --- a/rcdsigner_test.go +++ b/rcdsigner_test.go @@ -82,8 +82,16 @@ func TestValidateRCD0eVectors(t *testing.T) { } } +// generateVector prints out all the fields needed to check an implementation. func generateVector() { - + s, _ := GenerateEthSecret() + fmt.Printf("%20s: %s\n", "Private Key", s) + fmt.Printf("%20s: 0x%x\n", "Public Key", s.PublicKeyBytes()) + fmt.Printf("%20s: %s\n", "FAAddress", s.FAAddress()) + fmt.Printf("%20s: %s\n", "EthAddress", s.EthAddress()) + fmt.Println() + fmt.Printf("%20s: %x\n", "Digest", make([]byte, 32)) + fmt.Printf("%20s: %x\n", "Signature", s.Sign(make([]byte, 32))) } func rcdFields(adr RCDSigner) (rcd []byte, sig []byte, digest []byte) { From ae652e00f3b2eadffb01a8b89319c8a32e5c78f3 Mon Sep 17 00:00:00 2001 From: Emyrk Date: Tue, 10 Dec 2019 16:36:56 -0600 Subject: [PATCH 5/6] Add Fe address type --- address.go | 100 ++++++++++++++++++++++++++++++++++++++++++------ address_test.go | 2 +- 2 files changed, 90 insertions(+), 12 deletions(-) diff --git a/address.go b/address.go index 5bea888..53649b9 100644 --- a/address.go +++ b/address.go @@ -25,9 +25,9 @@ package factom import ( "context" "crypto/ecdsa" + "crypto/ed25519" "crypto/rand" "crypto/sha256" - "crypto/ed25519" "encoding/hex" "fmt" @@ -55,6 +55,9 @@ type FsAddress [sha256.Size]byte // It is not in a constant. type EthSecret [32]byte +// FeAddress is a Public Factoid Address using the rcde. +type FeAddress [sha256.Size]byte + // ECAddress is a Public Entry Credit Address. type ECAddress [sha256.Size]byte @@ -69,6 +72,9 @@ func (adr *FAAddress) payload() *payload { func (adr *FsAddress) payload() *payload { return (*payload)(adr) } +func (adr *FeAddress) payload() *payload { + return (*payload)(adr) +} func (adr *ECAddress) payload() *payload { return (*payload)(adr) } @@ -81,6 +87,10 @@ var ( fsPrefixBytes = [...]byte{0x64, 0x78} ecPrefixBytes = [...]byte{0x59, 0x2a} esPrefixBytes = [...]byte{0x5d, 0xb6} + + // RCD-e prefixes + fePrefixBytes = [...]byte{0x62, 0xf4} // Fe... + fEPrefixBytes = [...]byte{0x60, 0x28} // FE... ) // PrefixBytes returns the two byte prefix for the address type as a byte @@ -99,6 +109,14 @@ func (FsAddress) PrefixBytes() Bytes { return prefix[:] } +// PrefixBytes returns the two byte prefix for the address type as a byte +// slice. Note that the prefix for a given address type is always the same and +// does not depend on the address value. Returns []byte{0x62, 0xf4}. +func (FeAddress) PrefixBytes() Bytes { + prefix := fePrefixBytes + return prefix[:] +} + // PrefixBytes returns the two byte prefix for the address type as a byte // slice. Note that the prefix for a given address type is always the same and // does not depend on the address value. Returns []byte{0x59, 0x2a}. @@ -118,6 +136,7 @@ func (EsAddress) PrefixBytes() Bytes { const ( faPrefixStr = "FA" fsPrefixStr = "Fs" + fePrefixStr = "Fe" ecPrefixStr = "EC" esPrefixStr = "Es" ) @@ -136,6 +155,13 @@ func (FsAddress) PrefixString() string { return fsPrefixStr } +// PrefixString returns the two prefix bytes for the address type as an encoded +// string. Note that the prefix for a given address type is always the same and +// does not depend on the address value. Returns "Fe". +func (FeAddress) PrefixString() string { + return fePrefixStr +} + // PrefixString returns the two prefix bytes for the address type as an encoded // string. Note that the prefix for a given address type is always the same and // does not depend on the address value. Returns "EC". @@ -162,6 +188,12 @@ func (adr FsAddress) String() string { return adr.payload().StringWithPrefix(adr.PrefixBytes()) } +// String encodes adr into its human readable form: base58check with +// adr.PrefixBytes(). +func (adr FeAddress) String() string { + return adr.payload().StringWithPrefix(adr.PrefixBytes()) +} + // String encodes adr into its human readable form: base58check with // adr.PrefixBytes(). func (adr EthSecret) String() string { @@ -190,6 +222,11 @@ func (adr FsAddress) MarshalText() ([]byte, error) { return adr.payload().MarshalTextWithPrefix(adr.PrefixBytes()) } +// MarshalText encodes adr as a string using adr.String(). +func (adr FeAddress) MarshalText() ([]byte, error) { + return adr.payload().MarshalTextWithPrefix(adr.PrefixBytes()) +} + // MarshalText encodes adr as a string using adr.String(). func (adr EthSecret) MarshalText() ([]byte, error) { return []byte(adr.String()), nil @@ -245,6 +282,12 @@ func NewFsAddress(adrStr string) (adr FsAddress, err error) { return } +// NewFeAddress attempts to parse adrStr into a new FeAddress. +func NewFeAddress(adrStr string) (adr FeAddress, err error) { + err = adr.Set(adrStr) + return +} + // NewEthSecret attempts to parse adrStr into a new EthSecret. func NewEthSecret(adrStr string) (adr EthSecret, err error) { err = adr.Set(adrStr) @@ -273,6 +316,11 @@ func (adr *FsAddress) Set(adrStr string) error { return adr.payload().SetWithPrefix(adrStr, adr.PrefixString()) } +// Set attempts to parse adrStr into adr. +func (adr *FeAddress) Set(adrStr string) error { + return adr.payload().SetWithPrefix(adrStr, adr.PrefixString()) +} + // Set attempts to parse adrStr into adr. // adrStr is in format 0x[64 character hex] func (e *EthSecret) Set(adrStr string) error { @@ -314,6 +362,12 @@ func (adr *FsAddress) UnmarshalText(text []byte) error { return adr.payload().UnmarshalTextWithPrefix(text, adr.PrefixString()) } +// UnmarshalText decodes a string with a human readable secret Factoid address +// into adr. +func (adr *FeAddress) UnmarshalText(text []byte) error { + return adr.payload().UnmarshalTextWithPrefix(text, adr.PrefixString()) +} + // UnmarshalText decodes a string with a human readable secret Factoid address // into adr. func (adr *EthSecret) UnmarshalText(text []byte) error { @@ -339,9 +393,10 @@ func (adr FAAddress) GetFsAddress(ctx context.Context, c *Client) (FsAddress, er return privAdr, err } -func (adr EthSecret) GetEthSecret(ctx context.Context, c *Client) (EthSecret, error) { - panic("Not yet implemented") // TODO: Implement - return EthSecret{}, nil +func (adr FeAddress) GetEthSecret(ctx context.Context, c *Client) (EthSecret, error) { + var privAdr EthSecret + err := c.getAddress(ctx, adr, &privAdr) + return privAdr, err } // GetEsAddress queries factom-walletd for the EsAddress corresponding to adr. @@ -361,32 +416,41 @@ func (c *Client) getAddress(ctx context.Context, pubAdr, privAdr interface{}) er } // GetPrivateAddresses queries factom-walletd for all private addresses. -func (c *Client) GetPrivateAddresses(ctx context.Context) ([]FsAddress, []EsAddress, +func (c *Client) GetPrivateAddresses(ctx context.Context) ([]FsAddress, []EsAddress, []EthSecret, error) { var result struct{ Addresses []struct{ Secret string } } if err := c.WalletdRequest(ctx, "all-addresses", nil, &result); err != nil { - return nil, nil, err + return nil, nil, nil, err } fss := make([]FsAddress, 0, len(result.Addresses)) ess := make([]EsAddress, 0, len(result.Addresses)) + eths := make([]EthSecret, 0, len(result.Addresses)) for _, adr := range result.Addresses { adrStr := adr.Secret + if has0xPrefix(adrStr) { + eth, err := NewEthSecret(adrStr) + if err != nil { + return nil, nil, nil, err + } + eths = append(eths, eth) + continue + } switch adrStr[:2] { case fsPrefixStr: fs, err := NewFsAddress(adrStr) if err != nil { - return nil, nil, err + return nil, nil, nil, err } fss = append(fss, fs) case esPrefixStr: es, err := NewEsAddress(adrStr) if err != nil { - return nil, nil, err + return nil, nil, nil, err } ess = append(ess, es) } } - return fss, ess, nil + return fss, ess, eths, nil } // Save adr with factom-walletd. @@ -395,8 +459,7 @@ func (adr FsAddress) Save(ctx context.Context, c *Client) error { } func (adr EthSecret) Save(ctx context.Context, c *Client) error { - panic("Not yet implemented") // TODO: Implement - return nil + return c.SavePrivateAddresses(ctx, adr.String()) } // Save adr with factom-walletd. @@ -427,6 +490,11 @@ func (adr FsAddress) GetBalance(ctx context.Context, c *Client) (uint64, error) return adr.FAAddress().GetBalance(ctx, c) } +// GetBalance queries factomd for the Factoid Balance for adr. +func (adr FeAddress) GetBalance(ctx context.Context, c *Client) (uint64, error) { + return adr.FAAddress().GetBalance(ctx, c) +} + // GetBalance queries factomd for the Factoid Balance for adr. func (adr EthSecret) GetBalance(ctx context.Context, c *Client) (uint64, error) { return adr.FAAddress().GetBalance(ctx, c) @@ -493,11 +561,21 @@ func (adr FsAddress) FAAddress() FAAddress { return sha256d(adr.RCD()) } +// FAAddress returns the FAAddress corresponding to adr. +func (e EthSecret) FeAddress() FeAddress { + return sha256d(e.RCD()) +} + // FAAddress returns the FAAddress corresponding to adr. func (e EthSecret) FAAddress() FAAddress { return sha256d(e.RCD()) } +// FAAddress returns the FAAddress corresponding to adr. +func (e FeAddress) FAAddress() FAAddress { + return FAAddress(e) +} + // ECAddress returns the ECAddress corresponding to adr. func (adr EsAddress) ECAddress() (ec ECAddress) { copy(ec[:], adr.PublicKey()) diff --git a/address_test.go b/address_test.go index ba8f381..ba1c49c 100644 --- a/address_test.go +++ b/address_test.go @@ -229,7 +229,7 @@ func TestAddress(t *testing.T) { }) t.Run("GetPrivateAddresses", func(t *testing.T) { - fss, ess, err := c.GetPrivateAddresses(nil) + fss, ess, _, err := c.GetPrivateAddresses(nil) assert := assert.New(t) assert.NoError(err) assert.NotEmpty(fss) From 60e2808aaba7cafc3502381fbdfba9e335eb8fba Mon Sep 17 00:00:00 2001 From: Emyrk Date: Tue, 10 Dec 2019 16:40:43 -0600 Subject: [PATCH 6/6] go mod tidy --- go.mod | 4 ++- go.sum | 107 +++++++++++++++++---------------------------------------- 2 files changed, 35 insertions(+), 76 deletions(-) diff --git a/go.mod b/go.mod index 5ba1468..8e90d44 100644 --- a/go.mod +++ b/go.mod @@ -8,9 +8,11 @@ require ( github.com/AdamSLevy/jsonrpc2/v13 v13.0.1 github.com/AdamSLevy/retry v0.0.0-20191017184328-cce921f261f4 github.com/Factom-Asset-Tokens/base58 v0.0.0-20181227014902-61655c4dd885 - github.com/kr/pretty v0.1.0 // indirect + github.com/btcsuite/btcd v0.20.1-beta // indirect github.com/ethereum/go-ethereum v1.9.7 + github.com/kr/pretty v0.1.0 // indirect github.com/stretchr/testify v1.4.0 + golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 // indirect golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect ) diff --git a/go.sum b/go.sum index ae3bf3e..344e186 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,7 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -crawshaw.io/iox v0.0.0-20181124134642-c51c3df30797/go.mod h1:sXBiorCo8c46JlQV3oXPKINnZ8mcqnye1EkVkqsectk= -crawshaw.io/sqlite v0.1.2/go.mod h1:BZaitnE9BVpocOuCdi/y5XReJMUelG53e/rDSLwSFzY= -crawshaw.io/sqlite v0.1.3-0.20190520153332-66f853b01dfb/go.mod h1:igAO5JulrQ1DbdZdtVq48mnZUBAPOeFzer7VhDWNtW4= github.com/AdamSLevy/go-merkle v0.0.0-20190611101253-ca33344a884d h1:FWutTJGVqBnL4rLgeNaspUYnmnvkXcmDA3QO3rHBGgU= github.com/AdamSLevy/go-merkle v0.0.0-20190611101253-ca33344a884d/go.mod h1:Nw3sh5L40Xs1wno7ndbD/dYWg+vARpBvpX9Zz1YSxbo= github.com/AdamSLevy/jsonrpc2/v12 v12.0.1 h1:cVyqoBa4Qgw8bQj3vCBnZHOX/E+uvPM8TbQPobGwY8Q= github.com/AdamSLevy/jsonrpc2/v12 v12.0.1/go.mod h1:UUmIu8A7Sjw+yI0tIc/iGQHoSu/7loifZ7E/AbjFFcI= -github.com/AdamSLevy/jsonrpc2/v12 v12.0.2-0.20191015223217-9181d6ac9347 h1:bnHpux+c+kROwUL+2nscrUODAa33JQWlViGCBD2W5bg= -github.com/AdamSLevy/jsonrpc2/v12 v12.0.2-0.20191015223217-9181d6ac9347/go.mod h1:UUmIu8A7Sjw+yI0tIc/iGQHoSu/7loifZ7E/AbjFFcI= github.com/AdamSLevy/jsonrpc2/v13 v13.0.1 h1:hQ5rfCFBQrXQNtvP+2mtH6EmsUAEN61ZF1n8UGVNis0= github.com/AdamSLevy/jsonrpc2/v13 v13.0.1/go.mod h1:8QsYqGKdPEim+n/j9KFTYB2tIj250f044Vxh2XRKhP4= github.com/AdamSLevy/retry v0.0.0-20191017184328-cce921f261f4 h1:qTRFsX5Cb/zeePRrKCfLkH4FJpRTP6DbrzPofBWjF5Y= @@ -16,98 +10,61 @@ github.com/Factom-Asset-Tokens/base58 v0.0.0-20181227014902-61655c4dd885 h1:rfy2 github.com/Factom-Asset-Tokens/base58 v0.0.0-20181227014902-61655c4dd885/go.mod h1:RVXsRSp6VzXw5l1uiGazuf3qo23Qk0h1HzMcQk+X4LE= github.com/JohnCGriffin/overflow v0.0.0-20170615021017-4d914c927216 h1:2ZboyJ8vl75fGesnG9NpMTD2DyQI3FzMXy4x752rGF0= github.com/JohnCGriffin/overflow v0.0.0-20170615021017-4d914c927216/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/ethereum/go-ethereum v1.9.7 h1:p4O+z0MGzB7xxngHbplcYNloxkFwGkeComhkzWnq0ig= github.com/ethereum/go-ethereum v1.9.7/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nightlyone/lockfile v0.0.0-20180618180623-0ad87eef1443/go.mod h1:JbxfV1Iifij2yhRjXai0oFrbpxszXHRx1E5RuM26o4Y= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.2.1/go.mod h1:6gapUrK/U1TAN7ciCoNRIdVC5sbdBTUh1DKN0g6uH7E= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=