From 761d087b93bcf0bfb2775fd4401f2dbc32625e86 Mon Sep 17 00:00:00 2001 From: Ekaterina Lebedeva Date: Mon, 27 Jan 2025 12:00:58 +0300 Subject: [PATCH 1/2] [#302] user: Make `ScriptHash` return no error Signed-off-by: Ekaterina Lebedeva --- user/id.go | 5 +++-- user/id_test.go | 3 +-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/user/id.go b/user/id.go index 2d64d43..d185992 100644 --- a/user/id.go +++ b/user/id.go @@ -73,8 +73,9 @@ func (x *ID) SetScriptHash(scriptHash util.Uint160) { } // ScriptHash calculates and returns script hash of ID. -func (x *ID) ScriptHash() (util.Uint160, error) { - return util.Uint160DecodeBytesBE(x.w[1:21]) +func (x *ID) ScriptHash() util.Uint160 { + res, _ := util.Uint160DecodeBytesBE(x.w[1:21]) + return res } // WalletBytes returns FrostFS user ID as Neo3 wallet address in a binary format. diff --git a/user/id_test.go b/user/id_test.go index afeb746..c517dc5 100644 --- a/user/id_test.go +++ b/user/id_test.go @@ -51,8 +51,7 @@ func TestID_SetScriptHash(t *testing.T) { func TestID_ScriptHash(t *testing.T) { userID := usertest.ID() - scriptHash, err := userID.ScriptHash() - require.NoError(t, err) + scriptHash := userID.ScriptHash() ownerAddress := userID.EncodeToString() decodedScriptHash, err := address.StringToUint160(ownerAddress) -- 2.45.3 From 00cebd297f8ed490e014f485412acbd75b5a07a6 Mon Sep 17 00:00:00 2001 From: Ekaterina Lebedeva Date: Mon, 27 Jan 2025 19:07:45 +0300 Subject: [PATCH 2/2] [#303] user: Make `user.ID` a `util.Uint160` Signed-off-by: Ekaterina Lebedeva --- user/id.go | 76 +++++++++++++++++++++++++----------------------------- 1 file changed, 35 insertions(+), 41 deletions(-) diff --git a/user/id.go b/user/id.go index d185992..c8e2d14 100644 --- a/user/id.go +++ b/user/id.go @@ -12,9 +12,8 @@ import ( "github.com/nspcc-dev/neo-go/pkg/util" ) -const idSize = 25 - -var zeroSlice = bytes.Repeat([]byte{0}, idSize) +// idFullSize is the size of ID in bytes, including prefix and checksum. +const idFullSize = util.Uint160Size + 5 // ID identifies users of the FrostFS system. // @@ -25,7 +24,7 @@ var zeroSlice = bytes.Repeat([]byte{0}, idSize) // so it MUST be initialized using some modifying function (e.g. SetScriptHash, // IDFromKey, etc.). type ID struct { - w []byte + w util.Uint160 } // ReadFromV2 reads ID from the refs.OwnerID message. Returns an error if @@ -33,22 +32,7 @@ type ID struct { // // See also WriteToV2. func (x *ID) ReadFromV2(m refs.OwnerID) error { - w := m.GetValue() - if len(w) != idSize { - return fmt.Errorf("invalid length %d, expected %d", len(w), idSize) - } - - if w[0] != address.NEO3Prefix { - return fmt.Errorf("invalid prefix byte 0x%X, expected 0x%X", w[0], address.NEO3Prefix) - } - - if !bytes.Equal(w[21:], hash.Checksum(w[:21])) { - return errors.New("checksum mismatch") - } - - x.w = w - - return nil + return x.setUserID(m.GetValue()) } // WriteToV2 writes ID to the refs.OwnerID message. @@ -56,26 +40,17 @@ func (x *ID) ReadFromV2(m refs.OwnerID) error { // // See also ReadFromV2. func (x ID) WriteToV2(m *refs.OwnerID) { - m.SetValue(x.w) + m.SetValue(x.WalletBytes()) } // SetScriptHash forms user ID from wallet address scripthash. func (x *ID) SetScriptHash(scriptHash util.Uint160) { - if cap(x.w) < idSize { - x.w = make([]byte, idSize) - } else if len(x.w) < idSize { - x.w = x.w[:idSize] - } - - x.w[0] = address.Prefix - copy(x.w[1:], scriptHash.BytesBE()) - copy(x.w[21:], hash.Checksum(x.w[:21])) + x.w = scriptHash } // ScriptHash calculates and returns script hash of ID. func (x *ID) ScriptHash() util.Uint160 { - res, _ := util.Uint160DecodeBytesBE(x.w[1:21]) - return res + return x.w } // WalletBytes returns FrostFS user ID as Neo3 wallet address in a binary format. @@ -84,14 +59,18 @@ func (x *ID) ScriptHash() util.Uint160 { // // See also Neo3 wallet docs. func (x ID) WalletBytes() []byte { - return x.w + v := make([]byte, idFullSize) + v[0] = address.Prefix + copy(v[1:], x.w[:]) + copy(v[21:], hash.Checksum(v[:21])) + return v } // EncodeToString encodes ID into FrostFS API V2 protocol string. // // See also DecodeString. func (x ID) EncodeToString() string { - return base58.Encode(x.w) + return base58.Encode(x.WalletBytes()) } // DecodeString decodes FrostFS API V2 protocol string. Returns an error @@ -101,14 +80,11 @@ func (x ID) EncodeToString() string { // // See also EncodeToString. func (x *ID) DecodeString(s string) error { - var err error - - x.w, err = base58.Decode(s) + w, err := base58.Decode(s) if err != nil { return fmt.Errorf("decode base58: %w", err) } - - return nil + return x.setUserID(w) } // String implements fmt.Stringer. @@ -122,10 +98,28 @@ func (x ID) String() string { // Equals defines a comparison relation between two ID instances. func (x ID) Equals(x2 ID) bool { - return bytes.Equal(x.w, x2.w) + return x.w == x2.w } // IsEmpty returns True, if ID is empty value. func (x ID) IsEmpty() bool { - return bytes.Equal(zeroSlice, x.w) + return x.w == util.Uint160{} +} + +func (x *ID) setUserID(w []byte) error { + if len(w) != idFullSize { + return fmt.Errorf("invalid length %d, expected %d", len(w), idFullSize) + } + + if w[0] != address.NEO3Prefix { + return fmt.Errorf("invalid prefix byte 0x%X, expected 0x%X", w[0], address.NEO3Prefix) + } + + if !bytes.Equal(w[21:], hash.Checksum(w[:21])) { + return errors.New("checksum mismatch") + } + + copy(x.w[:], w[1:21]) + + return nil } -- 2.45.3