diff --git a/pkg/encoding/bigint/bigint.go b/pkg/encoding/bigint/bigint.go index 15d6df77b..aa189ca0a 100644 --- a/pkg/encoding/bigint/bigint.go +++ b/pkg/encoding/bigint/bigint.go @@ -4,6 +4,8 @@ import ( "encoding/binary" "math/big" "math/bits" + + "github.com/nspcc-dev/neo-go/pkg/util" ) const ( @@ -13,6 +15,12 @@ const ( wordSizeBytes = bits.UintSize / 8 ) +// FromBytesUnsigned converts data in little-endian format to an unsigned integer. +func FromBytesUnsigned(data []byte) *big.Int { + bs := util.ArrayReverse(data) + return new(big.Int).SetBytes(bs) +} + // FromBytes converts data in little-endian format to // an integer. func FromBytes(data []byte) *big.Int { diff --git a/pkg/encoding/bigint/bigint_test.go b/pkg/encoding/bigint/bigint_test.go index bb8c2207c..287582670 100644 --- a/pkg/encoding/bigint/bigint_test.go +++ b/pkg/encoding/bigint/bigint_test.go @@ -122,6 +122,31 @@ func TestBytesToInt(t *testing.T) { }) } +var unsignedCases = []struct { + number int64 + buf []byte +}{ + {0xff00000000, []byte{0x00, 0x00, 0x00, 0x00, 0xff}}, + {0xfd00000000, []byte{0x00, 0x00, 0x00, 0x00, 0xfd}}, + {0x8000000000, []byte{0x00, 0x00, 0x00, 0x00, 0x80}}, + {0xff0200000000, []byte{0x00, 0x00, 0x00, 0x00, 0x02, 0xff}}, + {0xff0100000000, []byte{0x00, 0x00, 0x00, 0x00, 0x01, 0xff}}, + {0xff0100000000, []byte{0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x00}}, +} + +func TestBytesToUnsigned(t *testing.T) { + for _, tc := range testCases { + if tc.number > 0 { + num := FromBytesUnsigned(tc.buf) + assert.Equal(t, tc.number, num.Int64(), "expected %x, got %x", tc.number, num.Int64()) + } + } + for _, tc := range unsignedCases { + num := FromBytesUnsigned(tc.buf) + assert.Equal(t, tc.number, num.Int64(), "expected %x, got %x", tc.number, num.Int64()) + } +} + func TestEquivalentRepresentations(t *testing.T) { for _, tc := range testCases { buf := tc.buf