Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensuring HexAddress is Wrapped in String format and as HexAddress #278

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
43 changes: 40 additions & 3 deletions pkg/types/hex_address.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,51 @@

package types

import "gopkg.in/yaml.v3"
import (
"encoding/hex"

"github.com/hyperledger/firefly-signer/pkg/ethtypes"
"gopkg.in/yaml.v3"
)

type HexAddress string

type HexWrapper struct {
addrStr *ethtypes.Address0xHex
}

// WrapHexAddress wraps a hex address as HexAddress
func (h *HexWrapper) WrapHexAddress(addr [20]byte) (string, error) {
hexStr := "0x" + hex.EncodeToString(addr[:])
// Initialize addrStr before using it
h.addrStr = new(ethtypes.Address0xHex)
if err := h.addrStr.SetString(hexStr); err != nil {
return "", err
}
return hexStr, nil
}

type HexType struct {
HexValue HexAddress `yaml:"hexvalue"`
HexWrap HexWrapper
}

// Explicitly quote hex addresses so that they are interpreted as string (not int)
func (h HexAddress) MarshalYAML() (interface{}, error) {
func (ht *HexType) MarshalYAML() (interface{}, error) {
//convert to byte type
hexBytes, err := hex.DecodeString(string(ht.HexValue[2:]))
if err != nil {
return nil, err
}
//copy bytes to fixed array
var hexArray [20]byte
copy(hexArray[:], hexBytes)
hexAddr, err := ht.HexWrap.WrapHexAddress([20]byte(hexArray))
if err != nil {
return nil, err
}
return yaml.Node{
Value: string(h),
Value: hexAddr,
Kind: yaml.ScalarNode,
Style: yaml.DoubleQuotedStyle,
}, nil
Expand Down
122 changes: 122 additions & 0 deletions pkg/types/hex_address_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package types

import (
"encoding/hex"
"testing"

"github.com/hyperledger/firefly-signer/pkg/ethtypes"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
)

func TestWrapHexAddress(t *testing.T) {
tests := []struct {
Name string
Hexvalue string `yaml:"hexvalue"`
}{
{
Name: "Case 16-Bits",
Hexvalue: "0x1f2a000000000000000000000000000000000000",
},
{
Name: "Case 24-Bits",
Hexvalue: "0x123abc0000000000000000000000000000000000",
},
{
Name: "Case 32-Bits",
Hexvalue: "0xabcdeffedcba9876543210abcdeffedc00000000",
},
{
Name: "Case 64-Bits",
Hexvalue: "0x1234567890abcdef012345670000000000000000",
},
{
Name: "Case 65-Bits",
Hexvalue: "0x1234567890abcdef0123456789abcdef6789abcd",
},
{
Name: "Case 128-Bits",
Hexvalue: "0x1234567890abcdef0123456789abcdef00000000",
},
{
Name: "Case 152-Bits",
Hexvalue: "0x549b5f43a40e1a0522864a004cfff2b0ca473a65",
},
}
for _, tc := range tests {
t.Run(tc.Name, func(t *testing.T) {
var hexType HexType
//[2:] is used to skip the "0x" prefix before decoding the hexadecimal string into a byte slice.
//because x isnt a valid hexadecimal digit
hexBytes, err := hex.DecodeString(tc.Hexvalue[2:])
if err != nil {
t.Log("Unable to decode values:", err)
}
if len(hexBytes) != 20 {
t.Fatalf("expected 20 bytes, got %d bytes", len(hexBytes))
}
// Copy bytes to a fixed-size array
var hexArray [20]byte
copy(hexArray[:], hexBytes)
//encodes the decoded values to hexadecimal and returns string
//Ethereum convention for representing hexadecimal values, the prefix must have "0x"
result, err := hexType.HexWrap.WrapHexAddress([20]byte(hexArray))
if err != nil {
t.Log("error in generating result", err)
t.Fail()
return
}
assert.Equal(t, tc.Hexvalue, result)
})

}
}

type HexAddr struct {
ethtypes.Address0xHex
}

func TestYamlMarshal(t *testing.T) {
testAddress := []struct {
Name string
Hexvalue string `yaml:"hexvalue"`
}{
{
Name: "Case 16-Bits",
Hexvalue: "0x1f2a000000000000000000000000000000000000",
},
{
Name: "Case 24-Bits",
Hexvalue: "0x123abc0000000000000000000000000000000000",
},
{
Name: "Case 32-Bits",
Hexvalue: "0xabcdeffedcba9876543210abcdeffedc00000000",
},
{
Name: "Case 64-Bits",
Hexvalue: "0x1234567890abcdef012345670000000000000000",
},
}
for _, tc := range testAddress {
t.Run(tc.Name, func(t *testing.T) {
var hexType HexType
hexbyte, err := hex.DecodeString(tc.Hexvalue[2:])
if err != nil {
t.Log("unable to decode values")
}
var hexArray [20]byte
copy(hexArray[:], hexbyte)
YamlHex, err := hexType.HexWrap.WrapHexAddress([20]byte(hexArray))
if err != nil {
t.Log("unable to generate yaml string")
}

YamlNode := yaml.Node{
Value: YamlHex,
}
assert.YAMLEq(t, YamlNode.Value, YamlHex)
})

}
}
Loading