Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 136 additions & 4 deletions accounts/abi/unpack.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,143 @@ func ReadFixedBytes(t Type, word []byte) (interface{}, error) {
if t.T != FixedBytesTy {
return nil, errors.New("abi: invalid type in call to make fixed byte array")
}
// convert
array := reflect.New(t.GetType()).Elem()

reflect.Copy(array, reflect.ValueOf(word[0:t.Size]))
return array.Interface(), nil
if t.Size < 1 || t.Size > 32 {
return nil, errors.New("abi: invalid size")
}

switch t.Size {
case 1:
var arr [1]byte
copy(arr[:], word[:1])
return arr, nil
case 2:
var arr [2]byte
copy(arr[:], word[:2])
return arr, nil
case 3:
var arr [3]byte
copy(arr[:], word[:3])
return arr, nil
case 4:
var arr [4]byte
copy(arr[:], word[:4])
return arr, nil
case 5:
var arr [5]byte
copy(arr[:], word[:5])
return arr, nil
case 6:
var arr [6]byte
copy(arr[:], word[:6])
return arr, nil
case 7:
var arr [7]byte
copy(arr[:], word[:7])
return arr, nil
case 8:
var arr [8]byte
copy(arr[:], word[:8])
return arr, nil
case 9:
var arr [9]byte
copy(arr[:], word[:9])
return arr, nil
case 10:
var arr [10]byte
copy(arr[:], word[:10])
return arr, nil
case 11:
var arr [11]byte
copy(arr[:], word[:11])
return arr, nil
case 12:
var arr [12]byte
copy(arr[:], word[:12])
return arr, nil
case 13:
var arr [13]byte
copy(arr[:], word[:13])
return arr, nil
case 14:
var arr [14]byte
copy(arr[:], word[:14])
return arr, nil
case 15:
var arr [15]byte
copy(arr[:], word[:15])
return arr, nil
case 16:
var arr [16]byte
copy(arr[:], word[:16])
return arr, nil
case 17:
var arr [17]byte
copy(arr[:], word[:17])
return arr, nil
case 18:
var arr [18]byte
copy(arr[:], word[:18])
return arr, nil
case 19:
var arr [19]byte
copy(arr[:], word[:19])
return arr, nil
case 20:
var arr [20]byte
copy(arr[:], word[:20])
return arr, nil
case 21:
var arr [21]byte
copy(arr[:], word[:21])
return arr, nil
case 22:
var arr [22]byte
copy(arr[:], word[:22])
return arr, nil
case 23:
var arr [23]byte
copy(arr[:], word[:23])
return arr, nil
case 24:
var arr [24]byte
copy(arr[:], word[:24])
return arr, nil
case 25:
var arr [25]byte
copy(arr[:], word[:25])
return arr, nil
case 26:
var arr [26]byte
copy(arr[:], word[:26])
return arr, nil
case 27:
var arr [27]byte
copy(arr[:], word[:27])
return arr, nil
case 28:
var arr [28]byte
copy(arr[:], word[:28])
return arr, nil
case 29:
var arr [29]byte
copy(arr[:], word[:29])
return arr, nil
case 30:
var arr [30]byte
copy(arr[:], word[:30])
return arr, nil
case 31:
var arr [31]byte
copy(arr[:], word[:31])
return arr, nil
case 32:
var arr [32]byte
copy(arr[:], word[:32])
return arr, nil
default:
return nil, errors.New("unsupported size")
}
}

// forEachUnpack iteratively unpack elements.
Expand Down
187 changes: 187 additions & 0 deletions accounts/abi/unpack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1162,3 +1162,190 @@ func TestPackAndUnpackIncompatibleNumber(t *testing.T) {
}
}
}

func TestReadFixedBytes(t *testing.T) {
word := make([]byte, 33)
for i := range word {
word[i] = byte(i)
}

tests := []struct {
name string
tType Type
word []byte
wantErr bool
}{
{"size0", Type{T: FixedBytesTy, Size: 0}, word, true},
{"size33", Type{T: FixedBytesTy, Size: 33}, word, true},
}
for size := 1; size <= 32; size++ {
tests = append(tests, struct {
name string
tType Type
word []byte
wantErr bool
}{
name: fmt.Sprintf("size_%d", size),
tType: Type{T: FixedBytesTy, Size: size},
word: word,
wantErr: false,
})
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := ReadFixedBytes(tt.tType, tt.word)
if tt.wantErr {
if err == nil {
t.Errorf("expected error, got nil")
}
return
}
if err != nil {
t.Errorf("unexpected error: %v", err)
return
}

switch arr := got.(type) {
case [1]byte:
if !bytes.Equal(arr[:], word[:1]) {
t.Errorf("data mismatch")
}
case [2]byte:
if !bytes.Equal(arr[:], word[:2]) {
t.Errorf("data mismatch")
}
case [3]byte:
if !bytes.Equal(arr[:], word[:3]) {
t.Errorf("data mismatch")
}
case [4]byte:
if !bytes.Equal(arr[:], word[:4]) {
t.Errorf("data mismatch")
}
case [5]byte:
if !bytes.Equal(arr[:], word[:5]) {
t.Errorf("data mismatch")
}
case [6]byte:
if !bytes.Equal(arr[:], word[:6]) {
t.Errorf("data mismatch")
}
case [7]byte:
if !bytes.Equal(arr[:], word[:7]) {
t.Errorf("data mismatch")
}
case [8]byte:
if !bytes.Equal(arr[:], word[:8]) {
t.Errorf("data mismatch")
}
case [9]byte:
if !bytes.Equal(arr[:], word[:9]) {
t.Errorf("data mismatch")
}
case [10]byte:
if !bytes.Equal(arr[:], word[:10]) {
t.Errorf("data mismatch")
}
case [11]byte:
if !bytes.Equal(arr[:], word[:11]) {
t.Errorf("data mismatch")
}
case [12]byte:
if !bytes.Equal(arr[:], word[:12]) {
t.Errorf("data mismatch")
}
case [13]byte:
if !bytes.Equal(arr[:], word[:13]) {
t.Errorf("data mismatch")
}
case [14]byte:
if !bytes.Equal(arr[:], word[:14]) {
t.Errorf("data mismatch")
}
case [15]byte:
if !bytes.Equal(arr[:], word[:15]) {
t.Errorf("data mismatch")
}
case [16]byte:
if !bytes.Equal(arr[:], word[:16]) {
t.Errorf("data mismatch")
}
case [17]byte:
if !bytes.Equal(arr[:], word[:17]) {
t.Errorf("data mismatch")
}
case [18]byte:
if !bytes.Equal(arr[:], word[:18]) {
t.Errorf("data mismatch")
}
case [19]byte:
if !bytes.Equal(arr[:], word[:19]) {
t.Errorf("data mismatch")
}
case [20]byte:
if !bytes.Equal(arr[:], word[:20]) {
t.Errorf("data mismatch")
}
case [21]byte:
if !bytes.Equal(arr[:], word[:21]) {
t.Errorf("data mismatch")
}
case [22]byte:
if !bytes.Equal(arr[:], word[:22]) {
t.Errorf("data mismatch")
}
case [23]byte:
if !bytes.Equal(arr[:], word[:23]) {
t.Errorf("data mismatch")
}
case [24]byte:
if !bytes.Equal(arr[:], word[:24]) {
t.Errorf("data mismatch")
}
case [25]byte:
if !bytes.Equal(arr[:], word[:25]) {
t.Errorf("data mismatch")
}
case [26]byte:
if !bytes.Equal(arr[:], word[:26]) {
t.Errorf("data mismatch")
}
case [27]byte:
if !bytes.Equal(arr[:], word[:27]) {
t.Errorf("data mismatch")
}
case [28]byte:
if !bytes.Equal(arr[:], word[:28]) {
t.Errorf("data mismatch")
}
case [29]byte:
if !bytes.Equal(arr[:], word[:29]) {
t.Errorf("data mismatch")
}
case [30]byte:
if !bytes.Equal(arr[:], word[:30]) {
t.Errorf("data mismatch")
}
case [31]byte:
if !bytes.Equal(arr[:], word[:31]) {
t.Errorf("data mismatch")
}
case [32]byte:
if !bytes.Equal(arr[:], word[:32]) {
t.Errorf("data mismatch")
}
default:
t.Errorf("unexpected type %T", got)
}
})
}
}

func BenchmarkReadFixedBytes(b *testing.B) {
t := Type{T: FixedBytesTy, Size: 32}
word := make([]byte, 32)
for i := 0; i < b.N; i++ {
_, _ = ReadFixedBytes(t, word)
}
}