Skip to content

Commit 4e3fce0

Browse files
authoredMar 11, 2025
Merge pull request #39 from dkatzan/feature/fix-address-decoding
Fix decoding stacks address when hash160 has leading zeroes
2 parents 006d15e + 4fc0e6f commit 4e3fce0

File tree

2 files changed

+44
-19
lines changed

2 files changed

+44
-19
lines changed
 

‎pkg/c32/c32.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,19 @@ func C32Decode(input string) ([]byte, error) {
6262

6363
bytes := bi.Bytes()
6464

65-
for len(bytes) > 0 && bytes[0] == 0 {
66-
bytes = bytes[1:]
65+
leadingZeros := 0
66+
for _, char := range input {
67+
if char == '0' {
68+
leadingZeros++
69+
} else {
70+
break
71+
}
6772
}
6873

69-
return bytes, nil
74+
decoded := make([]byte, leadingZeros+len(bytes))
75+
copy(decoded[leadingZeros:], bytes)
76+
77+
return decoded, nil
7078
}
7179

7280
func DecodeC32Address(address string) (version byte, hash160 [20]byte, err error) {

‎pkg/c32/c32_test.go

+33-16
Original file line numberDiff line numberDiff line change
@@ -90,26 +90,43 @@ func TestDecodeC32Address(t *testing.T) {
9090
}
9191

9292
func TestC32CheckEncodeDecode(t *testing.T) {
93-
hash160, err := hex.DecodeString("1a2b3c4d5e6f7081920a1b2c3d4e5f60718293a4")
94-
if err != nil {
95-
t.Fatalf("Failed to decode hash160: %v", err)
93+
tests := []struct {
94+
name string
95+
hash160 string
96+
}{
97+
{
98+
name: "Sanity",
99+
hash160: "1a2b3c4d5e6f7081920a1b2c3d4e5f60718293a4",
100+
},
101+
{
102+
name: "With leading zeros",
103+
hash160: "00aa83fa8c13e363bcd190e22a8be3344c9fa416",
104+
},
96105
}
106+
for _, tt := range tests {
107+
t.Run(tt.name, func(t *testing.T) {
108+
hash160, err := hex.DecodeString(tt.hash160)
109+
if err != nil {
110+
t.Fatalf("Failed to decode hash160: %v", err)
111+
}
97112

98-
address, err := SerializeAddress(stacks.AddressVersionMainnetSingleSig, hash160)
99-
if err != nil {
100-
t.Fatalf("Failed to serialize address: %v", err)
101-
}
113+
address, err := SerializeAddress(stacks.AddressVersionMainnetSingleSig, hash160)
114+
if err != nil {
115+
t.Fatalf("Failed to serialize address: %v", err)
116+
}
102117

103-
version, decodedHash, err := DeserializeAddress(address)
104-
if err != nil {
105-
t.Fatalf("Failed to deserialize address: %v", err)
106-
}
118+
version, decodedHash, err := DeserializeAddress(address)
119+
if err != nil {
120+
t.Fatalf("Failed to deserialize address: %v", err)
121+
}
107122

108-
if version != stacks.AddressVersionMainnetSingleSig {
109-
t.Errorf("Expected version %d, got %d", stacks.AddressVersionMainnetSingleSig, version)
110-
}
123+
if version != stacks.AddressVersionMainnetSingleSig {
124+
t.Errorf("Expected version %d, got %d", stacks.AddressVersionMainnetSingleSig, version)
125+
}
111126

112-
if string(decodedHash) != string(hash160) {
113-
t.Errorf("Decoded hash160 does not match original")
127+
if string(decodedHash) != string(hash160) {
128+
t.Errorf("Decoded hash160 does not match original")
129+
}
130+
})
114131
}
115132
}

0 commit comments

Comments
 (0)