All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bloxbean.cardano.client.address.AddressService Maven / Gradle / Ivy

The newest version!
package com.bloxbean.cardano.client.address;

import com.bloxbean.cardano.client.common.model.Network;
import com.bloxbean.cardano.client.crypto.bip32.key.HdPublicKey;
import com.bloxbean.cardano.client.crypto.bip32.util.BytesUtil;
import com.bloxbean.cardano.client.exception.AddressRuntimeException;
import com.bloxbean.cardano.client.exception.CborSerializationException;
import com.bloxbean.cardano.client.spec.NetworkId;
import com.bloxbean.cardano.client.spec.Script;
import com.google.common.primitives.Bytes;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

import static com.bloxbean.cardano.client.address.util.AddressEncoderDecoderUtil.*;
import static com.bloxbean.cardano.client.crypto.Blake2bUtil.blake2bHash224;

@Slf4j
/**
 * @deprecated
 * 

This class will be removed in future release. Use {@link AddressProvider} instead

*/ @Deprecated(since = "0.4.3", forRemoval = true) public class AddressService { private static AddressService instance; private AddressService() { } public static AddressService getInstance() { if (instance == null) { synchronized (AddressService.class) { if (instance == null) instance = new AddressService(); } } return instance; } //header: 0000.... public Address getBaseAddress(HdPublicKey paymentKey, HdPublicKey delegationKey, Network networkInfo) { if (paymentKey == null || delegationKey == null) throw new AddressRuntimeException("paymentkey and delegationKey cannot be null"); byte[] paymentKeyHash = paymentKey.getKeyHash(); byte[] delegationKeyHash = delegationKey.getKeyHash(); byte headerType = 0b0000_0000; return getAddress(paymentKeyHash, delegationKeyHash, headerType, networkInfo, AddressType.Base); } //header: 0001.... public Address getBaseAddress(Script paymentKey, HdPublicKey delegationKey, Network networkInfo) throws CborSerializationException { if (paymentKey == null || delegationKey == null) throw new AddressRuntimeException("paymentkey and delegationKey cannot be null"); byte[] paymentKeyHash = paymentKey.getScriptHash(); byte[] delegationKeyHash = delegationKey.getKeyHash(); byte headerType = 0b0001_0000; return getAddress(paymentKeyHash, delegationKeyHash, headerType, networkInfo, AddressType.Base); } //header: 0010.... public Address getBaseAddress(HdPublicKey paymentKey, Script delegationKey, Network networkInfo) throws CborSerializationException { if (paymentKey == null || delegationKey == null) throw new AddressRuntimeException("paymentkey and delegationKey cannot be null"); byte[] paymentKeyHash = paymentKey.getKeyHash(); byte[] delegationKeyHash = delegationKey.getScriptHash(); byte headerType = 0b0010_0000; return getAddress(paymentKeyHash, delegationKeyHash, headerType, networkInfo, AddressType.Base); } //header: 0011.... public Address getBaseAddress(Script paymentKey, Script delegationKey, Network networkInfo) throws CborSerializationException { if (paymentKey == null || delegationKey == null) throw new AddressRuntimeException("paymentkey and delegationKey cannot be null"); byte[] paymentKeyHash = paymentKey.getScriptHash(); byte[] delegationKeyHash = delegationKey.getScriptHash(); byte headerType = 0b0011_0000; return getAddress(paymentKeyHash, delegationKeyHash, headerType, networkInfo, AddressType.Base); } //TODO -- Implement Pointer address //header: 0100.... public Address getPointerAddress(HdPublicKey paymentKey, Pointer delegationPointer, Network networkInfo) { if (paymentKey == null || delegationPointer == null) throw new AddressRuntimeException("paymentkey and delegationKey cannot be null"); byte[] paymentKeyHash = paymentKey.getKeyHash(); byte[] delegationPointerHash = BytesUtil.merge(variableNatEncode(delegationPointer.slot), variableNatEncode(delegationPointer.txIndex), variableNatEncode(delegationPointer.certIndex)); byte headerType = 0b0100_0000; return getAddress(paymentKeyHash, delegationPointerHash, headerType, networkInfo, AddressType.Ptr); } //header: 0101.... public Address getPointerAddress(Script paymentKey, Pointer delegationPointer, Network networkInfo) throws CborSerializationException { if (paymentKey == null || delegationPointer == null) throw new AddressRuntimeException("paymentkey and delegationKey cannot be null"); byte[] paymentKeyHash = paymentKey.getScriptHash(); byte[] delegationPointerHash = BytesUtil.merge(variableNatEncode(delegationPointer.slot), variableNatEncode(delegationPointer.txIndex), variableNatEncode(delegationPointer.certIndex)); byte headerType = 0b0101_0000; return getAddress(paymentKeyHash, delegationPointerHash, headerType, networkInfo, AddressType.Ptr); } //header: 0110.... public Address getEntAddress(HdPublicKey paymentKey, Network networkInfo) { if (paymentKey == null) throw new AddressRuntimeException("paymentkey cannot be null"); byte[] paymentKeyHash = paymentKey.getKeyHash(); byte headerType = 0b0110_0000; return getAddress(paymentKeyHash, null, headerType, networkInfo, AddressType.Enterprise); } //header: 0111.... public Address getEntAddress(Script paymentKey, Network networkInfo) throws CborSerializationException { if (paymentKey == null) throw new AddressRuntimeException("paymentkey cannot be null"); byte[] paymentKeyHash = paymentKey.getScriptHash(); byte headerType = 0b0111_0000; return getAddress(paymentKeyHash, null, headerType, networkInfo, AddressType.Enterprise); } //header: 1110.... public Address getRewardAddress(HdPublicKey stakeKey, Network networkInfo) { if (stakeKey == null) throw new AddressRuntimeException("stakeKey cannot be null"); byte[] stakeKeyHash = stakeKey.getKeyHash(); int headerType = 0b1110_0000; return getAddress(null, stakeKeyHash, (byte) headerType, networkInfo, AddressType.Reward); } //header: 1111.... public Address getRewardAddress(Script stakeKey, Network networkInfo) throws CborSerializationException { if (stakeKey == null) throw new AddressRuntimeException("stakeKey cannot be null"); byte[] stakeKeyHash = stakeKey.getScriptHash(); int headerType = 0b1111_0000; return getAddress(null, stakeKeyHash, (byte) headerType, networkInfo, AddressType.Reward); } private Address getAddress(byte[] paymentKeyHash, byte[] stakeKeyHash, byte headerKind, Network networkInfo, AddressType addressType) { NetworkId network = getNetworkId(networkInfo); //get prefix String prefix = getPrefixHeader(addressType) + getPrefixTail(network); //get header byte header = getAddressHeader(headerKind, networkInfo, addressType); byte[] addressArray = getAddressBytes(paymentKeyHash, stakeKeyHash, addressType, header); return new Address(prefix, addressArray); } private byte[] getAddressBytes(byte[] paymentKeyHash, byte[] stakeKeyHash, AddressType addressType, byte header) { //get body byte[] addressArray; switch (addressType) { case Base: addressArray = new byte[1 + paymentKeyHash.length + stakeKeyHash.length]; addressArray[0] = header; System.arraycopy(paymentKeyHash, 0, addressArray, 1, paymentKeyHash.length); System.arraycopy(stakeKeyHash, 0, addressArray, paymentKeyHash.length + 1, stakeKeyHash.length); break; case Enterprise: addressArray = new byte[1 + paymentKeyHash.length]; addressArray[0] = header; System.arraycopy(paymentKeyHash, 0, addressArray, 1, paymentKeyHash.length); break; case Reward: addressArray = new byte[1 + stakeKeyHash.length]; addressArray[0] = header; System.arraycopy(stakeKeyHash, 0, addressArray, 1, stakeKeyHash.length); break; case Ptr: addressArray = new byte[1 + paymentKeyHash.length + stakeKeyHash.length]; addressArray[0] = header; System.arraycopy(paymentKeyHash, 0, addressArray, 1, paymentKeyHash.length); System.arraycopy(stakeKeyHash, 0, addressArray, paymentKeyHash.length + 1, stakeKeyHash.length); break; default: throw new AddressRuntimeException("Unknown address type"); } return addressArray; } /** * Verify the provided address with publicKey * Reconstruct the address from public key and then compare it with the provided address * @param address * @param publicKey * @return true or false */ public boolean verifyAddress(@NonNull Address address, byte[] publicKey) { String prefix = address.getPrefix(); AddressType addressType = address.getAddressType(); byte[] addressBytes = address.getBytes(); byte header = addressBytes[0]; byte[] newAddressBytes; Address newAddress; if (AddressType.Reward.equals(addressType)) { byte[] stakeKeyHash = blake2bHash224(publicKey); //Get keyhash from publickey (stake credential) newAddressBytes = getAddressBytes(null, stakeKeyHash, addressType, header); } else { byte[] stakeKeyHash = getDelegationHash(address).orElse(null); //Get stakekeyhash from existing address byte[] paymentKeyHash = blake2bHash224(publicKey); //calculate keyhash from public key newAddressBytes = getAddressBytes(paymentKeyHash, stakeKeyHash, addressType, header); } newAddress = new Address(prefix, newAddressBytes); if (log.isDebugEnabled()) { log.debug("Address to compare : " + address.toBech32()); log.debug("Address derived from pub key : " + newAddress.toBech32()); } return newAddress.toBech32().equals(address.toBech32()); } /** * Get stake address from a base address * @param address BaseAddress * @return stake address * @throws AddressRuntimeException */ public Address getStakeAddress(@NonNull Address address) { if (AddressType.Base != address.getAddressType()) throw new AddressRuntimeException( String.format("Stake address can't be derived. Required address type: Base Address, Found: %s ", address.getAddressType())); byte[] stakeKeyHash = getDelegationHash(address) .orElseThrow(() -> new AddressRuntimeException("StakeKeyHash was not found for the address")); AddressType addressType = AddressType.Reward; //target type byte[] addressBytes = address.getBytes(); //existing add bytes byte header = addressBytes[0]; //existing header int stakeHeader; if ((header & (1 << 5)) > 0) { //Check if 5th bit is set //script hash stakeHeader = 0b1111_0000; } else { //stake key hash stakeHeader = 0b1110_0000; } int network = header & 0b0000_1111; //reset everything except network id bits stakeHeader = stakeHeader | network; byte[] rewardAddressBytes = getAddressBytes(null, stakeKeyHash, addressType, (byte) stakeHeader); return new Address(rewardAddressBytes); } /** * Get StakeKeyHash or ScriptHash from delegation part of a Shelley {@link Address} * @param address * @return StakeKeyHash or ScriptHash. For Pointer address, delegationPointerHash */ public Optional getDelegationHash(Address address) { AddressType addressType = address.getAddressType(); byte[] addressBytes = address.getBytes(); byte[] stakeKeyHash; switch (addressType) { case Base: stakeKeyHash = new byte[28]; System.arraycopy(addressBytes, 1 + 28, stakeKeyHash, 0, stakeKeyHash.length); break; case Enterprise: stakeKeyHash = null; break; case Reward: stakeKeyHash = new byte[28]; System.arraycopy(addressBytes, 1, stakeKeyHash, 0, stakeKeyHash.length); break; case Ptr: //TODO -- Remove if not required stakeKeyHash = new byte[addressBytes.length - 1 - 28]; System.arraycopy(addressBytes, 1 + 28, stakeKeyHash, 0, stakeKeyHash.length); break; default: throw new AddressRuntimeException("DelegationHash can't be found for address type : " + addressType); } return Optional.ofNullable(stakeKeyHash); } /** * Get PaymentKeyHash from {@link Address} * @param address * @return payment key hash */ public Optional getPaymentKeyHash(Address address) { AddressType addressType = address.getAddressType(); byte[] addressBytes = address.getBytes(); byte[] paymentKeyHash; switch (addressType) { case Base: case Enterprise: case Ptr: paymentKeyHash = new byte[28]; System.arraycopy(addressBytes, 1, paymentKeyHash, 0, paymentKeyHash.length); break; case Reward: paymentKeyHash = null; break; default: { throw new AddressRuntimeException("Unable to get payment key hash for address type: " + addressType + ", address=" + address.getAddress()); } } return Optional.ofNullable(paymentKeyHash); } /** * Check if payment part of a Shelley address is PubkeyHash * @param address * @return true if PubkeyHash, otherwise false */ public boolean isPubKeyHashInPaymentPart(@NonNull Address address) { AddressType addressType = address.getAddressType(); if (addressType != AddressType.Base && addressType != AddressType.Enterprise && addressType != AddressType.Ptr) { if (log.isDebugEnabled()) log.warn("Method not supported for address type=" + addressType + ", address=" + address.getAddress()); return false; } byte[] addressBytes = address.getBytes(); byte header = addressBytes[0]; if ((header & (1 << 4)) == 0) { //Check if 4th bit is not set. If not set, it's pubkey hash return true; } else return false; } /** * Check if payment part of a Shelley address is ScriptHash * @param address * @return true if ScriptHash, otherwise false */ public boolean isScriptHashInPaymentPart(@NonNull Address address) { AddressType addressType = address.getAddressType(); if (addressType != AddressType.Base && addressType != AddressType.Enterprise && addressType != AddressType.Ptr) { if (log.isDebugEnabled()) log.warn("Method not supported for address type=" + addressType + ", address=" + address.getAddress()); return false; } return !isPubKeyHashInPaymentPart(address); } /** * Check if delegation part of a Shelley address is StakeKeyHash * @param address * @return true if StakeKeyHash, otherwise false */ public boolean isStakeKeyHashInDelegationPart(@NonNull Address address) { AddressType addressType = address.getAddressType(); if (addressType != AddressType.Base && addressType != AddressType.Ptr && addressType != AddressType.Reward) { if (log.isDebugEnabled()) log.warn("Method not supported for address type=" + addressType + ", address=" + address.getAddress()); return false; } byte[] addressBytes = address.getBytes(); byte header = addressBytes[0]; if (addressType == AddressType.Reward) { if ((header & (1 << 4)) == 0) { //Check if 4th bit is not set. If not set, it's stakekey hash return true; } else return false; } else { //For Base, Ptr if ((header & (1 << 5)) == 0) { //Check if 5th bit is not set. If not set, it's stakekey hash return true; } else return false; } } /** * Check if delegation part of a Shelley address is ScriptHash * @param address * @return true if ScriptHash, otherwise false */ public boolean isScriptHashInDelegationPart(@NonNull Address address) { AddressType addressType = address.getAddressType(); if (addressType != AddressType.Base && addressType != AddressType.Ptr && addressType != AddressType.Reward) { if (log.isDebugEnabled()) log.warn("Method not supported for address type=" + addressType + ", address=" + address.getAddress()); return false; } return !isStakeKeyHashInDelegationPart(address); } private byte[] variableNatEncode(long num) { List output = new ArrayList<>(); output.add((byte)(num & 0x7F)); num /= 128; while(num > 0) { output.add((byte)((num & 0x7F) | 0x80)); num /= 128; } Collections.reverse(output); return Bytes.toArray(output); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy