use of io.nuls.account.model.MultiSigAccount in project nuls by nuls-io.
the class PocConsensusResource method createWithdrawMutil.
@POST
@Path("/multiAccount/mutilWithdraw")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "多签账户退出共识", notes = "返回退出成功的交易hash")
@ApiResponses(value = { @ApiResponse(code = 200, message = "success", response = String.class) })
public RpcClientResult createWithdrawMutil(@ApiParam(name = "form", value = "多签退出共识表单数据", required = true) CreateMultiWithdrawForm form) throws Exception {
AssertUtil.canNotEmpty(form);
AssertUtil.canNotEmpty(form.getTxHash());
AssertUtil.canNotEmpty(form.getAddress());
AssertUtil.canNotEmpty(form.getSignAddress());
if (!NulsDigestData.validHash(form.getTxHash())) {
return Result.getFailed(KernelErrorCode.PARAMETER_ERROR).toRpcClientResult();
}
if (!AddressTool.validAddress(form.getAddress()) || !AddressTool.validAddress(form.getSignAddress())) {
return Result.getFailed(AccountErrorCode.ADDRESS_ERROR).toRpcClientResult();
}
Account account = accountService.getAccount(form.getSignAddress()).getData();
if (null == account) {
return Result.getFailed(AccountErrorCode.ACCOUNT_NOT_EXIST).toRpcClientResult();
}
if (account.isEncrypted() && account.isLocked()) {
AssertUtil.canNotEmpty(form.getPassword(), "password is wrong");
if (!account.validatePassword(form.getPassword())) {
return Result.getFailed(AccountErrorCode.PASSWORD_IS_WRONG).toRpcClientResult();
}
}
Result<MultiSigAccount> sigAccountResult = accountService.getMultiSigAccount(form.getAddress());
MultiSigAccount multiSigAccount = sigAccountResult.getData();
// 验证签名账户是否属于多签账户,如果不是多签账户下的地址则提示错误
if (!AddressTool.validSignAddress(multiSigAccount.getPubKeyList(), account.getPubKey())) {
return Result.getFailed(AccountErrorCode.SIGN_ADDRESS_NOT_MATCH).toRpcClientResult();
}
Script redeemScript = accountLedgerService.getRedeemScript(multiSigAccount);
if (redeemScript == null) {
return Result.getFailed(AccountErrorCode.ACCOUNT_NOT_EXIST).toRpcClientResult();
}
CancelDepositTransaction tx = new CancelDepositTransaction();
TransactionSignature transactionSignature = new TransactionSignature();
List<Script> scripts = new ArrayList<>();
CancelDeposit cancelDeposit = new CancelDeposit();
NulsDigestData hash = NulsDigestData.fromDigestHex(form.getTxHash());
DepositTransaction depositTransaction = null;
try {
depositTransaction = (DepositTransaction) ledgerService.getTx(hash);
} catch (Exception e) {
return Result.getFailed(KernelErrorCode.PARAMETER_ERROR).toRpcClientResult();
}
if (null == depositTransaction) {
return Result.getFailed(TransactionErrorCode.TX_NOT_EXIST).toRpcClientResult();
}
// Create unlock script
cancelDeposit.setAddress(AddressTool.getAddress(form.getAddress()));
cancelDeposit.setJoinTxHash(hash);
tx.setTxData(cancelDeposit);
CoinData coinData = new CoinData();
List<Coin> toList = new ArrayList<>();
if (cancelDeposit.getAddress()[2] == NulsContext.P2SH_ADDRESS_TYPE) {
Script scriptPubkey = SignatureUtil.createOutputScript(cancelDeposit.getAddress());
toList.add(new Coin(scriptPubkey.getProgram(), depositTransaction.getTxData().getDeposit(), PocConsensusConstant.CONSENSUS_LOCK_TIME));
} else {
toList.add(new Coin(cancelDeposit.getAddress(), depositTransaction.getTxData().getDeposit(), 0));
}
coinData.setTo(toList);
List<Coin> fromList = new ArrayList<>();
for (int index = 0; index < depositTransaction.getCoinData().getTo().size(); index++) {
Coin coin = depositTransaction.getCoinData().getTo().get(index);
if (coin.getLockTime() == -1L && coin.getNa().equals(depositTransaction.getTxData().getDeposit())) {
coin.setOwner(ArraysTool.concatenate(hash.serialize(), new VarInt(index).encode()));
fromList.add(coin);
break;
}
}
if (fromList.isEmpty()) {
return Result.getFailed(KernelErrorCode.DATA_ERROR).toRpcClientResult();
}
coinData.setFrom(fromList);
tx.setCoinData(coinData);
Na fee = TransactionFeeCalculator.getMaxFee(108 + tx.size());
coinData.getTo().get(0).setNa(coinData.getTo().get(0).getNa().subtract(fee));
tx.setHash(NulsDigestData.calcDigestData(tx.serializeForHash()));
// 将赎回脚本先存储在签名脚本中
scripts.add(redeemScript);
transactionSignature.setScripts(scripts);
Result resultData = accountLedgerService.txMultiProcess(tx, transactionSignature, account, form.getPassword());
if (resultData.isSuccess()) {
Map<String, String> valueMap = new HashMap<>();
valueMap.put("txData", (String) resultData.getData());
return Result.getSuccess().setData(valueMap).toRpcClientResult();
}
return resultData.toRpcClientResult();
}
use of io.nuls.account.model.MultiSigAccount in project nuls by nuls-io.
the class PocConsensusResource method createStopMutilAgent.
@POST
@Path("/multiAccount/agent/stopMultiAgent")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "多签账户注销共识节点", notes = "返回注销成功交易hash")
@ApiResponses(value = { @ApiResponse(code = 200, message = "success", response = String.class) })
public RpcClientResult createStopMutilAgent(@ApiParam(name = "form", value = "多签账户注销共识节点表单数据", required = true) CreateStopMultiAgentForm form) throws Exception {
if (NulsContext.MAIN_NET_VERSION <= 1) {
return Result.getFailed(KernelErrorCode.VERSION_TOO_LOW).toRpcClientResult();
}
AssertUtil.canNotEmpty(form);
AssertUtil.canNotEmpty(form.getAddress());
AssertUtil.canNotEmpty(form.getSignAddress());
if (!AddressTool.validAddress(form.getAddress()) || !AddressTool.validAddress(form.getSignAddress())) {
throw new NulsRuntimeException(KernelErrorCode.PARAMETER_ERROR);
}
Account account = accountService.getAccount(form.getSignAddress()).getData();
if (null == account) {
return Result.getFailed(AccountErrorCode.ACCOUNT_NOT_EXIST).toRpcClientResult();
}
if (account.isEncrypted() && account.isLocked()) {
AssertUtil.canNotEmpty(form.getPassword(), "password is wrong");
if (!account.validatePassword(form.getPassword())) {
return Result.getFailed(AccountErrorCode.PASSWORD_IS_WRONG).toRpcClientResult();
}
}
List<Agent> agentList = PocConsensusContext.getChainManager().getMasterChain().getChain().getAgentList();
Agent agent = null;
for (Agent p : agentList) {
if (p.getDelHeight() > 0) {
continue;
}
if (Arrays.equals(p.getAgentAddress(), AddressTool.getAddress(form.getAddress()))) {
agent = p;
break;
}
}
if (agent == null || agent.getDelHeight() > 0) {
return Result.getFailed(PocConsensusErrorCode.AGENT_NOT_EXIST).toRpcClientResult();
}
Result<MultiSigAccount> sigAccountResult = accountService.getMultiSigAccount(form.getAddress());
MultiSigAccount multiSigAccount = sigAccountResult.getData();
// 验证签名账户是否属于多签账户,如果不是多签账户下的地址则提示错误
if (!AddressTool.validSignAddress(multiSigAccount.getPubKeyList(), account.getPubKey())) {
return Result.getFailed(AccountErrorCode.SIGN_ADDRESS_NOT_MATCH).toRpcClientResult();
}
Script redeemScript = accountLedgerService.getRedeemScript(multiSigAccount);
if (redeemScript == null) {
return Result.getFailed(AccountErrorCode.ACCOUNT_NOT_EXIST).toRpcClientResult();
}
// 如果为交易发起人,则需要填写组装交易需要的信息
StopAgentTransaction tx = new StopAgentTransaction();
TransactionSignature transactionSignature = new TransactionSignature();
List<Script> scripts = new ArrayList<>();
StopAgent stopAgent = new StopAgent();
stopAgent.setAddress(agent.getAgentAddress());
stopAgent.setCreateTxHash(agent.getTxHash());
tx.setTime(TimeService.currentTimeMillis());
tx.setTxData(stopAgent);
CoinData coinData = ConsensusTool.getStopAgentCoinData(agent, TimeService.currentTimeMillis() + PocConsensusConstant.STOP_AGENT_LOCK_TIME, null);
tx.setCoinData(coinData);
Na fee = TransactionFeeCalculator.getMaxFee(108 + tx.size());
coinData.getTo().get(0).setNa(coinData.getTo().get(0).getNa().subtract(fee));
tx.setHash(NulsDigestData.calcDigestData(tx.serializeForHash()));
// 将赎回脚本先存储在签名脚本中
scripts.add(redeemScript);
transactionSignature.setScripts(scripts);
// 使用签名账户对交易进行签名
Result resultData = accountLedgerService.txMultiProcess(tx, transactionSignature, account, form.getPassword());
if (resultData.isSuccess()) {
Map<String, String> valueMap = new HashMap<>();
valueMap.put("txData", (String) resultData.getData());
return Result.getSuccess().setData(valueMap).toRpcClientResult();
}
return resultData.toRpcClientResult();
}
use of io.nuls.account.model.MultiSigAccount in project nuls by nuls-io.
the class AccountLedgerServiceImpl method createP2shTransfer.
/**
* A transfers NULS to B 多签交易
*
* @param fromAddr 输入地址
* @param signAddr 签名地址
* @param outputs 输出地址
* @param password password of A
* @param remark remarks of transaction
* @return Result
*/
@Override
public Result createP2shTransfer(String fromAddr, String signAddr, List<MultipleAddressTransferModel> outputs, String password, String remark) {
try {
Result<Account> accountResult = accountService.getAccount(signAddr);
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);
}
}
TransferTransaction tx = new TransferTransaction();
TransactionSignature transactionSignature = new TransactionSignature();
List<Script> scripts = new ArrayList<>();
Result<MultiSigAccount> result = accountService.getMultiSigAccount(fromAddr);
MultiSigAccount multiSigAccount = result.getData();
// 验证签名账户是否属于多签账户,如果不是多签账户下的地址则提示错误
if (!AddressTool.validSignAddress(multiSigAccount.getPubKeyList(), account.getPubKey())) {
return Result.getFailed(AccountErrorCode.SIGN_ADDRESS_NOT_MATCH);
}
Script redeemScript = getRedeemScript(multiSigAccount);
if (redeemScript == null) {
return Result.getFailed(AccountErrorCode.ACCOUNT_NOT_EXIST);
}
tx.setTime(TimeService.currentTimeMillis());
if (StringUtils.isNotBlank(remark)) {
try {
tx.setRemark(remark.getBytes(NulsConfig.DEFAULT_ENCODING));
} catch (UnsupportedEncodingException e) {
Log.error(e);
}
}
CoinData coinData = new CoinData();
Na values = Na.ZERO;
for (MultipleAddressTransferModel to : outputs) {
// 如果为多签地址
Coin toCoin = null;
values = values.add(Na.valueOf(to.getAmount()));
if (to.getAddress()[2] == NulsContext.P2SH_ADDRESS_TYPE) {
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);
}
// 交易签名的长度为m*单个签名长度+赎回脚本长度
int scriptSignLenth = redeemScript.getProgram().length + ((int) multiSigAccount.getM()) * 72;
CoinDataResult coinDataResult = getMutilCoinData(AddressTool.getAddress(fromAddr), values, tx.size() + coinData.size() + scriptSignLenth, TransactionFeeCalculator.MIN_PRICE_PRE_1024_BYTES);
if (!coinDataResult.isEnough()) {
return Result.getFailed(AccountLedgerErrorCode.INSUFFICIENT_BALANCE);
}
coinData.setFrom(coinDataResult.getCoinList());
if (coinDataResult.getChange() != null) {
coinData.getTo().add(coinDataResult.getChange());
}
tx.setCoinData(coinData);
tx.setHash(NulsDigestData.calcDigestData(tx.serializeForHash()));
// 将赎回脚本先存储在签名脚本中
scripts.add(redeemScript);
transactionSignature.setScripts(scripts);
return txMultiProcess(tx, transactionSignature, account, password);
} catch (IOException e) {
Log.error(e);
return Result.getFailed(KernelErrorCode.IO_ERROR);
} catch (NulsException e) {
Log.error(e);
return Result.getFailed(e.getErrorCode());
} catch (Exception e) {
Log.error(e);
return Result.getFailed(AccountErrorCode.ACCOUNT_NOT_EXIST);
}
}
Aggregations