Skip to content

Commit

Permalink
Add hex package (#291)
Browse files Browse the repository at this point in the history
  • Loading branch information
dimriou authored Dec 19, 2023
1 parent bd451bb commit be61f25
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 9 deletions.
55 changes: 55 additions & 0 deletions pkg/utils/hex/hex.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package hex

import (
"encoding/hex"
"errors"
"fmt"
"math/big"
"strings"
)

// EnsurePrefix adds the prefix (0x) to a given hex string.
func EnsurePrefix(str string) string {
if !strings.HasPrefix(str, "0x") {
str = "0x" + str
}
return str
}

// ParseBig parses the given hex string and returns error if it is invalid.
func ParseBig(s string) (*big.Int, error) {
n, ok := new(big.Int).SetString(s, 16)
if !ok {
return nil, fmt.Errorf(`failed to convert "%s" as hex to big.Int`, s)
}
return n, nil
}

// TrimPrefix removes the prefix (0x) of a given hex string.
func TrimPrefix(str string) string {
if HasPrefix(str) {
return str[2:]
}
return str
}

// HasPrefix returns true if the string starts with 0x.
func HasPrefix(str string) bool {
return len(str) >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')
}

// DecodeString parses the given hex string to bytes,
// it can return error if the hex string is invalid.
// Follows the semantic of ethereum's FromHex.
func DecodeString(s string) (b []byte, err error) {
if !HasPrefix(s) {
err = errors.New("hex string must have 0x prefix")
} else {
s = s[2:]
if len(s)%2 == 1 {
s = "0" + s
}
b, err = hex.DecodeString(s)
}
return
}
103 changes: 103 additions & 0 deletions pkg/utils/hex/hex_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package hex_test

import (
"testing"

"github.com/smartcontractkit/chainlink-common/pkg/utils/hex"
"github.com/stretchr/testify/assert"
)

func TestParseBig(t *testing.T) {
t.Parallel()

t.Run("parses successfully", func(t *testing.T) {
t.Parallel()

_, err := hex.ParseBig("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F")
assert.NoError(t, err)
})

t.Run("returns error", func(t *testing.T) {
t.Parallel()

_, err := hex.ParseBig("0xabc")
assert.Error(t, err)
})
}

func TestTrimPrefix(t *testing.T) {
t.Parallel()

t.Run("trims prefix", func(t *testing.T) {
t.Parallel()

s := hex.TrimPrefix("0xabc")
assert.Equal(t, "abc", s)
})

t.Run("returns the same string if it doesn't have prefix", func(t *testing.T) {
t.Parallel()

s := hex.TrimPrefix("defg")
assert.Equal(t, "defg", s)
})
}

func TestHasPrefix(t *testing.T) {
t.Parallel()

t.Run("has prefix", func(t *testing.T) {
t.Parallel()

r := hex.HasPrefix("0xabc")
assert.True(t, r)
})

t.Run("doesn't have prefix", func(t *testing.T) {
t.Parallel()

r := hex.HasPrefix("abc")
assert.False(t, r)
})

t.Run("has 0x suffix", func(t *testing.T) {
t.Parallel()

r := hex.HasPrefix("abc0x")
assert.False(t, r)
})
}

func TestDecodeString(t *testing.T) {
t.Parallel()

t.Run("0x prefix missing", func(t *testing.T) {
t.Parallel()

_, err := hex.DecodeString("abcd")
assert.Error(t, err)
})

t.Run("wrong hex characters", func(t *testing.T) {
t.Parallel()

_, err := hex.DecodeString("0xabcdzzz")
assert.Error(t, err)
})

t.Run("valid hex string", func(t *testing.T) {
t.Parallel()

b, err := hex.DecodeString("0x1234")
assert.NoError(t, err)
assert.Equal(t, []byte{0x12, 0x34}, b)
})

t.Run("prepend odd length with zero", func(t *testing.T) {
t.Parallel()

b, err := hex.DecodeString("0x123")
assert.NoError(t, err)
assert.Equal(t, []byte{0x1, 0x23}, b)
})
}
9 changes: 0 additions & 9 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"math"
mrand "math/rand"
"strings"
"time"

"github.com/smartcontractkit/chainlink-common/pkg/services"
Expand Down Expand Up @@ -50,11 +49,3 @@ func IsZero[C comparable](val C) bool {
var zero C
return zero == val
}

// EnsureHexPrefix adds the prefix (0x) to a given hex string.
func EnsureHexPrefix(str string) string {
if !strings.HasPrefix(str, "0x") {
str = "0x" + str
}
return str
}

0 comments on commit be61f25

Please sign in to comment.