use of io.nuls.kernel.exception.NulsException in project nuls by nuls-io.
the class AccountLedgerServiceImpl method sendToAddress.
@Override
public Result sendToAddress(byte[] from, byte[] to, Na values, String password, byte[] remark, Na price) {
try {
Result<Account> accountResult = accountService.getAccount(from);
if (accountResult.isFailed()) {
return accountResult;
}
Account account = accountResult.getData();
if (account.isEncrypted() && account.isLocked()) {
AssertUtil.canNotEmpty(password, "the password can not be empty");
if (!account.validatePassword(password)) {
return Result.getFailed(AccountErrorCode.PASSWORD_IS_WRONG);
}
}
// 检查to是否为合约地址,如果是合约地址,则返回错误
if (contractService.isContractAddress(to)) {
return Result.getFailed(ContractErrorCode.NON_CONTRACTUAL_TRANSACTION_NO_TRANSFER);
}
if (price == null) {
price = TransactionFeeCalculator.MIN_PRICE_PRE_1024_BYTES;
}
TransactionDataResult txResult = createTransferTx(from, values, price, to, remark);
if (!txResult.isEnough()) {
return Result.getFailed(AccountLedgerErrorCode.INSUFFICIENT_BALANCE);
}
Transaction tx = txResult.getTransaction();
tx.setHash(NulsDigestData.calcDigestData(tx.serializeForHash()));
// 生成签名
List<ECKey> signEckeys = new ArrayList<>();
List<ECKey> scriptEckeys = new ArrayList<>();
ECKey eckey = account.getEcKey(password);
// 如果最后一位为1则表示该交易包含普通签名
if ((txResult.getSignType() & 0x01) == 0x01) {
signEckeys.add(eckey);
}
// 如果倒数第二位位为1则表示该交易包含脚本签名
if ((txResult.getSignType() & 0x02) == 0x02) {
scriptEckeys.add(eckey);
}
SignatureUtil.createTransactionSignture(tx, scriptEckeys, signEckeys);
// 保存未确认交易到本地账户
Result saveResult = verifyAndSaveUnconfirmedTransaction(tx);
if (saveResult.isFailed()) {
if (KernelErrorCode.DATA_SIZE_ERROR.getCode().equals(saveResult.getErrorCode().getCode())) {
// 重新算一次交易(不超出最大交易数据大小下)的最大金额
Result rs = getMaxAmountOfOnce(from, tx, price);
if (rs.isSuccess()) {
Na maxAmount = (Na) rs.getData();
rs = Result.getFailed(KernelErrorCode.DATA_SIZE_ERROR_EXTEND);
rs.setMsg(rs.getMsg() + maxAmount.toDouble());
}
return rs;
}
return saveResult;
}
// transactionService.newTx(tx);
Result sendResult = transactionService.broadcastTx(tx);
if (sendResult.isFailed()) {
this.deleteTransaction(tx);
return sendResult;
}
return Result.getSuccess().setData(tx.getHash().getDigestHex());
} catch (IOException e) {
Log.error(e);
return Result.getFailed(KernelErrorCode.IO_ERROR);
} catch (NulsException e) {
Log.error(e);
return Result.getFailed(e.getErrorCode());
}
}
use of io.nuls.kernel.exception.NulsException in project nuls by nuls-io.
the class AccountLedgerServiceImpl method addToCoinMap.
private Map<String, Coin> addToCoinMap(Transaction transaction) {
Map<String, Coin> toMap = new HashMap<>();
CoinData coinData = transaction.getCoinData();
if (coinData == null) {
return toMap;
}
List<Coin> froms = coinData.getFrom();
if (froms == null || froms.size() == 0) {
return toMap;
}
for (Coin coin : froms) {
byte[] keyBytes = coin.getOwner();
try {
Transaction unconfirmedTx = getUnconfirmedTransaction(NulsDigestData.fromDigestHex(LedgerUtil.getTxHash(keyBytes))).getData();
if (unconfirmedTx != null) {
int index = LedgerUtil.getIndex(keyBytes);
Coin toCoin = unconfirmedTx.getCoinData().getTo().get(index);
toMap.put(LedgerUtil.asString(keyBytes), toCoin);
}
} catch (NulsException e) {
Log.error(e);
}
}
return toMap;
}
use of io.nuls.kernel.exception.NulsException in project nuls by nuls-io.
the class AccountLedgerServiceImpl method txMultiProcess.
@Override
public Result txMultiProcess(Transaction tx, TransactionSignature transactionSignature, Account account, String password) {
try {
List<P2PHKSignature> p2PHKSignatures = new ArrayList<>();
if (transactionSignature.getP2PHKSignatures() != null && transactionSignature.getP2PHKSignatures().size() > 0) {
p2PHKSignatures = transactionSignature.getP2PHKSignatures();
}
List<Script> scripts = transactionSignature.getScripts();
// 使用签名账户对交易进行签名
P2PHKSignature p2PHKSignature = new P2PHKSignature();
ECKey eckey = account.getEcKey(password);
p2PHKSignature.setPublicKey(eckey.getPubKey());
// 用当前交易的hash和账户的私钥账户
p2PHKSignature.setSignData(accountService.signDigest(tx.getHash().getDigestBytes(), eckey));
p2PHKSignatures.add(p2PHKSignature);
// 当已签名数等于M则自动广播该交易
if (p2PHKSignatures.size() == SignatureUtil.getM(scripts.get(0))) {
// 将交易中的签名数据P2PHKSignatures按规则排序
p2PHKSignatures.sort(P2PHKSignature.PUBKEY_COMPARATOR);
// 将排序后的P2PHKSignatures的签名数据取出和赎回脚本结合生成解锁脚本
List<byte[]> signatures = new ArrayList<>();
for (P2PHKSignature p2PHKSignatureTemp : p2PHKSignatures) {
signatures.add(p2PHKSignatureTemp.getSignData().getSignBytes());
}
transactionSignature.setP2PHKSignatures(null);
Script scriptSign = ScriptBuilder.createNulsP2SHMultiSigInputScript(signatures, scripts.get(0));
transactionSignature.getScripts().clear();
transactionSignature.getScripts().add(scriptSign);
tx.setTransactionSignature(transactionSignature.serialize());
// 保存未确认交易到本地账户
Result saveResult = verifyAndSaveUnconfirmedTransaction(tx);
if (saveResult.isFailed()) {
return saveResult;
}
transactionService.newTx(tx);
Result sendResult = transactionService.broadcastTx(tx);
if (sendResult.isFailed()) {
this.deleteTransaction(tx);
return sendResult;
}
return Result.getSuccess().setData(tx.getHash().getDigestHex());
} else // 如果签名数还没达到,则返回交易
{
transactionSignature.setP2PHKSignatures(p2PHKSignatures);
tx.setTransactionSignature(transactionSignature.serialize());
return Result.getSuccess().setData(Hex.encode(tx.serialize()));
}
} catch (IOException e) {
Log.error(e);
return Result.getFailed(KernelErrorCode.IO_ERROR);
} catch (NulsException e) {
Log.error(e);
return Result.getFailed(e.getErrorCode());
}
}
use of io.nuls.kernel.exception.NulsException in project nuls by nuls-io.
the class AccountLedgerServiceImpl method multipleAddressTransfer.
@Override
public Result multipleAddressTransfer(Set<String> addressSet, List<MultipleAddressTransferModel> fromList, List<MultipleAddressTransferModel> toList, Na amount, String remark, Na price) {
try {
for (MultipleAddressTransferModel from : fromList) {
Result<Account> accountResult = accountService.getAccount(from.getAddress());
if (accountResult.isFailed()) {
return accountResult;
}
Account account = accountResult.getData();
if (account.isEncrypted() && account.isLocked()) {
AssertUtil.canNotEmpty(from.getPassword(), "the password can not be empty");
if (!account.validatePassword(from.getPassword())) {
Result result = Result.getFailed(AccountErrorCode.PASSWORD_IS_WRONG);
result.setMsg(result.getErrorCode().getMsg() + ",address :" + AddressTool.getStringAddressByBytes(from.getAddress()));
return result;
}
}
}
for (MultipleAddressTransferModel to : toList) {
// 检查to是否为合约地址,如果是合约地址,则返回错误
if (contractService.isContractAddress(to.getAddress())) {
return Result.getFailed(ContractErrorCode.NON_CONTRACTUAL_TRANSACTION_NO_TRANSFER);
}
}
TransferTransaction tx = new TransferTransaction();
if (StringUtils.isNotBlank(remark)) {
try {
tx.setRemark(remark.getBytes(NulsConfig.DEFAULT_ENCODING));
} catch (UnsupportedEncodingException e) {
Log.error(e);
}
}
tx.setTime(TimeService.currentTimeMillis());
CoinData coinData = new CoinData();
for (MultipleAddressTransferModel to : toList) {
// 如果为多签地址
Coin toCoin = null;
if (to.getAddress()[2] == 3) {
Script scriptPubkey = SignatureUtil.createOutputScript(to.getAddress());
toCoin = new Coin(scriptPubkey.getProgram(), Na.valueOf(to.getAmount()));
} else {
toCoin = new Coin(to.getAddress(), Na.valueOf(to.getAmount()));
}
coinData.getTo().add(toCoin);
}
if (price == null) {
price = TransactionFeeCalculator.MIN_PRICE_PRE_1024_BYTES;
}
CoinDataResult coinDataResult = getCoinDataMultipleAdresses(fromList, amount, tx.size() + coinData.size() + addressSet.size() * P2PHKSignature.SERIALIZE_LENGTH, price);
// 从多个地址中获取币 from
List<Coin> fromCoinList = new ArrayList<>();
List<Coin> changeCoinList = new ArrayList<>();
if (!coinDataResult.isEnough()) {
// 验证utxo是否足够
return Result.getFailed(AccountLedgerErrorCode.INSUFFICIENT_BALANCE);
}
// 把每个地址获取的币放到list里面
fromCoinList.addAll(coinDataResult.getCoinList());
if (coinDataResult.getChange() != null) {
changeCoinList.add(coinDataResult.getChange());
}
// 每个地址from获取的utxo list
coinData.setFrom(fromCoinList);
// 找零钱
coinData.getTo().addAll(changeCoinList);
tx.setCoinData(coinData);
tx.setHash(NulsDigestData.calcDigestData(tx.serializeForHash()));
// 生成签名
List<ECKey> signEckeys = new ArrayList<>();
List<ECKey> scriptEckeys = new ArrayList<>();
for (int index = 0; index < fromList.size(); index++) {
Result<Account> accountResult = accountService.getAccount(fromList.get(index).getAddress());
Account account = accountResult.getData();
// 用于生成ECKey
ECKey ecKey = account.getEcKey(fromList.get(index).getPassword());
// 如果最后一位为1则表示该交易包含普通签名
if ((coinDataResult.getSignType() & 0x01) == 0x01) {
signEckeys.add(ecKey);
}
// 如果倒数第二位位为1则表示该交易包含脚本签名
if ((coinDataResult.getSignType() & 0x02) == 0x02) {
scriptEckeys.add(ecKey);
}
}
SignatureUtil.createTransactionSignture(tx, scriptEckeys, signEckeys);
// 保存未确认交易到本地账户
Result saveResult = verifyAndSaveUnconfirmedTransaction(tx);
if (saveResult.isFailed()) {
for (MultipleAddressTransferModel from : fromList) {
if (KernelErrorCode.DATA_SIZE_ERROR.getCode().equals(saveResult.getErrorCode().getCode())) {
// 重新算一次交易(不超出最大交易数据大小下)的最大金额
Na maxAmount = getMaxAmountOfOnce(from.getAddress(), tx, price).getData();
Result rs = Result.getFailed(KernelErrorCode.DATA_SIZE_ERROR_EXTEND);
rs.setMsg(rs.getMsg() + maxAmount.toDouble());
return rs;
}
}
return saveResult;
}
Result sendResult = transactionService.broadcastTx(tx);
if (sendResult.isFailed()) {
this.deleteTransaction(tx);
return sendResult;
}
return Result.getSuccess().setData(tx.getHash().getDigestHex());
} catch (IOException e) {
Log.error(e);
return Result.getFailed(KernelErrorCode.IO_ERROR);
} catch (NulsException e) {
Log.error(e);
return Result.getFailed(e.getErrorCode());
}
}
use of io.nuls.kernel.exception.NulsException in project nuls by nuls-io.
the class TransactionInfoServiceImpl method getTxInfoList.
@Override
public Result<List<TransactionInfo>> getTxInfoList(byte[] address) {
try {
List<TransactionInfoPo> infoPoList = transactionInfoStorageService.getTransactionInfoListByAddress(address);
List<TransactionInfo> infoList = new ArrayList<>();
for (TransactionInfoPo po : infoPoList) {
if (po.getTxType() == ConsensusConstant.TX_TYPE_RED_PUNISH || po.getTxType() == ConsensusConstant.TX_TYPE_YELLOW_PUNISH) {
continue;
}
infoList.add(po.toTransactionInfo());
}
Collections.sort(infoList, TxInfoComparator.getInstance());
return Result.getSuccess().setData(infoList);
} catch (NulsException e) {
Log.error(e);
return Result.getFailed(e.getErrorCode());
}
}
Aggregations