use of io.nuls.core.tools.crypto.ECKey in project nuls by nuls-io.
the class AliasService method setMutilAlias.
/**
* 多签账户设置别名
* Initiate a transaction to set alias.
*
* @param addr Address of account
* @param password password of account
* @param aliasName the alias to set
* @return txhash
*/
public Result<String> setMutilAlias(String addr, String signAddr, String aliasName, String password, List<String> pubKeys, int m, String txdata) {
// 签名账户
Account account = accountService.getAccount(signAddr).getData();
if (null == account) {
return Result.getFailed(AccountErrorCode.ACCOUNT_NOT_EXIST);
}
if (account.isEncrypted() && account.isLocked()) {
if (!account.validatePassword(password)) {
return Result.getFailed(AccountErrorCode.PASSWORD_IS_WRONG);
}
}
try {
AliasTransaction tx = new AliasTransaction();
TransactionSignature transactionSignature = new TransactionSignature();
List<P2PHKSignature> p2PHKSignatures = new ArrayList<>();
List<Script> scripts = new ArrayList<>();
byte[] addressBytes = AddressTool.getAddress(addr);
// 如果txdata为空则表示当前请求为多签发起者调用,需要创建交易
if (txdata == null || txdata.trim().length() == 0) {
if (!StringUtils.validAlias(aliasName)) {
return Result.getFailed(AccountErrorCode.ALIAS_FORMAT_WRONG);
}
if (!isAliasUsable(aliasName)) {
return Result.getFailed(AccountErrorCode.ALIAS_EXIST);
}
// 创建一笔设置别名的交易
tx = new AliasTransaction();
Script redeemScript = ScriptBuilder.createNulsRedeemScript(m, pubKeys);
tx.setTime(TimeService.currentTimeMillis());
Alias alias = new Alias(addressBytes, aliasName);
tx.setTxData(alias);
// 交易签名的长度为m*单个签名长度+赎回脚本长度
int scriptSignLenth = redeemScript.getProgram().length + m * 72;
CoinDataResult coinDataResult = accountLedgerService.getMutilCoinData(addressBytes, AccountConstant.ALIAS_NA, tx.size() + scriptSignLenth, TransactionFeeCalculator.OTHER_PRICE_PRE_1024_BYTES);
if (!coinDataResult.isEnough()) {
return Result.getFailed(AccountErrorCode.INSUFFICIENT_BALANCE);
}
CoinData coinData = new CoinData();
coinData.setFrom(coinDataResult.getCoinList());
Coin change = coinDataResult.getChange();
if (null != change) {
// 创建toList
List<Coin> toList = new ArrayList<>();
toList.add(change);
coinData.setTo(toList);
}
Coin coin = new Coin(NulsConstant.BLACK_HOLE_ADDRESS, Na.parseNuls(1), 0);
coinData.addTo(coin);
tx.setCoinData(coinData);
tx.setHash(NulsDigestData.calcDigestData(tx.serializeForHash()));
// 将赎回脚本先存储在签名脚本中
scripts.add(redeemScript);
transactionSignature.setScripts(scripts);
} else // 如果txdata不为空表示多签交易已经创建好了,将交易反序列化出来
{
byte[] txByte = Hex.decode(txdata);
tx.parse(new NulsByteBuffer(txByte));
transactionSignature.parse(new NulsByteBuffer(tx.getTransactionSignature()));
p2PHKSignatures = transactionSignature.getP2PHKSignatures();
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);
Result result = txMutilProcessing(tx, p2PHKSignatures, scripts, transactionSignature, addressBytes);
return result;
} catch (Exception e) {
Log.error(e);
return Result.getFailed(KernelErrorCode.SYS_UNKOWN_EXCEPTION);
}
}
use of io.nuls.core.tools.crypto.ECKey in project nuls by nuls-io.
the class AliasService method setAlias.
/**
* 设置别名
* Initiate a transaction to set alias.
*
* @param addr Address of account
* @param password password of account
* @param aliasName the alias to set
* @return txhash
*/
public Result<String> setAlias(String addr, String aliasName, String password) {
if (!AddressTool.validAddress(addr)) {
return Result.getFailed(AccountErrorCode.ADDRESS_ERROR);
}
Account account = accountService.getAccount(addr).getData();
if (null == account) {
return Result.getFailed(AccountErrorCode.ACCOUNT_NOT_EXIST);
}
if (account.isEncrypted() && account.isLocked()) {
if (!account.validatePassword(password)) {
return Result.getFailed(AccountErrorCode.PASSWORD_IS_WRONG);
}
}
if (!account.isOk()) {
return Result.getFailed(AccountErrorCode.IMPORTING_ACCOUNT);
}
if (StringUtils.isNotBlank(account.getAlias())) {
return Result.getFailed(AccountErrorCode.ACCOUNT_ALREADY_SET_ALIAS);
}
if (!StringUtils.validAlias(aliasName)) {
return Result.getFailed(AccountErrorCode.ALIAS_FORMAT_WRONG);
}
if (!isAliasUsable(aliasName)) {
return Result.getFailed(AccountErrorCode.ALIAS_EXIST);
}
byte[] addressBytes = account.getAddress().getAddressBytes();
try {
// 创建一笔设置别名的交易
AliasTransaction tx = new AliasTransaction();
tx.setTime(TimeService.currentTimeMillis());
Alias alias = new Alias(addressBytes, aliasName);
tx.setTxData(alias);
CoinDataResult coinDataResult = accountLedgerService.getCoinData(addressBytes, AccountConstant.ALIAS_NA, tx.size(), TransactionFeeCalculator.OTHER_PRICE_PRE_1024_BYTES);
if (!coinDataResult.isEnough()) {
return Result.getFailed(AccountErrorCode.INSUFFICIENT_BALANCE);
}
CoinData coinData = new CoinData();
coinData.setFrom(coinDataResult.getCoinList());
Coin change = coinDataResult.getChange();
if (null != change) {
// 创建toList
List<Coin> toList = new ArrayList<>();
toList.add(change);
coinData.setTo(toList);
}
Coin coin = new Coin(NulsConstant.BLACK_HOLE_ADDRESS, AccountConstant.ALIAS_NA, 0);
coinData.addTo(coin);
tx.setCoinData(coinData);
tx.setHash(NulsDigestData.calcDigestData(tx.serializeForHash()));
// 生成签名
List<ECKey> signEckeys = new ArrayList<>();
List<ECKey> scriptEckeys = new ArrayList<>();
;
ECKey eckey = account.getEcKey(password);
// 如果最后一位为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 = accountLedgerService.verifyAndSaveUnconfirmedTransaction(tx);
if (saveResult.isFailed()) {
if (KernelErrorCode.DATA_SIZE_ERROR.getCode().equals(saveResult.getErrorCode().getCode())) {
// 重新算一次交易(不超出最大交易数据大小下)的最大金额
Result rs = accountLedgerService.getMaxAmountOfOnce(account.getAddress().getAddressBytes(), tx, TransactionFeeCalculator.OTHER_PRICE_PRE_1024_BYTES);
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;
}
this.transactionService.newTx(tx);
Result sendResult = this.transactionService.broadcastTx(tx);
if (sendResult.isFailed()) {
accountLedgerService.deleteTransaction(tx);
return sendResult;
}
String hash = tx.getHash().getDigestHex();
return Result.getSuccess().setData(hash);
} catch (Exception e) {
Log.error(e);
return Result.getFailed(KernelErrorCode.SYS_UNKOWN_EXCEPTION);
}
}
use of io.nuls.core.tools.crypto.ECKey in project nuls by nuls-io.
the class AccountResource method setPassword.
@POST
@Path("/offline/password/")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "[设密码] 设置离线账户密码")
@ApiResponses(value = { @ApiResponse(code = 200, message = "success", response = RpcClientResult.class) })
public RpcClientResult setPassword(@ApiParam(name = "form", value = "设置离线账户密码表单数据", required = true) OfflineAccountPasswordForm form) {
String address = form.getAddress();
String priKey = form.getPriKey();
String password = form.getPassword();
if (StringUtils.isBlank(address) || !AddressTool.validAddress(address)) {
return Result.getFailed(AccountErrorCode.ADDRESS_ERROR).toRpcClientResult();
}
if (StringUtils.isBlank(priKey) || !ECKey.isValidPrivteHex(priKey)) {
return Result.getFailed(AccountErrorCode.PARAMETER_ERROR).toRpcClientResult();
}
if (StringUtils.isBlank(password) || !StringUtils.validPassword(password)) {
return Result.getFailed(AccountErrorCode.PASSWORD_FORMAT_WRONG).toRpcClientResult();
}
// 验证地址是否正确
ECKey key = ECKey.fromPrivate(new BigInteger(1, Hex.decode(priKey)));
try {
String newAddress = AccountTool.newAddress(key).getBase58();
if (!newAddress.equals(address)) {
return Result.getFailed(AccountErrorCode.ADDRESS_ERROR).toRpcClientResult();
}
} catch (NulsException e) {
return Result.getFailed(AccountErrorCode.ADDRESS_ERROR).toRpcClientResult();
}
try {
Account account = AccountTool.createAccount(priKey);
account.encrypt(password);
Map<String, String> map = new HashMap<>();
map.put("value", Hex.encode(account.getEncryptedPriKey()));
return Result.getSuccess().setData(map).toRpcClientResult();
} catch (NulsException e) {
return Result.getFailed(AccountErrorCode.FAILED).toRpcClientResult();
}
}
use of io.nuls.core.tools.crypto.ECKey in project nuls by nuls-io.
the class AccountResource method importAccountByPriKey.
@POST
@Path("/import/pri")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "[导入] 根据私钥导入账户", notes = "返回账户地址")
@ApiResponses(value = { @ApiResponse(code = 200, message = "success", response = RpcClientResult.class) })
public RpcClientResult importAccountByPriKey(@ApiParam(name = "form", value = "导入账户表单数据", required = true) AccountPriKeyPasswordForm form) {
if (null == form || null == form.getOverwrite()) {
return Result.getFailed(AccountErrorCode.PARAMETER_ERROR).toRpcClientResult();
}
String priKey = form.getPriKey();
if (!ECKey.isValidPrivteHex(priKey)) {
return Result.getFailed(AccountErrorCode.PARAMETER_ERROR).toRpcClientResult();
}
if (!form.getOverwrite()) {
ECKey key = null;
try {
key = ECKey.fromPrivate(new BigInteger(1, Hex.decode(form.getPriKey())));
} catch (Exception e) {
return Result.getFailed(AccountErrorCode.PARAMETER_ERROR).toRpcClientResult();
}
Address address = new Address(NulsContext.getInstance().getDefaultChainId(), NulsContext.DEFAULT_ADDRESS_TYPE, SerializeUtils.sha256hash160(key.getPubKey()));
Account account = accountService.getAccount(address).getData();
if (null != account) {
return Result.getFailed(AccountErrorCode.ACCOUNT_EXIST).toRpcClientResult();
}
}
String password = form.getPassword();
if (StringUtils.isNotBlank(password) && !StringUtils.validPassword(password)) {
return Result.getFailed(AccountErrorCode.PASSWORD_IS_WRONG).toRpcClientResult();
}
Result result = accountService.importAccount(priKey, password);
if (result.isSuccess()) {
Account account = (Account) result.getData();
Map<String, String> map = new HashMap<>();
map.put("value", account.getAddress().toString());
result.setData(map);
}
return result.toRpcClientResult();
}
use of io.nuls.core.tools.crypto.ECKey in project nuls by nuls-io.
the class AccountServiceImpl method verifyMessageSignature.
/**
* @auther EdwardChan
*
* @since Mar. 20th 2019
*
* 验证消息签名是否正确
*
* @param address 需要验证的地址
*
* @param message 消息
*
* @param signatureBase64 签名值
*
* @return 如果签名验证通过返回true,如果签名验证失败返回false
*/
@Override
public Result<Boolean> verifyMessageSignature(String address, String message, String signatureBase64) throws SignatureException {
boolean result = false;
message = AccountConstant.SIGN_MESSAGE_SALT + message;
try {
ECKey recoveryECKey = ECKey.signedMessageToKey(message, signatureBase64);
String recoveryAddress = AddressTool.getStringAddressByBytes(AddressTool.getAddress(recoveryECKey.getPubKey()));
if (recoveryAddress != null && recoveryAddress.equals(address)) {
result = true;
} else {
Log.info("verifyMessageSignature failed,address:{},message:{},signatureBase64:{}", address, message, signatureBase64);
}
} catch (SignatureException e) {
Log.info("", e);
}
return Result.getSuccess().setData(result);
}
Aggregations