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 signAddr Address of account
* @param password password of account
* @param aliasName the alias to set
* @return Result
*/
public Result<String> setMutilAlias(String addr, String signAddr, String aliasName, String password) {
// 签名账户
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 {
byte[] addressBytes = AddressTool.getAddress(addr);
Result<MultiSigAccount> sigAccountResult = accountService.getMultiSigAccount(addr);
MultiSigAccount multiSigAccount = sigAccountResult.getData();
if (!AddressTool.validSignAddress(multiSigAccount.getPubKeyList(), account.getPubKey())) {
return Result.getFailed(AccountErrorCode.SIGN_ADDRESS_NOT_MATCH);
}
Script redeemScript = accountLedgerService.getRedeemScript(multiSigAccount);
if (redeemScript == null) {
return Result.getFailed(AccountErrorCode.ACCOUNT_NOT_EXIST);
}
AliasTransaction tx = new AliasTransaction();
TransactionSignature transactionSignature = new TransactionSignature();
List<P2PHKSignature> p2PHKSignatures = new ArrayList<>();
List<Script> scripts = new ArrayList<>();
tx.setTime(TimeService.currentTimeMillis());
Alias alias = new Alias(addressBytes, aliasName);
tx.setTxData(alias);
// 交易签名的长度为m*单个签名长度+赎回脚本长度
int scriptSignLenth = redeemScript.getProgram().length + ((int) multiSigAccount.getM()) * 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);
// 使用签名账户对交易进行签名
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 AccountTest method privateKeyTest.
// 测试私钥
@Test
public void privateKeyTest() {
for (int i = 1; i < 1000000000; i++) {
ECKey ecKey = new ECKey();
String prikey = Hex.encode(ecKey.getPrivKeyBytes());
ECKey ecKey2 = ECKey.fromPrivate(new BigInteger(1, Hex.decode(prikey)));
ECKey ecKey3 = ECKey.fromPrivate(new BigInteger(Hex.decode(prikey)));
if (!Arrays.equals(ecKey.getPubKey(), ecKey3.getPubKey())) {
// 1.0.1的bug, 导入私钥BigInteger少传参数, 如果不等说明问题大了。
System.out.println("error: " + prikey);
Address address1 = new Address(NulsContext.getInstance().getDefaultChainId(), NulsContext.DEFAULT_ADDRESS_TYPE, SerializeUtils.sha256hash160(ecKey.getPubKey()));
Address address3 = new Address(NulsContext.getInstance().getDefaultChainId(), NulsContext.DEFAULT_ADDRESS_TYPE, SerializeUtils.sha256hash160(ecKey3.getPubKey()));
System.out.println("原始地址: " + address1.getBase58());
System.out.println("导入后地址3: " + address3.getBase58());
try {
System.out.println("原始ecKey: " + JSONUtils.obj2json(ecKey));
System.out.println("导入后ecKey3: " + JSONUtils.obj2json(ecKey3));
} catch (Exception e) {
e.printStackTrace();
}
break;
}
if (!Arrays.equals(ecKey.getPubKey(), ecKey2.getPubKey())) {
System.out.println("error: " + prikey);
Address address1 = new Address(NulsContext.getInstance().getDefaultChainId(), NulsContext.DEFAULT_ADDRESS_TYPE, SerializeUtils.sha256hash160(ecKey.getPubKey()));
Address address2 = new Address(NulsContext.getInstance().getDefaultChainId(), NulsContext.DEFAULT_ADDRESS_TYPE, SerializeUtils.sha256hash160(ecKey2.getPubKey()));
System.out.println("原始地址: " + address1.getBase58());
System.out.println("导入后地址: " + address2.getBase58());
try {
System.out.println("原始ecKey: " + JSONUtils.obj2json(ecKey));
System.out.println("导入后ecKey: " + JSONUtils.obj2json(ecKey2));
} catch (Exception e) {
e.printStackTrace();
}
break;
} else {
System.out.println(i + " ok: " + prikey);
Address addr = new Address(NulsContext.getInstance().getDefaultChainId(), NulsContext.DEFAULT_ADDRESS_TYPE, SerializeUtils.sha256hash160(ecKey.getPubKey()));
if (addr.getBase58().endsWith("lichao") || addr.getBase58().endsWith("Charlie")) {
System.out.println(" yeah yeah yeah: " + addr.getBase58());
System.out.println(" yeah yeah yeah: " + prikey);
break;
}
}
/* try {
Thread.sleep(1L);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
}
}
use of io.nuls.core.tools.crypto.ECKey in project nuls by nuls-io.
the class PocConsensusResource method txProcessing.
public RpcClientResult txProcessing(Transaction tx, CoinDataResult result, Account account, String password) {
if (null != result) {
if (result.isEnough()) {
tx.getCoinData().setFrom(result.getCoinList());
if (null != result.getChange()) {
tx.getCoinData().getTo().add(result.getChange());
}
} else {
return Result.getFailed(TransactionErrorCode.INSUFFICIENT_BALANCE).toRpcClientResult();
}
}
try {
tx.setHash(NulsDigestData.calcDigestData(tx.serializeForHash()));
// 生成签名
List<ECKey> signEckeys = new ArrayList<>();
ECKey eckey = account.getEcKey(password);
signEckeys.add(eckey);
SignatureUtil.createTransactionSignture(tx, null, signEckeys);
} catch (Exception e) {
Log.error(e);
return Result.getFailed(KernelErrorCode.SYS_UNKOWN_EXCEPTION).toRpcClientResult();
}
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.toRpcClientResult();
}
return saveResult.toRpcClientResult();
}
transactionService.newTx(tx);
Result sendResult = this.transactionService.broadcastTx(tx);
if (sendResult.isFailed()) {
accountLedgerService.deleteTransaction(tx);
return sendResult.toRpcClientResult();
}
return Result.getSuccess().toRpcClientResult();
}
use of io.nuls.core.tools.crypto.ECKey in project nuls by nuls-io.
the class RegisterAgentProcessTest method newTx.
private CreateAgentTransaction newTx() {
CreateAgentTransaction tx = new CreateAgentTransaction();
Agent agent = new Agent();
tx.setTxData(agent);
byte[] address = AddressTool.getAddress(ecKey.getPubKey());
byte[] address1 = AddressTool.getAddress(new ECKey().getPubKey());
byte[] address2 = AddressTool.getAddress(new ECKey().getPubKey());
agent.setRewardAddress(address);
agent.setPackingAddress(address1);
agent.setAgentAddress(address2);
agent.setDeposit(PocConsensusProtocolConstant.AGENT_DEPOSIT_LOWER_LIMIT);
tx.setTime(System.currentTimeMillis());
return tx;
}
use of io.nuls.core.tools.crypto.ECKey in project nuls by nuls-io.
the class AccountLedgerServiceImpl method transferP2SH.
/**
* A transfers NULS to B 多签交易
*
* @param fromAddr address of A
* @param signAddr address of B
* @param values NULS amount
* @param password password of A
* @param remark remarks of transaction
* @param price Unit price of fee
* @param pubkeys 公钥列表
* @param m 至少需要签名验证通过
* @return Result
*/
@Override
public Result transferP2SH(byte[] fromAddr, byte[] signAddr, List<MultipleAddressTransferModel> outputs, Na values, String password, String remark, Na price, List<String> pubkeys, int m, String txdata) {
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);
}
}
if (!account.isOk()) {
return Result.getFailed(AccountErrorCode.IMPORTING_ACCOUNT);
}
TransferTransaction tx = new TransferTransaction();
TransactionSignature transactionSignature = new TransactionSignature();
List<P2PHKSignature> p2PHKSignatures = new ArrayList<>();
List<Script> scripts = new ArrayList<>();
// 如果txdata为空则表示当前请求为多签发起者调用,需要创建交易
if (txdata == null || txdata.trim().length() == 0) {
if (StringUtils.isNotBlank(remark)) {
try {
tx.setRemark(remark.getBytes(NulsConfig.DEFAULT_ENCODING));
} catch (UnsupportedEncodingException e) {
Log.error(e);
}
}
Script redeemScript = ScriptBuilder.createNulsRedeemScript(m, pubkeys);
tx.setTime(TimeService.currentTimeMillis());
CoinData coinData = new CoinData();
for (MultipleAddressTransferModel to : outputs) {
// 如果为多签地址
Coin toCoin = null;
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);
}
if (price == null) {
price = TransactionFeeCalculator.MIN_PRICE_PRE_1024_BYTES;
}
// 交易签名的长度为m*单个签名长度+赎回脚本长度
int scriptSignLenth = redeemScript.getProgram().length + m * 72;
CoinDataResult coinDataResult = getMutilCoinData(fromAddr, values, tx.size() + coinData.size() + scriptSignLenth, price);
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);
} 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);
// 当已签名数等于M则自动广播该交易
if (p2PHKSignatures.size() == SignatureUtil.getM(scripts.get(0))) {
// 将交易中的签名数据P2PHKSignatures按规则排序
Collections.sort(p2PHKSignatures, 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()) {
if (KernelErrorCode.DATA_SIZE_ERROR.getCode().equals(saveResult.getErrorCode().getCode())) {
// 重新算一次交易(不超出最大交易数据大小下)的最大金额
Result rs = getMaxAmountOfOnce(fromAddr, 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;
}
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());
}
}
Aggregations