diff --git a/pkg/owner/id.go b/pkg/owner/id.go index 4862b67..08971e8 100644 --- a/pkg/owner/id.go +++ b/pkg/owner/id.go @@ -3,12 +3,18 @@ package owner import ( "github.com/mr-tron/base58" "github.com/nspcc-dev/neo-go/pkg/encoding/address" + "github.com/nspcc-dev/neofs-api-go/internal" "github.com/nspcc-dev/neofs-api-go/v2/refs" + "github.com/pkg/errors" ) // ID represents v2-compatible owner identifier. type ID refs.OwnerID +// ErrBadID should be returned when bytes slice isn't Owner.ID size (NEO3WalletSize). +// Notice: if byte slice changed, please, replace error message. +const ErrBadID = internal.Error("owner.ID should be 25 bytes length") + // NewIDFromV2 wraps v2 OwnerID message to ID. func NewIDFromV2(idV2 *refs.OwnerID) *ID { return (*ID)(idV2) @@ -51,3 +57,17 @@ func NewIDFromNeo3Wallet(v *NEO3Wallet) *ID { return id } + +// Parse converts base58 string representation into ID. +func (id *ID) Parse(s string) error { + data, err := base58.Decode(s) + if err != nil { + return errors.Wrap(err, "could not parse owner.ID from string") + } else if len(data) != NEO3WalletSize { + return ErrBadID + } + + (*refs.OwnerID)(id).SetValue(data) + + return nil +} diff --git a/pkg/owner/id_test.go b/pkg/owner/id_test.go index 581d9f2..a36324f 100644 --- a/pkg/owner/id_test.go +++ b/pkg/owner/id_test.go @@ -2,8 +2,10 @@ package owner import ( "crypto/rand" + "strconv" "testing" + "github.com/mr-tron/base58" "github.com/nspcc-dev/neofs-crypto/test" "github.com/stretchr/testify/require" ) @@ -30,3 +32,34 @@ func TestNewIDFromNeo3Wallet(t *testing.T) { id := NewIDFromNeo3Wallet(wallet) require.Equal(t, id.ToV2().GetValue(), wallet.Bytes()) } + +func TestID_Parse(t *testing.T) { + t.Run("should parse successful", func(t *testing.T) { + for i := 0; i < 10; i++ { + j := i + t.Run(strconv.Itoa(j), func(t *testing.T) { + wallet, err := NEO3WalletFromPublicKey(&test.DecodeKey(j).PublicKey) + require.NoError(t, err) + + eid := NewIDFromNeo3Wallet(wallet) + aid := NewID() + + require.NoError(t, aid.Parse(eid.String())) + require.Equal(t, eid, aid) + }) + } + }) + + t.Run("should failure on parse", func(t *testing.T) { + for i := 0; i < 10; i++ { + j := i + t.Run(strconv.Itoa(j), func(t *testing.T) { + cs := []byte{1, 2, 3, 4, 5, byte(j)} + str := base58.Encode(cs) + cid := NewID() + + require.EqualError(t, cid.Parse(str), ErrBadID.Error()) + }) + } + }) +}