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

org.fisco.bcos.web3j.precompile.cns.CnsService Maven / Gradle / Ivy

package org.fisco.bcos.web3j.precompile.cns;

import java.io.IOException;
import java.util.List;

import org.fisco.bcos.web3j.crypto.Credentials;
import org.fisco.bcos.web3j.crypto.WalletUtils;
import org.fisco.bcos.web3j.precompile.common.PrecompiledCommon;
import org.fisco.bcos.web3j.protocol.ObjectMapperFactory;
import org.fisco.bcos.web3j.protocol.Web3j;
import org.fisco.bcos.web3j.protocol.core.DefaultBlockParameterName;
import org.fisco.bcos.web3j.protocol.core.methods.response.BcosBlock;
import org.fisco.bcos.web3j.protocol.core.methods.response.SyncStatus;
import org.fisco.bcos.web3j.protocol.core.methods.response.TransactionReceipt;
import org.fisco.bcos.web3j.tx.RawTransactionManager;
import org.fisco.bcos.web3j.tx.TransactionManager;
import org.fisco.bcos.web3j.tx.gas.DefaultGasProvider;
import org.fisco.bcos.web3j.tx.gas.StaticGasProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.ObjectMapper;

/** Resolution logic for contract addresses. */
public class CnsService {
  private static Logger logger = LoggerFactory.getLogger(CnsService.class);
  private static final long DEFAULT_SYNC_THRESHOLD = 1000 * 60 * 3L;
  public static final int MAX_VERSION_LENGTH = 40;

  private final Web3j web3j;
  private final TransactionManager transactionManager;
  private long syncThreshold; // non-final in case this value needs to be tweaked
  private static String registryContract = "0x0000000000000000000000000000000000001004";

  private CNS cnsRegistry;

  public CnsService(Web3j web3j, long syncThreshold, Credentials credentials) {
    this.web3j = web3j;
    transactionManager = new RawTransactionManager(web3j, credentials);
    this.syncThreshold = syncThreshold;
  }

  public CnsService(Web3j web3j, Credentials credentials) {
    this(web3j, DEFAULT_SYNC_THRESHOLD, credentials);
  }

  public void setSyncThreshold(long syncThreshold) {
    this.syncThreshold = syncThreshold;
  }

  public long getSyncThreshold() {
    return syncThreshold;
  }

  public String getAddressByContractNameAndVersion(String contractNameAndVersion) {

    if (!isValidCnsName(contractNameAndVersion)) {
      return contractNameAndVersion;
    }
    CNS cns;
    cns = lookupResolver();
    String contractAddressInfo;
    String address;

    try {
      // if has version
      if (contractNameAndVersion.contains(":")) {
        String contractName = contractNameAndVersion.split(":")[0];
        String contractVersion = contractNameAndVersion.split(":")[1];

        contractAddressInfo = cns.selectByNameAndVersion(contractName, contractVersion).send();
        logger.debug("get contractName ", contractAddressInfo);
        List cNSInfos = jsonToCNSInfos(contractAddressInfo);
        address = cNSInfos.get(0).getAddress();
      } else {
        // only contract name
        contractAddressInfo = cns.selectByName(contractNameAndVersion).send();
        logger.debug("get contractName ", contractAddressInfo);
        List CNSInfos = jsonToCNSInfos(contractAddressInfo);
        CnsInfo c = CNSInfos.get(CNSInfos.size() - 1);
        address = c.getAddress();
      }
    } catch (Exception e) {
      throw new RuntimeException(e);
    }

    if (!WalletUtils.isValidAddress(address)) {
      throw new RuntimeException("Unable to resolve address for name: " + contractNameAndVersion);
    } else {
      return address;
    }
  }

  public String registerCns(String name, String version, String address, String abi)
      throws Exception {
    CNS cns = lookupResolver();
    if (version.length() > MAX_VERSION_LENGTH) {
      return PrecompiledCommon.transferToJson(PrecompiledCommon.VersionExceeds);
    }
    TransactionReceipt receipt = cns.insert(name, version, address, abi).send();
    return PrecompiledCommon.handleTransactionReceipt(receipt);
  }

  public List queryCnsByName(String name) throws Exception {
    CNS cns = lookupResolver();
    String cnsInfo = cns.selectByName(name).send();
    ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper();
    return objectMapper.readValue(
        cnsInfo, objectMapper.getTypeFactory().constructCollectionType(List.class, CnsInfo.class));
  }

  public List queryCnsByNameAndVersion(String name, String version) throws Exception {
    CNS cns = lookupResolver();
    String cnsInfo = cns.selectByNameAndVersion(name, version).send();
    ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper();
    return objectMapper.readValue(
        cnsInfo, objectMapper.getTypeFactory().constructCollectionType(List.class, CnsInfo.class));
  }

  private List jsonToCNSInfos(String contractAddressInfo) throws IOException {

    ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper();
    List cnsInfo =
        objectMapper.readValue(
            contractAddressInfo,
            objectMapper.getTypeFactory().constructCollectionType(List.class, CnsInfo.class));
    return cnsInfo;
  }

  public CNS lookupResolver() {

    if (this.cnsRegistry == null) {
      CNS cnsRegistry =
          CNS.load(
              registryContract,
              web3j,
              transactionManager,
              new StaticGasProvider(DefaultGasProvider.GAS_PRICE, DefaultGasProvider.GAS_LIMIT));
      this.cnsRegistry = cnsRegistry;
    }
    return this.cnsRegistry;
  }

  boolean isSynced() throws Exception {
    SyncStatus ethSyncing = web3j.getSyncStatus().send();
    if (ethSyncing.isSyncing()) {
      return false;
    } else {
      BcosBlock block = web3j.getBlockByNumber(DefaultBlockParameterName.LATEST, false).send();
      long timestamp = block.getBlock().getTimestamp().longValueExact() * 1000;

      return System.currentTimeMillis() - syncThreshold < timestamp;
    }
  }

  public static boolean isValidCnsName(String input) {
    return input != null // will be set to null on new Contract creation
        && (input.contains(":") || !WalletUtils.isValidAddress(input));
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy