Skip to content

Commit 9e5c48c

Browse files
committed
chore: Added PointerAddress class to decode a pointer address
1 parent 8c94e69 commit 9e5c48c

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package com.bloxbean.cardano.client.address;
2+
3+
import com.bloxbean.cardano.client.exception.AddressRuntimeException;
4+
import com.bloxbean.cardano.client.util.Tuple;
5+
6+
import java.util.Arrays;
7+
8+
/**
9+
* PointerAddress class represents Shelley Pointer address. This class is useful to decode Pointer address and get the Pointer
10+
*/
11+
public class PointerAddress extends Address {
12+
private Pointer pointer;
13+
14+
public PointerAddress(String prefix, byte[] bytes) {
15+
super(prefix, bytes);
16+
17+
if (getAddressType() != AddressType.Ptr)
18+
throw new AddressRuntimeException("Invalid address type. Expected Pointer address type");
19+
20+
decodePointer();
21+
}
22+
23+
public PointerAddress(String address) {
24+
super(address);
25+
26+
if (getAddressType() != AddressType.Ptr)
27+
throw new AddressRuntimeException("Invalid address type. Expected Pointer address type");
28+
29+
decodePointer();
30+
}
31+
32+
public PointerAddress(byte[] addressBytes) {
33+
super(addressBytes);
34+
35+
if (getAddressType() != AddressType.Ptr)
36+
throw new AddressRuntimeException("Invalid address type. Expected Pointer address type");
37+
38+
decodePointer();
39+
}
40+
41+
private void decodePointer() {
42+
byte[] pointerBytes = getDelegationCredentialHash()
43+
.orElseThrow(() -> new AddressRuntimeException("Delegation credential hash not found"));
44+
45+
int index = 0;
46+
Tuple<Long, Integer> slot = variableNatDecode(pointerBytes);
47+
index += slot._2;
48+
Tuple<Long, Integer> txIndex = variableNatDecode(getSubBytes(pointerBytes, index));
49+
index += txIndex._2;
50+
Tuple<Long, Integer> certIndex = variableNatDecode(getSubBytes(pointerBytes, index));
51+
52+
pointer = new Pointer(slot._1, txIndex._1.intValue(), certIndex._1.intValue());
53+
}
54+
55+
private Tuple<Long, Integer> variableNatDecode(byte[] raw) {
56+
long output = 0;
57+
int bytesRead = 0;
58+
59+
for (byte rbyte : raw) {
60+
output = (output << 7) | (rbyte & 0x7F);
61+
bytesRead++;
62+
63+
if ((rbyte & 0x80) == 0) {
64+
return new Tuple<>(output, bytesRead);
65+
}
66+
}
67+
68+
throw new IllegalArgumentException("Invalid variable nat encoding. Unexpected bytes");
69+
}
70+
71+
// Get subarray from startPosition to the end of the array
72+
private byte[] getSubBytes(byte[] array, int startPosition) {
73+
// Validate startPosition
74+
if (startPosition < 0 || startPosition > array.length) {
75+
throw new IllegalArgumentException("Invalid start position");
76+
}
77+
78+
return Arrays.copyOfRange(array, startPosition, array.length);
79+
}
80+
81+
public Pointer getPointer() {
82+
return pointer;
83+
}
84+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.bloxbean.cardano.client.address;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static org.junit.jupiter.api.Assertions.*;
6+
7+
class PointerAddressTest {
8+
9+
@Test
10+
void getPointer() {
11+
PointerAddress pointerAddress = new PointerAddress("addr1gx2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer5ph3wczvf2w8lunk");
12+
assertEquals(new Pointer(24157, 177, 42), pointerAddress.getPointer());
13+
}
14+
15+
@Test
16+
void getPointer2() {
17+
PointerAddress pointerAddress = new PointerAddress("addr_test1gz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzerspqgpsqe70et");
18+
assertEquals(new Pointer(1, 2, 3), pointerAddress.getPointer());
19+
}
20+
21+
@Test
22+
void getPointer3() {
23+
PointerAddress pointerAddress = new PointerAddress("addr128phkx6acpnf78fuvxn0mkew3l0fd058hzquvz7w36x4gtupnz75xxcrtw79hu");
24+
assertEquals(new Pointer(2498243, 27, 3), pointerAddress.getPointer());
25+
}
26+
}

0 commit comments

Comments
 (0)