
cn.bif.module.contract.impl.BIFContractServiceImpl Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* © COPYRIGHT 2021 Corporation CAICT All rights reserved.
* http://www.caict.ac.cn
*/
package cn.bif.module.contract.impl;
import cn.bif.common.Constant;
import cn.bif.common.General;
import cn.bif.common.JsonUtils;
import cn.bif.common.Tools;
import cn.bif.exception.SDKException;
import cn.bif.exception.SdkError;
import cn.bif.utils.http.HttpUtils;
import cn.bif.model.request.*;
import cn.bif.model.request.operation.BIFContractCreateOperation;
import cn.bif.model.request.operation.BIFContractInvokeOperation;
import cn.bif.model.response.*;
import cn.bif.model.response.result.*;
import cn.bif.model.response.result.data.BIFContractAddressInfo;
import cn.bif.model.response.result.data.BIFContractInfo;
import cn.bif.model.response.result.data.BIFTransactionHistory;
import cn.bif.module.blockchain.BIFTransactionService;
import cn.bif.module.blockchain.impl.BIFTransactionServiceImpl;
import cn.bif.module.contract.BIFContractService;
import cn.bif.module.encryption.key.PublicKeyManager;
import cn.bif.protobuf.Chain;
import com.google.protobuf.ByteString;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.*;
import java.util.stream.Collectors;
public class BIFContractServiceImpl implements BIFContractService {
/**
* @Method create
* @Params [contractCreateOperation]
* @Return cn.bif.model.response.ContractCreateResponse
*/
public static Chain.Operation create(BIFContractCreateOperation contractCreateOperation) throws SDKException {
Chain.Operation.Builder operation;
try {
String sourceAddress = contractCreateOperation.getSourceAddress();
if (!Tools.isEmpty(sourceAddress) && !PublicKeyManager.isAddressValid(sourceAddress)) {
throw new SDKException(SdkError.INVALID_SOURCEADDRESS_ERROR);
}
Long initBalance = contractCreateOperation.getInitBalance();
if (!Tools.isEmpty(initBalance) && initBalance < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_INITBALANCE_ERROR);
}
Integer type = contractCreateOperation.getType();
if (!Tools.isEmpty(type) && type < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_CONTRACT_TYPE_ERROR);
}
String payload = contractCreateOperation.getPayload();
if (Tools.isEmpty(payload)) {
throw new SDKException(SdkError.PAYLOAD_EMPTY_ERROR);
}
String metadata = contractCreateOperation.getMetadata();
String initInput = contractCreateOperation.getInitInput();
// build operation
operation = Chain.Operation.newBuilder();
operation.setType(Chain.Operation.Type.CREATE_ACCOUNT);
if (!Tools.isEmpty(sourceAddress)) {
operation.setSourceAddress(sourceAddress);
}
if (!Tools.isEmpty(metadata)) {
operation.setMetadata(ByteString.copyFromUtf8(metadata));
}
Chain.OperationCreateAccount.Builder operationCreateContract = operation.getCreateAccountBuilder();
if (!Tools.isEmpty(initBalance)) {
operationCreateContract.setInitBalance(initBalance);
}
if (!Tools.isEmpty(initInput)) {
operationCreateContract.setInitInput(initInput);
}
Chain.Contract.Builder contract = operationCreateContract.getContractBuilder();
if (!Tools.isEmpty(type)) {
Chain.Contract.ContractType contractType = Chain.Contract.ContractType.forNumber(type);
if (Tools.isEmpty(contractType)) {
throw new SDKException(SdkError.INVALID_CONTRACT_TYPE_ERROR);
}
contract.setType(contractType);
}
contract.setPayload(payload);
Chain.AccountPrivilege.Builder accountPrivilege = operationCreateContract.getPrivBuilder();
accountPrivilege.setMasterWeight(Constant.INIT_ZERO);
Chain.AccountThreshold.Builder accountThreshold = accountPrivilege.getThresholdsBuilder();
accountThreshold.setTxThreshold(Constant.INIT_ONE);
} catch (SDKException sdkException) {
throw sdkException;
} catch (Exception e) {
throw new SDKException(SdkError.SYSTEM_ERROR.getCode(), e.getMessage());
}
return operation.build();
}
/**
* @Method invokeByGas
* @Params [contractInvokeByGasOperation]
* @Return cn.bif.model.response.ContractInvokeByGasResponse
*/
public static Chain.Operation invokeByGas(BIFContractInvokeOperation contractInvokeByGasOperation, String transSourceAddress) throws SDKException {
Chain.Operation.Builder operation;
try {
String sourceAddress = contractInvokeByGasOperation.getSourceAddress();
if (!Tools.isEmpty(sourceAddress) && !PublicKeyManager.isAddressValid(sourceAddress)) {
throw new SDKException(SdkError.INVALID_SOURCEADDRESS_ERROR);
}
String contractAddress = contractInvokeByGasOperation.getContractAddress();
if (!PublicKeyManager.isAddressValid(contractAddress)) {
throw new SDKException(SdkError.INVALID_CONTRACTADDRESS_ERROR);
}
if ((!Tools.isEmpty(sourceAddress) && sourceAddress.equals(contractAddress)) || transSourceAddress.equals(contractAddress)) {
throw new SDKException(SdkError.SOURCEADDRESS_EQUAL_CONTRACTADDRESS_ERROR);
}
Long bifAmount = contractInvokeByGasOperation.getBIFAmount();
if (Tools.isEmpty(bifAmount) || bifAmount < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_AMOUNT_ERROR);
}
String metadata = contractInvokeByGasOperation.getMetadata();
Integer domainId=contractInvokeByGasOperation.getDomainId();
if(Tools.isNULL(domainId)){
domainId=Constant.INIT_ZERO;
}
if(!Tools.isNULL(domainId) && domainId < Constant.INIT_ZERO){
throw new SDKException(SdkError.INVALID_DOMAINID_ERROR);
}
// if (!checkContractValid(contractAddress,domainId)) {
// throw new SDKException(SdkError.CONTRACTADDRESS_NOT_CONTRACTACCOUNT_ERROR);
// }
String input = contractInvokeByGasOperation.getInput();
// build operation
operation = Chain.Operation.newBuilder();
operation.setType(Chain.Operation.Type.PAY_COIN);
if (!Tools.isEmpty(sourceAddress)) {
operation.setSourceAddress(sourceAddress);
}
if (!Tools.isEmpty(metadata)) {
operation.setMetadata(ByteString.copyFromUtf8(metadata));
}
Chain.OperationPayCoin.Builder operationPayCoin = operation.getPayCoinBuilder();
operationPayCoin.setDestAddress(contractAddress);
operationPayCoin.setAmount(bifAmount);
if (!Tools.isEmpty(input)) {
operationPayCoin.setInput(input);
}
} catch (SDKException sdkException) {
throw sdkException;
} catch (Exception e) {
throw new SDKException(SdkError.SYSTEM_ERROR.getCode(), e.getMessage());
}
return operation.build();
}
public static BIFContractCallResponse callContract(String sourceAddress, String contractAddress, Integer optType,
String input, Long gasPrice, Long feeLimit,Integer domainId)
throws Exception {
if (Tools.isEmpty(General.getInstance().getUrl())) {
throw new SDKException(SdkError.URL_EMPTY_ERROR);
}
Map params = new HashMap<>();
params.put("opt_type", optType);
params.put("fee_limit", feeLimit);
if (!Tools.isEmpty(sourceAddress)) {
params.put("source_address", sourceAddress);
}
if (!Tools.isEmpty(contractAddress)) {
params.put("contract_address", contractAddress);
}
if (!Tools.isEmpty(input)) {
params.put("input", input);
}
if (!Tools.isEmpty(gasPrice)) {
params.put("gas_price", gasPrice);
}
params.put("domain_id",domainId);
// call contract
String contractCallUrl = General.getInstance().contractCallUrl();
String result = HttpUtils.httpPost(contractCallUrl, JsonUtils.toJSONString(params));
return JsonUtils.toJavaObject(result, BIFContractCallResponse.class);
}
private static BIFContractGetInfoResponse getContractInfo(String contractAddress,Integer domainId) throws Exception {
if (Tools.isEmpty(General.getInstance().getUrl())) {
throw new SDKException(SdkError.URL_EMPTY_ERROR);
}
BIFContractGetInfoResponse contractGetInfoResponse;
String contractGetInfoUrl = General.getInstance().accountGetInfoUrl(contractAddress,domainId);
String result = HttpUtils.httpGet(contractGetInfoUrl);
contractGetInfoResponse = JsonUtils.toJavaObject(result, BIFContractGetInfoResponse.class);
Integer errorCode = contractGetInfoResponse.getErrorCode();
String errorDesc = contractGetInfoResponse.getErrorDesc();
if (!Tools.isEmpty(errorCode) && errorCode.equals(Constant.ERRORCODE)) {
throw new SDKException(errorCode, (null == errorDesc ? "contract account (" + contractAddress + ") doest not exist" : errorDesc));
}else if(!Tools.isEmpty(errorCode) && errorCode.equals(Constant.DOMAINID_ERRORCODE)){
throw new SDKException(errorCode, (null == errorDesc ? "Domainid(" + domainId + ") (" + contractAddress + ") doest not exist" : errorDesc));
}
SdkError.checkErrorCode(contractGetInfoResponse);
BIFContractInfo contractInfo = contractGetInfoResponse.getResult().getContract();
if (Tools.isEmpty(contractInfo)) {
throw new SDKException(SdkError.CONTRACTADDRESS_NOT_CONTRACTACCOUNT_ERROR);
}
String payLoad = contractInfo.getPayload();
if (Tools.isEmpty(payLoad)) {
throw new SDKException(SdkError.CONTRACTADDRESS_NOT_CONTRACTACCOUNT_ERROR);
}
return contractGetInfoResponse;
}
private static boolean checkContractValid(String contractAddress,Integer domainId) throws Exception {
boolean isValid = false;
try {
getContractInfo(contractAddress,domainId);
isValid = true;
} catch (SDKException sdkException) {
}
return isValid;
}
/**
* @Method getInfo
* @Params [contractGetInfoRequest]
* @Return ContractGetInfoResponse
*/
@Override
public BIFContractGetInfoResponse getContractInfo(BIFContractGetInfoRequest contractGetInfoRequest) {
BIFContractGetInfoResponse contractGetInfoResponse = new BIFContractGetInfoResponse();
BIFContractGetInfoResult contractGetInfoResult = new BIFContractGetInfoResult();
try {
if (Tools.isEmpty(contractGetInfoRequest)) {
throw new SDKException(SdkError.REQUEST_NULL_ERROR);
}
String contractAddress = contractGetInfoRequest.getContractAddress();
if (!PublicKeyManager.isAddressValid(contractAddress)) {
throw new SDKException(SdkError.INVALID_CONTRACTADDRESS_ERROR);
}
Integer domainId=contractGetInfoRequest.getDomainId();
if(Tools.isNULL(domainId)){
domainId=Constant.INIT_ZERO;
}
if(!Tools.isNULL(domainId) && domainId < Constant.INIT_ZERO){
throw new SDKException(SdkError.INVALID_DOMAINID_ERROR);
}
contractGetInfoResponse = getContractInfo(contractAddress,domainId);
} catch (SDKException apiException) {
Integer errorCode = apiException.getErrorCode();
String errorDesc = apiException.getErrorDesc();
contractGetInfoResponse.buildResponse(errorCode, errorDesc, contractGetInfoResult);
} catch (NoSuchAlgorithmException | KeyManagementException | NoSuchProviderException | IOException e) {
contractGetInfoResponse.buildResponse(SdkError.CONNECTNETWORK_ERROR, contractGetInfoResult);
} catch (Exception e) {
contractGetInfoResponse.buildResponse(SdkError.SYSTEM_ERROR.getCode(), e.getMessage(), contractGetInfoResult);
}
return contractGetInfoResponse;
}
/**
* @Method checkValid
* @Params [contractCheckValidRequest]
* @Return ContractCheckValidResponse
*/
@Override
public BIFContractCheckValidResponse checkContractAddress(BIFContractCheckValidRequest contractCheckValidRequest) {
BIFContractCheckValidResponse contractCheckValidResponse = new BIFContractCheckValidResponse();
BIFContractCheckValidResult contractCheckValidResult = new BIFContractCheckValidResult();
try {
if (Tools.isEmpty(contractCheckValidRequest)) {
throw new SDKException(SdkError.REQUEST_NULL_ERROR);
}
String contractAddress = contractCheckValidRequest.getContractAddress();
if (!PublicKeyManager.isAddressValid(contractAddress)) {
throw new SDKException(SdkError.INVALID_CONTRACTADDRESS_ERROR);
}
Integer domainId=contractCheckValidRequest.getDomainId();
if(Tools.isNULL(domainId)){
domainId=Constant.INIT_ZERO;
}
if(!Tools.isNULL(domainId) && domainId < Constant.INIT_ZERO){
throw new SDKException(SdkError.INVALID_DOMAINID_ERROR);
}
boolean isValid = checkContractValid(contractAddress,domainId);
contractCheckValidResult.setValid(isValid);
contractCheckValidResponse.buildResponse(SdkError.SUCCESS, contractCheckValidResult);
} catch (SDKException apiException) {
Integer errorCode = apiException.getErrorCode();
String errorDesc = apiException.getErrorDesc();
contractCheckValidResponse.buildResponse(errorCode, errorDesc, contractCheckValidResult);
} catch (Exception e) {
contractCheckValidResponse.buildResponse(SdkError.SYSTEM_ERROR.getCode(), e.getMessage(), contractCheckValidResult);
}
return contractCheckValidResponse;
}
/**
* @Method call
* @Params [contractCallRequest]
* @Return ContractCallResponse
*/
@Override
public BIFContractCallResponse contractQuery(BIFContractCallRequest contractCallRequest) {
BIFContractCallResponse contractCallResponse = new BIFContractCallResponse();
BIFContractCallResult contractCallResult = new BIFContractCallResult();
try {
if (Tools.isEmpty(contractCallRequest)) {
throw new SDKException(SdkError.REQUEST_NULL_ERROR);
}
String sourceAddress = contractCallRequest.getSourceAddress();
if (!Tools.isEmpty(sourceAddress) && !sourceAddress.isEmpty() && !PublicKeyManager.isAddressValid(sourceAddress)) {
throw new SDKException(SdkError.INVALID_SOURCEADDRESS_ERROR);
}
String contractAddress = contractCallRequest.getContractAddress();
if (!Tools.isNULL(contractAddress) && !contractAddress.isEmpty() && !PublicKeyManager.isAddressValid(contractAddress)) {
throw new SDKException(SdkError.INVALID_CONTRACTADDRESS_ERROR);
}
if (!Tools.isEmpty(sourceAddress) && !Tools.isNULL(contractAddress) && sourceAddress.equals(contractAddress)) {
throw new SDKException(SdkError.SOURCEADDRESS_EQUAL_CONTRACTADDRESS_ERROR);
}
String input = contractCallRequest.getInput();
Long feeLimit = contractCallRequest.getFeeLimit();
if (Tools.isEmpty(feeLimit)) {
feeLimit = Constant.FEE_LIMIT;
}
if (Tools.isEmpty(feeLimit) || feeLimit < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_FEELIMIT_ERROR);
}
Long gasPrice = contractCallRequest.getGasPrice();
if (Tools.isEmpty(gasPrice)) {
gasPrice = Constant.GAS_PRICE;
}
if (Tools.isEmpty(gasPrice) || gasPrice < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_GASPRICE_ERROR);
}
Integer domainId=contractCallRequest.getDomainId();
if(Tools.isNULL(domainId)){
domainId=Constant.INIT_ZERO;
}
if(!Tools.isNULL(domainId) && domainId < Constant.INIT_ZERO){
throw new SDKException(SdkError.INVALID_DOMAINID_ERROR);
}
contractCallResponse = callContract(sourceAddress, contractAddress, Constant.CONTRACT_QUERY_OPT_TYPE, input,gasPrice,
feeLimit,domainId);
} catch (SDKException sdkException) {
Integer errorCode = sdkException.getErrorCode();
String errorDesc = sdkException.getErrorDesc();
contractCallResponse.buildResponse(errorCode, errorDesc, contractCallResult);
} catch (NoSuchAlgorithmException | KeyManagementException | NoSuchProviderException | IOException e) {
contractCallResponse.buildResponse(SdkError.CONNECTNETWORK_ERROR, contractCallResult);
} catch (Exception e) {
contractCallResponse.buildResponse(SdkError.SYSTEM_ERROR.getCode(), e.getMessage(), contractCallResult);
}
return contractCallResponse;
}
@Override
public BIFContractGetAddressResponse getContractAddress(BIFContractGetAddressRequest contractGetAddressRequest) {
BIFContractGetAddressResponse contractGetAddressResponse = new BIFContractGetAddressResponse();
BIFContractGetAddressResult contractGetAddressResult = new BIFContractGetAddressResult();
try {
if (Tools.isEmpty(contractGetAddressRequest)) {
throw new SDKException(SdkError.REQUEST_NULL_ERROR);
}
String hash = contractGetAddressRequest.getHash();
if (Tools.isEmpty(hash) || hash.length() != Constant.HASH_HEX_LENGTH) {
throw new SDKException(SdkError.INVALID_HASH_ERROR);
}
Integer domainId=contractGetAddressRequest.getDomainId();
if(Tools.isNULL(domainId)){
domainId=Constant.INIT_ZERO;
}
if(!Tools.isNULL(domainId) && domainId < Constant.INIT_ZERO){
throw new SDKException(SdkError.INVALID_DOMAINID_ERROR);
}
BIFTransactionGetInfoResponse transactionGetInfoResponse = BIFTransactionServiceImpl.getTransactionInfo(hash,domainId);
SdkError.checkErrorCode(transactionGetInfoResponse);
BIFTransactionHistory transactionHistory = transactionGetInfoResponse.getResult().getTransactions()[0];
if (Tools.isEmpty(transactionHistory)) {
throw new SDKException(SdkError.INVALID_CONTRACT_HASH_ERROR);
}
SdkError.checkErrorCode(transactionHistory.getErrorCode(), transactionHistory.getErrorDesc());
String contractAddress = transactionHistory.getErrorDesc();
if (Tools.isEmpty(contractAddress)) {
throw new SDKException(SdkError.INVALID_CONTRACT_HASH_ERROR);
}
List contractAddressInfos = JsonUtils.toJavaObjectList(contractAddress, BIFContractAddressInfo.class);
if (Tools.isEmpty(contractAddressInfos)) {
throw new SDKException(SdkError.INVALID_CONTRACT_HASH_ERROR);
}
contractGetAddressResult.setContractAddressInfos(contractAddressInfos);
contractGetAddressResponse.buildResponse(SdkError.SUCCESS, contractGetAddressResult);
} catch (SDKException apiException) {
Integer errorCode = apiException.getErrorCode();
String errorDesc = apiException.getErrorDesc();
contractGetAddressResponse.buildResponse(errorCode, errorDesc, contractGetAddressResult);
} catch (NoSuchAlgorithmException | KeyManagementException | NoSuchProviderException | IOException e) {
contractGetAddressResponse.buildResponse(SdkError.CONNECTNETWORK_ERROR, contractGetAddressResult);
} catch (Exception e) {
contractGetAddressResponse.buildResponse(SdkError.SYSTEM_ERROR.getCode(), e.getMessage(), contractGetAddressResult);
}
return contractGetAddressResponse;
}
@Override
public BIFContractCreateResponse contractCreate(BIFContractCreateRequest request) {
BIFContractCreateResponse response = new BIFContractCreateResponse();
BIFContractCreateResult result = new BIFContractCreateResult();
try {
if (Tools.isEmpty(request)) {
throw new SDKException(SdkError.REQUEST_NULL_ERROR);
}
String senderAddress = request.getSenderAddress();
if (!PublicKeyManager.isAddressValid(senderAddress)) {
throw new SDKException(SdkError.INVALID_ADDRESS_ERROR);
}
BIFContractCreateOperation operation = new BIFContractCreateOperation();
Long initBalance = request.getInitBalance();
if (!Tools.isEmpty(initBalance) && initBalance < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_INITBALANCE_ERROR);
}
String payload = request.getPayload();
if (Tools.isEmpty(payload)) {
throw new SDKException(SdkError.PAYLOAD_EMPTY_ERROR);
}
String initInput = request.getInitInput();
Integer type = request.getType();
operation.setInitBalance(initBalance);
operation.setPayload(payload);
operation.setInitInput(initInput);
operation.setType(type);
String privateKey = request.getPrivateKey();
if (Tools.isEmpty(privateKey)) {
throw new SDKException(SdkError.PRIVATEKEY_NULL_ERROR);
}
Long feeLimit = request.getFeeLimit();
if (Tools.isEmpty(feeLimit)) {
feeLimit = Constant.FEE_LIMIT;
}
if (Tools.isEmpty(feeLimit) || feeLimit < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_FEELIMIT_ERROR);
}
Long gasPrice = request.getGasPrice();
if (Tools.isEmpty(gasPrice)) {
gasPrice = Constant.GAS_PRICE;
}
if (Tools.isEmpty(gasPrice) || gasPrice < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_GASPRICE_ERROR);
}
Long ceilLedgerSeq = request.getCeilLedgerSeq();
String remarks = request.getRemarks();
Integer domainId=request.getDomainId();
if(Tools.isNULL(domainId)){
domainId=Constant.INIT_ZERO;
}
if(!Tools.isNULL(domainId) && domainId < Constant.INIT_ZERO){
throw new SDKException(SdkError.INVALID_DOMAINID_ERROR);
}
Integer nonceType = request.getNonceType();
if(Tools.isNULL(nonceType)){
nonceType = Constant.INIT_ZERO;
}else if(!(nonceType == 0 || nonceType == 1)){
throw new SDKException(SdkError.INVALID_NONCE_TYPE_ERROR);
}
// 广播交易
BIFTransactionService transactionService = new BIFTransactionServiceImpl();
String hash = transactionService.radioTransaction(senderAddress, feeLimit, gasPrice, operation,
ceilLedgerSeq, remarks, privateKey, domainId,nonceType);
result.setHash(hash);
response.buildResponse(SdkError.SUCCESS, result);
} catch (SDKException apiException) {
Integer errorCode = apiException.getErrorCode();
String errorDesc = apiException.getErrorDesc();
response.buildResponse(errorCode, errorDesc, result);
} catch (Exception e) {
response.buildResponse(SdkError.SYSTEM_ERROR.getCode(), e.getMessage(), result);
}
return response;
}
@Override
public BIFContractInvokeResponse batchContractInvoke(BIFBatchContractInvokeRequest request) {
BIFContractInvokeResponse response = new BIFContractInvokeResponse();
BIFContractInvokeResult result = new BIFContractInvokeResult();
try {
if (Tools.isEmpty(request)) {
throw new SDKException(SdkError.REQUEST_NULL_ERROR);
}
String senderAddress = request.getSenderAddress();
if (!PublicKeyManager.isAddressValid(senderAddress)) {
throw new SDKException(SdkError.INVALID_ADDRESS_ERROR);
}
Integer domainId=request.getDomainId();
if(Tools.isNULL(domainId)){
domainId=Constant.INIT_ZERO;
}
if(!Tools.isNULL(domainId) && domainId < Constant.INIT_ZERO){
throw new SDKException(SdkError.INVALID_DOMAINID_ERROR);
}
List operations = request.getOperations();
if(Tools.isEmpty(operations)){
throw new SDKException(SdkError.OPERATIONS_EMPTY_ERROR);
}
Map> map = new HashMap<>();
for (BIFContractInvokeOperation opt: operations) {
if(map.containsKey(opt.getContractAddress())){//map中存在此id,将数据存放当前key的map中
map.get(opt.getContractAddress()).add(opt);
}else{//map中不存在,新建key,用来存放数据
List tmpList = new ArrayList<>();
tmpList.add(opt);
if (!PublicKeyManager.isAddressValid(opt.getContractAddress())) {
throw new SDKException(SdkError.INVALID_CONTRACTADDRESS_ERROR);
}
if (!checkContractValid(opt.getContractAddress(),domainId)) {
throw new SDKException(SdkError.CONTRACTADDRESS_NOT_CONTRACTACCOUNT_ERROR);
}
map.put(opt.getContractAddress(), tmpList);
}
Long bifAmount = opt.getBIFAmount();
if (Tools.isEmpty(bifAmount) || bifAmount < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_AMOUNT_ERROR);
}
}
String privateKey = request.getPrivateKey();
if (Tools.isEmpty(privateKey)) {
throw new SDKException(SdkError.PRIVATEKEY_NULL_ERROR);
}
Long feeLimit = request.getFeeLimit();
if (Tools.isEmpty(feeLimit)) {
feeLimit = Constant.FEE_LIMIT;
}
if (Tools.isEmpty(feeLimit) || feeLimit < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_FEELIMIT_ERROR);
}
Long gasPrice = request.getGasPrice();
if (Tools.isEmpty(gasPrice)) {
gasPrice = Constant.GAS_PRICE;
}
if (Tools.isEmpty(gasPrice) || gasPrice < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_GASPRICE_ERROR);
}
Long ceilLedgerSeq = request.getCeilLedgerSeq();
String remarks = request.getRemarks();
Integer nonceType = request.getNonceType();
if(Tools.isNULL(nonceType)){
nonceType = Constant.INIT_ZERO;
}else if(!(nonceType == 0 || nonceType == 1)){
throw new SDKException(SdkError.INVALID_NONCE_TYPE_ERROR);
}
// 广播交易
BIFTransactionService transactionService = new BIFTransactionServiceImpl();
String hash = transactionService.radioTransaction(senderAddress, feeLimit, gasPrice, operations,
ceilLedgerSeq, remarks, privateKey, domainId, nonceType);
result.setHash(hash);
response.buildResponse(SdkError.SUCCESS, result);
} catch (SDKException apiException) {
Integer errorCode = apiException.getErrorCode();
String errorDesc = apiException.getErrorDesc();
response.buildResponse(errorCode, errorDesc, result);
} catch (Exception e) {
response.buildResponse(SdkError.SYSTEM_ERROR.getCode(), e.getMessage(), result);
}
return response;
}
@Override
public BIFContractInvokeResponse contractInvoke(BIFContractInvokeRequest request) {
BIFContractInvokeResponse response = new BIFContractInvokeResponse();
BIFContractInvokeResult result = new BIFContractInvokeResult();
try {
if (Tools.isEmpty(request)) {
throw new SDKException(SdkError.REQUEST_NULL_ERROR);
}
String senderAddress = request.getSenderAddress();
if (!PublicKeyManager.isAddressValid(senderAddress)) {
throw new SDKException(SdkError.INVALID_ADDRESS_ERROR);
}
BIFContractInvokeOperation operation = new BIFContractInvokeOperation();
String contractAddress = request.getContractAddress();
if (!PublicKeyManager.isAddressValid(contractAddress)) {
throw new SDKException(SdkError.INVALID_CONTRACTADDRESS_ERROR);
}
Long bifAmount = request.getBIFAmount();
if (Tools.isEmpty(bifAmount) || bifAmount < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_AMOUNT_ERROR);
}
String input = request.getInput();
operation.setContractAddress(contractAddress);
operation.setBIFAmount(bifAmount);
operation.setInput(input);
String privateKey = request.getPrivateKey();
if (Tools.isEmpty(privateKey)) {
throw new SDKException(SdkError.PRIVATEKEY_NULL_ERROR);
}
Long feeLimit = request.getFeeLimit();
if (Tools.isEmpty(feeLimit)) {
feeLimit = Constant.FEE_LIMIT;
}
if (Tools.isEmpty(feeLimit) || feeLimit < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_FEELIMIT_ERROR);
}
Long gasPrice = request.getGasPrice();
if (Tools.isEmpty(gasPrice)) {
gasPrice = Constant.GAS_PRICE;
}
if (Tools.isEmpty(gasPrice) || gasPrice < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_GASPRICE_ERROR);
}
Long ceilLedgerSeq = request.getCeilLedgerSeq();
String remarks = request.getRemarks();
Integer domainId=request.getDomainId();
if(Tools.isNULL(domainId)){
domainId=Constant.INIT_ZERO;
}
if(!Tools.isNULL(domainId) && domainId < Constant.INIT_ZERO){
throw new SDKException(SdkError.INVALID_DOMAINID_ERROR);
}
Integer nonceType = request.getNonceType();
if(Tools.isNULL(nonceType)){
nonceType = Constant.INIT_ZERO;
}else if(!(nonceType == 0 || nonceType == 1)){
throw new SDKException(SdkError.INVALID_NONCE_TYPE_ERROR);
}
if (!checkContractValid(contractAddress,domainId)) {
throw new SDKException(SdkError.CONTRACTADDRESS_NOT_CONTRACTACCOUNT_ERROR);
}
// 广播交易
BIFTransactionService transactionService = new BIFTransactionServiceImpl();
String hash = transactionService.radioTransaction(senderAddress, feeLimit, gasPrice, operation,
ceilLedgerSeq, remarks, privateKey,domainId,nonceType);
result.setHash(hash);
response.buildResponse(SdkError.SUCCESS, result);
} catch (SDKException apiException) {
Integer errorCode = apiException.getErrorCode();
String errorDesc = apiException.getErrorDesc();
response.buildResponse(errorCode, errorDesc, result);
} catch (Exception e) {
response.buildResponse(SdkError.SYSTEM_ERROR.getCode(), e.getMessage(), result);
}
return response;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy