From 873f0896cabb7256095fb209bd9573814ea6ead6 Mon Sep 17 00:00:00 2001 From: Ekaterina Lebedeva Date: Mon, 27 Jan 2025 19:07:45 +0300 Subject: [PATCH] [#303] user: Make `user.ID` a `[20]byte` array Signed-off-by: Ekaterina Lebedeva --- user/id.go | 74 ++++++++++++++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/user/id.go b/user/id.go index d185992..64727c4 100644 --- a/user/id.go +++ b/user/id.go @@ -12,9 +12,9 @@ import ( "github.com/nspcc-dev/neo-go/pkg/util" ) -const idSize = 25 +const idSizeFull = 25 -var zeroSlice = bytes.Repeat([]byte{0}, idSize) +var zeroSlice = bytes.Repeat([]byte{0}, 20) // ID identifies users of the FrostFS system. // @@ -25,7 +25,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 [20]byte } // ReadFromV2 reads ID from the refs.OwnerID message. Returns an error if @@ -33,22 +33,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,25 +41,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])) + copy(x.w[:], scriptHash.BytesBE()) } // ScriptHash calculates and returns script hash of ID. func (x *ID) ScriptHash() util.Uint160 { - res, _ := util.Uint160DecodeBytesBE(x.w[1:21]) + res, _ := util.Uint160DecodeBytesBE(x.w[:]) return res } @@ -84,14 +61,18 @@ func (x *ID) ScriptHash() util.Uint160 { // // See also Neo3 wallet docs. func (x ID) WalletBytes() []byte { - return x.w + v := make([]byte, idSizeFull) + 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 +82,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 +100,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 bytes.Equal(x.w[:], x2.w[:]) } // IsEmpty returns True, if ID is empty value. func (x ID) IsEmpty() bool { - return bytes.Equal(zeroSlice, x.w) + return bytes.Equal(zeroSlice, x.w[:]) +} + +func (x *ID) setUserID(w []byte) error { + if len(w) != idSizeFull { + return fmt.Errorf("invalid length %d, expected %d", len(w), idSizeFull) + } + + 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 }