Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
cn.bif.module.blockchain.impl.BIFTransactionServiceImpl 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.blockchain.impl;
import cn.bif.api.BIFSDK;
import cn.bif.common.*;
import cn.bif.exception.SDKException;
import cn.bif.exception.SdkError;
import cn.bif.model.response.bid.BID;
import cn.bif.model.response.result.data.*;
import cn.bif.utils.http.HttpUtils;
import cn.bif.model.request.*;
import cn.bif.model.request.operation.*;
import cn.bif.model.response.*;
import cn.bif.model.response.result.*;
import cn.bif.module.account.impl.BIFAccountServiceImpl;
import cn.bif.module.blockchain.BIFBlockService;
import cn.bif.module.blockchain.BIFTransactionService;
import cn.bif.module.contract.impl.BIFContractServiceImpl;
import cn.bif.module.encryption.key.PrivateKeyManager;
import cn.bif.module.encryption.key.PublicKeyManager;
import cn.bif.utils.hash.HashUtil;
import cn.bif.utils.hash.model.HashType;
import cn.bif.utils.hex.HexFormat;
import cn.bif.protobuf.Chain;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.googlecode.protobuf.format.JsonFormat;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class BIFTransactionServiceImpl implements BIFTransactionService {
/**
* @Method BIFSerializable
* @Params [bifTransactionSerializeRequest]
* @Return BIFTransactionSerializeResponse
*/
@Override
public BIFTransactionSerializeResponse BIFSerializable(BIFTransactionSerializeRequest bifTransactionSerializeRequest) {
BIFTransactionSerializeResponse bifTransactionSerializeResponse = new BIFTransactionSerializeResponse();
BIFTransactionSerializeResult transactionSerializeResult = new BIFTransactionSerializeResult();
try {
if (Tools.isEmpty(bifTransactionSerializeRequest)) {
throw new SDKException(SdkError.REQUEST_NULL_ERROR);
}
// check sourceAddress
String sourceAddress = bifTransactionSerializeRequest.getSourceAddress();
if (!PublicKeyManager.isAddressValid(sourceAddress)) {
throw new SDKException(SdkError.INVALID_SOURCEADDRESS_ERROR);
}
// check nonce
Long nonce = bifTransactionSerializeRequest.getNonce();
if (Tools.isEmpty(nonce) || nonce < Constant.INIT_ONE) {
throw new SDKException(SdkError.INVALID_NONCE_ERROR);
}
// check gasPrice
Long gasPrice = bifTransactionSerializeRequest.getGasPrice();
if (Tools.isEmpty(gasPrice) || gasPrice < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_GASPRICE_ERROR);
}
// check feeLimit
Long feeLimit = bifTransactionSerializeRequest.getFeeLimit();
if (Tools.isEmpty(feeLimit) || feeLimit < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_FEELIMIT_ERROR);
}
Long ceilLedgerSeq = bifTransactionSerializeRequest.getCeilLedgerSeq();
if (!Tools.isEmpty(ceilLedgerSeq) && ceilLedgerSeq < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_CEILLEDGERSEQ_ERROR);
}
// check metadata
String metadata = bifTransactionSerializeRequest.getMetadata();
// build transaction
Chain.Transaction.Builder transaction = Chain.Transaction.newBuilder();
// add note
if (!Tools.isEmpty(metadata)) {
transaction.setMetadata(ByteString.copyFromUtf8(metadata));
}
Long maxLedgerSeq = bifTransactionSerializeRequest.getMaxLedgerSeq();
if (!Tools.isEmpty(maxLedgerSeq)) {
transaction.setMaxLedgerSeq(maxLedgerSeq);
}
Integer nonceType = bifTransactionSerializeRequest.getNonceType();
if (!Tools.isEmpty(nonceType)) {
transaction.setNonceTypeValue(nonceType);
transaction.setNonceType(Chain.Transaction.NonceType.forNumber(nonceType));
}
// check operation
BIFBaseOperation[] operations = bifTransactionSerializeRequest.getOperations();
//domainId
Integer domainId = bifTransactionSerializeRequest.getDomainId();
operations[0].setDomainId(domainId);
if (Tools.isEmpty(operations)) {
throw new SDKException(SdkError.OPERATIONS_EMPTY_ERROR);
}
buildOperations(operations, sourceAddress, transaction);
// add other information
transaction.setSourceAddress(sourceAddress);
transaction.setNonce(nonce);
transaction.setFeeLimit(feeLimit);
transaction.setGasPrice(gasPrice);
transaction.setDomainId(domainId);
if (!Tools.isEmpty(BIFSDK.getSdk().getChainId())) {
transaction.setChainId(BIFSDK.getSdk().getChainId());
}
if (!Tools.isEmpty(ceilLedgerSeq)) {
// get blockNumber
BIFBlockGetNumberInfoRequest request =new BIFBlockGetNumberInfoRequest();
request.setDomainId(domainId);
BIFBlockService blockService = new BIFBlockServiceImpl();
BIFBlockGetNumberResponse blockGetNumberResponse = blockService.getBlockNumber(request);
Integer errorCode = blockGetNumberResponse.getErrorCode();
if (!Tools.isEmpty(errorCode) && !errorCode.equals(Constant.SUCCESS)) {
String errorDesc = blockGetNumberResponse.getErrorDesc();
throw new SDKException(errorCode, errorDesc);
} else if (Tools.isEmpty(errorCode)) {
throw new SDKException(SdkError.CONNECTNETWORK_ERROR);
}
// check ceilLedgerSeq
Long blockNumber = blockGetNumberResponse.getResult().getHeader().getBlockNumber();
transaction.setCeilLedgerSeq(ceilLedgerSeq + blockNumber);
}
byte[] transactionBlobBytes = transaction.build().toByteArray();
String transactionBlob = HexFormat.byteToHex(transactionBlobBytes);
transactionSerializeResult.setTransactionBlob(transactionBlob);
transactionSerializeResult.setHash(HashUtil.GenerateHashHex(transactionBlobBytes, HashType.SHA256));
bifTransactionSerializeResponse.buildResponse(SdkError.SUCCESS, transactionSerializeResult);
} catch (SDKException apiException) {
Integer errorCode = apiException.getErrorCode();
String errorDesc = apiException.getErrorDesc();
bifTransactionSerializeResponse.buildResponse(errorCode, errorDesc, transactionSerializeResult);
} catch (Exception e) {
bifTransactionSerializeResponse.buildResponse(SdkError.SYSTEM_ERROR.getCode(), e.getMessage(), transactionSerializeResult);
}
return bifTransactionSerializeResponse;
}
/**
* @Method submit
* @Params [transactionSubmitRequest]
* @Return TransactionSubmitResponse
*/
@Override
public BIFTransactionSubmitResponse BIFSubmit(BIFTransactionSubmitRequest bifTransactionSubmitRequest) {
BIFTransactionSubmitResponse bifTransactionSubmitResponse = new BIFTransactionSubmitResponse();
BIFTransactionSubmitResult transactionSubmitResult = new BIFTransactionSubmitResult();
try {
if (Tools.isEmpty(General.getInstance().getUrl())) {
throw new SDKException(SdkError.URL_EMPTY_ERROR);
}
if (Tools.isEmpty(bifTransactionSubmitRequest)) {
throw new SDKException(SdkError.REQUEST_NULL_ERROR);
}
String blob = bifTransactionSubmitRequest.getSerialization();
if (Tools.isEmpty(blob)) {
throw new SDKException(SdkError.INVALID_SERIALIZATION_ERROR);
}
Chain.Transaction.parseFrom(HexFormat.hexToByte(blob));
// serializable transaction request
Map transactionItemsRequest = new HashMap<>();
List transactionItems = new ArrayList<>();
Map transactionItem = new HashMap<>();
transactionItem.put("transaction_blob", blob);
// build sign
List signatureItems = new ArrayList<>();
if(bifTransactionSubmitRequest.getSignatures() != null && bifTransactionSubmitRequest.getSignatures().length > 0){
for (BIFSignature signature:bifTransactionSubmitRequest.getSignatures()) {
Map signatureItem = new HashMap<>();
String signData = signature.getSignData();
if (Tools.isEmpty(signData)) {
throw new SDKException(SdkError.SIGNDATA_NULL_ERROR);
}
String publicKey = signature.getPublicKey();
if (Tools.isEmpty(publicKey)) {
throw new SDKException(SdkError.PUBLICKEY_NULL_ERROR);
}
signatureItem.put("sign_data", signData);
signatureItem.put("public_key", publicKey);
signatureItems.add(signatureItem);
}
}else {
String signData = bifTransactionSubmitRequest.getSignData();
if (Tools.isEmpty(signData)) {
throw new SDKException(SdkError.SIGNDATA_NULL_ERROR);
}
String publicKey = bifTransactionSubmitRequest.getPublicKey();
if (Tools.isEmpty(publicKey)) {
throw new SDKException(SdkError.PUBLICKEY_NULL_ERROR);
}
Map signatureItem = new HashMap<>();
signatureItem.put("sign_data", signData);
signatureItem.put("public_key", publicKey);
signatureItems.add(signatureItem);
}
transactionItem.put("signatures", signatureItems);
transactionItems.add(transactionItem);
transactionItemsRequest.put("items", transactionItems);
// submit
String submitUrl = General.getInstance().transactionSubmitUrl();
String transactionRequest = JsonUtils.toJSONString(transactionItemsRequest);
String result = HttpUtils.httpPost(submitUrl, transactionRequest);
BIFTransactionSubmitHttpResponse transactionSubmitHttpResponse = JsonUtils.toJavaObject(result, BIFTransactionSubmitHttpResponse.class);
Integer successCount = transactionSubmitHttpResponse.getSuccessCount();
BIFTransactionSubmitHttpResult[] httpResults = transactionSubmitHttpResponse.getResults();
if (!Tools.isEmpty(httpResults)) {
transactionSubmitResult.setHash(httpResults[0].getHash());
if (!Tools.isEmpty(successCount) && 0 == successCount) {
Integer errorCode = httpResults[0].getErrorCode();
String errorDesc = httpResults[0].getErrorDesc();
throw new SDKException(errorCode, errorDesc);
}
} else {
throw new SDKException(SdkError.INVALID_SERIALIZATION_ERROR);
}
bifTransactionSubmitResponse.buildResponse(SdkError.SUCCESS, transactionSubmitResult);
} catch (SDKException apiException) {
Integer errorCode = apiException.getErrorCode();
String errorDesc = apiException.getErrorDesc();
bifTransactionSubmitResponse.buildResponse(errorCode, errorDesc, transactionSubmitResult);
} catch (InvalidProtocolBufferException | IllegalArgumentException e) {
bifTransactionSubmitResponse.buildResponse(SdkError.INVALID_SERIALIZATION_ERROR, transactionSubmitResult);
} catch (NoSuchAlgorithmException | KeyManagementException | NoSuchProviderException | IOException e) {
bifTransactionSubmitResponse.buildResponse(SdkError.CONNECTN_BLOCKCHAIN_ERROR, transactionSubmitResult);
} catch (Exception e) {
bifTransactionSubmitResponse.buildResponse(SdkError.SYSTEM_ERROR.getCode(), e.getMessage(), transactionSubmitResult);
}
return bifTransactionSubmitResponse;
}
/**
* 广播交易
*
* @return
*/
@Override
public String radioTransaction(String senderAddress, Long feeLimit, Long gasPrice, BIFBaseOperation operation,
Long ceilLedgerSeq, String remarks, String senderPrivateKey,Integer domainId,
Integer nonceType) {
BIFAccountServiceImpl accountService = new BIFAccountServiceImpl();
BIFBlockServiceImpl blockService = new BIFBlockServiceImpl();
Long nonce = null;
Long maxLedgerSeq = null;
if(nonceType == 1){
//随机nonce
//1.获取区块高度
BIFBlockGetNumberInfoRequest request = new BIFBlockGetNumberInfoRequest();
BIFBlockGetNumberResponse response = blockService.getBlockNumber(request);
if (!response.getErrorCode().equals(Constant.SUCCESS)) {
throw new SDKException(response.getErrorCode(), response.getErrorDesc());
}
maxLedgerSeq = response.getResult().getHeader().getBlockNumber() + RandomNonceUtils.getDefaultRangeRandom();
//2.获取nonce值
nonce = SnowFlake.generateId();
}else{
// 一、获取交易发起的账号nonce值
BIFAccountGetNonceRequest getNonceRequest = new BIFAccountGetNonceRequest();
getNonceRequest.setAddress(senderAddress);
getNonceRequest.setDomainId(domainId);
// 调用getBIFNonce接口
BIFAccountGetNonceResponse nonceResponse = accountService.getNonce(getNonceRequest);
if (!nonceResponse.getErrorCode().equals(Constant.SUCCESS)) {
throw new SDKException(nonceResponse.getErrorCode(), nonceResponse.getErrorDesc());
}
nonce = nonceResponse.getResult().getNonce();
if (Tools.isEmpty(nonce) || nonce < 1) {
nonce=0L;
}
}
// 二、构建操作、序列化交易
// 初始化请求参数
BIFTransactionSerializeRequest serializeRequest = new BIFTransactionSerializeRequest();
serializeRequest.setSourceAddress(senderAddress);
serializeRequest.setNonce(nonce + 1);
serializeRequest.setFeeLimit(feeLimit);
serializeRequest.setGasPrice(gasPrice);
serializeRequest.setOperation(operation);
serializeRequest.setCeilLedgerSeq(ceilLedgerSeq);
serializeRequest.setDomainId(domainId);
serializeRequest.setNonceType(nonceType);
serializeRequest.setMaxLedgerSeq(maxLedgerSeq);
// 调用BIFSerializable接口
serializeRequest.setMetadata(remarks);
BIFTransactionSerializeResponse serializeResponse = BIFSerializable(serializeRequest);
if (!serializeResponse.getErrorCode().equals(Constant.SUCCESS)) {
throw new SDKException(serializeResponse.getErrorCode(), serializeResponse.getErrorDesc());
}
String transactionBlob = serializeResponse.getResult().getTransactionBlob();
// 三、签名
byte[] signBytes = PrivateKeyManager.sign(HexFormat.hexToByte(transactionBlob), senderPrivateKey);
String publicKey = PrivateKeyManager.getEncPublicKey(senderPrivateKey);
//四、提交交易
BIFTransactionSubmitRequest submitRequest = new BIFTransactionSubmitRequest();
submitRequest.setSerialization(transactionBlob);
submitRequest.addSignature(publicKey,HexFormat.byteToHex(signBytes));
//submitRequest.setPublicKey(publicKey);
//submitRequest.setSignData(HexFormat.byteToHex(signBytes));
// 调用bifSubmit接口
BIFTransactionSubmitResponse transactionSubmitResponse = BIFSubmit(submitRequest);
if (!transactionSubmitResponse.getErrorCode().equals(Constant.SUCCESS)) {
throw new SDKException(transactionSubmitResponse.getErrorCode(), transactionSubmitResponse.getErrorDesc());
}
return transactionSubmitResponse.getResult().getHash();
}
/**
* 广播交易
*
* @return
*/
@Override
public String radioTransaction(String senderAddress, Long feeLimit, Long gasPrice, List operations,
Long ceilLedgerSeq, String remarks, String senderPrivateKey, Integer domainId, Integer nonceType) {
BIFAccountServiceImpl accountService = new BIFAccountServiceImpl();
BIFBlockServiceImpl blockService = new BIFBlockServiceImpl();
Long nonce = null;
Long maxLedgerSeq = null;
if(nonceType == 1){
//随机nonce
//1.获取区块高度
BIFBlockGetNumberInfoRequest request = new BIFBlockGetNumberInfoRequest();
BIFBlockGetNumberResponse response = blockService.getBlockNumber(request);
if (!response.getErrorCode().equals(Constant.SUCCESS)) {
throw new SDKException(response.getErrorCode(), response.getErrorDesc());
}
maxLedgerSeq = response.getResult().getHeader().getBlockNumber() + RandomNonceUtils.getDefaultRangeRandom();
//2.获取nonce值
nonce = SnowFlake.generateId();
}else{
// 一、获取交易发起的账号nonce值
BIFAccountGetNonceRequest getNonceRequest = new BIFAccountGetNonceRequest();
getNonceRequest.setAddress(senderAddress);
getNonceRequest.setDomainId(domainId);
// 调用getBIFNonce接口
BIFAccountGetNonceResponse nonceResponse = accountService.getNonce(getNonceRequest);
if (!nonceResponse.getErrorCode().equals(Constant.SUCCESS)) {
throw new SDKException(nonceResponse.getErrorCode(), nonceResponse.getErrorDesc());
}
nonce = nonceResponse.getResult().getNonce();
if (Tools.isEmpty(nonce) || nonce < 1) {
nonce=0L;
}
}
// 二、构建操作、序列化交易
// 初始化请求参数
BIFTransactionSerializeRequest serializeRequest = new BIFTransactionSerializeRequest();
serializeRequest.setSourceAddress(senderAddress);
serializeRequest.setNonce(nonce + 1);
serializeRequest.setFeeLimit(feeLimit);
serializeRequest.setGasPrice(gasPrice);
serializeRequest.setDomainId(domainId);
serializeRequest.setNonceType(nonceType);
serializeRequest.setMaxLedgerSeq(maxLedgerSeq);
for (BIFContractInvokeOperation opt: operations
) {
serializeRequest.addOperation(opt);
}
serializeRequest.setCeilLedgerSeq(ceilLedgerSeq);
// 调用BIFSerializable接口
serializeRequest.setMetadata(remarks);
BIFTransactionSerializeResponse serializeResponse = BIFSerializable(serializeRequest);
if (!serializeResponse.getErrorCode().equals(Constant.SUCCESS)) {
throw new SDKException(serializeResponse.getErrorCode(), serializeResponse.getErrorDesc());
}
String transactionBlob = serializeResponse.getResult().getTransactionBlob();
// 三、签名
byte[] signBytes = PrivateKeyManager.sign(HexFormat.hexToByte(transactionBlob), senderPrivateKey);
String publicKey = PrivateKeyManager.getEncPublicKey(senderPrivateKey);
//四、提交交易
BIFTransactionSubmitRequest submitRequest = new BIFTransactionSubmitRequest();
submitRequest.setSerialization(transactionBlob);
submitRequest.addSignature(publicKey,HexFormat.byteToHex(signBytes));
//submitRequest.setPublicKey(publicKey);
//submitRequest.setSignData(HexFormat.byteToHex(signBytes));
// 调用bifSubmit接口
BIFTransactionSubmitResponse transactionSubmitResponse = BIFSubmit(submitRequest);
if (!transactionSubmitResponse.getErrorCode().equals(Constant.SUCCESS)) {
throw new SDKException(transactionSubmitResponse.getErrorCode(), transactionSubmitResponse.getErrorDesc());
}
return transactionSubmitResponse.getResult().getHash();
}
/**
* 广播交易--批量gas
*
* @return
*/
@Override
public String radioGasTransaction(String senderAddress, Long feeLimit, Long gasPrice, List operations,
Long ceilLedgerSeq, String remarks, String senderPrivateKey, Integer domainId, Integer nonceType) {
BIFAccountServiceImpl accountService = new BIFAccountServiceImpl();
// 一、获取交易发起的账号nonce值
BIFBlockServiceImpl blockService = new BIFBlockServiceImpl();
Long nonce = null;
Long maxLedgerSeq = null;
if(nonceType == 1){
//随机nonce
//1.获取区块高度
BIFBlockGetNumberInfoRequest request = new BIFBlockGetNumberInfoRequest();
BIFBlockGetNumberResponse response = blockService.getBlockNumber(request);
if (!response.getErrorCode().equals(Constant.SUCCESS)) {
throw new SDKException(response.getErrorCode(), response.getErrorDesc());
}
maxLedgerSeq = response.getResult().getHeader().getBlockNumber() + RandomNonceUtils.getDefaultRangeRandom();
//2.获取nonce值
nonce = SnowFlake.generateId();
}else {
BIFAccountGetNonceRequest getNonceRequest = new BIFAccountGetNonceRequest();
getNonceRequest.setAddress(senderAddress);
getNonceRequest.setDomainId(domainId);
// 调用getBIFNonce接口
BIFAccountGetNonceResponse nonceResponse = accountService.getNonce(getNonceRequest);
if (!nonceResponse.getErrorCode().equals(Constant.SUCCESS)) {
throw new SDKException(nonceResponse.getErrorCode(), nonceResponse.getErrorDesc());
}
nonce = nonceResponse.getResult().getNonce();
if (Tools.isEmpty(nonce) || nonce < 1) {
nonce = 0L;
}
}
// 二、构建操作、序列化交易
// 初始化请求参数
BIFTransactionSerializeRequest serializeRequest = new BIFTransactionSerializeRequest();
serializeRequest.setSourceAddress(senderAddress);
serializeRequest.setNonce(nonce + 1);
serializeRequest.setFeeLimit(feeLimit);
serializeRequest.setGasPrice(gasPrice);
serializeRequest.setDomainId(domainId);
serializeRequest.setNonceType(nonceType);
serializeRequest.setMaxLedgerSeq(maxLedgerSeq);
for (BIFGasSendOperation opt: operations
) {
serializeRequest.addOperation(opt);
}
serializeRequest.setCeilLedgerSeq(ceilLedgerSeq);
// 调用BIFSerializable接口
serializeRequest.setMetadata(remarks);
BIFTransactionSerializeResponse serializeResponse = BIFSerializable(serializeRequest);
if (!serializeResponse.getErrorCode().equals(Constant.SUCCESS)) {
throw new SDKException(serializeResponse.getErrorCode(), serializeResponse.getErrorDesc());
}
String transactionBlob = serializeResponse.getResult().getTransactionBlob();
// 三、签名
byte[] signBytes = PrivateKeyManager.sign(HexFormat.hexToByte(transactionBlob), senderPrivateKey);
String publicKey = PrivateKeyManager.getEncPublicKey(senderPrivateKey);
//四、提交交易
BIFTransactionSubmitRequest submitRequest = new BIFTransactionSubmitRequest();
submitRequest.setSerialization(transactionBlob);
submitRequest.addSignature(publicKey,HexFormat.byteToHex(signBytes));
//submitRequest.setPublicKey(publicKey);
//submitRequest.setSignData(HexFormat.byteToHex(signBytes));
// 调用bifSubmit接口
BIFTransactionSubmitResponse transactionSubmitResponse = BIFSubmit(submitRequest);
if (!transactionSubmitResponse.getErrorCode().equals(Constant.SUCCESS)) {
throw new SDKException(transactionSubmitResponse.getErrorCode(), transactionSubmitResponse.getErrorDesc());
}
return transactionSubmitResponse.getResult().getHash();
}
/**
* @Method getInfo
* @Params [transactionGetInfoRequest]
* @Return TransactionGetInfoResponse
*/
@Override
public BIFTransactionGetInfoResponse getTransactionInfo(BIFTransactionGetInfoRequest transactionGetInfoRequest) {
BIFTransactionGetInfoResponse transactionGetInfoResponse = new BIFTransactionGetInfoResponse();
BIFTransactionGetInfoResult transactionGetInfoResult = new BIFTransactionGetInfoResult();
try {
if (Tools.isEmpty(General.getInstance().getUrl())) {
throw new SDKException(SdkError.URL_EMPTY_ERROR);
}
if (Tools.isEmpty(transactionGetInfoRequest)) {
throw new SDKException(SdkError.REQUEST_NULL_ERROR);
}
String hash = transactionGetInfoRequest.getHash();
if (Tools.isEmpty(hash) || hash.length() != Constant.HASH_HEX_LENGTH) {
throw new SDKException(SdkError.INVALID_HASH_ERROR);
}
Integer domainId=transactionGetInfoRequest.getDomainId();
if(Tools.isNULL(domainId)){
domainId=Constant.INIT_ZERO;
}
if(!Tools.isNULL(domainId) && domainId < Constant.INIT_ZERO){
throw new SDKException(SdkError.INVALID_DOMAINID_ERROR);
}
transactionGetInfoResponse = getTransactionInfo(hash,domainId);
} catch (SDKException apiException) {
Integer errorCode = apiException.getErrorCode();
String errorDesc = apiException.getErrorDesc();
transactionGetInfoResponse.buildResponse(errorCode, errorDesc, transactionGetInfoResult);
} catch (NoSuchAlgorithmException | KeyManagementException | NoSuchProviderException | IOException e) {
transactionGetInfoResponse.buildResponse(SdkError.CONNECTNETWORK_ERROR, transactionGetInfoResult);
} catch (Exception e) {
transactionGetInfoResponse.buildResponse(SdkError.SYSTEM_ERROR.getCode(), e.getMessage(), transactionGetInfoResult);
}
return transactionGetInfoResponse;
}
@Override
public BIFTransactionGasSendResponse gasSend(BIFTransactionGasSendRequest request) {
BIFTransactionGasSendResponse response = new BIFTransactionGasSendResponse();
BIFTransactionGasSendResult result = new BIFTransactionGasSendResult();
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);
}
String privateKey = request.getPrivateKey();
if (Tools.isEmpty(privateKey)) {
throw new SDKException(SdkError.PRIVATEKEY_NULL_ERROR);
}
Long ceilLedgerSeq = request.getCeilLedgerSeq();
String remarks = request.getRemarks();
BIFGasSendOperation operation = new BIFGasSendOperation();
String destAddress = request.getDestAddress();
if (!PublicKeyManager.isAddressValid(destAddress)) {
throw new SDKException(SdkError.INVALID_DESTADDRESS_ERROR);
}
Long amount = request.getAmount();
if (Tools.isEmpty(amount) || amount < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_GAS_AMOUNT_ERROR);
}
operation.setDestAddress(destAddress);
operation.setAmount(amount);
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);
}
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);
}
// 广播交易
String hash = 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;
}
/**
* @Method evaluateFee
* @Params [TransactionEvaluateFeeRequest]
* @Return TransactionEvaluateFeeResponse
*/
@Override
public BIFTransactionEvaluateFeeResponse evaluateFee(BIFTransactionEvaluateFeeRequest BIFTransactionEvaluateFeeRequest) {
BIFTransactionEvaluateFeeResponse BIFTransactionEvaluateFeeResponse = new BIFTransactionEvaluateFeeResponse();
BIFTransactionEvaluateFeeResult BIFTransactionEvaluateFeeResult = new BIFTransactionEvaluateFeeResult();
try {
if (Tools.isEmpty(General.getInstance().getUrl())) {
throw new SDKException(SdkError.URL_EMPTY_ERROR);
}
if (Tools.isEmpty(BIFTransactionEvaluateFeeRequest)) {
throw new SDKException(SdkError.REQUEST_NULL_ERROR);
}
// check sourceAddress
String sourceAddress = BIFTransactionEvaluateFeeRequest.getSourceAddress();
if (!PublicKeyManager.isAddressValid(sourceAddress)) {
throw new SDKException(SdkError.INVALID_SOURCEADDRESS_ERROR);
}
Integer nonceType = BIFTransactionEvaluateFeeRequest.getNonceType();
if(Tools.isNULL(nonceType)){
nonceType = Constant.INIT_ZERO;
}else if(!(nonceType == 0 || nonceType == 1)){
throw new SDKException(SdkError.INVALID_NONCE_TYPE_ERROR);
}
// check nonce
BIFAccountServiceImpl accountService = new BIFAccountServiceImpl();
BIFBlockServiceImpl blockService = new BIFBlockServiceImpl();
Long nonce = null;
Long maxLedgerSeq = null;
if(nonceType == 1){
//随机nonce
//1.获取区块高度
BIFBlockGetNumberInfoRequest request = new BIFBlockGetNumberInfoRequest();
BIFBlockGetNumberResponse response = blockService.getBlockNumber(request);
if (!response.getErrorCode().equals(Constant.SUCCESS)) {
throw new SDKException(response.getErrorCode(), response.getErrorDesc());
}
maxLedgerSeq = response.getResult().getHeader().getBlockNumber() + RandomNonceUtils.getDefaultRangeRandom();
//2.获取nonce值
nonce = SnowFlake.generateId();
}else {
// 一、获取交易发起的账号nonce值
BIFAccountGetNonceRequest getNonceRequest = new BIFAccountGetNonceRequest();
getNonceRequest.setAddress(sourceAddress);
getNonceRequest.setDomainId(BIFTransactionEvaluateFeeRequest.getDomainId());
// 调用getBIFNonce接口
BIFAccountGetNonceResponse nonceResponse = accountService.getNonce(getNonceRequest);
if (!nonceResponse.getErrorCode().equals(Constant.SUCCESS)) {
throw new SDKException(nonceResponse.getErrorCode(), nonceResponse.getErrorDesc());
}
nonce = nonceResponse.getResult().getNonce();
if (Tools.isEmpty(nonce) || nonce < 1) {
nonce = 0L;
}
}
// check signatureNum
Integer signatureNum = BIFTransactionEvaluateFeeRequest.getSignatureNumber();
if (Tools.isEmpty(signatureNum) || signatureNum < 1) {
throw new SDKException(SdkError.INVALID_SIGNATURENUMBER_ERROR);
}
// check metadata
String metadata = BIFTransactionEvaluateFeeRequest.getRemarks();
// build transaction
Chain.Transaction.Builder transaction = Chain.Transaction.newBuilder();
BIFBaseOperation baseOperations = BIFTransactionEvaluateFeeRequest.getOperation();
if(Tools.isEmpty(baseOperations)){
throw new SDKException(SdkError.OPERATIONS_EMPTY_ERROR);
}
Long feeLimit = BIFTransactionEvaluateFeeRequest.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 = BIFTransactionEvaluateFeeRequest.getGasPrice();
if (Tools.isEmpty(gasPrice) || gasPrice < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_GASPRICE_ERROR);
}
Integer domainId = BIFTransactionEvaluateFeeRequest.getDomainId();
if(Tools.isNULL(domainId)){
domainId=Constant.INIT_ZERO;
}
if(!Tools.isNULL(domainId) && domainId < Constant.INIT_ZERO){
throw new SDKException(SdkError.INVALID_DOMAINID_ERROR);
}
BIFBaseOperation[] operations = new BIFBaseOperation[1];
operations[0] = baseOperations;
buildOperations(operations, sourceAddress, transaction);
transaction.setSourceAddress(sourceAddress);
transaction.setNonce(nonce+1);
transaction.setDomainId(domainId);
if (!Tools.isEmpty(maxLedgerSeq)) {
transaction.setMaxLedgerSeq(maxLedgerSeq);
}
if (!Tools.isEmpty(nonceType)) {
transaction.setNonceTypeValue(nonceType);
transaction.setNonceType(Chain.Transaction.NonceType.forNumber(nonceType));
}
if (!Tools.isEmpty(feeLimit)) {
transaction.setFeeLimit(feeLimit);
}
if(!Tools.isEmpty(gasPrice)){
transaction.setGasPrice(gasPrice);
}
if (!Tools.isEmpty(metadata)) {
transaction.setMetadata(ByteString.copyFromUtf8(HexFormat.byteToHex(metadata.getBytes())));
}
// protocol buffer to json
JsonFormat jsonFormat = new JsonFormat();
String transactionStr = jsonFormat.printToString(transaction.build());
Map transactionJson = JsonUtils.toMap(transactionStr);
// build testTransaction request
Map testTransactionRequest = new HashMap<>();;
List transactionItems = new ArrayList<>();
Map transactionItem = new HashMap<>();
transactionItem.put("transaction_json", transactionJson);
transactionItems.add(transactionItem);
testTransactionRequest.put("items", transactionItems);
String evaluationFeeUrl = General.getInstance().transactionEvaluationFee();
String result = HttpUtils.httpPost(evaluationFeeUrl, JsonUtils.toJSONString(testTransactionRequest));
BIFTransactionEvaluateFeeResponse = JsonUtils.toJavaObject(result, BIFTransactionEvaluateFeeResponse.class);
} catch (SDKException apiException) {
Integer errorCode = apiException.getErrorCode();
String errorDesc = apiException.getErrorDesc();
BIFTransactionEvaluateFeeResponse.buildResponse(errorCode, errorDesc, BIFTransactionEvaluateFeeResult);
} catch (NoSuchAlgorithmException | KeyManagementException | NoSuchProviderException | IOException e) {
BIFTransactionEvaluateFeeResponse.buildResponse(SdkError.CONNECTNETWORK_ERROR, BIFTransactionEvaluateFeeResult);
} catch (Exception e) {
BIFTransactionEvaluateFeeResponse.buildResponse(SdkError.SYSTEM_ERROR.getCode(), e.getMessage(), BIFTransactionEvaluateFeeResult);
}
return BIFTransactionEvaluateFeeResponse;
}
@Override
public BIFTransactionEvaluateFeeResponse batchEvaluateFee(BIFTransactionEvaluateFeeRequest BIFTransactionEvaluateFeeRequest) {
BIFTransactionEvaluateFeeResponse BIFTransactionEvaluateFeeResponse = new BIFTransactionEvaluateFeeResponse();
BIFTransactionEvaluateFeeResult BIFTransactionEvaluateFeeResult = new BIFTransactionEvaluateFeeResult();
try {
if (Tools.isEmpty(General.getInstance().getUrl())) {
throw new SDKException(SdkError.URL_EMPTY_ERROR);
}
if (Tools.isEmpty(BIFTransactionEvaluateFeeRequest)) {
throw new SDKException(SdkError.REQUEST_NULL_ERROR);
}
// check sourceAddress
String sourceAddress = BIFTransactionEvaluateFeeRequest.getSourceAddress();
if (!PublicKeyManager.isAddressValid(sourceAddress)) {
throw new SDKException(SdkError.INVALID_SOURCEADDRESS_ERROR);
}
Integer nonceType = BIFTransactionEvaluateFeeRequest.getNonceType();
if(Tools.isNULL(nonceType)){
nonceType = Constant.INIT_ZERO;
}else if(!(nonceType == 0 || nonceType == 1)){
throw new SDKException(SdkError.INVALID_NONCE_TYPE_ERROR);
}
// check nonce
BIFAccountServiceImpl accountService = new BIFAccountServiceImpl();
BIFBlockServiceImpl blockService = new BIFBlockServiceImpl();
Long nonce = null;
Long maxLedgerSeq = null;
if(nonceType == 1){
//随机nonce
//1.获取区块高度
BIFBlockGetNumberInfoRequest request = new BIFBlockGetNumberInfoRequest();
BIFBlockGetNumberResponse response = blockService.getBlockNumber(request);
if (!response.getErrorCode().equals(Constant.SUCCESS)) {
throw new SDKException(response.getErrorCode(), response.getErrorDesc());
}
maxLedgerSeq = response.getResult().getHeader().getBlockNumber() + RandomNonceUtils.getDefaultRangeRandom();
//2.获取nonce值
nonce = SnowFlake.generateId();
}else {
// 一、获取交易发起的账号nonce值
BIFAccountGetNonceRequest getNonceRequest = new BIFAccountGetNonceRequest();
getNonceRequest.setAddress(sourceAddress);
getNonceRequest.setDomainId(BIFTransactionEvaluateFeeRequest.getDomainId());
// 调用getBIFNonce接口
BIFAccountGetNonceResponse nonceResponse = accountService.getNonce(getNonceRequest);
if (!nonceResponse.getErrorCode().equals(Constant.SUCCESS)) {
throw new SDKException(nonceResponse.getErrorCode(), nonceResponse.getErrorDesc());
}
nonce = nonceResponse.getResult().getNonce();
if (Tools.isEmpty(nonce) || nonce < 1) {
nonce = 0L;
}
}
// check signatureNum
Integer signatureNum = BIFTransactionEvaluateFeeRequest.getSignatureNumber();
if (Tools.isEmpty(signatureNum) || signatureNum < 1) {
throw new SDKException(SdkError.INVALID_SIGNATURENUMBER_ERROR);
}
// check metadata
String metadata = BIFTransactionEvaluateFeeRequest.getRemarks();
// build transaction
Chain.Transaction.Builder transaction = Chain.Transaction.newBuilder();
List baseOperations = BIFTransactionEvaluateFeeRequest.getOperations();
if(Tools.isEmpty(baseOperations)){
throw new SDKException(SdkError.OPERATIONS_EMPTY_ERROR);
}
Long feeLimit = BIFTransactionEvaluateFeeRequest.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 = BIFTransactionEvaluateFeeRequest.getGasPrice();
if (Tools.isEmpty(gasPrice) || gasPrice < Constant.INIT_ZERO) {
throw new SDKException(SdkError.INVALID_GASPRICE_ERROR);
}
Integer domainId = BIFTransactionEvaluateFeeRequest.getDomainId();
if(Tools.isNULL(domainId)){
domainId=Constant.INIT_ZERO;
}
if(!Tools.isNULL(domainId) && domainId < Constant.INIT_ZERO){
throw new SDKException(SdkError.INVALID_DOMAINID_ERROR);
}
//批量处理
BIFBaseOperation[] operations = new BIFBaseOperation[baseOperations.size()];
for (int i = 0; i < baseOperations.size(); i++) {
operations[i]=baseOperations.get(i);
}
buildOperations(operations, sourceAddress, transaction);
transaction.setSourceAddress(sourceAddress);
transaction.setNonce(nonce+1);
transaction.setDomainId(domainId);
if (!Tools.isEmpty(maxLedgerSeq)) {
transaction.setMaxLedgerSeq(maxLedgerSeq);
}
if (!Tools.isEmpty(nonceType)) {
transaction.setNonceTypeValue(nonceType);
transaction.setNonceType(Chain.Transaction.NonceType.forNumber(nonceType));
}
if (!Tools.isEmpty(feeLimit)) {
transaction.setFeeLimit(feeLimit);
}
if(!Tools.isEmpty(gasPrice)){
transaction.setGasPrice(gasPrice);
}
if (!Tools.isEmpty(metadata)) {
transaction.setMetadata(ByteString.copyFromUtf8(metadata));
}
// protocol buffer to json
JsonFormat jsonFormat = new JsonFormat();
String transactionStr = jsonFormat.printToString(transaction.build());
Map transactionJson = JsonUtils.toMap(transactionStr);
// build testTransaction request
Map testTransactionRequest = new HashMap<>();;
List transactionItems = new ArrayList<>();
Map transactionItem = new HashMap<>();
transactionItem.put("transaction_json", transactionJson);
transactionItems.add(transactionItem);
testTransactionRequest.put("items", transactionItems);
String evaluationFeeUrl = General.getInstance().transactionEvaluationFee();
String result = HttpUtils.httpPost(evaluationFeeUrl, JsonUtils.toJSONString(testTransactionRequest));
BIFTransactionEvaluateFeeResponse = JsonUtils.toJavaObject(result, BIFTransactionEvaluateFeeResponse.class);
} catch (SDKException apiException) {
Integer errorCode = apiException.getErrorCode();
String errorDesc = apiException.getErrorDesc();
BIFTransactionEvaluateFeeResponse.buildResponse(errorCode, errorDesc, BIFTransactionEvaluateFeeResult);
} catch (NoSuchAlgorithmException | KeyManagementException | NoSuchProviderException | IOException e) {
BIFTransactionEvaluateFeeResponse.buildResponse(SdkError.CONNECTNETWORK_ERROR, BIFTransactionEvaluateFeeResult);
} catch (Exception e) {
BIFTransactionEvaluateFeeResponse.buildResponse(SdkError.SYSTEM_ERROR.getCode(), e.getMessage(), BIFTransactionEvaluateFeeResult);
}
return BIFTransactionEvaluateFeeResponse;
}
/**
* @Method buildOperations
* @Params [operationBase, transaction]
* @Return void
*/
private void buildOperations(BIFBaseOperation[] operationBase, String transSourceAddress, Chain.Transaction.Builder transaction) throws SDKException {
for (int i = 0; i < operationBase.length; i++) {
Chain.Operation operation;
OperationType operationType = operationBase[i].getOperationType();
switch (operationType) {
case ACCOUNT_ACTIVATE:
operation = BIFAccountServiceImpl.activate((BIFAccountActivateOperation) operationBase[i], transSourceAddress);
break;
case ACCOUNT_SET_METADATA:
operation = BIFAccountServiceImpl.accountSetMetadata((BIFAccountSetMetadataOperation) operationBase[i]);
break;
case ACCOUNT_SET_PRIVILEGE:
operation = BIFAccountServiceImpl.accountSetPrivilege((BIFAccountSetPrivilegeOperation) operationBase[i]);
break;
case GAS_SEND:
operation = BIFGasServiceImpl.send((BIFGasSendOperation) operationBase[i], transSourceAddress);
break;
case CONTRACT_CREATE:
operation = BIFContractServiceImpl.create((BIFContractCreateOperation) operationBase[i]);
break;
case CONTRACT_INVOKE:
operation = BIFContractServiceImpl.invokeByGas((BIFContractInvokeOperation) operationBase[i], transSourceAddress);
break;
default:
throw new SDKException(SdkError.OPERATIONS_ONE_ERROR);
}
if (Tools.isEmpty(operation)) {
throw new SDKException(SdkError.OPERATIONS_ONE_ERROR);
}
transaction.addOperations(operation);
}
}
/**
* @Method getTxCacheSize
* @Return BIFTransactionGetTxCacheSizeResponse
*/
@Override
public BIFTransactionGetTxCacheSizeResponse getTxCacheSize() {
BIFTransactionGetTxCacheSizeResponse response = new BIFTransactionGetTxCacheSizeResponse();
Long queueSize=0L;
try {
if (Tools.isEmpty(General.getInstance().getUrl())) {
throw new SDKException(SdkError.URL_EMPTY_ERROR);
}
String getInfoUrl = General.getInstance().getTxCacheSize(null);
String result = HttpUtils.httpGet(getInfoUrl);
response = JsonUtils.toJavaObject(result, BIFTransactionGetTxCacheSizeResponse.class);
response.buildResponse(SdkError.SUCCESS,response.getQueueSize());
} catch (SDKException apiException) {
Integer errorCode = apiException.getErrorCode();
String errorDesc = apiException.getErrorDesc();
response.buildResponse(errorCode, errorDesc, queueSize);
} catch (NoSuchAlgorithmException | KeyManagementException | NoSuchProviderException | IOException e) {
response.buildResponse(SdkError.CONNECTNETWORK_ERROR, queueSize);
} catch (Exception e) {
response.buildResponse(SdkError.SYSTEM_ERROR.getCode(), e.getMessage(), queueSize);
}
return response;
}
/**
* @Method getTxCacheSize
* @Return BIFTransactionGetTxCacheSizeResponse
*/
@Override
public BIFTransactionGetTxCacheSizeResponse getTxCacheSize(Integer domainId) {
BIFTransactionGetTxCacheSizeResponse response = new BIFTransactionGetTxCacheSizeResponse();
Long queueSize=0L;
try {
if (Tools.isEmpty(General.getInstance().getUrl())) {
throw new SDKException(SdkError.URL_EMPTY_ERROR);
}
if(!Tools.isNULL(domainId) && domainId < Constant.INIT_ZERO){
throw new SDKException(SdkError.INVALID_DOMAINID_ERROR);
}
String getInfoUrl = General.getInstance().getTxCacheSize(domainId);
String result = HttpUtils.httpGet(getInfoUrl);
response = JsonUtils.toJavaObject(result, BIFTransactionGetTxCacheSizeResponse.class);
response.buildResponse(SdkError.SUCCESS,response.getQueueSize());
} catch (SDKException apiException) {
Integer errorCode = apiException.getErrorCode();
String errorDesc = apiException.getErrorDesc();
response.buildResponse(errorCode, errorDesc, queueSize);
} catch (NoSuchAlgorithmException | KeyManagementException | NoSuchProviderException | IOException e) {
response.buildResponse(SdkError.CONNECTNETWORK_ERROR, queueSize);
} catch (Exception e) {
response.buildResponse(SdkError.SYSTEM_ERROR.getCode(), e.getMessage(), queueSize);
}
return response;
}
public static BIFTransactionGetInfoResponse getTransactionInfo(String hash,Integer domainId) throws Exception {
if (Tools.isEmpty(General.getInstance().getUrl())) {
throw new SDKException(SdkError.URL_EMPTY_ERROR);
}
String getInfoUrl = General.getInstance().transactionGetInfoUrl(hash,domainId);
String result = HttpUtils.httpGet(getInfoUrl);
return JsonUtils.toJavaObject(result, BIFTransactionGetInfoResponse.class);
}
/**
* @Method getTxCacheData
* @Return BIFTransactionCacheRequest
*/
@Override
public BIFTransactionCacheResponse getTxCacheData(BIFTransactionCacheRequest request) {
BIFTransactionCacheResponse response = new BIFTransactionCacheResponse();
BIFTransactionCacheResult bifTransactionCacheResult = new BIFTransactionCacheResult();
try {
if (Tools.isEmpty(General.getInstance().getUrl())) {
throw new SDKException(SdkError.URL_EMPTY_ERROR);
}
String hash = request.getHash();
if (!Tools.isEmpty(hash) && hash.length() != Constant.HASH_HEX_LENGTH) {
throw new SDKException(SdkError.INVALID_HASH_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);
}
String address = request.getAddress();
if (!Tools.isEmpty(address) && !PublicKeyManager.isAddressValid(address)) {
throw new SDKException(SdkError.INVALID_ADDRESS_ERROR);
}
String getInfoUrl = General.getInstance().getTxCacheData(domainId,hash,address);
String result = HttpUtils.httpGet(getInfoUrl);
response = JsonUtils.toJavaObject(result, BIFTransactionCacheResponse.class);
response.buildResponse(SdkError.SUCCESS, response.getResult());
} catch (SDKException apiException) {
Integer errorCode = apiException.getErrorCode();
String errorDesc = apiException.getErrorDesc();
response.buildResponse(errorCode, errorDesc, bifTransactionCacheResult);
} catch (NoSuchAlgorithmException | KeyManagementException | NoSuchProviderException | IOException e) {
response.buildResponse(SdkError.CONNECTNETWORK_ERROR, bifTransactionCacheResult);
} catch (Exception e) {
response.buildResponse(SdkError.SYSTEM_ERROR.getCode(), e.getMessage(), bifTransactionCacheResult);
}
return response;
}
@Override
public BIFTransactionParseBlobResponse parseBlob(String blob) {
BIFTransactionParseBlobResponse transactionParseBlobResponse = new BIFTransactionParseBlobResponse();
BIFTransactionParseBlobResult transactionParseBlobResult = new BIFTransactionParseBlobResult();
try {
if (Tools.isEmpty(blob)) {
throw new SDKException(SdkError.REQUEST_NULL_ERROR);
}
Chain.Transaction transaction = Chain.Transaction.parseFrom(HexFormat.hexToByte(blob));
JsonFormat jsonFormat = new JsonFormat();
ByteString meta=transaction.getMetadata();
String remarks =meta.toStringUtf8();
String transactionJson = jsonFormat.printToString(transaction);
transactionParseBlobResult = JsonUtils.toJavaObject(transactionJson, BIFTransactionParseBlobResult.class);
if(!Tools.isEmpty(remarks)){
transactionParseBlobResult.setRemarks(remarks);
}
transactionParseBlobResponse.buildResponse(SdkError.SUCCESS, transactionParseBlobResult);
} catch (SDKException sdkException) {
Integer errorCode = sdkException.getErrorCode();
String errorDesc = sdkException.getErrorDesc();
transactionParseBlobResponse.buildResponse(errorCode, errorDesc, transactionParseBlobResult);
} catch (InvalidProtocolBufferException | IllegalArgumentException e) {
transactionParseBlobResponse.buildResponse(SdkError.INVALID_SERIALIZATION_ERROR, transactionParseBlobResult);
} catch (Exception e) {
transactionParseBlobResponse.buildResponse(SdkError.SYSTEM_ERROR.getCode(), e.getMessage(), transactionParseBlobResult);
}
return transactionParseBlobResponse;
}
/**
* @Method getBidByHash
* @Return BIFTransactionGetBidResponse
*/
@Override
public BIFTransactionGetBidResponse getBidByHash(BIFTransactionGetInfoRequest request) {
BIFTransactionGetInfoResponse transactionGetInfoResponse = new BIFTransactionGetInfoResponse();
BIFTransactionGetInfoResult transactionGetInfoResult = new BIFTransactionGetInfoResult();
List result=new ArrayList<>();
try {
if (Tools.isEmpty(General.getInstance().getUrl())) {
throw new SDKException(SdkError.URL_EMPTY_ERROR);
}
if (Tools.isEmpty(request.getHash()) || request.getHash().length() != Constant.HASH_HEX_LENGTH) {
throw new SDKException(SdkError.INVALID_HASH_ERROR);
}
Integer domainId=request.getDomainId();
if(Tools.isNULL(domainId)){
domainId=Constant.INIT_ZERO;
}
transactionGetInfoResponse = getTransactionInfo(request.getHash(),domainId);
}catch (SDKException apiException) {
Integer errorCode = apiException.getErrorCode();
String errorDesc = apiException.getErrorDesc();
transactionGetInfoResponse.buildResponse(errorCode, errorDesc, transactionGetInfoResult);
} catch (NoSuchAlgorithmException | KeyManagementException | NoSuchProviderException | IOException e) {
transactionGetInfoResponse.buildResponse(SdkError.CONNECTNETWORK_ERROR, transactionGetInfoResult);
} catch (Exception e) {
transactionGetInfoResponse.buildResponse(SdkError.SYSTEM_ERROR.getCode(), e.getMessage(), transactionGetInfoResult);
}
BIFTransactionGetBidResponse response=new BIFTransactionGetBidResponse();
if (transactionGetInfoResponse.getErrorCode() == 0) {
if(transactionGetInfoResponse.getResult().getTotalCount().intValue() > 0){
BIFTransactionHistory transactionHistory[]=transactionGetInfoResponse.getResult().getTransactions();
for (BIFTransactionHistory item:transactionHistory) {
BIFTransactionInfo transactionInfo=item.getTransaction();
if(transactionInfo.getOperations().length > 0){
BIFOperation operation[]=transactionInfo.getOperations();
for (BIFOperation oper:operation) {
BIFGasSendInfo sendInfo= oper.getSendGas();
String destAddress= sendInfo.getDestAddress();
if(destAddress.equals(Constant.DDO_CONTRACT)){
String input=sendInfo.getInput();
Map inputMap=JsonUtils.toMap(input);
String params=JsonUtils.toJSONString(inputMap.get("params"));
BID bid=JsonUtils.toJavaObject(params,BID.class);
result.add(bid.getDocument().getId());
}
}
}
}
}
if(result.size() > 0){
response.buildResponse(SdkError.SUCCESS,result);
}else{
response.buildResponse(SdkError.INVALID_HASH_ERROR, result);
}
}else{
response.buildResponse(SdkError.INVALID_HASH_ERROR, result);
}
return response;
}
@Override
public BIFTransactionGasSendResponse batchGasSend(BIFBatchGasSendRequest request) {
BIFTransactionGasSendResponse response = new BIFTransactionGasSendResponse();
BIFTransactionGasSendResult result = new BIFTransactionGasSendResult();
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);
}
if(operations.size()>100 || operations.size()==0){
throw new SDKException(SdkError.OPERATIONS_INVALID_ERROR);
}
Map map = new HashMap<>();
for (BIFGasSendOperation opt: operations) {
if(!map.containsKey(opt.getDestAddress())){//map中存在此id,将数据存放当前key的map中
if (!PublicKeyManager.isAddressValid(opt.getDestAddress())) {
throw new SDKException(SdkError.INVALID_ADDRESS_ERROR);
}
map.put(opt.getDestAddress(),1);
}
Long bifAmount = opt.getAmount();
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.radioGasTransaction(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;
}
}