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.
io.nuls.base.signture.SignatureUtil Maven / Gradle / Ivy
/*
* MIT License
*
* Copyright (c) 2017-2018 nuls.io
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package io.nuls.base.signture;
import io.nuls.base.basic.AddressTool;
import io.nuls.base.data.NulsHash;
import io.nuls.base.data.NulsSignData;
import io.nuls.base.data.Transaction;
import io.nuls.base.script.Script;
import io.nuls.base.script.ScriptBuilder;
import io.nuls.base.script.ScriptChunk;
import io.nuls.base.script.ScriptOpCodes;
import io.nuls.core.constant.BaseConstant;
import io.nuls.core.core.annotation.Component;
import io.nuls.core.crypto.ECKey;
import io.nuls.core.crypto.HexUtil;
import io.nuls.core.exception.NulsException;
import io.nuls.core.log.Log;
import java.io.IOException;
import java.math.BigInteger;
import java.util.*;
/**
* 交易签名工具类
* Transaction Signature Tool Class
*
* @author tag
* 2018/10/10
*/
@Component
public class SignatureUtil {
/**
* 验证交易中所有签名正确性
*
* @param tx 交易
*/
public static boolean validateTransactionSignture(Transaction tx) throws NulsException {
try {
if (tx.getTransactionSignature() == null || tx.getTransactionSignature().length == 0) {
throw new NulsException(new Exception());
}
if (!tx.isMultiSignTx()) {
TransactionSignature transactionSignature = new TransactionSignature();
transactionSignature.parse(tx.getTransactionSignature(), 0);
if ((transactionSignature.getP2PHKSignatures() == null || transactionSignature.getP2PHKSignatures().size() == 0)) {
throw new NulsException(new Exception("Transaction unsigned !"));
}
int signCount = tx.getCoinDataInstance().getFromAddressCount();
int passCount = 0;
for (P2PHKSignature signature : transactionSignature.getP2PHKSignatures()) {
if (!ECKey.verify(tx.getHash().getBytes(), signature.getSignData().getSignBytes(), signature.getPublicKey())) {
throw new NulsException(new Exception("Transaction signature error !"));
}
passCount++;
if(passCount >= signCount){
break;
}
}
} else {
MultiSignTxSignature transactionSignature = new MultiSignTxSignature();
transactionSignature.parse(tx.getTransactionSignature(), 0);
if ((transactionSignature.getP2PHKSignatures() == null || transactionSignature.getP2PHKSignatures().size() == 0)) {
throw new NulsException(new Exception("Transaction unsigned !"));
}
List validSignatures = transactionSignature.getValidSignature();
int validCount = 0;
for (P2PHKSignature signature : validSignatures) {
if (ECKey.verify(tx.getHash().getBytes(), signature.getSignData().getSignBytes(), signature.getPublicKey())) {
validCount++;
}
if (validCount >= transactionSignature.getM()) {
break;
}
}
if (validCount < transactionSignature.getM()) {
throw new NulsException(new Exception("Transaction signature error !"));
}
}
} catch (NulsException e) {
Log.error("TransactionSignature parse error!");
throw e;
}
return true;
}
/**
* 跨链交易验证签名
*
* @param tx 交易
*/
public static boolean validateCtxSignture(Transaction tx)throws NulsException{
if (tx.getTransactionSignature() == null || tx.getTransactionSignature().length == 0) {
return false;
}
TransactionSignature transactionSignature = new TransactionSignature();
transactionSignature.parse(tx.getTransactionSignature(), 0);
for (P2PHKSignature signature : transactionSignature.getP2PHKSignatures()) {
if (!ECKey.verify(tx.getHash().getBytes(), signature.getSignData().getSignBytes(), signature.getPublicKey())) {
throw new NulsException(new Exception("Transaction signature error !"));
}
}
return true;
}
/**
* 验证数据签名
*
* @param digestBytes
* @param p2PHKSignature
* @return
* @throws NulsException
*/
public static boolean validateSignture(byte[] digestBytes, P2PHKSignature p2PHKSignature) throws NulsException {
if (null == p2PHKSignature) {
throw new NulsException(new Exception("P2PHKSignature is null!"));
}
if (ECKey.verify(digestBytes, p2PHKSignature.getSignData().getSignBytes(), p2PHKSignature.getPublicKey())) {
return true;
}
return false;
}
/**
* 判断交易是否存在某地址
*
* @param tx 交易
*/
public static boolean containsAddress(Transaction tx, byte[] address, int chainId) throws NulsException {
Set addressSet = getAddressFromTX(tx, chainId);
if (addressSet == null || addressSet.size() == 0) {
return false;
}
return addressSet.contains(AddressTool.getStringAddressByBytes(address));
}
/**
* 获取交易签名地址
*
* @param tx 交易
*/
public static Set getAddressFromTX(Transaction tx, int chainId) throws NulsException {
Set addressSet = new HashSet<>();
if (tx.getTransactionSignature() == null || tx.getTransactionSignature().length == 0) {
return null;
}
try {
List p2PHKSignatures;
if (tx.isMultiSignTx()) {
MultiSignTxSignature transactionSignature = new MultiSignTxSignature();
transactionSignature.parse(tx.getTransactionSignature(), 0);
p2PHKSignatures = transactionSignature.getP2PHKSignatures();
} else {
TransactionSignature transactionSignature = new TransactionSignature();
transactionSignature.parse(tx.getTransactionSignature(), 0);
p2PHKSignatures = transactionSignature.getP2PHKSignatures();
}
if ((p2PHKSignatures == null || p2PHKSignatures.size() == 0)) {
return null;
}
for (P2PHKSignature signature : p2PHKSignatures) {
if (signature.getPublicKey() != null && signature.getPublicKey().length != 0) {
addressSet.add(AddressTool.getStringAddressByBytes(AddressTool.getAddress(signature.getPublicKey(), chainId)));
}
}
} catch (NulsException e) {
Log.error("TransactionSignature parse error!");
throw e;
}
return addressSet;
}
/**
* 生成交易TransactionSignture
*
* @param tx 交易
* @param signEckeys 需要生成普通签名的秘钥
*/
public static void createTransactionSignture(Transaction tx, List signEckeys) throws IOException {
if (signEckeys == null || signEckeys.size() == 0) {
Log.error("TransactionSignature signEckeys is null!");
throw new NullPointerException();
}
TransactionSignature transactionSignature = new TransactionSignature();
List p2PHKSignatures = null;
try {
p2PHKSignatures = createSignaturesByEckey(tx, signEckeys);
transactionSignature.setP2PHKSignatures(p2PHKSignatures);
tx.setTransactionSignature(transactionSignature.serialize());
} catch (IOException e) {
Log.error("TransactionSignature serialize error!");
throw e;
}
}
/**
* 生成交易多个传统签名(多地址转账可能会用到)
*
* @param tx 交易
* @param eckeys 秘钥列表
*/
public static List createSignaturesByEckey(Transaction tx, List eckeys) {
List signatures = new ArrayList<>();
for (ECKey ecKey : eckeys) {
signatures.add(createSignatureByEckey(tx, ecKey));
}
return signatures;
}
public static List createSignaturesByEckey(NulsHash hash, List eckeys) {
List signatures = new ArrayList<>();
for (ECKey ecKey : eckeys) {
signatures.add(createSignatureByEckey(hash, ecKey));
}
return signatures;
}
/**
* 生成交易的签名传统
*
* @param tx 交易
* @param priKey 私钥
*/
public static P2PHKSignature createSignatureByPriKey(Transaction tx, String priKey) {
ECKey ecKey = ECKey.fromPrivate(new BigInteger(1, HexUtil.decode(priKey)));
P2PHKSignature p2PHKSignature = new P2PHKSignature();
p2PHKSignature.setPublicKey(ecKey.getPubKey());
//用当前交易的hash和账户的私钥账户
p2PHKSignature.setSignData(signDigest(tx.getHash().getBytes(), ecKey));
return p2PHKSignature;
}
/**
* 生成交易的签名传统
*
* @param tx 交易
* @param ecKey 秘钥
*/
public static P2PHKSignature createSignatureByEckey(Transaction tx, ECKey ecKey) {
P2PHKSignature p2PHKSignature = new P2PHKSignature();
p2PHKSignature.setPublicKey(ecKey.getPubKey());
//用当前交易的hash和账户的私钥账户
p2PHKSignature.setSignData(signDigest(tx.getHash().getBytes(), ecKey));
return p2PHKSignature;
}
public static P2PHKSignature createSignatureByEckey(NulsHash hash, ECKey ecKey) {
P2PHKSignature p2PHKSignature = new P2PHKSignature();
p2PHKSignature.setPublicKey(ecKey.getPubKey());
//用当前交易的hash和账户的私钥账户
p2PHKSignature.setSignData(signDigest(hash.getBytes(), ecKey));
return p2PHKSignature;
}
/**
* 生成多个解锁脚本
*
* @param signtures 签名列表
* @param pubkeys 公钥列表
*/
public static List