Skip to content

Commit

Permalink
chore: Added PointerAddress class to decode a pointer address
Browse files Browse the repository at this point in the history
  • Loading branch information
satran004 committed Feb 16, 2024
1 parent 8c94e69 commit 9e5c48c
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.bloxbean.cardano.client.address;

import com.bloxbean.cardano.client.exception.AddressRuntimeException;
import com.bloxbean.cardano.client.util.Tuple;

import java.util.Arrays;

/**
* PointerAddress class represents Shelley Pointer address. This class is useful to decode Pointer address and get the Pointer
*/
public class PointerAddress extends Address {
private Pointer pointer;

public PointerAddress(String prefix, byte[] bytes) {
super(prefix, bytes);

if (getAddressType() != AddressType.Ptr)
throw new AddressRuntimeException("Invalid address type. Expected Pointer address type");

decodePointer();
}

public PointerAddress(String address) {
super(address);

if (getAddressType() != AddressType.Ptr)
throw new AddressRuntimeException("Invalid address type. Expected Pointer address type");

decodePointer();
}

public PointerAddress(byte[] addressBytes) {
super(addressBytes);

if (getAddressType() != AddressType.Ptr)
throw new AddressRuntimeException("Invalid address type. Expected Pointer address type");

decodePointer();
}

private void decodePointer() {
byte[] pointerBytes = getDelegationCredentialHash()
.orElseThrow(() -> new AddressRuntimeException("Delegation credential hash not found"));

int index = 0;
Tuple<Long, Integer> slot = variableNatDecode(pointerBytes);
index += slot._2;
Tuple<Long, Integer> txIndex = variableNatDecode(getSubBytes(pointerBytes, index));
index += txIndex._2;
Tuple<Long, Integer> certIndex = variableNatDecode(getSubBytes(pointerBytes, index));

pointer = new Pointer(slot._1, txIndex._1.intValue(), certIndex._1.intValue());
}

private Tuple<Long, Integer> variableNatDecode(byte[] raw) {
long output = 0;
int bytesRead = 0;

for (byte rbyte : raw) {
output = (output << 7) | (rbyte & 0x7F);
bytesRead++;

if ((rbyte & 0x80) == 0) {
return new Tuple<>(output, bytesRead);
}
}

throw new IllegalArgumentException("Invalid variable nat encoding. Unexpected bytes");
}

// Get subarray from startPosition to the end of the array
private byte[] getSubBytes(byte[] array, int startPosition) {
// Validate startPosition
if (startPosition < 0 || startPosition > array.length) {
throw new IllegalArgumentException("Invalid start position");
}

return Arrays.copyOfRange(array, startPosition, array.length);
}

public Pointer getPointer() {
return pointer;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.bloxbean.cardano.client.address;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class PointerAddressTest {

@Test
void getPointer() {
PointerAddress pointerAddress = new PointerAddress("addr1gx2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer5ph3wczvf2w8lunk");
assertEquals(new Pointer(24157, 177, 42), pointerAddress.getPointer());
}

@Test
void getPointer2() {
PointerAddress pointerAddress = new PointerAddress("addr_test1gz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzerspqgpsqe70et");
assertEquals(new Pointer(1, 2, 3), pointerAddress.getPointer());
}

@Test
void getPointer3() {
PointerAddress pointerAddress = new PointerAddress("addr128phkx6acpnf78fuvxn0mkew3l0fd058hzquvz7w36x4gtupnz75xxcrtw79hu");
assertEquals(new Pointer(2498243, 27, 3), pointerAddress.getPointer());
}
}

0 comments on commit 9e5c48c

Please sign in to comment.