cn.tdchain.Trans Maven / Gradle / Ivy
/*
* Copyright (c) 2017 Beijing Tiande Technology Co., Ltd.
* All Rights Reserved.
*/
package cn.tdchain;
import cn.tdchain.cipher.rsa.RsaUtil;
import cn.tdchain.cipher.utils.HashCheckUtil;
import cn.tdchain.cipher.utils.StringUtils;
import cn.tdchain.jbcc.DateUtils;
import cn.tdchain.jbcc.SQLCheckUtil;
import cn.tdchain.jbcc.SensitiveWordsUtil;
import cn.tdchain.jbcc.TransInfoException;
import cn.tdchain.jbcc.TransUtil;
import org.apache.commons.collections.MapUtils;
import java.util.Map;
/**
* Description: 天德区块链交易实体
*
* @author xiaoming
* 2019年4月18日
*/
public class Trans extends TransHead {
protected String account;//客户端账户
protected String data;//其他交易数据,json object 的字符串结构
protected Category category;
protected Map keyVersionMap;
protected Map signMap;
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
public Map getKeyVersionMap() {
return keyVersionMap;
}
public void setKeyVersionMap(Map keyVersionMap) {
this.keyVersionMap = keyVersionMap;
}
public Map getSignMap() {
return signMap;
}
public void setSignMap(Map signMap) {
this.signMap = signMap;
}
/**
* note: no need to call this method
*/
@Deprecated
public void upHash() {
//验证key不能为null
if (this.key == null || this.key.trim().length() == 0 || this.key.trim().length() > 255) {
throw new TransInfoException("key is null or too long.");
}
if (StringUtils.isBlank(this.account)) {
throw new TransInfoException("account is blank.");
}
if (timestamp == null) {
this.setTimestamp(DateUtils.getCurrentTime());
}
if (this.hash != null && this.hash.length() > 0 && !this.hash.equals("null")) {
this.preHash = this.hash;//当前交易hash会变成历史交易hash
}
this.hash = computHash(this);
}
/**
* Description: 计算出交易hash
*
* @param t
* @return String
*/
public String computHash(Trans t) {
return TransUtil.getTransHash(t);
}
public void check() {
check(false);
}
/**
* Description: 验证自己属性
*/
public void check(boolean enableVerifySensitiveWorks) {
// 交易属性验证
TransUtil.verifyKey(this.getKey());
//type字段不能有特殊字符
if (HashCheckUtil.illegalCharacterCheck(this.type) || (this.type != null && this.type.length() > 45)) {
throw new TransInfoException("type have Illegal character.");
}
if (SQLCheckUtil.checkSQLError(this.getKey())) {
throw new TransInfoException("key have Illegal character.");
}
if (this.getData() == null || this.getData().trim().length() == 0 || this.getData().trim().getBytes().length > 65535) {
throw new TransInfoException("data is null or too long, max byte size is 65535.");
}
//data不能有特殊字符
if (HashCheckUtil.illegalCharacterCheck(this.data)) {
throw new TransInfoException("data have Illegal character.");
}
// if ("null".equals(this.getHash()) || this.getHash().trim().length() < 64) {
// this.upHash();
// }
// 交易分类校验
if (category == null) { //非智能合约
if (keyVersionMap != null) {
throw new TransInfoException("category is null & keyVersionMap should be null");
}
if (signMap != null) {
throw new TransInfoException("category is null & keyVersionMap should be null");
}
} else if (Category.contract == category) {// 智能交易的合约
if (version == null) {
throw new TransInfoException("contract version none init");
}
if (keyVersionMap != null) {
if (keyVersionMap.size() > 10) {
throw new TransInfoException("contract keyVersionMap size is limit to 10.");
}
keyVersionMap.forEach((k, v) -> {
TransUtil.verifyKey(k);
});
}
if (MapUtils.isNotEmpty(signMap)) {
String thash = TransUtil.getTransHash(this);
signMap.forEach((k, v) -> {
boolean verify = RsaUtil.verify(k, v, thash);
if (!verify) {
throw new TransInfoException("contract signMap sign error.");
}
});
}
}
//hash验证
if (!HashCheckUtil.hashCheck(this.hash)) {
throw new TransInfoException("hash error:" + this.hash);
}
//pre hash验证,要么等于"null"要么就是正常的hash字符串
if (!HashCheckUtil.hashCheck(this.preHash) && !"".equals(this.preHash)) {
throw new TransInfoException("pre hash error:" + this.preHash);
}
// 验证是否包含敏感词汇
if (enableVerifySensitiveWorks) {
checkSensitiveWords();
}
//检查超交易生成时间,超过1秒的交易可能存在问题.
checkStartTime();
}
/**
* Description: 验证交易是否包含敏感词汇
*/
private void checkSensitiveWords() {
String key = this.getKey();
String data = this.getData();
boolean isContains = SensitiveWordsUtil.containsSensitiveWords(key, SensitiveWordsUtil.MATCH_TYPE_MIN);
if (isContains) {
throw new TransInfoException("trans[key=" + key + "] contains sensitive words");
}
isContains = SensitiveWordsUtil.containsSensitiveWords(data, SensitiveWordsUtil.MATCH_TYPE_MIN);
if (isContains) {
throw new TransInfoException("trans[data=" + data + "] contains sensitive words");
}
}
/**
* Description: 检查交易是否过时?不能超过6秒之后再提交交易。
*/
protected void checkStartTime() {
Long differ_time = (System.currentTimeMillis() - this.getTimestamp());
if ((differ_time > 6000) || differ_time < -6000) {
//过时交易或者交易时间戳超前
throw new TransInfoException("the trans out of time or timestamp is error.");
}
}
public enum Category {
contract
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy