From 1daa3f517f5b3595629a6463e979ac9ec1b3e20c Mon Sep 17 00:00:00 2001 From: LightKool Date: Mon, 16 Mar 2020 17:42:58 +0800 Subject: [PATCH 01/40] tuning tbl_tx_detail_index structure --- .../db/migration/V1.38__tbl_tx_detail_index.sql | 16 ++++++++++++++++ .../db/migration/V1.39__tbl_oep5_tx_detail.sql | 5 +++++ .../main/resources/mapper/Oep5TxDetailMapper.xml | 16 +++++----------- .../src/main/resources/mapper/TxDetailMapper.xml | 2 -- .../resources/mapper/TxDetailIndexMapper.xml | 12 ++++++------ 5 files changed, 32 insertions(+), 19 deletions(-) create mode 100644 back-end-projects/Explorer/src/main/resources/db/migration/V1.38__tbl_tx_detail_index.sql create mode 100644 back-end-projects/Explorer/src/main/resources/db/migration/V1.39__tbl_oep5_tx_detail.sql diff --git a/back-end-projects/Explorer/src/main/resources/db/migration/V1.38__tbl_tx_detail_index.sql b/back-end-projects/Explorer/src/main/resources/db/migration/V1.38__tbl_tx_detail_index.sql new file mode 100644 index 00000000..fddbea58 --- /dev/null +++ b/back-end-projects/Explorer/src/main/resources/db/migration/V1.38__tbl_tx_detail_index.sql @@ -0,0 +1,16 @@ +-- ---------------------------- +-- Table structure for tbl_tx_detail_index +-- ---------------------------- +DROP TABLE IF EXISTS `tbl_tx_detail_index`; +CREATE TABLE `tbl_tx_detail_index` ( + `address` CHAR(80) NOT NULL DEFAULT '' COMMENT '交易地址', + `desc_block_height` INT(11) NOT NULL COMMENT '倒序区块高度', + `tx_hash` CHAR(64) NOT NULL DEFAULT '' COMMENT '交易hash', + `tx_index` INT(11) NOT NULL COMMENT '该event在交易eventlog里的索引', + `called_contract_hash` CHAR(40) NOT NULL DEFAULT '' COMMENT '该交易真正调用的合约hash', + `tx_time` INT(11) NOT NULL COMMENT '交易时间戳', + `asset_name` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '交易资产名', + `tx_direction` TINYINT NOT NULL COMMENT '交易方向 0:FROM 1:TO 2:BOTH', + PRIMARY KEY (`address`, `desc_block_height`, `tx_hash`, `tx_index`), + KEY `idx_contract_block_height`(`called_contract_hash`, `desc_block_height`) +) ENGINE = InnoDB DEFAULT CHARSET = utf8; diff --git a/back-end-projects/Explorer/src/main/resources/db/migration/V1.39__tbl_oep5_tx_detail.sql b/back-end-projects/Explorer/src/main/resources/db/migration/V1.39__tbl_oep5_tx_detail.sql new file mode 100644 index 00000000..a34a174c --- /dev/null +++ b/back-end-projects/Explorer/src/main/resources/db/migration/V1.39__tbl_oep5_tx_detail.sql @@ -0,0 +1,5 @@ +-- ---------------------------- +-- Change index structure for tbl_oep5_tx_detail +-- ---------------------------- +DROP INDEX idx_called_contract_hash ON tbl_oep5_tx_detail; +CREATE INDEX idx_called_contract_hash_block_height ON tbl_oep5_tx_detail(`called_contract_hash`, `block_height`); diff --git a/back-end-projects/Explorer/src/main/resources/mapper/Oep5TxDetailMapper.xml b/back-end-projects/Explorer/src/main/resources/mapper/Oep5TxDetailMapper.xml index fc48779d..88781ab7 100644 --- a/back-end-projects/Explorer/src/main/resources/mapper/Oep5TxDetailMapper.xml +++ b/back-end-projects/Explorer/src/main/resources/mapper/Oep5TxDetailMapper.xml @@ -53,7 +53,7 @@ diff --git a/back-end-projects/Explorer/src/main/resources/mapper/TxDetailMapper.xml b/back-end-projects/Explorer/src/main/resources/mapper/TxDetailMapper.xml index d15a60dc..ba3da1f4 100644 --- a/back-end-projects/Explorer/src/main/resources/mapper/TxDetailMapper.xml +++ b/back-end-projects/Explorer/src/main/resources/mapper/TxDetailMapper.xml @@ -107,7 +107,6 @@ AND asset_name = #{assetName} - AND event_type IN (2, 3) ORDER BY desc_block_height, tx_hash, tx_index LIMIT #{startIndex}, #{pageSize} ) idx ON idx.hash = d.tx_hash @@ -134,7 +133,6 @@ AND asset_name = #{assetName} - AND event_type IN (2, 3) ORDER BY desc_block_height, tx_hash, tx_index ) idx ON idx.hash = d.tx_hash AND idx.`index` = d.tx_index diff --git a/back-end-projects/OntSynHandler/src/main/resources/mapper/TxDetailIndexMapper.xml b/back-end-projects/OntSynHandler/src/main/resources/mapper/TxDetailIndexMapper.xml index 87b68c00..69a98c51 100644 --- a/back-end-projects/OntSynHandler/src/main/resources/mapper/TxDetailIndexMapper.xml +++ b/back-end-projects/OntSynHandler/src/main/resources/mapper/TxDetailIndexMapper.xml @@ -4,19 +4,19 @@ INSERT INTO tbl_tx_detail_index - (address, desc_block_height, tx_hash, tx_index, called_contract_hash, tx_time, event_type, asset_name, tx_direction) - SELECT from_address, (~0 >> 33) - block_height, tx_hash, tx_index, called_contract_hash, tx_time, event_type, asset_name, 0 + (address, desc_block_height, tx_hash, tx_index, called_contract_hash, tx_time, asset_name, tx_direction) + SELECT from_address, (~0 >> 33) - block_height, tx_hash, tx_index, called_contract_hash, tx_time, asset_name, 0 FROM tbl_tx_detail - WHERE block_height BETWEEN #{beginHeight} AND #{endHeight} + WHERE block_height BETWEEN #{beginHeight} AND #{endHeight} AND from_address <> '' AND event_type IN (2, 3) ORDER BY block_height, tx_time; INSERT INTO tbl_tx_detail_index - (address, desc_block_height, tx_hash, tx_index, called_contract_hash, tx_time, event_type, asset_name, tx_direction) - SELECT to_address, (~0 >> 33) - block_height, tx_hash, tx_index, called_contract_hash, tx_time, event_type, asset_name, 1 + (address, desc_block_height, tx_hash, tx_index, called_contract_hash, tx_time, asset_name, tx_direction) + SELECT to_address, (~0 >> 33) - block_height, tx_hash, tx_index, called_contract_hash, tx_time, asset_name, 1 FROM tbl_tx_detail - WHERE block_height BETWEEN #{beginHeight} AND #{endHeight} + WHERE block_height BETWEEN #{beginHeight} AND #{endHeight} AND to_address <> '' AND event_type IN (2, 3) ORDER BY block_height, tx_time ON DUPLICATE KEY UPDATE tx_direction = 2; From b76bb1190802648c9db9d22e3eeaee6586f8b85a Mon Sep 17 00:00:00 2001 From: LightKool Date: Tue, 17 Mar 2020 10:38:31 +0800 Subject: [PATCH 02/40] tuning old transactions query performance --- .../resources/mapper/TxEventLogMapper.xml | 19 ++++++++++--------- .../github/ontio/mapper/TxEventLogMapper.java | 4 ++++ .../github/ontio/service/CommonService.java | 2 ++ .../resources/mapper/TxEventLogMapper.xml | 10 ++++++++++ 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/back-end-projects/Explorer/src/main/resources/mapper/TxEventLogMapper.xml b/back-end-projects/Explorer/src/main/resources/mapper/TxEventLogMapper.xml index ae3532ee..9a98535b 100644 --- a/back-end-projects/Explorer/src/main/resources/mapper/TxEventLogMapper.xml +++ b/back-end-projects/Explorer/src/main/resources/mapper/TxEventLogMapper.xml @@ -42,15 +42,16 @@ + SELECT if(max(id) IS NULL, 0, max(id)) + FROM tbl_tx_eventlog; + \ No newline at end of file From 9c19a54f62a5144f9744dcf9b1cac8480bb821e5 Mon Sep 17 00:00:00 2001 From: LightKool Date: Tue, 17 Mar 2020 10:54:31 +0800 Subject: [PATCH 03/40] performance tuning /contract/other/d9722202f715e751412838d47d713a2d899904bc/10/1 --- .../main/resources/db/migration/V1.40__tbl_tx_eventlog.sql | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 back-end-projects/Explorer/src/main/resources/db/migration/V1.40__tbl_tx_eventlog.sql diff --git a/back-end-projects/Explorer/src/main/resources/db/migration/V1.40__tbl_tx_eventlog.sql b/back-end-projects/Explorer/src/main/resources/db/migration/V1.40__tbl_tx_eventlog.sql new file mode 100644 index 00000000..c810eeae --- /dev/null +++ b/back-end-projects/Explorer/src/main/resources/db/migration/V1.40__tbl_tx_eventlog.sql @@ -0,0 +1,5 @@ +-- ---------------------------- +-- Change index structure for tbl_tx_eventlog +-- ---------------------------- +DROP INDEX idx_called_contract_hash ON tbl_tx_eventlog; +CREATE INDEX idx_called_contract_hash_block_height ON tbl_tx_eventlog (`called_contract_hash`, `block_height`); From 0361fb24e19f08b7aa587ff4371741dc8ddd187f Mon Sep 17 00:00:00 2001 From: LightKool Date: Tue, 17 Mar 2020 11:47:43 +0800 Subject: [PATCH 04/40] performance tuning /token/detail/oep4/b52b63902ed5d6455cd7929a13613fc1b88a056f/Spok kz/10/1 --- .../resources/db/migration/V1.41__tbl_oep4_tx_detail.sql | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 back-end-projects/Explorer/src/main/resources/db/migration/V1.41__tbl_oep4_tx_detail.sql diff --git a/back-end-projects/Explorer/src/main/resources/db/migration/V1.41__tbl_oep4_tx_detail.sql b/back-end-projects/Explorer/src/main/resources/db/migration/V1.41__tbl_oep4_tx_detail.sql new file mode 100644 index 00000000..951ab650 --- /dev/null +++ b/back-end-projects/Explorer/src/main/resources/db/migration/V1.41__tbl_oep4_tx_detail.sql @@ -0,0 +1,5 @@ +-- ---------------------------- +-- Change index structure for tbl_oep4_tx_detail +-- ---------------------------- +DROP INDEX idx_called_contract_hash ON tbl_oep4_tx_detail; +CREATE INDEX idx_called_contract_hash_block_height ON tbl_oep4_tx_detail (`called_contract_hash`, `block_height`); \ No newline at end of file From 58d9bd901c3a9e0912cf771003c1a80222cbffca Mon Sep 17 00:00:00 2001 From: LightKool Date: Fri, 20 Mar 2020 16:27:00 +0800 Subject: [PATCH 05/40] tbl_tx_detail_index table structure change --- .../main/resources/db/migration/V1.38__tbl_tx_detail_index.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back-end-projects/Explorer/src/main/resources/db/migration/V1.38__tbl_tx_detail_index.sql b/back-end-projects/Explorer/src/main/resources/db/migration/V1.38__tbl_tx_detail_index.sql index fddbea58..ffb9d4a1 100644 --- a/back-end-projects/Explorer/src/main/resources/db/migration/V1.38__tbl_tx_detail_index.sql +++ b/back-end-projects/Explorer/src/main/resources/db/migration/V1.38__tbl_tx_detail_index.sql @@ -12,5 +12,5 @@ CREATE TABLE `tbl_tx_detail_index` ( `asset_name` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '交易资产名', `tx_direction` TINYINT NOT NULL COMMENT '交易方向 0:FROM 1:TO 2:BOTH', PRIMARY KEY (`address`, `desc_block_height`, `tx_hash`, `tx_index`), - KEY `idx_contract_block_height`(`called_contract_hash`, `desc_block_height`) + KEY `idx_address_contract_hash`(`address`, `called_contract_hash`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8; From 76e041b72b88932397a1731f5114003dee5b6d4b Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Fri, 27 Mar 2020 21:01:51 +0800 Subject: [PATCH 06/40] add new table --- .../ontio/mapper/UserAddressMapper.java | 13 ++ .../com/github/ontio/mapper/UserMapper.java | 7 + .../java/com/github/ontio/model/dao/User.java | 128 ++++++++++++++++ .../github/ontio/model/dao/UserAddress.java | 141 ++++++++++++++++++ .../resources/mapper/UserAddressMapper.xml | 30 ++++ .../src/main/resources/mapper/UserMapper.xml | 14 ++ 6 files changed, 333 insertions(+) create mode 100644 back-end-projects/OntSynHandler/src/main/java/com/github/ontio/mapper/UserAddressMapper.java create mode 100644 back-end-projects/OntSynHandler/src/main/java/com/github/ontio/mapper/UserMapper.java create mode 100644 back-end-projects/OntSynHandler/src/main/java/com/github/ontio/model/dao/User.java create mode 100644 back-end-projects/OntSynHandler/src/main/java/com/github/ontio/model/dao/UserAddress.java create mode 100644 back-end-projects/OntSynHandler/src/main/resources/mapper/UserAddressMapper.xml create mode 100644 back-end-projects/OntSynHandler/src/main/resources/mapper/UserMapper.xml diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/mapper/UserAddressMapper.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/mapper/UserAddressMapper.java new file mode 100644 index 00000000..82a34b5e --- /dev/null +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/mapper/UserAddressMapper.java @@ -0,0 +1,13 @@ +package com.github.ontio.mapper; + +import com.github.ontio.model.dao.UserAddress; +import com.github.ontio.txPush.model.PushUserAddressInfoDto; +import tk.mybatis.mapper.common.Mapper; + +import java.util.List; + +public interface UserAddressMapper extends Mapper { + + List selectUserAddressInfo(); + +} \ No newline at end of file diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/mapper/UserMapper.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/mapper/UserMapper.java new file mode 100644 index 00000000..9d216fd8 --- /dev/null +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/mapper/UserMapper.java @@ -0,0 +1,7 @@ +package com.github.ontio.mapper; + +import com.github.ontio.model.dao.User; +import tk.mybatis.mapper.common.Mapper; + +public interface UserMapper extends Mapper { +} \ No newline at end of file diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/model/dao/User.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/model/dao/User.java new file mode 100644 index 00000000..98071fc5 --- /dev/null +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/model/dao/User.java @@ -0,0 +1,128 @@ +package com.github.ontio.model.dao; + +import java.util.Date; +import javax.persistence.*; + +@Table(name = "tbl_user") +public class User { + /** + * ONT ID + */ + @Id + @Column(name = "ont_id") + @GeneratedValue(generator = "JDBC") + private String ontId; + + /** + * 用户名 + */ + @Column(name = "user_name") + private String userName; + + /** + * 邮箱 + */ + private String email; + + /** + * 创建时间 + */ + @Column(name = "create_time") + private Date createTime; + + /** + * 上次登录时间 + */ + @Column(name = "last_login_time") + private Date lastLoginTime; + + /** + * 获取ONT ID + * + * @return ont_id - ONT ID + */ + public String getOntId() { + return ontId; + } + + /** + * 设置ONT ID + * + * @param ontId ONT ID + */ + public void setOntId(String ontId) { + this.ontId = ontId == null ? null : ontId.trim(); + } + + /** + * 获取用户名 + * + * @return user_name - 用户名 + */ + public String getUserName() { + return userName; + } + + /** + * 设置用户名 + * + * @param userName 用户名 + */ + public void setUserName(String userName) { + this.userName = userName == null ? null : userName.trim(); + } + + /** + * 获取邮箱 + * + * @return email - 邮箱 + */ + public String getEmail() { + return email; + } + + /** + * 设置邮箱 + * + * @param email 邮箱 + */ + public void setEmail(String email) { + this.email = email == null ? null : email.trim(); + } + + /** + * 获取创建时间 + * + * @return create_time - 创建时间 + */ + public Date getCreateTime() { + return createTime; + } + + /** + * 设置创建时间 + * + * @param createTime 创建时间 + */ + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + /** + * 获取上次登录时间 + * + * @return last_login_time - 上次登录时间 + */ + public Date getLastLoginTime() { + return lastLoginTime; + } + + /** + * 设置上次登录时间 + * + * @param lastLoginTime 上次登录时间 + */ + public void setLastLoginTime(Date lastLoginTime) { + this.lastLoginTime = lastLoginTime; + } +} \ No newline at end of file diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/model/dao/UserAddress.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/model/dao/UserAddress.java new file mode 100644 index 00000000..bbd37025 --- /dev/null +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/model/dao/UserAddress.java @@ -0,0 +1,141 @@ +package com.github.ontio.model.dao; + +import javax.persistence.*; + +@Table(name = "tbl_user_address") +public class UserAddress { + @Id + @GeneratedValue(generator = "JDBC") + private Integer id; + + /** + * ONT ID + */ + @Column(name = "ont_id") + private String ontId; + + /** + * 地址 + */ + private String address; + + /** + * 地址备注 + */ + private String note; + + /** + * 监听策略。0:不监听 1:监听所有入金出金,2:只监听入金 3:只监听出金 + */ + private Integer strategy; + + /** + * 1:监听oep资产 0:不监听oep资产 + */ + @Column(name = "include_oep_token") + private Boolean includeOepToken; + + /** + * @return id + */ + public Integer getId() { + return id; + } + + /** + * @param id + */ + public void setId(Integer id) { + this.id = id; + } + + /** + * 获取ONT ID + * + * @return ont_id - ONT ID + */ + public String getOntId() { + return ontId; + } + + /** + * 设置ONT ID + * + * @param ontId ONT ID + */ + public void setOntId(String ontId) { + this.ontId = ontId == null ? null : ontId.trim(); + } + + /** + * 获取地址 + * + * @return address - 地址 + */ + public String getAddress() { + return address; + } + + /** + * 设置地址 + * + * @param address 地址 + */ + public void setAddress(String address) { + this.address = address == null ? null : address.trim(); + } + + /** + * 获取地址备注 + * + * @return note - 地址备注 + */ + public String getNote() { + return note; + } + + /** + * 设置地址备注 + * + * @param note 地址备注 + */ + public void setNote(String note) { + this.note = note == null ? null : note.trim(); + } + + /** + * 获取监听策略。0:不监听 1:监听所有入金出金,2:只监听入金 3:只监听出金 + * + * @return strategy - 监听策略。0:不监听 1:监听所有入金出金,2:只监听入金 3:只监听出金 + */ + public Integer getStrategy() { + return strategy; + } + + /** + * 设置监听策略。0:不监听 1:监听所有入金出金,2:只监听入金 3:只监听出金 + * + * @param strategy 监听策略。0:不监听 1:监听所有入金出金,2:只监听入金 3:只监听出金 + */ + public void setStrategy(Integer strategy) { + this.strategy = strategy; + } + + /** + * 获取1:监听oep资产 0:不监听oep资产 + * + * @return include_oep_token - 1:监听oep资产 0:不监听oep资产 + */ + public Boolean getIncludeOepToken() { + return includeOepToken; + } + + /** + * 设置1:监听oep资产 0:不监听oep资产 + * + * @param includeOepToken 1:监听oep资产 0:不监听oep资产 + */ + public void setIncludeOepToken(Boolean includeOepToken) { + this.includeOepToken = includeOepToken; + } +} \ No newline at end of file diff --git a/back-end-projects/OntSynHandler/src/main/resources/mapper/UserAddressMapper.xml b/back-end-projects/OntSynHandler/src/main/resources/mapper/UserAddressMapper.xml new file mode 100644 index 00000000..067b2aac --- /dev/null +++ b/back-end-projects/OntSynHandler/src/main/resources/mapper/UserAddressMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/back-end-projects/OntSynHandler/src/main/resources/mapper/UserMapper.xml b/back-end-projects/OntSynHandler/src/main/resources/mapper/UserMapper.xml new file mode 100644 index 00000000..99b58702 --- /dev/null +++ b/back-end-projects/OntSynHandler/src/main/resources/mapper/UserMapper.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file From eb66f3f6f1328a2116fc936e3bcbcd525c72c4ec Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Fri, 27 Mar 2020 21:02:18 +0800 Subject: [PATCH 07/40] judge transfer tx --- .../github/ontio/thread/TxHandlerThread.java | 25 ++- .../github/ontio/utils/HttpClientUtil.java | 161 ++++++++++++++++++ .../resources/generator/generatorConfig.xml | 15 +- 3 files changed, 196 insertions(+), 5 deletions(-) create mode 100644 back-end-projects/OntSynHandler/src/main/java/com/github/ontio/utils/HttpClientUtil.java diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/thread/TxHandlerThread.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/thread/TxHandlerThread.java index 458a4c34..9c4a4fe4 100644 --- a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/thread/TxHandlerThread.java +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/thread/TxHandlerThread.java @@ -36,6 +36,7 @@ import com.github.ontio.network.exception.RestfulException; import com.github.ontio.service.CommonService; import com.github.ontio.smartcontract.neovm.abi.BuildParams; +import com.github.ontio.txPush.TransferTransactionPush; import com.github.ontio.utils.ConstantParam; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -73,13 +74,16 @@ public class TxHandlerThread { private final Oep5Mapper oep5Mapper; + private final TransferTransactionPush transferTransactionPush; + @Autowired - public TxHandlerThread(ParamsConfig paramsConfig, ContractMapper contractMapper, CommonService commonService, Oep8Mapper oep8Mapper, Oep5Mapper oep5Mapper) { + public TxHandlerThread(ParamsConfig paramsConfig, ContractMapper contractMapper, CommonService commonService, Oep8Mapper oep8Mapper, Oep5Mapper oep5Mapper, TransferTransactionPush transferTransactionPush) { this.paramsConfig = paramsConfig; this.contractMapper = contractMapper; this.commonService = commonService; this.oep8Mapper = oep8Mapper; this.oep5Mapper = oep5Mapper; + this.transferTransactionPush = transferTransactionPush; } @Async @@ -464,7 +468,9 @@ private void handleNativeTransferTx(JSONArray stateList, int txType, String txHa ConstantParam.BATCHBLOCKDTO.getOep4TxDetails().add(TxDetail.toOep4TxDetail(txDetail)); } } - + if (EventTypeEnum.Transfer.type() == eventType) { + transferTransactionPush.publish(txDetail); + } } @@ -721,6 +727,8 @@ private void handleOep8TransferTx(JSONArray stateArray, int txType, String txHas ConstantParam.BATCHBLOCKDTO.getTxDetails().add(txDetail); ConstantParam.BATCHBLOCKDTO.getTxDetailDailys().add(TxDetail.toTxDetailDaily(txDetail)); ConstantParam.BATCHBLOCKDTO.getOep8TxDetails().add(TxDetail.toOep8TxDetail(txDetail)); + + transferTransactionPush.publish(txDetail); } /** @@ -743,6 +751,7 @@ private void handleOep5TransferTxn(JSONArray stateArray, int txType, String txHa int blockTime, int indexInBlock, BigDecimal gasConsumed, int indexInTx, int confirmFlag, String contractAddress, JSONObject oep5Obj, String payer, String calledContractHash) throws Exception { + Boolean isTransfer = Boolean.FALSE; String action = new String(Helper.hexToBytes((String) stateArray.get(0))); //只解析birth和transfer合约方法 if (!(action.equalsIgnoreCase("transfer") || action.equalsIgnoreCase("birth"))) { @@ -784,6 +793,7 @@ private void handleOep5TransferTxn(JSONArray stateArray, int txType, String txHa } else { amount = ConstantParam.ONE; dragonId = Helper.BigIntFromNeoBytes(Helper.hexToBytes((String) stateArray.get(3))).toString(); + isTransfer = Boolean.TRUE; } assetName = ConstantParam.ASSET_NAME_DRAGON + dragonId; } else { @@ -805,6 +815,7 @@ private void handleOep5TransferTxn(JSONArray stateArray, int txType, String txHa //transfer方法,tokenid在位置3 assetName = oep5Obj.getString("symbol") + stateArray.get(3); amount = ConstantParam.ONE; + isTransfer = Boolean.TRUE; } } @@ -816,6 +827,10 @@ private void handleOep5TransferTxn(JSONArray stateArray, int txType, String txHa ConstantParam.BATCHBLOCKDTO.getTxDetails().add(txDetail); ConstantParam.BATCHBLOCKDTO.getTxDetailDailys().add(TxDetail.toTxDetailDaily(txDetail)); ConstantParam.BATCHBLOCKDTO.getOep5TxDetails().add(TxDetail.toOep5TxDetail(txDetail)); + + if (isTransfer) { + transferTransactionPush.publish(txDetail); + } } private void handleOep4TransferTxn(JSONArray stateArray, int txType, String txHash, int blockHeight, @@ -824,6 +839,7 @@ private void handleOep4TransferTxn(JSONArray stateArray, int txType, String txHa String fromAddress = ""; String toAddress = ""; BigDecimal eventAmount = new BigDecimal("0"); + Boolean isTransfer = Boolean.FALSE; if (stateArray.size() != 4) { log.warn("Invalid OEP-4 event in transaction {}", txHash); @@ -851,6 +867,7 @@ private void handleOep4TransferTxn(JSONArray stateArray, int txType, String txHa log.warn("Parsing OEP-4 transfer event failed in transaction {}", txHash); } log.info("Parsing OEP4 transfer event: from {}, to {}, amount {}", fromAddress, toAddress, eventAmount); + isTransfer = Boolean.TRUE; } if (paramsConfig.PAX_CONTRACTHASH.equals(contractHash)) { @@ -886,6 +903,10 @@ private void handleOep4TransferTxn(JSONArray stateArray, int txType, String txHa ConstantParam.BATCHBLOCKDTO.getTxDetails().add(txDetail); ConstantParam.BATCHBLOCKDTO.getTxDetailDailys().add(TxDetail.toTxDetailDaily(txDetail)); ConstantParam.BATCHBLOCKDTO.getOep4TxDetails().add(TxDetail.toOep4TxDetail(txDetail)); + + if (isTransfer) { + transferTransactionPush.publish(txDetail); + } } private BigDecimal BigDecimalFromNeoVmData(String value) { diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/utils/HttpClientUtil.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/utils/HttpClientUtil.java new file mode 100644 index 00000000..07f8e017 --- /dev/null +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/utils/HttpClientUtil.java @@ -0,0 +1,161 @@ +package com.github.ontio.utils; + +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpEntity; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.config.SocketConfig; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author zhouq + */ +@Slf4j +public class HttpClientUtil { + + private static HttpClient httpClient; + + static { + RequestConfig.Builder requestConfigBuilder = RequestConfig.custom(); + requestConfigBuilder.setConnectTimeout(30000); + requestConfigBuilder.setConnectionRequestTimeout(30000); + requestConfigBuilder.setSocketTimeout(60000); + + HttpClientBuilder clientBuilder = HttpClientBuilder.create(); + clientBuilder.setDefaultRequestConfig(requestConfigBuilder.build()); + clientBuilder.setDefaultSocketConfig(SocketConfig.custom().setSoTimeout(60000).build()); + clientBuilder.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()); + + PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); + cm.setMaxTotal(200); + cm.setDefaultMaxPerRoute(30); + httpClient = clientBuilder.setConnectionManager(cm).build(); + } + + /** + * httpclient post + * + * @param reqBodyStr + * @param url + * @return + * @throws Exception + */ + public static String postRequest(String url, String reqBodyStr, Map headerMap) throws Exception { + + String responseStr = ""; + + StringEntity stringEntity = new StringEntity(reqBodyStr, Charset.forName("UTF-8")); + stringEntity.setContentType(ContentType.APPLICATION_JSON.getMimeType()); + HttpPost httpPost = new HttpPost(url); + httpPost.setEntity(stringEntity); + //set header + headerMap.forEach((key, value) -> { + httpPost.setHeader(key, value.toString()); + }); + CloseableHttpResponse response = null; + try { + response = (CloseableHttpResponse) httpClient.execute(httpPost); + HttpEntity httpEntity = response.getEntity(); + responseStr = EntityUtils.toString(httpEntity); + } catch (IOException e) { + throw e; + } + if (response.getStatusLine().getStatusCode() == 200) { + return responseStr; + } else { + log.error("send request body:{} to {},response status:{},{}", reqBodyStr, url, response.getStatusLine().getStatusCode(), responseStr); + throw new Exception(response.toString()); + } + } + + /** + * httpclient get + * + * @param uri + * @return + * @throws Exception + */ + public static String getRequest(String uri, Map paramMap, Map headerMap) throws Exception { + String responseStr = ""; + CloseableHttpResponse response = null; + URIBuilder uriBuilder = null; + try { + uriBuilder = new URIBuilder(uri); + List params = new ArrayList<>(); + paramMap.forEach((key, value) -> { + params.add(new BasicNameValuePair(key, value.toString())); + }); + uriBuilder.setParameters(params); + + HttpGet httpGet = new HttpGet(uriBuilder.build()); + //set header + headerMap.forEach((key, value) -> { + httpGet.setHeader(key, value.toString()); + }); + response = (CloseableHttpResponse) httpClient.execute(httpGet); + HttpEntity httpEntity = response.getEntity(); + responseStr = EntityUtils.toString(httpEntity); + } catch (Exception e) { + throw e; + } + if (response.getStatusLine().getStatusCode() == 200) { + return responseStr; + } else { + log.error("send to {},response status:{},{}", uriBuilder.toString(), response.getStatusLine().getStatusCode(), responseStr); + throw new Exception(response.toString()); + } + } + + + /** + * httpclient post + * + * @param url + * @param urlParameters + * @param headerMap + * @return + * @throws Exception + */ + public static String postRequest(String url, List urlParameters, Map headerMap) throws Exception { + String responseStr = ""; + HttpPost httpPost = new HttpPost(url); + //set header + headerMap.forEach((key, value) -> { + httpPost.setHeader(key, value); + }); + CloseableHttpResponse response = null; + try { + httpPost.setEntity(new UrlEncodedFormEntity(urlParameters)); + response = (CloseableHttpResponse) httpClient.execute(httpPost); + HttpEntity httpEntity = response.getEntity(); + responseStr = EntityUtils.toString(httpEntity); + } catch (IOException e) { + throw e; + } + if (response.getStatusLine().getStatusCode() == 200) { + return responseStr; + } else { + log.error("send to {},response status:{},{}", url + urlParameters.toString(), response.getStatusLine().getStatusCode(), responseStr); + throw new Exception(response.toString()); + } + } + +} diff --git a/back-end-projects/OntSynHandler/src/main/resources/generator/generatorConfig.xml b/back-end-projects/OntSynHandler/src/main/resources/generator/generatorConfig.xml index 837e2069..67124722 100644 --- a/back-end-projects/OntSynHandler/src/main/resources/generator/generatorConfig.xml +++ b/back-end-projects/OntSynHandler/src/main/resources/generator/generatorConfig.xml @@ -16,7 +16,7 @@ @@ -55,9 +55,9 @@ --> - + +
+ +
+ + + +
+ + \ No newline at end of file From 7ce349b788b2dc22f00ce15605a66a89cf3f18b2 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Fri, 27 Mar 2020 21:04:14 +0800 Subject: [PATCH 08/40] add push transfer tx email notice function --- back-end-projects/OntSynHandler/pom.xml | 24 +++ .../github/ontio/txPush/DisruptorEvent.java | 22 +++ .../ontio/txPush/DisruptorEventPublisher.java | 34 ++++ .../com/github/ontio/txPush/EmailService.java | 110 +++++++++++++ .../ontio/txPush/TransferTransactionPush.java | 146 ++++++++++++++++++ .../github/ontio/txPush/model/PushConfig.java | 33 ++++ .../ontio/txPush/model/PushConstant.java | 12 ++ .../ontio/txPush/model/PushEmailDto.java | 62 ++++++++ .../ontio/txPush/model/PushStrategyEnum.java | 26 ++++ .../txPush/model/PushUserAddressInfoDto.java | 33 ++++ 10 files changed, 502 insertions(+) create mode 100644 back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/DisruptorEvent.java create mode 100644 back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/DisruptorEventPublisher.java create mode 100644 back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/EmailService.java create mode 100644 back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java create mode 100644 back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushConfig.java create mode 100644 back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushConstant.java create mode 100644 back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushEmailDto.java create mode 100644 back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushStrategyEnum.java create mode 100644 back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushUserAddressInfoDto.java diff --git a/back-end-projects/OntSynHandler/pom.xml b/back-end-projects/OntSynHandler/pom.xml index ea1e8235..d8cb758e 100644 --- a/back-end-projects/OntSynHandler/pom.xml +++ b/back-end-projects/OntSynHandler/pom.xml @@ -22,6 +22,7 @@ UTF-8 1.8 2.9.2 + 3.4.2 @@ -134,6 +135,29 @@ runtime + + + com.lmax + disruptor + ${disruptor.version} + + + + com.github.ben-manes.caffeine + caffeine + + + + org.apache.httpcomponents + httpclient + 4.5 + + + org.apache.httpcomponents + httpmime + 4.5 + + diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/DisruptorEvent.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/DisruptorEvent.java new file mode 100644 index 00000000..183e67b5 --- /dev/null +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/DisruptorEvent.java @@ -0,0 +1,22 @@ +package com.github.ontio.txPush; + +import com.lmax.disruptor.EventFactory; +import com.lmax.disruptor.EventHandler; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + +/** + * @author zhouq + */ +public class DisruptorEvent implements Serializable { + + public static final EventFactory FACTORY = DisruptorEvent::new; + + public static final EventHandler CLEANER = (event, sequence, endOfBatch) -> event.setEvent(null); + + @Getter + @Setter + private Object event; +} diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/DisruptorEventPublisher.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/DisruptorEventPublisher.java new file mode 100644 index 00000000..706de48a --- /dev/null +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/DisruptorEventPublisher.java @@ -0,0 +1,34 @@ +package com.github.ontio.txPush; + +import com.lmax.disruptor.BlockingWaitStrategy; +import com.lmax.disruptor.RingBuffer; +import com.lmax.disruptor.WaitStrategy; +import com.lmax.disruptor.dsl.Disruptor; +import com.lmax.disruptor.dsl.ProducerType; + +import java.util.concurrent.ThreadFactory; + +/** + * @author zhouq + */ +public interface DisruptorEventPublisher { + + RingBuffer getRingBuffer(); + + default void publish(final T event) { + getRingBuffer().publishEvent((disruptorEvent, sequence, e) -> disruptorEvent.setEvent(e), event); + } + + default ThreadFactory threadFactory() { + return r -> new Thread(r, getClass().getSimpleName() + "-disruptor-thread"); + } + + default WaitStrategy waitStrategy() { + return new BlockingWaitStrategy(); + } + + default Disruptor createDisruptor(int bufferSize, ProducerType producerType) { + return new Disruptor<>(DisruptorEvent.FACTORY, bufferSize, threadFactory(), producerType, waitStrategy()); + } + +} diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/EmailService.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/EmailService.java new file mode 100644 index 00000000..b28c7e82 --- /dev/null +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/EmailService.java @@ -0,0 +1,110 @@ +package com.github.ontio.txPush; + +import com.alibaba.fastjson.JSONObject; +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.Expiry; +import com.github.benmanes.caffeine.cache.LoadingCache; +import com.github.ontio.txPush.model.PushConfig; +import com.github.ontio.txPush.model.PushConstant; +import com.github.ontio.txPush.model.PushEmailDto; +import com.github.ontio.utils.Helper; +import com.github.ontio.utils.HttpClientUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.message.BasicNameValuePair; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; + +/** + * @author zhouq + * @version 1.0 + * @date 2020/3/26 + */ +@RequiredArgsConstructor +@Slf4j +@Service +public class EmailService { + + private final PushConfig pushConfig; + + private LoadingCache emailCountCache; + + @Autowired + public void setCache() { + emailCountCache = Caffeine.newBuilder() + .expireAfter(new Expiry() { + @Override + public long expireAfterCreate(String key, Integer time, long currentTime) { + Calendar endCalendar = new GregorianCalendar(); + endCalendar.set(Calendar.HOUR_OF_DAY, 23); + endCalendar.set(Calendar.MINUTE, 59); + endCalendar.set(Calendar.SECOND, 59); + long endTime = endCalendar.getTimeInMillis(); + return (endTime - System.currentTimeMillis()) * 1000000L; + } + + @Override + public long expireAfterUpdate(String key, Integer time, long currentTime, + long currentDuration) { + return currentDuration; + } + + @Override + public long expireAfterRead(String key, Integer time, long currentTime, + long currentDuration) { + return currentDuration; + } + }) + .build(key -> { + return 1; + }); + } + + + public void sendTransferTxInfoEmail(PushEmailDto pushEmailDto) { + log.info("{}...email:{},ontId:{},txDetail:{}", Helper.currentMethod(), pushEmailDto.getEmail(), pushEmailDto.getOntId(), JSONObject.toJSONString(pushEmailDto)); + int time = emailCountCache.get(pushEmailDto.getEmail()); + if (time > pushConfig.ONEEMAIL_ONEDAY_MAXTIME) { + log.warn("email:{} exceed one day max time:{}", pushEmailDto.getEmail(), pushConfig.ONEEMAIL_ONEDAY_MAXTIME); + return; + } + + String xsmtpapi = convertVerificationCode(pushEmailDto); + List params = new ArrayList<>(); + params.add(new BasicNameValuePair("apiUser", pushConfig.SC_EMAIL_APIUSER)); + params.add(new BasicNameValuePair("apiKey", pushConfig.SC_EMAIL_APIKEY)); + params.add(new BasicNameValuePair("xsmtpapi", xsmtpapi)); + params.add(new BasicNameValuePair("templateInvokeName", pushConfig.SC_EMAIL_TX_TEMPLATE)); + params.add(new BasicNameValuePair("from", pushConfig.SC_EMAIL_SENDER)); + params.add(new BasicNameValuePair("fromName", pushConfig.SC_EMAIL_SENDERNAME)); + try { + HttpClientUtil.postRequest(PushConstant.SC_EMAIL_TEMPLATEMAIL_URL, params, new HashMap<>()); + time++; + emailCountCache.put(pushEmailDto.getEmail(), time); + } catch (Exception e) { + log.error("{} error...", Helper.currentMethod(), e); + } + } + + + private String convertVerificationCode(PushEmailDto pushEmailDto) { + + JSONObject sub = new JSONObject(); + sub.put("%address%", Arrays.asList(pushEmailDto.getUserAddress())); + sub.put("%des%", Arrays.asList(pushEmailDto.getTxDes())); + sub.put("%hash%", Arrays.asList(pushEmailDto.getTxHash())); + sub.put("%assetname%", Arrays.asList(pushEmailDto.getAssetName())); + sub.put("%time%", Arrays.asList(pushEmailDto.getTime())); + sub.put("%taddress%", Arrays.asList(pushEmailDto.getTAddress())); + sub.put("%amount%", Arrays.asList(pushEmailDto.getAmount())); + + JSONObject ret = new JSONObject(); + ret.put("to", Arrays.asList(pushEmailDto.getEmail())); + ret.put("sub", sub); + return ret.toString(); + } + + +} diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java new file mode 100644 index 00000000..4ce569eb --- /dev/null +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java @@ -0,0 +1,146 @@ +package com.github.ontio.txPush; + +import com.alibaba.fastjson.JSONObject; +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.LoadingCache; +import com.github.ontio.mapper.Oep4Mapper; +import com.github.ontio.mapper.UserAddressMapper; +import com.github.ontio.model.dao.Oep4; +import com.github.ontio.model.dao.TxDetail; +import com.github.ontio.txPush.model.PushEmailDto; +import com.github.ontio.txPush.model.PushStrategyEnum; +import com.github.ontio.txPush.model.PushUserAddressInfoDto; +import com.github.ontio.utils.ConstantParam; +import com.lmax.disruptor.EventHandler; +import com.lmax.disruptor.RingBuffer; +import com.lmax.disruptor.dsl.Disruptor; +import com.lmax.disruptor.dsl.ProducerType; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * @author zhouq + */ +@Service +@Slf4j +public class TransferTransactionPush implements DisruptorEventPublisher, EventHandler { + + private static final String USERADDRCACHE_KEY = "userAddress"; + + private LoadingCache>> userAddressCache; + + private final UserAddressMapper userAddressMapper; + private final EmailService emailService; + + @Getter + private RingBuffer ringBuffer; + + @Autowired + public TransferTransactionPush(UserAddressMapper userAddressMapper, EmailService emailService) { + Disruptor disruptor = createDisruptor(65536, ProducerType.MULTI); + disruptor.handleEventsWith(this).then(DisruptorEvent.CLEANER); + disruptor.start(); + this.ringBuffer = disruptor.getRingBuffer(); + this.userAddressMapper = userAddressMapper; + this.emailService = emailService; + } + + @Override + public void onEvent(DisruptorEvent disruptorEvent, long sequence, boolean endOfBatch) { + TxDetail txDetail = (TxDetail) disruptorEvent.getEvent(); + log.info("{} disruptor consumer receive tx:{}", Thread.currentThread().getName(), JSONObject.toJSONString(txDetail)); + String fromAddress = txDetail.getFromAddress(); + String toAddress = txDetail.getToAddress(); + if (fromAddress.equals(toAddress)) { + return; + } + Map> cacheMap = userAddressCache.get(USERADDRCACHE_KEY); + List fromAddrPushUserAddressInfoDtos = cacheMap.get(fromAddress); + if (fromAddrPushUserAddressInfoDtos != null) { + fromAddrPushUserAddressInfoDtos.forEach(dto -> { + handleWithdrawTransferTx(txDetail, dto); + }); + } + List toAddrPushUserAddressInfoDtos = cacheMap.get(toAddress); + if (toAddrPushUserAddressInfoDtos != null) { + toAddrPushUserAddressInfoDtos.forEach(dto -> { + handleDepositTransferTx(txDetail, dto); + }); + } + } + + + private void handleWithdrawTransferTx(TxDetail txDetail, PushUserAddressInfoDto dto) { + if (dto.getStrategy() == PushStrategyEnum.AllPush.value() || + dto.getStrategy() == PushStrategyEnum.WithdrawPush.value()) { + if (ConstantParam.ASSET_NAME_ONT.equals(txDetail.getAssetName())) { + PushEmailDto pushEmailDto = PushEmailDto.buildDto(dto, txDetail, PushEmailDto.WITHDRAW); + emailService.sendTransferTxInfoEmail(pushEmailDto); + } else if (ConstantParam.ASSET_NAME_ONG.equals(txDetail.getAssetName())) { + txDetail.setAmount(txDetail.getAmount().divide(ConstantParam.ONG_DECIMAL)); + + PushEmailDto pushEmailDto = PushEmailDto.buildDto(dto, txDetail, PushEmailDto.WITHDRAW); + emailService.sendTransferTxInfoEmail(pushEmailDto); + } else if (dto.getIncludeOepToken()) { + PushEmailDto pushEmailDto = PushEmailDto.buildDto(dto, txDetail, PushEmailDto.WITHDRAW); + emailService.sendTransferTxInfoEmail(pushEmailDto); + } + } + } + + + private void handleDepositTransferTx(TxDetail txDetail, PushUserAddressInfoDto dto) { + if (dto.getStrategy() == PushStrategyEnum.AllPush.value() || + dto.getStrategy() == PushStrategyEnum.DepositPush.value()) { + if (ConstantParam.ASSET_NAME_ONT.equals(txDetail.getAssetName())) { + PushEmailDto pushEmailDto = PushEmailDto.buildDto(dto, txDetail, PushEmailDto.DEPOSIT); + emailService.sendTransferTxInfoEmail(pushEmailDto); + } else if (ConstantParam.ASSET_NAME_ONG.equals(txDetail.getAssetName())) { + txDetail.setAmount(txDetail.getAmount().divide(ConstantParam.ONG_DECIMAL)); + + PushEmailDto pushEmailDto = PushEmailDto.buildDto(dto, txDetail, PushEmailDto.DEPOSIT); + emailService.sendTransferTxInfoEmail(pushEmailDto); + } else if (dto.getIncludeOepToken()) { + PushEmailDto pushEmailDto = PushEmailDto.buildDto(dto, txDetail, PushEmailDto.DEPOSIT); + emailService.sendTransferTxInfoEmail(pushEmailDto); + } + } + } + + + @Autowired + private void setCache() { + userAddressCache = Caffeine.newBuilder() + .expireAfterWrite(1, TimeUnit.MINUTES) + .build(key -> { + return getUserAddress(); + }); + } + + private Map> getUserAddress() { + Map> map = new HashMap<>(); + List userAddressInfoDtos = userAddressMapper.selectUserAddressInfo(); + userAddressInfoDtos.forEach(item -> { + if (map.containsKey(item.getAddress())) { + List list = map.get(item.getAddress()); + list.add(item); + } else { + map.put(item.getAddress(), new ArrayList() {{ + add(item); + }}); + } + }); + return map; + } + + +} diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushConfig.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushConfig.java new file mode 100644 index 00000000..50f1567c --- /dev/null +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushConfig.java @@ -0,0 +1,33 @@ +package com.github.ontio.txPush.model; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * @author zhouq + * @version 1.0 + * @date 2020/3/26 + */ +@Component +public class PushConfig { + + + @Value("${sendcloud.email.apiUser}") + public String SC_EMAIL_APIUSER; + + @Value("${sendcloud.email.apiKey}") + public String SC_EMAIL_APIKEY; + + @Value("${sendcloud.email.sender}") + public String SC_EMAIL_SENDER; + + @Value("${sendcloud.email.senderName}") + public String SC_EMAIL_SENDERNAME; + + @Value("${sendcloud.email.transaction.template}") + public String SC_EMAIL_TX_TEMPLATE; + + @Value("${oneEmail.oneDay.maxTime}") + public int ONEEMAIL_ONEDAY_MAXTIME; + +} diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushConstant.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushConstant.java new file mode 100644 index 00000000..3fd3e609 --- /dev/null +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushConstant.java @@ -0,0 +1,12 @@ +package com.github.ontio.txPush.model; + +/** + * @author zhouq + * @version 1.0 + * @date 2020/3/26 + */ +public class PushConstant { + + public static final String SC_EMAIL_TEMPLATEMAIL_URL = "http://api.sendcloud.net/apiv2/mail/sendtemplate"; + +} diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushEmailDto.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushEmailDto.java new file mode 100644 index 00000000..4ee8f5c1 --- /dev/null +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushEmailDto.java @@ -0,0 +1,62 @@ +package com.github.ontio.txPush.model; + +import com.github.ontio.model.dao.TxDetail; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * @author zhouq + * @version 1.0 + * @date 2020/3/27 + */ +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Data +public class PushEmailDto { + + private String email; + private String userName; + private String ontId; + private String userAddress; + private String txDes; + private String txHash; + private String assetName; + private String amount; + private String time; + private String tAddress; + + public static final String DEPOSIT = "deposit"; + public static final String WITHDRAW = "withdraw"; + + private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + public static PushEmailDto buildDto(PushUserAddressInfoDto pushUserAddressInfoDto, TxDetail txDetail, String txDes) { + PushEmailDtoBuilder builder = PushEmailDto.builder() + .email(pushUserAddressInfoDto.getEmail()) + .userName(pushUserAddressInfoDto.getUserName()) + .ontId(pushUserAddressInfoDto.getOntId()) + .txHash(txDetail.getTxHash()) + .amount(txDetail.getAmount().stripTrailingZeros().toPlainString()) + .time(sdf.format(new Date(txDetail.getTxTime() * 1000L))) + .assetName(txDetail.getAssetName()); + if (DEPOSIT.equals(txDes)) { + return builder.userAddress(txDetail.getToAddress()) + .tAddress(txDetail.getFromAddress()) + .txDes(DEPOSIT) + .build(); + } else { + return builder.userAddress(txDetail.getFromAddress()) + .tAddress(txDetail.getToAddress()) + .txDes(WITHDRAW) + .build(); + } + } + + +} diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushStrategyEnum.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushStrategyEnum.java new file mode 100644 index 00000000..b6154c26 --- /dev/null +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushStrategyEnum.java @@ -0,0 +1,26 @@ +package com.github.ontio.txPush.model; + +/** + * @author zhouq + * @version 1.0 + * @date 2020/3/26 + */ +public enum PushStrategyEnum { + + NoPush(0), + AllPush(1), + DepositPush(2), + WithdrawPush(3); + + private int value; + + PushStrategyEnum(int value){ + this.value = value; + } + + public int value(){ + return this.value; + } + + +} diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushUserAddressInfoDto.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushUserAddressInfoDto.java new file mode 100644 index 00000000..43d9d03d --- /dev/null +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushUserAddressInfoDto.java @@ -0,0 +1,33 @@ +package com.github.ontio.txPush.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author zhouq + * @version 1.0 + * @date 2020/3/26 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class PushUserAddressInfoDto { + + private String address; + + private String ontId; + + private String userName; + + private String email; + + private String note; + + private Integer strategy; + + private Boolean includeOepToken; + +} From faead6ee697ae0e10e651231a8afc62a66be3d6e Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Fri, 27 Mar 2020 21:06:11 +0800 Subject: [PATCH 09/40] add new table --- .../ontio/mapper/AddressBlacklistMapper.java | 7 + .../ontio/mapper/UserAddressMapper.java | 12 ++ .../com/github/ontio/mapper/UserMapper.java | 10 ++ .../ontio/model/dao/AddressBlacklist.java | 68 ++++++++ .../java/com/github/ontio/model/dao/User.java | 144 +++++++++++++++++ .../github/ontio/model/dao/UserAddress.java | 148 ++++++++++++++++++ .../mapper/AddressBlacklistMapper.xml | 12 ++ .../resources/mapper/UserAddressMapper.xml | 42 +++++ .../src/main/resources/mapper/UserMapper.xml | 39 +++++ 9 files changed, 482 insertions(+) create mode 100644 back-end-projects/Explorer/src/main/java/com/github/ontio/mapper/AddressBlacklistMapper.java create mode 100644 back-end-projects/Explorer/src/main/java/com/github/ontio/mapper/UserAddressMapper.java create mode 100644 back-end-projects/Explorer/src/main/java/com/github/ontio/mapper/UserMapper.java create mode 100644 back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/AddressBlacklist.java create mode 100644 back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/User.java create mode 100644 back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/UserAddress.java create mode 100644 back-end-projects/Explorer/src/main/resources/mapper/AddressBlacklistMapper.xml create mode 100644 back-end-projects/Explorer/src/main/resources/mapper/UserAddressMapper.xml create mode 100644 back-end-projects/Explorer/src/main/resources/mapper/UserMapper.xml diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/mapper/AddressBlacklistMapper.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/mapper/AddressBlacklistMapper.java new file mode 100644 index 00000000..e3f07b94 --- /dev/null +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/mapper/AddressBlacklistMapper.java @@ -0,0 +1,7 @@ +package com.github.ontio.mapper; + +import com.github.ontio.model.dao.AddressBlacklist; +import tk.mybatis.mapper.common.Mapper; + +public interface AddressBlacklistMapper extends Mapper { +} \ No newline at end of file diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/mapper/UserAddressMapper.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/mapper/UserAddressMapper.java new file mode 100644 index 00000000..41e1629a --- /dev/null +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/mapper/UserAddressMapper.java @@ -0,0 +1,12 @@ +package com.github.ontio.mapper; + +import com.github.ontio.model.dao.UserAddress; +import tk.mybatis.mapper.common.Mapper; + +import java.util.List; + +public interface UserAddressMapper extends Mapper { + + int saveUserAddress(List userAddresses); + +} \ No newline at end of file diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/mapper/UserMapper.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/mapper/UserMapper.java new file mode 100644 index 00000000..f7d444dc --- /dev/null +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/mapper/UserMapper.java @@ -0,0 +1,10 @@ +package com.github.ontio.mapper; + +import com.github.ontio.model.dao.User; +import tk.mybatis.mapper.common.Mapper; + +public interface UserMapper extends Mapper { + + int saveUser(User user); + +} \ No newline at end of file diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/AddressBlacklist.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/AddressBlacklist.java new file mode 100644 index 00000000..73004555 --- /dev/null +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/AddressBlacklist.java @@ -0,0 +1,68 @@ +package com.github.ontio.model.dao; + +import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; +import java.util.Date; + +@Table(name = "tbl_address_blacklist") +public class AddressBlacklist { + @Id + @GeneratedValue(generator = "JDBC") + private String address; + + /** + * 备注 + */ + private String note; + + @Column(name = "create_time") + private Date createTime; + + /** + * @return address + */ + public String getAddress() { + return address; + } + + /** + * @param address + */ + public void setAddress(String address) { + this.address = address == null ? null : address.trim(); + } + + /** + * 获取备注 + * + * @return note - 备注 + */ + public String getNote() { + return note; + } + + /** + * 设置备注 + * + * @param note 备注 + */ + public void setNote(String note) { + this.note = note == null ? null : note.trim(); + } + + /** + * @return create_time + */ + public Date getCreateTime() { + return createTime; + } + + /** + * @param createTime + */ + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } +} \ No newline at end of file diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/User.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/User.java new file mode 100644 index 00000000..8a3c9e63 --- /dev/null +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/User.java @@ -0,0 +1,144 @@ +package com.github.ontio.model.dao; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.github.ontio.util.TxDateSerializer; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.NoArgsConstructor; + +import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.validation.constraints.Pattern; +import java.util.Date; + +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "tbl_user") +public class User { + /** + * ONT ID + */ + @Id + @Column(name = "ont_id") + @GeneratedValue(generator = "JDBC") + private String ontId; + + /** + * 用户名 + */ + @Column(name = "user_name") + private String userName; + + /** + * 邮箱 + */ + @Pattern(regexp = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$", message = "email format error") + private String email; + + /** + * 创建时间 + */ + @JsonSerialize(using = TxDateSerializer.class) + @Column(name = "create_time") + private Date createTime; + + /** + * 上次登录时间 + */ + @JsonSerialize(using = TxDateSerializer.class) + @Column(name = "last_login_time") + private Date lastLoginTime; + + /** + * 获取ONT ID + * + * @return ont_id - ONT ID + */ + public String getOntId() { + return ontId; + } + + /** + * 设置ONT ID + * + * @param ontId ONT ID + */ + public void setOntId(String ontId) { + this.ontId = ontId == null ? null : ontId.trim(); + } + + /** + * 获取用户名 + * + * @return user_name - 用户名 + */ + public String getUserName() { + return userName; + } + + /** + * 设置用户名 + * + * @param userName 用户名 + */ + public void setUserName(String userName) { + this.userName = userName == null ? null : userName.trim(); + } + + /** + * 获取邮箱 + * + * @return email - 邮箱 + */ + public String getEmail() { + return email; + } + + /** + * 设置邮箱 + * + * @param email 邮箱 + */ + public void setEmail(String email) { + this.email = email == null ? null : email.trim(); + } + + /** + * 获取创建时间 + * + * @return create_time - 创建时间 + */ + public Date getCreateTime() { + return createTime; + } + + /** + * 设置创建时间 + * + * @param createTime 创建时间 + */ + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + /** + * 获取上次登录时间 + * + * @return last_login_time - 上次登录时间 + */ + public Date getLastLoginTime() { + return lastLoginTime; + } + + /** + * 设置上次登录时间 + * + * @param lastLoginTime 上次登录时间 + */ + public void setLastLoginTime(Date lastLoginTime) { + this.lastLoginTime = lastLoginTime; + } +} \ No newline at end of file diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/UserAddress.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/UserAddress.java new file mode 100644 index 00000000..bab8fa74 --- /dev/null +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/UserAddress.java @@ -0,0 +1,148 @@ +package com.github.ontio.model.dao; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Table(name = "tbl_user_address") +public class UserAddress { + @Id + @GeneratedValue(generator = "JDBC") + private Integer id; + + /** + * ONT ID + */ + @Column(name = "ont_id") + private String ontId; + + /** + * 地址 + */ + private String address; + + /** + * 地址备注 + */ + private String note; + + /** + * 监听策略。0:不监听 1:监听所有入金出金,2:只监听入金 3:只监听出金 + */ + private Integer strategy; + + /** + * 1:监听oep资产 0:不监听oep资产 + */ + @Column(name = "include_oep_token") + private Boolean includeOepToken; + + /** + * @return id + */ + public Integer getId() { + return id; + } + + /** + * @param id + */ + public void setId(Integer id) { + this.id = id; + } + + /** + * 获取ONT ID + * + * @return ont_id - ONT ID + */ + public String getOntId() { + return ontId; + } + + /** + * 设置ONT ID + * + * @param ontId ONT ID + */ + public void setOntId(String ontId) { + this.ontId = ontId == null ? null : ontId.trim(); + } + + /** + * 获取地址 + * + * @return address - 地址 + */ + public String getAddress() { + return address; + } + + /** + * 设置地址 + * + * @param address 地址 + */ + public void setAddress(String address) { + this.address = address == null ? null : address.trim(); + } + + /** + * 获取地址备注 + * + * @return note - 地址备注 + */ + public String getNote() { + return note; + } + + /** + * 设置地址备注 + * + * @param note 地址备注 + */ + public void setNote(String note) { + this.note = note == null ? null : note.trim(); + } + + /** + * 获取监听策略。0:不监听 1:监听所有入金出金,2:只监听入金 3:只监听出金 + * + * @return strategy - 监听策略。0:不监听 1:监听所有入金出金,2:只监听入金 3:只监听出金 + */ + public Integer getStrategy() { + return strategy; + } + + /** + * 设置监听策略。0:不监听 1:监听所有入金出金,2:只监听入金 3:只监听出金 + * + * @param strategy 监听策略。0:不监听 1:监听所有入金出金,2:只监听入金 3:只监听出金 + */ + public void setStrategy(Integer strategy) { + this.strategy = strategy; + } + + /** + * 获取1:监听oep资产 0:不监听oep资产 + * + * @return include_oep_token - 1:监听oep资产 0:不监听oep资产 + */ + public Boolean getIncludeOepToken() { + return includeOepToken; + } + + /** + * 设置1:监听oep资产 0:不监听oep资产 + * + * @param includeOepToken 1:监听oep资产 0:不监听oep资产 + */ + public void setIncludeOepToken(Boolean includeOepToken) { + this.includeOepToken = includeOepToken; + } +} \ No newline at end of file diff --git a/back-end-projects/Explorer/src/main/resources/mapper/AddressBlacklistMapper.xml b/back-end-projects/Explorer/src/main/resources/mapper/AddressBlacklistMapper.xml new file mode 100644 index 00000000..97596a30 --- /dev/null +++ b/back-end-projects/Explorer/src/main/resources/mapper/AddressBlacklistMapper.xml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/back-end-projects/Explorer/src/main/resources/mapper/UserAddressMapper.xml b/back-end-projects/Explorer/src/main/resources/mapper/UserAddressMapper.xml new file mode 100644 index 00000000..6a3e343a --- /dev/null +++ b/back-end-projects/Explorer/src/main/resources/mapper/UserAddressMapper.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + INSERT INTO tbl_user_address + ( + ont_id, + address, + note, + strategy, + include_oep_token + ) + VALUES + + ( + #{item.ontId}, + #{item.address}, + #{item.note}, + #{item.strategy}, + #{item.includeOepToken} + ) + + ON DUPLICATE KEY UPDATE + note=values(note), + strategy=values(strategy), + include_oep_token=values(include_oep_token) + + + \ No newline at end of file diff --git a/back-end-projects/Explorer/src/main/resources/mapper/UserMapper.xml b/back-end-projects/Explorer/src/main/resources/mapper/UserMapper.xml new file mode 100644 index 00000000..8f87c1a6 --- /dev/null +++ b/back-end-projects/Explorer/src/main/resources/mapper/UserMapper.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + INSERT INTO tbl_user + ( + ont_id, + user_name, + email, + create_time, + last_login_time + ) + VALUES + ( + #{ontId}, + #{userName}, + #{email}, + #{createTime}, + #{lastLoginTime} + ) + ON DUPLICATE KEY UPDATE + user_name=values(user_name), + email=values(email), + last_login_time=values(last_login_time) + + + \ No newline at end of file From 1a00571af24494e4efd9a5d3db83f1c0c7f7a9e6 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Fri, 27 Mar 2020 21:08:13 +0800 Subject: [PATCH 10/40] add user address management apis --- back-end-projects/Explorer/pom.xml | 7 + .../com/github/ontio/config/ParamsConfig.java | 16 ++ .../ontio/controller/UserController.java | 147 +++++++++++ .../ontio/exception/ExplorerException.java | 13 + .../github/ontio/model/common/RedisKey.java | 12 + .../ontio/model/dto/login/CallBackDto.java | 31 +++ .../model/dto/login/CallBackResponse.java | 50 ++++ .../ontio/model/dto/login/QrCodeDto.java | 112 +++++++++ .../github/ontio/service/IUserService.java | 32 +++ .../ontio/service/impl/UserServiceImpl.java | 229 ++++++++++++++++++ .../com/github/ontio/util/ConstantParam.java | 4 + .../java/com/github/ontio/util/ErrorInfo.java | 20 ++ .../java/com/github/ontio/util/Helper.java | 27 ++- .../java/com/github/ontio/util/JwtUtil.java | 82 +++++++ .../github/ontio/util/OntologySDKService.java | 54 +++++ .../github/ontio/util/TxDateSerializer.java | 23 ++ 16 files changed, 858 insertions(+), 1 deletion(-) create mode 100644 back-end-projects/Explorer/src/main/java/com/github/ontio/controller/UserController.java create mode 100644 back-end-projects/Explorer/src/main/java/com/github/ontio/model/common/RedisKey.java create mode 100644 back-end-projects/Explorer/src/main/java/com/github/ontio/model/dto/login/CallBackDto.java create mode 100644 back-end-projects/Explorer/src/main/java/com/github/ontio/model/dto/login/CallBackResponse.java create mode 100644 back-end-projects/Explorer/src/main/java/com/github/ontio/model/dto/login/QrCodeDto.java create mode 100644 back-end-projects/Explorer/src/main/java/com/github/ontio/service/IUserService.java create mode 100644 back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java create mode 100644 back-end-projects/Explorer/src/main/java/com/github/ontio/util/JwtUtil.java create mode 100644 back-end-projects/Explorer/src/main/java/com/github/ontio/util/TxDateSerializer.java diff --git a/back-end-projects/Explorer/pom.xml b/back-end-projects/Explorer/pom.xml index a921634d..108212c7 100644 --- a/back-end-projects/Explorer/pom.xml +++ b/back-end-projects/Explorer/pom.xml @@ -24,6 +24,7 @@ 1.8 2.9.2 2.3.0 + 3.4.1 @@ -185,6 +186,12 @@ ${retrofit2.version} + + com.auth0 + java-jwt + ${jwt.version} + + diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java index 849c7ca7..6435e46f 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java @@ -141,4 +141,20 @@ public String getContractHash(String token) { } } + @Value("${login.callbackUrl:https://explorer.ont.io/v2/users/login}") + public String loginCallbackUrl; + + + @Value("${login.token.expired.minute:5}") + public int loginTokenExpiredMinute; + + @Value("${identity.ontid}") + public String IDENTITY_ONTID; + + @Value("${identity.password}") + public String IDENTITY_PASSWORD; + + @Value("${identity.salt}") + public String IDENTITY_SALT; + } \ No newline at end of file diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/controller/UserController.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/controller/UserController.java new file mode 100644 index 00000000..ff5e4bc6 --- /dev/null +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/controller/UserController.java @@ -0,0 +1,147 @@ +package com.github.ontio.controller; + +import com.alibaba.fastjson.JSONObject; +import com.github.ontio.exception.ExplorerException; +import com.github.ontio.model.common.ResponseBean; +import com.github.ontio.model.dao.User; +import com.github.ontio.model.dao.UserAddress; +import com.github.ontio.model.dto.login.CallBackDto; +import com.github.ontio.model.dto.login.CallBackResponse; +import com.github.ontio.service.IUserService; +import com.github.ontio.util.ConstantParam; +import com.github.ontio.util.ErrorInfo; +import com.github.ontio.util.Helper; +import com.github.ontio.util.JwtUtil; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * @author zhouq + * @version 1.0 + * @date 2020/3/24 + */ +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping("/v2/users/") +public class UserController { + + private final String CLASS_NAME = this.getClass().getSimpleName(); + + private final IUserService userService; + + + @ApiOperation(value = "Query login qrcode") + @GetMapping(value = "/login_qrcode") + public ResponseBean queryQrCode() { + ResponseBean rs = userService.queryQrCode(); + return rs; + } + + + @ApiOperation(value = "Query login user info") + @GetMapping(value = "/login_user_info") + public ResponseBean queryLoginUserInfo(@RequestParam("code") String code) { + ResponseBean rs = userService.queryLoginUserInfo(code); + return rs; + } + + + @ApiOperation(value = "ONTO User login") + @PostMapping(value = "/login") + public CallBackResponse userLogin(@RequestBody JSONObject jsonObject) { + log.info("###{}.{} begin...param:{}", CLASS_NAME, Helper.currentMethod(), jsonObject); + CallBackDto callBackDto = new CallBackDto(); + callBackDto.setSigner(jsonObject.getString("signer")); + callBackDto.setSignedTx(jsonObject.getString("signedTx")); + CallBackDto.CallbackExtraData callbackExtraData = CallBackDto.CallbackExtraData.builder() + .id(jsonObject.getJSONObject("extraData").getString("id")) + .build(); + callBackDto.setExtraData(callbackExtraData); + CallBackResponse rs = userService.login(callBackDto); + return rs; + } + + + @ApiImplicitParams({@ApiImplicitParam(paramType = "header", dataType = "String", name = "ONT_EXP_TOKEN", value = "login token", required = true)}) + @ApiOperation(value = "Query user addresses") + @GetMapping(value = "/addresses") + public ResponseBean queryUserAddresses(@RequestParam("ont_id") String ontId) { + log.info("###{}.{} begin...ontId:{}", CLASS_NAME, Helper.currentMethod(), ontId); + checkToken(ontId); + ResponseBean rs = userService.queryUserAddresses(ontId); + refreshToken(ontId); + return rs; + } + + + @ApiImplicitParams({@ApiImplicitParam(paramType = "header", dataType = "String", name = "ONT_EXP_TOKEN", value = "login token", required = true)}) + @ApiOperation(value = "Add or Update user addresses") + @PostMapping(value = "/addresses") + public ResponseBean addOrUpdateUserAddresses(@RequestParam("ont_id") String ontId, + @RequestBody List userAddresses) { + log.info("###{}.{} begin...ontId:{}", CLASS_NAME, Helper.currentMethod(), ontId); + checkToken(ontId); + ResponseBean rs = userService.addOrUpdateUserAddresses(userAddresses, ontId); + refreshToken(ontId); + return rs; + } + + + @ApiImplicitParams({@ApiImplicitParam(paramType = "header", dataType = "String", name = "ONT_EXP_TOKEN", value = "login token", required = true)}) + @ApiOperation(value = "Delete user address") + @DeleteMapping(value = "/addresses") + public ResponseBean delUserAddress(@RequestParam("ont_id") String ontId, + @RequestBody JSONObject jsonObject) { + log.info("###{}.{} begin...ontId:{}", CLASS_NAME, Helper.currentMethod(), ontId); + checkToken(ontId); + ResponseBean rs = userService.delUserAddress(jsonObject.getString("address"), ontId); + refreshToken(ontId); + return rs; + } + + + @ApiImplicitParams({@ApiImplicitParam(paramType = "header", dataType = "String", name = "ONT_EXP_TOKEN", value = "login token", required = true)}) + @ApiOperation(value = "Update user information") + @PostMapping + public ResponseBean updateUser(@RequestParam("ont_id") String ontId, + @RequestBody User user) { + log.info("###{}.{} begin...ontId:{}", CLASS_NAME, Helper.currentMethod(), ontId); + checkToken(ontId); + user.setOntId(ontId); + ResponseBean rs = userService.updateUser(user); + refreshToken(ontId); + return rs; + } + + + private void checkToken(String ontId) { + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + String token = request.getHeader(ConstantParam.HTTPHEADER_TOKEN); + if (Helper.isEmptyOrNull(token)) { + throw new ExplorerException(ErrorInfo.TOKEN_EMPTY); + } + if (!JwtUtil.verifyToken(token)) { + throw new ExplorerException(ErrorInfo.TOKEN_EXPIRED); + } else if (!JwtUtil.getClaim(token, ConstantParam.JWT_LOGINID).asString().equals(ontId)) { + throw new ExplorerException(ErrorInfo.TOKEN_UNMATCH); + } + } + + private void refreshToken(String ontId) { + String newToken = JwtUtil.signToken(ontId); + HttpServletResponse resp = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); + resp.setHeader(ConstantParam.HTTPHEADER_TOKEN, newToken); + } + +} diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/exception/ExplorerException.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/exception/ExplorerException.java index 0e91dbf8..546fcda6 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/exception/ExplorerException.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/exception/ExplorerException.java @@ -1,5 +1,6 @@ package com.github.ontio.exception; +import com.github.ontio.util.ErrorInfo; import lombok.Data; import lombok.EqualsAndHashCode; @@ -19,6 +20,18 @@ public ExplorerException(Integer code, String msg, Object result){ this.result = result; } + public ExplorerException(ErrorInfo errorInfo, Object result){ + this.code = errorInfo.code(); + this.msg = errorInfo.desc(); + this.result = result; + } + + public ExplorerException(ErrorInfo errorInfo){ + this.code = errorInfo.code(); + this.msg = errorInfo.desc(); + this.result = false; + } + public ExplorerException(){super();} public ExplorerException(String msg){super(msg);} diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/model/common/RedisKey.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/common/RedisKey.java new file mode 100644 index 00000000..18f16c3d --- /dev/null +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/common/RedisKey.java @@ -0,0 +1,12 @@ +package com.github.ontio.model.common; + +/** + * @author zhouq + * @version 1.0 + * @date 2020/3/25 + */ +public class RedisKey { + + public static final String USERLOGIN_CODE = "userLogin:code:%s"; + +} diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dto/login/CallBackDto.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dto/login/CallBackDto.java new file mode 100644 index 00000000..f080e5aa --- /dev/null +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dto/login/CallBackDto.java @@ -0,0 +1,31 @@ +package com.github.ontio.model.dto.login; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author zhouq + * @version 1.0 + * @date 2020/3/25 + */ +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Data +public class CallBackDto { + + private String signer; + private String signedTx; + private CallbackExtraData extraData; + + @NoArgsConstructor + @AllArgsConstructor + @Builder + @Data + public static class CallbackExtraData{ + private String id; + } + +} diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dto/login/CallBackResponse.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dto/login/CallBackResponse.java new file mode 100644 index 00000000..68828f65 --- /dev/null +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dto/login/CallBackResponse.java @@ -0,0 +1,50 @@ +package com.github.ontio.model.dto.login; + +import com.alibaba.fastjson.JSONObject; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.UUID; + +/** + * @author zhouq + * @version 1.0 + * @date 2020/3/25 + */ +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Data +public class CallBackResponse { + private String action; + private String version; + private long error; + private String id; + private JSONObject result; + + + public static CallBackResponse successResponse(JSONObject object) { + CallBackResponse callBackResponse = CallBackResponse.builder() + .action("") + .version("1.0.0") + .id(UUID.randomUUID().toString()) + .error(0L) + .result(object) + .build(); + return callBackResponse; + } + + public static CallBackResponse errorResponse(long error) { + CallBackResponse callBackResponse = CallBackResponse.builder() + .action("") + .version("1.0.0") + .id(UUID.randomUUID().toString()) + .error(error) + .result(new JSONObject()) + .build(); + return callBackResponse; + } + +} diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dto/login/QrCodeDto.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dto/login/QrCodeDto.java new file mode 100644 index 00000000..2c57579e --- /dev/null +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dto/login/QrCodeDto.java @@ -0,0 +1,112 @@ +package com.github.ontio.model.dto.login; + +import com.github.ontio.util.JacksonUtil; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.List; + +/** + * @author zhouq + * @version 1.0 + * @date 2020/3/25 + */ +@Builder +@Data +@AllArgsConstructor +@NoArgsConstructor +public class QrCodeDto { + + private String callback; + private String chain; + private String data; + private long exp; + private String id; + private String requester; + private String signature; + private String signer; + private String ver; + + + public static QrCodeDto mainNetLoginQrCode(String id, String requester, String signature, QrCodeData qrCodeData, String callback, long exp) { + QrCodeDto qrCodeDto = QrCodeDto.builder() + .ver("1.0.0") + .id(id) + .requester(requester) + .signature(signature) + .signer("") + .data(JacksonUtil.beanToJSonStr(qrCodeData)) + .callback(callback) + .exp(exp) + .chain("Mainnet") + .build(); + return qrCodeDto; + } + + public static QrCodeDto testNetLoginQrCode(String id, String requester, String signature, QrCodeData qrCodeData, String callback, long exp) { + QrCodeDto qrCodeDto = QrCodeDto.builder() + .ver("1.0.0") + .id(id) + .requester(requester) + .signature(signature) + .signer("") + .data(JacksonUtil.beanToJSonStr(qrCodeData)) + .callback(callback) + .exp(exp) + .chain("Testnet") + .build(); + return qrCodeDto; + } + + + @NoArgsConstructor + @AllArgsConstructor + @Builder + @Data + public static class QrCodeData { + private String action; + private QrCodeDataParam params; + } + + @NoArgsConstructor + @AllArgsConstructor + @Builder + @Data + public static class QrCodeDataParam { + private QrCodeDataParamDetail invokeConfig; + } + + @NoArgsConstructor + @AllArgsConstructor + @Builder + @Data + public static class QrCodeDataParamDetail { + private String contractHash; + private List functions; + private BigDecimal gasLimit; + private BigDecimal gasPrice; + private String payer; + } + + @NoArgsConstructor + @AllArgsConstructor + @Builder + @Data + public static class QrCodeDataParamFun { + private List args; + private String operation; + } + + @NoArgsConstructor + @AllArgsConstructor + @Builder + @Data + public static class QrCodeDataParamFunArg { + private String name; + private String value; + } + +} diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/IUserService.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/IUserService.java new file mode 100644 index 00000000..0b1a5bb6 --- /dev/null +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/IUserService.java @@ -0,0 +1,32 @@ +package com.github.ontio.service; + +import com.github.ontio.model.common.ResponseBean; +import com.github.ontio.model.dao.User; +import com.github.ontio.model.dao.UserAddress; +import com.github.ontio.model.dto.login.CallBackDto; +import com.github.ontio.model.dto.login.CallBackResponse; + +import java.util.List; + +/** + * @author zhouq + * @version 1.0 + * @date 2020/3/24 + */ +public interface IUserService { + + ResponseBean queryQrCode(); + + ResponseBean queryLoginUserInfo(String code); + + CallBackResponse login(CallBackDto callBackDto); + + ResponseBean queryUserAddresses(String ontId); + + ResponseBean addOrUpdateUserAddresses(List userAddresses, String ontId); + + ResponseBean delUserAddress(String address, String ontId); + + ResponseBean updateUser(User user); + +} diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java new file mode 100644 index 00000000..838adb40 --- /dev/null +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java @@ -0,0 +1,229 @@ +package com.github.ontio.service.impl; + +import com.alibaba.fastjson.JSONObject; +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.LoadingCache; +import com.github.ontio.config.ParamsConfig; +import com.github.ontio.core.asset.Sig; +import com.github.ontio.core.transaction.Transaction; +import com.github.ontio.crypto.Digest; +import com.github.ontio.exception.ExplorerException; +import com.github.ontio.mapper.AddressBlacklistMapper; +import com.github.ontio.mapper.UserAddressMapper; +import com.github.ontio.mapper.UserMapper; +import com.github.ontio.model.common.PageResponseBean; +import com.github.ontio.model.common.RedisKey; +import com.github.ontio.model.common.ResponseBean; +import com.github.ontio.model.dao.AddressBlacklist; +import com.github.ontio.model.dao.User; +import com.github.ontio.model.dao.UserAddress; +import com.github.ontio.model.dto.login.CallBackDto; +import com.github.ontio.model.dto.login.CallBackResponse; +import com.github.ontio.model.dto.login.QrCodeDto; +import com.github.ontio.service.IUserService; +import com.github.ontio.util.*; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * @author zhouq + * @version 1.0 + * @date 2020/3/24 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class UserServiceImpl implements IUserService { + + private static final String CACHEKEY_BLACKADDR = "blackAddress"; + private static final String SPILT_CHAR = ","; + + private final UserAddressMapper userAddressMapper; + private final UserMapper userMapper; + private final ParamsConfig paramsConfig; + private final StringRedisTemplate redisTemplate; + private final AddressBlacklistMapper addressBlacklistMapper; + private final OntologySDKService sdkService; + + private LoadingCache> blackAddressCache = null; + + @Autowired + private void setCache() { + blackAddressCache = Caffeine.newBuilder() + .expireAfterWrite(1, TimeUnit.MINUTES) + .build(key -> { + List addressBlacklist = addressBlacklistMapper.selectAll(); + return addressBlacklist.stream().map(item -> item.getAddress()).collect(Collectors.toList()); + }); + } + + @Override + public ResponseBean queryQrCode() { + String code = Helper.generateLoginCode(); + redisTemplate.opsForValue().set(String.format(RedisKey.USERLOGIN_CODE, code), "", 2, TimeUnit.MINUTES); + QrCodeDto qrCodeDto = generateQrCode(code); + return Helper.successResult(qrCodeDto); + } + + private QrCodeDto generateQrCode(String code) { + QrCodeDto.QrCodeDataParamFunArg qrCodeDataParamFunArg = QrCodeDto.QrCodeDataParamFunArg.builder() + .name("message") + .value("") + .build(); + QrCodeDto.QrCodeDataParamFun qrCodeDataParamFun = QrCodeDto.QrCodeDataParamFun.builder() + .operation("signMessage") + .args(Arrays.asList(qrCodeDataParamFunArg)) + .build(); + QrCodeDto.QrCodeDataParamDetail qrCodeDataParamDetail = QrCodeDto.QrCodeDataParamDetail.builder() + .contractHash("0000000000000000000000000000000000000000") + .payer("") + .gasLimit(new BigDecimal("0")) + .gasPrice(new BigDecimal("0")) + .functions(Arrays.asList(qrCodeDataParamFun)) + .build(); + QrCodeDto.QrCodeDataParam qrCodeDataParam = QrCodeDto.QrCodeDataParam.builder() + .invokeConfig(qrCodeDataParamDetail) + .build(); + QrCodeDto.QrCodeData qrCodeData = QrCodeDto.QrCodeData.builder() + .action("signMessage") + .params(qrCodeDataParam) + .build(); + String signature = sdkService.signData2HexStr(JacksonUtil.beanToJSonStr(qrCodeData)); + + return QrCodeDto.testNetLoginQrCode(code, paramsConfig.IDENTITY_ONTID, signature, qrCodeData, paramsConfig.loginCallbackUrl, System.currentTimeMillis() + 2 * 60 * 1000L); + } + + + @Override + public ResponseBean queryLoginUserInfo(String code) { + String token = redisTemplate.opsForValue().get(String.format(RedisKey.USERLOGIN_CODE, code)); + if (token == null) { + throw new ExplorerException(ErrorInfo.QRCODE_EXPIRED); + } else if ("".equals(token)) { + throw new ExplorerException(ErrorInfo.NO_LOGIN_USERINFO); + } + String ontId = JwtUtil.getClaim(token, ConstantParam.JWT_LOGINID).asString(); + User user = userMapper.selectByPrimaryKey(ontId); + //set token + HttpServletResponse resp = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); + resp.setHeader(ConstantParam.HTTPHEADER_TOKEN, token); + return Helper.successResult(user); + } + + + @Override + public CallBackResponse login(CallBackDto callBackDto) { + String ontId = callBackDto.getSigner(); + String signedTx = callBackDto.getSignedTx(); + String code = callBackDto.getExtraData().getId(); + Boolean verifyFlag = verifySignature(ontId, signedTx); + if (!verifyFlag) { + return CallBackResponse.errorResponse(ErrorInfo.VERIFY_SIGN_FAILED.code()); + } + String redisValue = redisTemplate.opsForValue().get(String.format(RedisKey.USERLOGIN_CODE, code)); + if (redisValue == null) { + return CallBackResponse.errorResponse(ErrorInfo.QRCODE_EXPIRED.code()); + } + String token = JwtUtil.signToken(ontId); + redisTemplate.opsForValue().set(String.format(RedisKey.USERLOGIN_CODE, code), token, 60, TimeUnit.SECONDS); + + Date now = new Date(); + User user = userMapper.selectByPrimaryKey(ontId); + if (user == null) { + user = User.builder() + .ontId(ontId) + .userName("") + .email("") + .lastLoginTime(now) + .createTime(now) + .build(); + userMapper.insert(user); + } else { + user.setLastLoginTime(now); + userMapper.updateByPrimaryKeySelective(user); + } + return CallBackResponse.successResponse(new JSONObject()); + } + + private boolean verifySignature(String ontId, String signedTx) { + Transaction transaction = null; + try { + transaction = Transaction.deserializeFrom(com.github.ontio.common.Helper.hexToBytes(signedTx)); + } catch (IOException e) { + throw new ExplorerException(ErrorInfo.TX_ERROR); + } + byte[] sigBytes = transaction.sigs[0].sigData[0]; + String signature = com.github.ontio.common.Helper.toHexString(sigBytes); + if (!signature.startsWith("01")) { + signature = String.format("01%s", signature); + } + transaction.sigs = new Sig[0]; + String hex = transaction.toHexString(); + String tx = hex.substring(0, hex.length() - 2); + String data = com.github.ontio.common.Helper.toHexString(Digest.hash256(com.github.ontio.common.Helper.hexToBytes(tx))); + return sdkService.verifySignature(ontId, data, signature); + } + + + @Override + public ResponseBean queryUserAddresses(String ontId) { + UserAddress userAddress = UserAddress.builder() + .ontId(ontId) + .build(); + List userAddresses = userAddressMapper.select(userAddress); + PageResponseBean pageResponseBean = new PageResponseBean(userAddresses, userAddresses.size()); + return Helper.successResult(pageResponseBean); + } + + + @Override + public ResponseBean addOrUpdateUserAddresses(List userAddressList, String ontId) { + if (userAddressList.size() > 5) { + //normal response can refresh token + return Helper.errorResult(ErrorInfo.ADDRESS_TOOMANY, false); + } + if (CollectionUtils.containsAny(blackAddressCache.get(CACHEKEY_BLACKADDR), userAddressList.stream().map(key -> key.getAddress()).collect(Collectors.toList()))) { + return Helper.errorResult(ErrorInfo.IN_BLACKADDRESS, false); + } + userAddressList.forEach(userAddress -> { + userAddress.setOntId(ontId); + }); + userAddressMapper.saveUserAddress(userAddressList); + return Helper.successResult(true); + } + + @Override + public ResponseBean delUserAddress(String address, String ontId) { + UserAddress userAddress = UserAddress.builder() + .ontId(ontId) + .address(address) + .build(); + int count = userAddressMapper.delete(userAddress); + if (count == 0) { + return Helper.errorResult(ErrorInfo.ADDRESS_ONTID_UNMATCH, false); + } + return Helper.successResult(true); + } + + + @Override + public ResponseBean updateUser(User user) { + userMapper.updateByPrimaryKeySelective(user); + return Helper.successResult(true); + } +} diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/util/ConstantParam.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/util/ConstantParam.java index 792f8fc3..a538fe2d 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/util/ConstantParam.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/util/ConstantParam.java @@ -172,5 +172,9 @@ public class ConstantParam { public static final String CONTRACTHASH_ONT = "0100000000000000000000000000000000000000"; + public static final String HTTPHEADER_TOKEN = "ONT_EXP_TOKEN"; + + public static final String JWT_LOGINID = "loginId"; + } diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/util/ErrorInfo.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/util/ErrorInfo.java index bfc6115e..4e822b4c 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/util/ErrorInfo.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/util/ErrorInfo.java @@ -88,6 +88,22 @@ public enum ErrorInfo { */ ALREADY_AUDITPASS(61011,"FAIL, already on shelves."), + QRCODE_EXPIRED(61012,"Qrcode expired."), + + NO_LOGIN_USERINFO(61013,"No login user info."), + + TOKEN_EXPIRED(61014,"Token expired."), + + TOKEN_UNMATCH(61015,"Token unmatch."), + + TOKEN_EMPTY(61016,"Token empty."), + + IN_BLACKADDRESS(61017,"Address in blacklist."), + + ADDRESS_TOOMANY(61018,"Too many addresses."), + + ADDRESS_ONTID_UNMATCH(61019,"Address unmatch ontid."), + @@ -116,6 +132,10 @@ public enum ErrorInfo { */ DB_ERROR(62005, "FAIL, db operate fail."), + VERIFY_SIGN_FAILED(62006,"Verify signature failed."), + + TX_ERROR(62007,"transaction error."), + /** * inner error diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/util/Helper.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/util/Helper.java index b1646492..4a7399cd 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/util/Helper.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/util/Helper.java @@ -21,12 +21,14 @@ import com.github.ontio.mapper.BlockMapper; import com.github.ontio.model.common.OntIdEventEnum; +import com.github.ontio.model.common.ResponseBean; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import java.util.Base64; +import java.util.Random; /** * @author zhouq @@ -60,6 +62,28 @@ public static Boolean isNotEmptyAndNull(Object... params) { return !isEmptyOrNull(params); } + public static ResponseBean successResult(Object obj) { + return new ResponseBean(ErrorInfo.SUCCESS.code(), ErrorInfo.SUCCESS.desc(), obj); + } + + public static ResponseBean errorResult(ErrorInfo errorInfo, Object obj) { + return new ResponseBean(errorInfo.code(), errorInfo.desc(), obj); + } + + public static String generateLoginCode() { + return String.valueOf(System.currentTimeMillis()) + getRandomString(5); + } + + public static String getRandomString(int length) { + String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + Random random = new Random(); + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < length; i++) { + int number = random.nextInt(62); + sb.append(str.charAt(number)); + } + return sb.toString(); + } /** * 判断时间范围是否超过一个月 @@ -133,6 +157,7 @@ public static String templateOntIdOperation(String inputStr) { /** * 判断redis的key是否属于REDIS_LONGEXPIRETIME_KEYLIST + * * @param redisKey * @return */ @@ -154,6 +179,7 @@ public static Boolean isBelongRedisLongExpireMapper(String redisKey) { /** * 判断redis的key是否属于REDIS_MEDIUMEXPIRETIME_KEYLIST + * * @param redisKey * @return */ @@ -221,7 +247,6 @@ public static String currentMethod() { } - /** * 根据base64后的图片数据生成本地文件 * diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/util/JwtUtil.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/util/JwtUtil.java new file mode 100644 index 00000000..543e4949 --- /dev/null +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/util/JwtUtil.java @@ -0,0 +1,82 @@ +package com.github.ontio.util; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.exceptions.JWTDecodeException; +import com.auth0.jwt.interfaces.Claim; +import com.auth0.jwt.interfaces.DecodedJWT; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.util.Base64; +import java.util.Date; + +/** + * JAVA-JWT util + */ +@Component +@Slf4j +public class JwtUtil { + + private static String accessTokenExpireTime; + + private static String encryptJWTKey; + + @Value("${jwt.accessTokenExpireTime}") + public void setAccessTokenExpireTime(String tokenExpireTime) { + JwtUtil.accessTokenExpireTime = tokenExpireTime.trim(); + } + + @Value("${jwt.encryptJWTKey}") + public void setEncryptJWTKey(String jWTKey) { + JwtUtil.encryptJWTKey = jWTKey.trim(); + } + + + public static boolean verifyToken(String token) { + try { + String ontId = getClaim(token, ConstantParam.JWT_LOGINID).asString(); + String secret = preSecret(ontId); + Algorithm algorithm = Algorithm.HMAC256(secret); + JWTVerifier verifier = JWT.require(algorithm).build(); + DecodedJWT jwt = verifier.verify(token); + log.info("verifytoken jwt:{}", jwt.toString()); + } catch (Exception e) { + log.error("verifyToken error...{}", e.getMessage()); + return false; + } + return true; + } + + + public static Claim getClaim(String token, String claim) { + try { + DecodedJWT jwt = JWT.decode(token); + return jwt.getClaim(claim); + } catch (JWTDecodeException e) { + log.error("getClaim error...{}", e.getMessage()); + return null; + } + } + + + public static String signToken(String ontId) { + // ontId+JWT key + String secret = preSecret(ontId); + Date date = new Date(System.currentTimeMillis() + Long.parseLong(accessTokenExpireTime) * 1000); + Algorithm algorithm = Algorithm.HMAC256(secret); + return JWT.create() + .withClaim(ConstantParam.JWT_LOGINID, ontId) + .withExpiresAt(date) + .sign(algorithm); + } + + private static String preSecret(String ontId) { + String secret = ontId + new String(Base64.getDecoder().decode(encryptJWTKey)); + return secret; + } + + +} diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/util/OntologySDKService.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/util/OntologySDKService.java index 9dfcc7fa..f4a6baac 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/util/OntologySDKService.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/util/OntologySDKService.java @@ -24,9 +24,11 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.github.ontio.OntSdk; +import com.github.ontio.account.Account; import com.github.ontio.common.Address; import com.github.ontio.common.Helper; import com.github.ontio.config.ParamsConfig; +import com.github.ontio.core.DataSignature; import com.github.ontio.core.payload.InvokeWasmCode; import com.github.ontio.core.transaction.Transaction; import com.github.ontio.smartcontract.neovm.abi.BuildParams; @@ -295,4 +297,56 @@ private OntSdk getOep5OntSdk(String codeHash) { return wm; } + + /** + * verify signature + * + * @param ontId + * @param origDataStr + * @param signatureStr + * @return + */ + public boolean verifySignature(String ontId, String origDataStr, String signatureStr) { + try { + Boolean verify = Boolean.FALSE; + OntSdk ontSdk = OntSdk.getInstance(); + ontSdk.setRestful(paramsConfig.MASTERNODE_RESTFUL_URL); + String issuerDdo = ontSdk.nativevm().ontId().sendGetDDO(ontId); + + JSONArray owners = JSONObject.parseObject(issuerDdo).getJSONArray("Owners"); + for (int i = 0; i < owners.size(); ++i) { + String pubkeyStr = owners.getJSONObject(i).getString("Value"); + Account account = new Account(false, Helper.hexToBytes(pubkeyStr)); + verify = account.verifySignature(Helper.hexToBytes(origDataStr), Helper.hexToBytes(signatureStr)); + if (verify) { + break; + } + } + return verify; + } catch (Exception e) { + log.error("{} error...", com.github.ontio.util.Helper.currentMethod(), e); + } + return false; + } + + /** + * sign + * + * @param origData + * @return + */ + public String signData2HexStr(String origData) { + try { + OntSdk ontSdk = OntSdk.getInstance(); + ontSdk.openWalletFile("account.json"); + Account account = ontSdk.getWalletMgr().getAccount(paramsConfig.IDENTITY_ONTID, paramsConfig.IDENTITY_PASSWORD, Base64.getDecoder().decode(paramsConfig.IDENTITY_SALT)); + DataSignature sign = new DataSignature(ontSdk.defaultSignScheme, account, origData.getBytes()); + String sigdata = Helper.toHexString(sign.signature()); + return sigdata; + } catch (Exception e) { + log.error("{} error...", com.github.ontio.util.Helper.currentMethod(), e); + } + return ""; + } + } diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/util/TxDateSerializer.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/util/TxDateSerializer.java new file mode 100644 index 00000000..06dd2b88 --- /dev/null +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/util/TxDateSerializer.java @@ -0,0 +1,23 @@ +package com.github.ontio.util; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; +import java.util.Date; + +/** + * @author zhouq + * @version 1.0 + * @date 2019/7/25 + */ +public class TxDateSerializer extends JsonSerializer { + + @Override + public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { + jsonGenerator.writeNumber(date.getTime() / 1000L); + } + +} From 5c8fb2b48c0c3f786c954c675d77c8a13818a2e2 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Fri, 27 Mar 2020 21:10:16 +0800 Subject: [PATCH 11/40] add identity file --- back-end-projects/Explorer/account.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 back-end-projects/Explorer/account.json diff --git a/back-end-projects/Explorer/account.json b/back-end-projects/Explorer/account.json new file mode 100644 index 00000000..58607a0f --- /dev/null +++ b/back-end-projects/Explorer/account.json @@ -0,0 +1 @@ +{"accounts":[],"createTime":"2020-03-26T10:46:52Z","defaultAccountAddress":"","defaultOntid":"did:ont:ARR7Rk4hpvnkAAWkyHGtrF2H3htHWrKFby","identities":[{"controls":[{"address":"ARR7Rk4hpvnkAAWkyHGtrF2H3htHWrKFby","algorithm":"ECDSA","enc-alg":"aes-256-gcm","hash":"sha256","id":"keys-1","key":"KDCGqt8JbwcN6wKQasQcUrDjjIUy152SfE1dIVvQjYGmuhzd74dnLnLhjgfJAkJY","parameters":{"curve":"P-256"},"publicKey":"034044d1ab03d42543e806c4242fe0ab42f0df530c7548f2078e00a79b087892bb","salt":"hf/9mY5kH9567GZQYnn4hw=="}],"isDefault":true,"label":"c7b82a36","lock":false,"ontid":"did:ont:ARR7Rk4hpvnkAAWkyHGtrF2H3htHWrKFby"}],"name":"com.github.ontio","scrypt":{"dkLen":64,"n":16384,"p":8,"r":8},"version":"1.0"} From 145f3397047abdf6fd32350a1f6403bce5ba1038 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Sun, 29 Mar 2020 16:44:44 +0800 Subject: [PATCH 12/40] use ProducerType.SINGLE --- .../github/ontio/txPush/TransferTransactionPush.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java index 4ce569eb..e2ed517e 100644 --- a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java @@ -41,13 +41,17 @@ public class TransferTransactionPush implements DisruptorEventPublisher, EventHa private final UserAddressMapper userAddressMapper; private final EmailService emailService; - @Getter private RingBuffer ringBuffer; + @Override + public RingBuffer getRingBuffer() { + return ringBuffer; + } + @Autowired public TransferTransactionPush(UserAddressMapper userAddressMapper, EmailService emailService) { - Disruptor disruptor = createDisruptor(65536, ProducerType.MULTI); - disruptor.handleEventsWith(this).then(DisruptorEvent.CLEANER); + Disruptor disruptor = createDisruptor(65536, ProducerType.SINGLE); + disruptor.handleEventsWith(this); disruptor.start(); this.ringBuffer = disruptor.getRingBuffer(); this.userAddressMapper = userAddressMapper; From 48403acfc22129a3e947d3e327d6e4d16b57e9e6 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Mon, 30 Mar 2020 10:57:07 +0800 Subject: [PATCH 13/40] use mainnet qrcode --- .../java/com/github/ontio/service/impl/UserServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java index 838adb40..36cb2b69 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java @@ -105,7 +105,7 @@ private QrCodeDto generateQrCode(String code) { .build(); String signature = sdkService.signData2HexStr(JacksonUtil.beanToJSonStr(qrCodeData)); - return QrCodeDto.testNetLoginQrCode(code, paramsConfig.IDENTITY_ONTID, signature, qrCodeData, paramsConfig.loginCallbackUrl, System.currentTimeMillis() + 2 * 60 * 1000L); + return QrCodeDto.mainNetLoginQrCode(code, paramsConfig.IDENTITY_ONTID, signature, qrCodeData, paramsConfig.loginCallbackUrl, System.currentTimeMillis() + 2 * 60 * 1000L); } From 214f29c31562c35b9eb79318d2d97f54e3870603 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Mon, 30 Mar 2020 10:57:45 +0800 Subject: [PATCH 14/40] judge event class --- .../ontio/txPush/TransferTransactionPush.java | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java index e2ed517e..c9128a4a 100644 --- a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java @@ -3,9 +3,7 @@ import com.alibaba.fastjson.JSONObject; import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.LoadingCache; -import com.github.ontio.mapper.Oep4Mapper; import com.github.ontio.mapper.UserAddressMapper; -import com.github.ontio.model.dao.Oep4; import com.github.ontio.model.dao.TxDetail; import com.github.ontio.txPush.model.PushEmailDto; import com.github.ontio.txPush.model.PushStrategyEnum; @@ -15,12 +13,10 @@ import com.lmax.disruptor.RingBuffer; import com.lmax.disruptor.dsl.Disruptor; import com.lmax.disruptor.dsl.ProducerType; -import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -60,26 +56,30 @@ public TransferTransactionPush(UserAddressMapper userAddressMapper, EmailService @Override public void onEvent(DisruptorEvent disruptorEvent, long sequence, boolean endOfBatch) { - TxDetail txDetail = (TxDetail) disruptorEvent.getEvent(); - log.info("{} disruptor consumer receive tx:{}", Thread.currentThread().getName(), JSONObject.toJSONString(txDetail)); - String fromAddress = txDetail.getFromAddress(); - String toAddress = txDetail.getToAddress(); - if (fromAddress.equals(toAddress)) { - return; - } - Map> cacheMap = userAddressCache.get(USERADDRCACHE_KEY); - List fromAddrPushUserAddressInfoDtos = cacheMap.get(fromAddress); - if (fromAddrPushUserAddressInfoDtos != null) { - fromAddrPushUserAddressInfoDtos.forEach(dto -> { - handleWithdrawTransferTx(txDetail, dto); - }); - } - List toAddrPushUserAddressInfoDtos = cacheMap.get(toAddress); - if (toAddrPushUserAddressInfoDtos != null) { - toAddrPushUserAddressInfoDtos.forEach(dto -> { - handleDepositTransferTx(txDetail, dto); - }); + Object event = disruptorEvent.getEvent(); + if(event instanceof TxDetail){ + TxDetail txDetail = (TxDetail) event; + log.info("{} disruptor consumer receive tx:{}", Thread.currentThread().getName(), JSONObject.toJSONString(txDetail)); + String fromAddress = txDetail.getFromAddress(); + String toAddress = txDetail.getToAddress(); + if (fromAddress.equals(toAddress)) { + return; + } + Map> cacheMap = userAddressCache.get(USERADDRCACHE_KEY); + List fromAddrPushUserAddressInfoDtos = cacheMap.get(fromAddress); + if (fromAddrPushUserAddressInfoDtos != null) { + fromAddrPushUserAddressInfoDtos.forEach(dto -> { + handleWithdrawTransferTx(txDetail, dto); + }); + } + List toAddrPushUserAddressInfoDtos = cacheMap.get(toAddress); + if (toAddrPushUserAddressInfoDtos != null) { + toAddrPushUserAddressInfoDtos.forEach(dto -> { + handleDepositTransferTx(txDetail, dto); + }); + } } + } From cadc29b4b604c1218d240952643c032cce0023ae Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Mon, 30 Mar 2020 11:01:30 +0800 Subject: [PATCH 15/40] add config param --- .../Explorer/config/application.properties | 15 ++++++++++++++- .../com/github/ontio/config/ParamsConfig.java | 4 ---- .../config/application-dev.properties | 9 +++++++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/back-end-projects/Explorer/config/application.properties b/back-end-projects/Explorer/config/application.properties index 848a1234..e9eb242a 100644 --- a/back-end-projects/Explorer/config/application.properties +++ b/back-end-projects/Explorer/config/application.properties @@ -63,4 +63,17 @@ tomcat.maxThread=2000 reqlimit.expire.millisecond=1000 -swagger.enable=true \ No newline at end of file +swagger.enable=true + +coinmarketcap.api.key= + + +##user login +login.callbackUrl= + +identity.ontid = +identity.password = +identity.salt = + +jwt.accessTokenExpireTime=120 +jwt.encryptJWTKey= \ No newline at end of file diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java index 6435e46f..664cdb76 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java @@ -144,10 +144,6 @@ public String getContractHash(String token) { @Value("${login.callbackUrl:https://explorer.ont.io/v2/users/login}") public String loginCallbackUrl; - - @Value("${login.token.expired.minute:5}") - public int loginTokenExpiredMinute; - @Value("${identity.ontid}") public String IDENTITY_ONTID; diff --git a/back-end-projects/OntSynHandler/config/application-dev.properties b/back-end-projects/OntSynHandler/config/application-dev.properties index c9c24b41..8ca0ceb5 100644 --- a/back-end-projects/OntSynHandler/config/application-dev.properties +++ b/back-end-projects/OntSynHandler/config/application-dev.properties @@ -79,3 +79,12 @@ ong.contractHash = 0200000000000000000000000000000000000000 ontId.contractHash = 0300000000000000000000000000000000000000 auth.contractHash = 0600000000000000000000000000000000000000 pax.contractHash = 6bbc07bae862db0d7867e4e5b1a13c663e2b4bc8 + + +####email +sendcloud.email.sender= +sendcloud.email.senderName= +sendcloud.email.transaction.template = +sendcloud.email.apiUser= +sendcloud.email.apiKey= +oneEmail.oneDay.maxTime=20 From 0208348785c81a50b362bb3cff17afa11f239b00 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Mon, 30 Mar 2020 11:11:07 +0800 Subject: [PATCH 16/40] line separators --- .../Explorer/src/main/resources/generator/generatorConfig.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back-end-projects/Explorer/src/main/resources/generator/generatorConfig.xml b/back-end-projects/Explorer/src/main/resources/generator/generatorConfig.xml index 2bb304d6..0f24b7ad 100644 --- a/back-end-projects/Explorer/src/main/resources/generator/generatorConfig.xml +++ b/back-end-projects/Explorer/src/main/resources/generator/generatorConfig.xml @@ -18,7 +18,7 @@ + password="zaq12wsx"> From 368ff988e1389de5bfdc76ea00752ea4032e4fe0 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Mon, 30 Mar 2020 11:21:04 +0800 Subject: [PATCH 17/40] add new table --- .../migration/V1.42__tbl_address_blacklist.sql | 10 ++++++++++ .../resources/db/migration/V1.43__tbl_user.sql | 12 ++++++++++++ .../db/migration/V1.44__tbl_user_address.sql | 16 ++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 back-end-projects/Explorer/src/main/resources/db/migration/V1.42__tbl_address_blacklist.sql create mode 100644 back-end-projects/Explorer/src/main/resources/db/migration/V1.43__tbl_user.sql create mode 100644 back-end-projects/Explorer/src/main/resources/db/migration/V1.44__tbl_user_address.sql diff --git a/back-end-projects/Explorer/src/main/resources/db/migration/V1.42__tbl_address_blacklist.sql b/back-end-projects/Explorer/src/main/resources/db/migration/V1.42__tbl_address_blacklist.sql new file mode 100644 index 00000000..10dd4ba0 --- /dev/null +++ b/back-end-projects/Explorer/src/main/resources/db/migration/V1.42__tbl_address_blacklist.sql @@ -0,0 +1,10 @@ +-- ---------------------------- +-- Table structure for tbl_address_blacklist +-- ---------------------------- +DROP TABLE IF EXISTS `tbl_address_blacklist`; +CREATE TABLE `tbl_address_blacklist` ( + `address` varchar(255) NOT NULL DEFAULT '', + `note` varchar(255) NOT NULL DEFAULT '' COMMENT '备注', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`address`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/back-end-projects/Explorer/src/main/resources/db/migration/V1.43__tbl_user.sql b/back-end-projects/Explorer/src/main/resources/db/migration/V1.43__tbl_user.sql new file mode 100644 index 00000000..54ef3536 --- /dev/null +++ b/back-end-projects/Explorer/src/main/resources/db/migration/V1.43__tbl_user.sql @@ -0,0 +1,12 @@ +-- ---------------------------- +-- Table structure for tbl_user +-- ---------------------------- +DROP TABLE IF EXISTS `tbl_user`; +CREATE TABLE `tbl_user` ( + `ont_id` varchar(255) NOT NULL DEFAULT '' COMMENT 'ONT ID', + `user_name` varchar(255) NOT NULL DEFAULT '' COMMENT '用户名', + `email` varchar(255) NOT NULL DEFAULT '' COMMENT '邮箱', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间', + `last_login_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '上次登录时间', + PRIMARY KEY (`ont_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/back-end-projects/Explorer/src/main/resources/db/migration/V1.44__tbl_user_address.sql b/back-end-projects/Explorer/src/main/resources/db/migration/V1.44__tbl_user_address.sql new file mode 100644 index 00000000..5e3ee632 --- /dev/null +++ b/back-end-projects/Explorer/src/main/resources/db/migration/V1.44__tbl_user_address.sql @@ -0,0 +1,16 @@ +-- ---------------------------- +-- Table structure for tbl_user_address +-- ---------------------------- +DROP TABLE IF EXISTS `tbl_user_address`; +CREATE TABLE `tbl_user_address` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ont_id` varchar(255) NOT NULL DEFAULT '' COMMENT 'ONT ID', + `address` varchar(255) NOT NULL DEFAULT '' COMMENT '地址', + `note` varchar(255) NOT NULL DEFAULT '' COMMENT '地址备注', + `strategy` int(11) NOT NULL DEFAULT '0' COMMENT '监听策略。0:不监听 1:监听所有入金出金,2:只监听入金 3:只监听出金', + `include_oep_token` tinyint(1) NOT NULL DEFAULT '0' COMMENT '1:监听oep资产 0:不监听oep资产', + PRIMARY KEY (`id`), + UNIQUE KEY `unq_ontid_address` (`address`,`ont_id`), + KEY `fkey_ontId` (`ont_id`), + CONSTRAINT `fkey_ontId` FOREIGN KEY (`ont_id`) REFERENCES `tbl_user` (`ont_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; From d4bf7068dc91e9cceb587203e258b77778bc6519 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Tue, 31 Mar 2020 17:54:46 +0800 Subject: [PATCH 18/40] add query oep logos api --- .../ontio/controller/TokenController.java | 22 ++- .../github/ontio/mapper/OepLogoMapper.java | 7 + .../com/github/ontio/model/dao/OepLogo.java | 166 ++++++++++++++++++ .../github/ontio/service/ITokenService.java | 2 + .../ontio/service/impl/TokenServiceImpl.java | 40 +++-- .../main/resources/mapper/OepLogoMapper.xml | 16 ++ 6 files changed, 227 insertions(+), 26 deletions(-) create mode 100644 back-end-projects/Explorer/src/main/java/com/github/ontio/mapper/OepLogoMapper.java create mode 100644 back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/OepLogo.java create mode 100644 back-end-projects/Explorer/src/main/resources/mapper/OepLogoMapper.xml diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/controller/TokenController.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/controller/TokenController.java index 4dd6aa75..22d069cf 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/controller/TokenController.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/controller/TokenController.java @@ -10,11 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.validation.constraints.Max; import javax.validation.constraints.Min; @@ -72,9 +68,9 @@ public ResponseBean queryTokenDetail(@PathVariable("token_type") @Pattern(regexp @GetMapping(value = "/oep8/{contract_hash}/{token_name}/transactions") public ResponseBean queryOep8TxsByPage(@PathVariable("contract_hash") @Length(min = 40, max = 40, message = "Incorrect " + "contract hash") String contractHash, - @PathVariable("token_name") String tokenName, - @RequestParam("page_size") @Min(1) @Max(20) Integer pageSize, - @RequestParam("page_number") @Min(1) Integer pageNumber) { + @PathVariable("token_name") String tokenName, + @RequestParam("page_size") @Min(1) @Max(20) Integer pageSize, + @RequestParam("page_number") @Min(1) Integer pageNumber) { log.info("###{}.{} begin...contract_hash:{},token_name:{}", CLASS_NAME, Helper.currentMethod(), contractHash, tokenName); @@ -120,4 +116,14 @@ public ResponseBean queryPrice( return tokenService.queryPrice(token, fiat); } + + @ApiOperation(value = "Get oep logos") + @GetMapping(value = "/logos") + public ResponseBean queryOepLogos(@RequestParam("contract_hash") @Length(min = 40, max = 40, message = "Incorrect contract hash") String contractHash, + @RequestParam("page_size") @Min(1) @Max(50) int pageSize, + @RequestParam("page_number") @Min(1) int pageNumber) { + log.info("###{}.{} begin...", CLASS_NAME, Helper.currentMethod()); + return tokenService.queryOepLogos(contractHash, pageSize, pageNumber); + } + } diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/mapper/OepLogoMapper.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/mapper/OepLogoMapper.java new file mode 100644 index 00000000..9a99e4c0 --- /dev/null +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/mapper/OepLogoMapper.java @@ -0,0 +1,7 @@ +package com.github.ontio.mapper; + +import com.github.ontio.model.dao.OepLogo; +import tk.mybatis.mapper.common.Mapper; + +public interface OepLogoMapper extends Mapper { +} \ No newline at end of file diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/OepLogo.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/OepLogo.java new file mode 100644 index 00000000..6a497fd0 --- /dev/null +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/OepLogo.java @@ -0,0 +1,166 @@ +package com.github.ontio.model.dao; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.github.ontio.util.TxDateSerializer; + +import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; +import java.util.Date; + +@Table(name = "tbl_oep_logo") +public class OepLogo { + @Id + @GeneratedValue(generator = "JDBC") + private Integer id; + + /** + * 合约hash + */ + @Column(name = "contract_hash") + private String contractHash; + + /** + * oep5,oep8 + */ + private String type; + + /** + * 合约token id + */ + @Column(name = "token_id") + private String tokenId; + + /** + * logo链接 + */ + private String logo; + + /** + * token名称 + */ + private String name; + + @JsonSerialize(using = TxDateSerializer.class) + @Column(name = "create_time") + private Date createTime; + + /** + * @return id + */ + public Integer getId() { + return id; + } + + /** + * @param id + */ + public void setId(Integer id) { + this.id = id; + } + + /** + * 获取合约hash + * + * @return contract_hash - 合约hash + */ + public String getContractHash() { + return contractHash; + } + + /** + * 设置合约hash + * + * @param contractHash 合约hash + */ + public void setContractHash(String contractHash) { + this.contractHash = contractHash == null ? null : contractHash.trim(); + } + + /** + * 获取oep5,oep8 + * + * @return type - oep5,oep8 + */ + public String getType() { + return type; + } + + /** + * 设置oep5,oep8 + * + * @param type oep5,oep8 + */ + public void setType(String type) { + this.type = type == null ? null : type.trim(); + } + + /** + * 获取合约token id + * + * @return token_id - 合约token id + */ + public String getTokenId() { + return tokenId; + } + + /** + * 设置合约token id + * + * @param tokenId 合约token id + */ + public void setTokenId(String tokenId) { + this.tokenId = tokenId == null ? null : tokenId.trim(); + } + + /** + * 获取logo链接 + * + * @return logo - logo链接 + */ + public String getLogo() { + return logo; + } + + /** + * 设置logo链接 + * + * @param logo logo链接 + */ + public void setLogo(String logo) { + this.logo = logo == null ? null : logo.trim(); + } + + /** + * 获取token名称 + * + * @return name - token名称 + */ + public String getName() { + return name; + } + + /** + * 设置token名称 + * + * @param name token名称 + */ + public void setName(String name) { + this.name = name == null ? null : name.trim(); + } + + /** + * @return create_time + */ + public Date getCreateTime() { + return createTime; + } + + /** + * @param createTime + */ + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } +} \ No newline at end of file diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/ITokenService.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/ITokenService.java index 40bbc5a3..79ba7ed8 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/ITokenService.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/ITokenService.java @@ -24,4 +24,6 @@ public interface ITokenService { ResponseBean queryPrice(String token, String fiat); + ResponseBean queryOepLogos(String contractHash, int pageSize, int pageNumber); + } diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/TokenServiceImpl.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/TokenServiceImpl.java index 8c44eda2..4687c361 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/TokenServiceImpl.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/TokenServiceImpl.java @@ -3,19 +3,11 @@ import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.LoadingCache; import com.github.ontio.config.ParamsConfig; -import com.github.ontio.mapper.Oep4Mapper; -import com.github.ontio.mapper.Oep5Mapper; -import com.github.ontio.mapper.Oep8Mapper; -import com.github.ontio.mapper.Oep8TxDetailMapper; -import com.github.ontio.mapper.RankingMapper; -import com.github.ontio.mapper.TokenDailyAggregationMapper; +import com.github.ontio.mapper.*; import com.github.ontio.model.common.PageResponseBean; import com.github.ontio.model.common.ResponseBean; -import com.github.ontio.model.dto.Oep4DetailDto; -import com.github.ontio.model.dto.Oep5DetailDto; -import com.github.ontio.model.dto.Oep8DetailDto; -import com.github.ontio.model.dto.TokenPriceDto; -import com.github.ontio.model.dto.TxDetailDto; +import com.github.ontio.model.dao.OepLogo; +import com.github.ontio.model.dto.*; import com.github.ontio.model.dto.ranking.TokenRankingDto; import com.github.ontio.service.ITokenService; import com.github.ontio.util.ConstantParam; @@ -28,13 +20,10 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import tk.mybatis.mapper.entity.Example; import java.time.Duration; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; /** @@ -53,11 +42,12 @@ public class TokenServiceImpl implements ITokenService { private final TokenDailyAggregationMapper tokenDailyAggregationMapper; private final RankingMapper rankingMapper; private final CoinMarketCapApi coinMarketCapApi; + private final OepLogoMapper oepLogoMapper; @Autowired public TokenServiceImpl(Oep4Mapper oep4Mapper, Oep5Mapper oep5Mapper, Oep8Mapper oep8Mapper, - Oep8TxDetailMapper oep8TxDetailMapper, TokenDailyAggregationMapper tokenDailyAggregationMapper, - RankingMapper rankingMapper, CoinMarketCapApi coinMarketCapApi) { + Oep8TxDetailMapper oep8TxDetailMapper, TokenDailyAggregationMapper tokenDailyAggregationMapper, + RankingMapper rankingMapper, CoinMarketCapApi coinMarketCapApi, OepLogoMapper oepLogoMapper) { this.oep4Mapper = oep4Mapper; this.oep5Mapper = oep5Mapper; this.oep8Mapper = oep8Mapper; @@ -65,6 +55,7 @@ public TokenServiceImpl(Oep4Mapper oep4Mapper, Oep5Mapper oep5Mapper, Oep8Mapper this.tokenDailyAggregationMapper = tokenDailyAggregationMapper; this.rankingMapper = rankingMapper; this.coinMarketCapApi = coinMarketCapApi; + this.oepLogoMapper = oepLogoMapper; } @Override @@ -220,4 +211,17 @@ public void setParamsConfig(ParamsConfig paramsConfig) { }); } + + @Override + public ResponseBean queryOepLogos(String contractHash, int pageSize, int pageNumber) { + PageHelper.startPage(pageNumber, pageSize); + Example example = new Example(OepLogo.class); + example.and() + .andEqualTo("contractHash", contractHash); + example.orderBy("createTime").desc(); + List oepLogos = oepLogoMapper.selectByExample(example); + Long total = ((Page) oepLogos).getTotal(); + PageResponseBean responseBean = new PageResponseBean(oepLogos, total.intValue()); + return new ResponseBean(ErrorInfo.SUCCESS.code(), ErrorInfo.SUCCESS.desc(), responseBean); + } } diff --git a/back-end-projects/Explorer/src/main/resources/mapper/OepLogoMapper.xml b/back-end-projects/Explorer/src/main/resources/mapper/OepLogoMapper.xml new file mode 100644 index 00000000..07972d54 --- /dev/null +++ b/back-end-projects/Explorer/src/main/resources/mapper/OepLogoMapper.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ No newline at end of file From 7dbd482e425484e2596c51515d2792b44568b270 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Tue, 31 Mar 2020 17:54:58 +0800 Subject: [PATCH 19/40] add new table --- .../resources/db/migration/V1.45_tbl_oep_logo.sql | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 back-end-projects/Explorer/src/main/resources/db/migration/V1.45_tbl_oep_logo.sql diff --git a/back-end-projects/Explorer/src/main/resources/db/migration/V1.45_tbl_oep_logo.sql b/back-end-projects/Explorer/src/main/resources/db/migration/V1.45_tbl_oep_logo.sql new file mode 100644 index 00000000..9be93cd6 --- /dev/null +++ b/back-end-projects/Explorer/src/main/resources/db/migration/V1.45_tbl_oep_logo.sql @@ -0,0 +1,15 @@ +-- ---------------------------- +-- Table structure for tbl_oep_logo +-- ---------------------------- +DROP TABLE IF EXISTS `tbl_oep_logo`; +CREATE TABLE `tbl_oep_logo` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `contract_hash` varchar(255) NOT NULL DEFAULT '' COMMENT '合约hash', + `type` varchar(255) NOT NULL DEFAULT '' COMMENT 'oep5,oep8', + `token_id` varchar(255) NOT NULL DEFAULT '' COMMENT '合约token id', + `logo` varchar(255) NOT NULL DEFAULT '' COMMENT 'logo链接', + `name` varchar(255) NOT NULL DEFAULT '' COMMENT 'token名称', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `unq_contracthash_tokenid` (`contract_hash`,`token_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; From b62ae62f82d7e2682711c719a8c9d948c77849c4 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Tue, 31 Mar 2020 19:51:47 +0800 Subject: [PATCH 20/40] update redis key name,code->qrCodeId --- .../github/ontio/model/common/RedisKey.java | 2 +- .../ontio/service/impl/UserServiceImpl.java | 41 ++++++++++--------- .../java/com/github/ontio/util/Helper.java | 2 +- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/model/common/RedisKey.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/common/RedisKey.java index 18f16c3d..87a0d5e0 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/model/common/RedisKey.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/common/RedisKey.java @@ -7,6 +7,6 @@ */ public class RedisKey { - public static final String USERLOGIN_CODE = "userLogin:code:%s"; + public static final String USERLOGIN_QRCODEID = "userLogin:qrCodeId:%s"; } diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java index 36cb2b69..8024a490 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java @@ -51,7 +51,7 @@ public class UserServiceImpl implements IUserService { private static final String CACHEKEY_BLACKADDR = "blackAddress"; - private static final String SPILT_CHAR = ","; + private static final String SIGNATURE_PREFIX = "01"; private final UserAddressMapper userAddressMapper; private final UserMapper userMapper; @@ -65,7 +65,7 @@ public class UserServiceImpl implements IUserService { @Autowired private void setCache() { blackAddressCache = Caffeine.newBuilder() - .expireAfterWrite(1, TimeUnit.MINUTES) + .expireAfterWrite(5, TimeUnit.MINUTES) .build(key -> { List addressBlacklist = addressBlacklistMapper.selectAll(); return addressBlacklist.stream().map(item -> item.getAddress()).collect(Collectors.toList()); @@ -74,13 +74,13 @@ private void setCache() { @Override public ResponseBean queryQrCode() { - String code = Helper.generateLoginCode(); - redisTemplate.opsForValue().set(String.format(RedisKey.USERLOGIN_CODE, code), "", 2, TimeUnit.MINUTES); - QrCodeDto qrCodeDto = generateQrCode(code); + String qrCodeId = Helper.generateQrCodeId(); + QrCodeDto qrCodeDto = generateQrCode(qrCodeId); + redisTemplate.opsForValue().set(String.format(RedisKey.USERLOGIN_QRCODEID, qrCodeId), "", 2, TimeUnit.MINUTES); return Helper.successResult(qrCodeDto); } - private QrCodeDto generateQrCode(String code) { + private QrCodeDto generateQrCode(String qrCodeId) { QrCodeDto.QrCodeDataParamFunArg qrCodeDataParamFunArg = QrCodeDto.QrCodeDataParamFunArg.builder() .name("message") .value("") @@ -105,13 +105,13 @@ private QrCodeDto generateQrCode(String code) { .build(); String signature = sdkService.signData2HexStr(JacksonUtil.beanToJSonStr(qrCodeData)); - return QrCodeDto.mainNetLoginQrCode(code, paramsConfig.IDENTITY_ONTID, signature, qrCodeData, paramsConfig.loginCallbackUrl, System.currentTimeMillis() + 2 * 60 * 1000L); + return QrCodeDto.mainNetLoginQrCode(qrCodeId, paramsConfig.IDENTITY_ONTID, signature, qrCodeData, paramsConfig.loginCallbackUrl, System.currentTimeMillis() + 2 * 60 * 1000L); } @Override - public ResponseBean queryLoginUserInfo(String code) { - String token = redisTemplate.opsForValue().get(String.format(RedisKey.USERLOGIN_CODE, code)); + public ResponseBean queryLoginUserInfo(String qrCodeId) { + String token = redisTemplate.opsForValue().get(String.format(RedisKey.USERLOGIN_QRCODEID, qrCodeId)); if (token == null) { throw new ExplorerException(ErrorInfo.QRCODE_EXPIRED); } else if ("".equals(token)) { @@ -119,6 +119,11 @@ public ResponseBean queryLoginUserInfo(String code) { } String ontId = JwtUtil.getClaim(token, ConstantParam.JWT_LOGINID).asString(); User user = userMapper.selectByPrimaryKey(ontId); + //get last login time + Date lastLoginTime = user.getLastLoginTime(); + user.setLastLoginTime(new Date()); + userMapper.updateByPrimaryKeySelective(user); + user.setLastLoginTime(lastLoginTime); //set token HttpServletResponse resp = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); resp.setHeader(ConstantParam.HTTPHEADER_TOKEN, token); @@ -130,21 +135,21 @@ public ResponseBean queryLoginUserInfo(String code) { public CallBackResponse login(CallBackDto callBackDto) { String ontId = callBackDto.getSigner(); String signedTx = callBackDto.getSignedTx(); - String code = callBackDto.getExtraData().getId(); + String qrCodeId = callBackDto.getExtraData().getId(); Boolean verifyFlag = verifySignature(ontId, signedTx); if (!verifyFlag) { return CallBackResponse.errorResponse(ErrorInfo.VERIFY_SIGN_FAILED.code()); } - String redisValue = redisTemplate.opsForValue().get(String.format(RedisKey.USERLOGIN_CODE, code)); + String redisValue = redisTemplate.opsForValue().get(String.format(RedisKey.USERLOGIN_QRCODEID, qrCodeId)); if (redisValue == null) { return CallBackResponse.errorResponse(ErrorInfo.QRCODE_EXPIRED.code()); } String token = JwtUtil.signToken(ontId); - redisTemplate.opsForValue().set(String.format(RedisKey.USERLOGIN_CODE, code), token, 60, TimeUnit.SECONDS); + redisTemplate.opsForValue().set(String.format(RedisKey.USERLOGIN_QRCODEID, qrCodeId), token, 60, TimeUnit.SECONDS); - Date now = new Date(); User user = userMapper.selectByPrimaryKey(ontId); if (user == null) { + Date now = new Date(); user = User.builder() .ontId(ontId) .userName("") @@ -153,9 +158,6 @@ public CallBackResponse login(CallBackDto callBackDto) { .createTime(now) .build(); userMapper.insert(user); - } else { - user.setLastLoginTime(now); - userMapper.updateByPrimaryKeySelective(user); } return CallBackResponse.successResponse(new JSONObject()); } @@ -165,12 +167,13 @@ private boolean verifySignature(String ontId, String signedTx) { try { transaction = Transaction.deserializeFrom(com.github.ontio.common.Helper.hexToBytes(signedTx)); } catch (IOException e) { - throw new ExplorerException(ErrorInfo.TX_ERROR); + log.error("{} error...", Helper.currentMethod(), e); + return false; } byte[] sigBytes = transaction.sigs[0].sigData[0]; String signature = com.github.ontio.common.Helper.toHexString(sigBytes); - if (!signature.startsWith("01")) { - signature = String.format("01%s", signature); + if (!signature.startsWith(SIGNATURE_PREFIX)) { + signature = SIGNATURE_PREFIX + signature; } transaction.sigs = new Sig[0]; String hex = transaction.toHexString(); diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/util/Helper.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/util/Helper.java index 4a7399cd..721dac81 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/util/Helper.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/util/Helper.java @@ -70,7 +70,7 @@ public static ResponseBean errorResult(ErrorInfo errorInfo, Object obj) { return new ResponseBean(errorInfo.code(), errorInfo.desc(), obj); } - public static String generateLoginCode() { + public static String generateQrCodeId() { return String.valueOf(System.currentTimeMillis()) + getRandomString(5); } From 24346c005721dff2a9bb6425a06c96e81460ab92 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Wed, 1 Apr 2020 10:16:54 +0800 Subject: [PATCH 21/40] alter table --- .../{V1.45_tbl_oep_logo.sql => V1.45__tbl_oep_logo.sql} | 0 .../Explorer/src/main/resources/db/migration/V1.46__tbl_user.sql | 1 + 2 files changed, 1 insertion(+) rename back-end-projects/Explorer/src/main/resources/db/migration/{V1.45_tbl_oep_logo.sql => V1.45__tbl_oep_logo.sql} (100%) create mode 100644 back-end-projects/Explorer/src/main/resources/db/migration/V1.46__tbl_user.sql diff --git a/back-end-projects/Explorer/src/main/resources/db/migration/V1.45_tbl_oep_logo.sql b/back-end-projects/Explorer/src/main/resources/db/migration/V1.45__tbl_oep_logo.sql similarity index 100% rename from back-end-projects/Explorer/src/main/resources/db/migration/V1.45_tbl_oep_logo.sql rename to back-end-projects/Explorer/src/main/resources/db/migration/V1.45__tbl_oep_logo.sql diff --git a/back-end-projects/Explorer/src/main/resources/db/migration/V1.46__tbl_user.sql b/back-end-projects/Explorer/src/main/resources/db/migration/V1.46__tbl_user.sql new file mode 100644 index 00000000..16df1f2d --- /dev/null +++ b/back-end-projects/Explorer/src/main/resources/db/migration/V1.46__tbl_user.sql @@ -0,0 +1 @@ +ALTER TABLE tbl_user MODIFY last_login_time datetime NOT NULL COMMENT '上次登录时间'; From 92b271e78d453aa12cfc1967dea13bebaf0c4e56 Mon Sep 17 00:00:00 2001 From: LightKool Date: Thu, 2 Apr 2020 10:11:39 +0800 Subject: [PATCH 22/40] hotfix db schema change --- .../main/resources/db/migration/V1.42__tbl_tx_detail_index.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 back-end-projects/Explorer/src/main/resources/db/migration/V1.42__tbl_tx_detail_index.sql diff --git a/back-end-projects/Explorer/src/main/resources/db/migration/V1.42__tbl_tx_detail_index.sql b/back-end-projects/Explorer/src/main/resources/db/migration/V1.42__tbl_tx_detail_index.sql new file mode 100644 index 00000000..06ada90e --- /dev/null +++ b/back-end-projects/Explorer/src/main/resources/db/migration/V1.42__tbl_tx_detail_index.sql @@ -0,0 +1,2 @@ +DROP INDEX idx_address_contract_hash ON tbl_tx_detail_index; +CREATE INDEX idx_contract_hash_block_height ON tbl_tx_detail_index(`called_contract_hash`, `desc_block_height`); \ No newline at end of file From 596ed5780a1ee750362edaec570fc6726a6e1751 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Thu, 2 Apr 2020 12:17:56 +0800 Subject: [PATCH 23/40] just return --- .../com/github/ontio/txPush/TransferTransactionPush.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java index c9128a4a..ddbdfa2f 100644 --- a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java @@ -56,7 +56,8 @@ public TransferTransactionPush(UserAddressMapper userAddressMapper, EmailService @Override public void onEvent(DisruptorEvent disruptorEvent, long sequence, boolean endOfBatch) { - Object event = disruptorEvent.getEvent(); + return; +/* Object event = disruptorEvent.getEvent(); if(event instanceof TxDetail){ TxDetail txDetail = (TxDetail) event; log.info("{} disruptor consumer receive tx:{}", Thread.currentThread().getName(), JSONObject.toJSONString(txDetail)); @@ -78,7 +79,7 @@ public void onEvent(DisruptorEvent disruptorEvent, long sequence, boolean endOfB handleDepositTransferTx(txDetail, dto); }); } - } + }*/ } From 3c0f48c5b5ebcbd7ebf13a7ac453944fc0743566 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Thu, 2 Apr 2020 12:21:20 +0800 Subject: [PATCH 24/40] new table --- .../src/main/resources/generator/generatorConfig.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/back-end-projects/Explorer/src/main/resources/generator/generatorConfig.xml b/back-end-projects/Explorer/src/main/resources/generator/generatorConfig.xml index 0f24b7ad..fb5b44e9 100644 --- a/back-end-projects/Explorer/src/main/resources/generator/generatorConfig.xml +++ b/back-end-projects/Explorer/src/main/resources/generator/generatorConfig.xml @@ -41,7 +41,7 @@ - + + +
+
From f959847a1d98abecb2e0d7e6a4ecaf5bc70279fa Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Thu, 2 Apr 2020 12:55:10 +0800 Subject: [PATCH 25/40] rename sql --- ...42__tbl_tx_detail_index.sql => V1.47__tbl_tx_detail_index.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename back-end-projects/Explorer/src/main/resources/db/migration/{V1.42__tbl_tx_detail_index.sql => V1.47__tbl_tx_detail_index.sql} (100%) diff --git a/back-end-projects/Explorer/src/main/resources/db/migration/V1.42__tbl_tx_detail_index.sql b/back-end-projects/Explorer/src/main/resources/db/migration/V1.47__tbl_tx_detail_index.sql similarity index 100% rename from back-end-projects/Explorer/src/main/resources/db/migration/V1.42__tbl_tx_detail_index.sql rename to back-end-projects/Explorer/src/main/resources/db/migration/V1.47__tbl_tx_detail_index.sql From 97aac85d08b2672a5b1061cd2ec2a31716bdb6a9 Mon Sep 17 00:00:00 2001 From: LightKool Date: Thu, 2 Apr 2020 13:58:49 +0800 Subject: [PATCH 26/40] oep5 dragon tx query bug fix --- .../service/impl/ContractServiceImpl.java | 20 +++++++++++ .../resources/mapper/Oep5TxDetailMapper.xml | 34 ++++++++++--------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/ContractServiceImpl.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/ContractServiceImpl.java index cfe9df50..17ea66e0 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/ContractServiceImpl.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/ContractServiceImpl.java @@ -57,6 +57,7 @@ import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -144,6 +145,7 @@ public ResponseBean queryTxsByContractHash(String contractType, String contractH //TODO 云斗龙特殊查询,多asset_name,json_url字段。后续oep5需要统一规范 if (paramsConfig.OEP5_DRAGON_CONTRACTHASH.equals(contractHash)) { List oep5TxDetailDtos = oep5TxDetailMapper.selectTxs4Dragon(contractHash, start, pageSize); + oep5TxDetailDtos = filterDragonTxDetails(oep5TxDetailDtos); count = oep5TxDetailMapper.selectCountByCalledContracthash(contractHash); pageResponseBean = new PageResponseBean(oep5TxDetailDtos, count); } else { @@ -191,6 +193,7 @@ public ResponseBean queryTxsByContractHash(String contractHash, Integer pageNumb //TODO 云斗龙特殊查询,多asset_name,json_url字段。后续oep5需要统一规范 if (paramsConfig.OEP5_DRAGON_CONTRACTHASH.equals(contractHash)) { List oep5TxDetailDtos = oep5TxDetailMapper.selectTxs4Dragon(contractHash, start, pageSize); + oep5TxDetailDtos = filterDragonTxDetails(oep5TxDetailDtos); count = oep5TxDetailMapper.selectCountByCalledContracthash(contractHash); pageResponseBean = new PageResponseBean(oep5TxDetailDtos, count); } else { @@ -636,4 +639,21 @@ private long getDaysAgo0HourTimestamp(int days) { return zeroHourTimestamp; } + private List filterDragonTxDetails(List details) { + if (details == null || details.isEmpty()) { + return details; + } + Map detailMap = new LinkedHashMap<>(); + details.forEach(detail -> detailMap.compute(detail.getTxHash(), (k, v) -> { + if (v == null) { + return detail; + } else if (detail.getAssetName() != null && detail.getAssetName().startsWith("HyperDragons")) { + return detail; + } else { + return v; + } + })); + return new ArrayList<>(detailMap.values()); + } + } diff --git a/back-end-projects/Explorer/src/main/resources/mapper/Oep5TxDetailMapper.xml b/back-end-projects/Explorer/src/main/resources/mapper/Oep5TxDetailMapper.xml index 88781ab7..8cca448e 100644 --- a/back-end-projects/Explorer/src/main/resources/mapper/Oep5TxDetailMapper.xml +++ b/back-end-projects/Explorer/src/main/resources/mapper/Oep5TxDetailMapper.xml @@ -51,24 +51,26 @@ From 374639f8663cdc15667a16c6cad847b7278cd2f0 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Thu, 2 Apr 2020 16:39:54 +0800 Subject: [PATCH 27/40] add param:login.qrcode.url --- back-end-projects/Explorer/account.json | 2 +- back-end-projects/Explorer/config/application.properties | 1 + .../src/main/java/com/github/ontio/config/ParamsConfig.java | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/back-end-projects/Explorer/account.json b/back-end-projects/Explorer/account.json index 58607a0f..79b1fa13 100644 --- a/back-end-projects/Explorer/account.json +++ b/back-end-projects/Explorer/account.json @@ -1 +1 @@ -{"accounts":[],"createTime":"2020-03-26T10:46:52Z","defaultAccountAddress":"","defaultOntid":"did:ont:ARR7Rk4hpvnkAAWkyHGtrF2H3htHWrKFby","identities":[{"controls":[{"address":"ARR7Rk4hpvnkAAWkyHGtrF2H3htHWrKFby","algorithm":"ECDSA","enc-alg":"aes-256-gcm","hash":"sha256","id":"keys-1","key":"KDCGqt8JbwcN6wKQasQcUrDjjIUy152SfE1dIVvQjYGmuhzd74dnLnLhjgfJAkJY","parameters":{"curve":"P-256"},"publicKey":"034044d1ab03d42543e806c4242fe0ab42f0df530c7548f2078e00a79b087892bb","salt":"hf/9mY5kH9567GZQYnn4hw=="}],"isDefault":true,"label":"c7b82a36","lock":false,"ontid":"did:ont:ARR7Rk4hpvnkAAWkyHGtrF2H3htHWrKFby"}],"name":"com.github.ontio","scrypt":{"dkLen":64,"n":16384,"p":8,"r":8},"version":"1.0"} +{"accounts":[],"createTime":"2020-03-26T10:46:52Z","defaultAccountAddress":"","defaultOntid":"did:ont:ARR7Rk4hpvnkAAWkyHGtrF2H3htHWrKFby","identities":[{"controls":[{"address":"ARR7Rk4hpvnkAAWkyHGtrF2H3htHWrKFby","algorithm":"ECDSA","enc-alg":"aes-256-gcm","hash":"sha256","id":"keys-1","key":"KDCGqt8JbwcN6wKQasQcUrDjjIUy152SfE1dIVvQjYGmuhzd74dnLnLhjgfJAkJY","parameters":{"curve":"P-256"},"publicKey":"034044d1ab03d42543e806c4242fe0ab42f0df530c7548f2078e00a79b087892bb","salt":"hf/9mY5kH9567GZQYnn4hw=="}],"isDefault":true,"label":"c7b82a36","lock":false,"ontid":"did:ont:ARR7Rk4hpvnkAAWkyHGtrF2H3htHWrKFby"},{"controls":[{"address":"Ae6XnePYWiBUALD2c2EdnuDAAWEsqf2JGr","algorithm":"ECDSA","enc-alg":"aes-256-gcm","hash":"sha256","id":"keys-1","key":"zgNPyJb3UtIA2jdHoS2I6RgnYPRc50cC89gIN9frbnZMtp+pMSm9iR3Oxd9/kIBQ","parameters":{"curve":"P-256"},"publicKey":"0376104dd7bba89580540f9e923a32ad9470af8759774c578936d96004fc492218","salt":"oNyhAmy2RLtv64wmnAlK6g=="}],"isDefault":false,"label":"06c59f9d","lock":false,"ontid":"did:ont:Ae6XnePYWiBUALD2c2EdnuDAAWEsqf2JGr"}],"name":"com.github.ontio","scrypt":{"dkLen":64,"n":16384,"p":8,"r":8},"version":"1.0"} diff --git a/back-end-projects/Explorer/config/application.properties b/back-end-projects/Explorer/config/application.properties index e9eb242a..c8f2d251 100644 --- a/back-end-projects/Explorer/config/application.properties +++ b/back-end-projects/Explorer/config/application.properties @@ -70,6 +70,7 @@ coinmarketcap.api.key= ##user login login.callbackUrl= +login.qrcode.url= identity.ontid = identity.password = diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java index 664cdb76..f67f5e61 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java @@ -153,4 +153,7 @@ public String getContractHash(String token) { @Value("${identity.salt}") public String IDENTITY_SALT; + @Value("${login.qrcode.url:https://explorer.ont.io/v2/users/login_qrcode/}") + public String loginQrCodeUrl; + } \ No newline at end of file From f3ad4ecbce6d8f1fe07cb6020a12985ae0a977dd Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Thu, 2 Apr 2020 16:40:41 +0800 Subject: [PATCH 28/40] update login qrcode logic --- .../ontio/controller/UserController.java | 16 ++++++++++---- .../github/ontio/service/IUserService.java | 5 ++++- .../ontio/service/impl/UserServiceImpl.java | 21 +++++++++++++------ .../java/com/github/ontio/util/ErrorInfo.java | 3 +++ 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/controller/UserController.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/controller/UserController.java index ff5e4bc6..6d3d181b 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/controller/UserController.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/controller/UserController.java @@ -7,6 +7,7 @@ import com.github.ontio.model.dao.UserAddress; import com.github.ontio.model.dto.login.CallBackDto; import com.github.ontio.model.dto.login.CallBackResponse; +import com.github.ontio.model.dto.login.QrCodeDto; import com.github.ontio.service.IUserService; import com.github.ontio.util.ConstantParam; import com.github.ontio.util.ErrorInfo; @@ -41,10 +42,17 @@ public class UserController { private final IUserService userService; - @ApiOperation(value = "Query login qrcode") - @GetMapping(value = "/login_qrcode") - public ResponseBean queryQrCode() { - ResponseBean rs = userService.queryQrCode(); + @ApiOperation(value = "Web Query login qrcode") + @GetMapping(value = "/web_login_qrcode") + public ResponseBean queryWebQrCode() { + ResponseBean rs = userService.queryWebQrCode(); + return rs; + } + + @ApiOperation(value = "ONTO APP Query login qrcode") + @GetMapping(value = "/login_qrcode/{qrcode_id}") + public QrCodeDto queryQrCode(@PathVariable("qrcode_id") String qrcodeId) { + QrCodeDto rs = userService.queryQrCode(qrcodeId); return rs; } diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/IUserService.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/IUserService.java index 0b1a5bb6..c26dc991 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/IUserService.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/IUserService.java @@ -5,6 +5,7 @@ import com.github.ontio.model.dao.UserAddress; import com.github.ontio.model.dto.login.CallBackDto; import com.github.ontio.model.dto.login.CallBackResponse; +import com.github.ontio.model.dto.login.QrCodeDto; import java.util.List; @@ -15,7 +16,9 @@ */ public interface IUserService { - ResponseBean queryQrCode(); + ResponseBean queryWebQrCode(); + + QrCodeDto queryQrCode(String qrcodeId); ResponseBean queryLoginUserInfo(String code); diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java index 8024a490..b755aada 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java @@ -34,9 +34,7 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.math.BigDecimal; -import java.util.Arrays; -import java.util.Date; -import java.util.List; +import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -73,11 +71,19 @@ private void setCache() { } @Override - public ResponseBean queryQrCode() { + public ResponseBean queryWebQrCode() { String qrCodeId = Helper.generateQrCodeId(); - QrCodeDto qrCodeDto = generateQrCode(qrCodeId); redisTemplate.opsForValue().set(String.format(RedisKey.USERLOGIN_QRCODEID, qrCodeId), "", 2, TimeUnit.MINUTES); - return Helper.successResult(qrCodeDto); + Map rsMap = new HashMap<>(); + rsMap.put("ONTAuthScanProtocol", paramsConfig.loginQrCodeUrl + qrCodeId); + rsMap.put("Id", qrCodeId); + return Helper.successResult(rsMap); + } + + @Override + public QrCodeDto queryQrCode(String qrCodeId) { + QrCodeDto qrCodeDto = generateQrCode(qrCodeId); + return qrCodeDto; } private QrCodeDto generateQrCode(String qrCodeId) { @@ -212,6 +218,9 @@ public ResponseBean addOrUpdateUserAddresses(List userAddressList, @Override public ResponseBean delUserAddress(String address, String ontId) { + if (address.length() != 34 || !address.startsWith("A")) { + return Helper.errorResult(ErrorInfo.ADDRESS_FORMAT_INCORRECT, false); + } UserAddress userAddress = UserAddress.builder() .ontId(ontId) .address(address) diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/util/ErrorInfo.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/util/ErrorInfo.java index 4e822b4c..f7d239e1 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/util/ErrorInfo.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/util/ErrorInfo.java @@ -104,6 +104,9 @@ public enum ErrorInfo { ADDRESS_ONTID_UNMATCH(61019,"Address unmatch ontid."), + ADDRESS_FORMAT_INCORRECT(61020,"Address format incorrect."), + + From 1959d4123231a69f70d43c82951fbeba4d5f9446 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Thu, 2 Apr 2020 16:43:19 +0800 Subject: [PATCH 29/40] resume email push logic --- .../com/github/ontio/txPush/TransferTransactionPush.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java index ddbdfa2f..1661cbad 100644 --- a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/TransferTransactionPush.java @@ -56,8 +56,8 @@ public TransferTransactionPush(UserAddressMapper userAddressMapper, EmailService @Override public void onEvent(DisruptorEvent disruptorEvent, long sequence, boolean endOfBatch) { - return; -/* Object event = disruptorEvent.getEvent(); + //return; + Object event = disruptorEvent.getEvent(); if(event instanceof TxDetail){ TxDetail txDetail = (TxDetail) event; log.info("{} disruptor consumer receive tx:{}", Thread.currentThread().getName(), JSONObject.toJSONString(txDetail)); @@ -79,7 +79,7 @@ public void onEvent(DisruptorEvent disruptorEvent, long sequence, boolean endOfB handleDepositTransferTx(txDetail, dto); }); } - }*/ + } } From 8a116f11c4f13be818b48c8e6a6fb10c38699f8d Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Thu, 2 Apr 2020 18:55:21 +0800 Subject: [PATCH 30/40] add param --- back-end-projects/Explorer/config/application.properties | 4 +++- .../src/main/java/com/github/ontio/config/ParamsConfig.java | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/back-end-projects/Explorer/config/application.properties b/back-end-projects/Explorer/config/application.properties index c8f2d251..f25e459a 100644 --- a/back-end-projects/Explorer/config/application.properties +++ b/back-end-projects/Explorer/config/application.properties @@ -77,4 +77,6 @@ identity.password = identity.salt = jwt.accessTokenExpireTime=120 -jwt.encryptJWTKey= \ No newline at end of file +jwt.encryptJWTKey= + +oneUser.address.count.limit=5 \ No newline at end of file diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java index f67f5e61..f9240eb9 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java @@ -156,4 +156,8 @@ public String getContractHash(String token) { @Value("${login.qrcode.url:https://explorer.ont.io/v2/users/login_qrcode/}") public String loginQrCodeUrl; + + @Value("${oneUser.address.count.limit") + public int oneUserAddressCountLimit; + } \ No newline at end of file From f394742650c7e812e407c46db03d9f2441cf0cb3 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Thu, 2 Apr 2020 18:57:29 +0800 Subject: [PATCH 31/40] add param validated --- .../github/ontio/controller/UserController.java | 16 ++++++++++------ .../java/com/github/ontio/model/dao/User.java | 2 ++ .../com/github/ontio/model/dao/UserAddress.java | 13 ++++++++++++- .../ontio/service/impl/UserServiceImpl.java | 2 +- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/controller/UserController.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/controller/UserController.java index 6d3d181b..a8dd64eb 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/controller/UserController.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/controller/UserController.java @@ -18,12 +18,15 @@ import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import javax.validation.constraints.Pattern; import java.util.List; /** @@ -35,6 +38,7 @@ @RestController @RequiredArgsConstructor @RequestMapping("/v2/users/") +@Validated public class UserController { private final String CLASS_NAME = this.getClass().getSimpleName(); @@ -84,7 +88,7 @@ public CallBackResponse userLogin(@RequestBody JSONObject jsonObject) { @ApiImplicitParams({@ApiImplicitParam(paramType = "header", dataType = "String", name = "ONT_EXP_TOKEN", value = "login token", required = true)}) @ApiOperation(value = "Query user addresses") @GetMapping(value = "/addresses") - public ResponseBean queryUserAddresses(@RequestParam("ont_id") String ontId) { + public ResponseBean queryUserAddresses(@RequestParam("ont_id") @Pattern(regexp = "did:ont:[A-Za-z0-9]{34}", message = "Incorrect ONT ID format") String ontId) { log.info("###{}.{} begin...ontId:{}", CLASS_NAME, Helper.currentMethod(), ontId); checkToken(ontId); ResponseBean rs = userService.queryUserAddresses(ontId); @@ -96,8 +100,8 @@ public ResponseBean queryUserAddresses(@RequestParam("ont_id") String ontId) { @ApiImplicitParams({@ApiImplicitParam(paramType = "header", dataType = "String", name = "ONT_EXP_TOKEN", value = "login token", required = true)}) @ApiOperation(value = "Add or Update user addresses") @PostMapping(value = "/addresses") - public ResponseBean addOrUpdateUserAddresses(@RequestParam("ont_id") String ontId, - @RequestBody List userAddresses) { + public ResponseBean addOrUpdateUserAddresses(@RequestParam("ont_id") @Pattern(regexp = "did:ont:[A-Za-z0-9]{34}", message = "Incorrect ONT ID format") String ontId, + @RequestBody @Valid List userAddresses) { log.info("###{}.{} begin...ontId:{}", CLASS_NAME, Helper.currentMethod(), ontId); checkToken(ontId); ResponseBean rs = userService.addOrUpdateUserAddresses(userAddresses, ontId); @@ -109,7 +113,7 @@ public ResponseBean addOrUpdateUserAddresses(@RequestParam("ont_id") String ontI @ApiImplicitParams({@ApiImplicitParam(paramType = "header", dataType = "String", name = "ONT_EXP_TOKEN", value = "login token", required = true)}) @ApiOperation(value = "Delete user address") @DeleteMapping(value = "/addresses") - public ResponseBean delUserAddress(@RequestParam("ont_id") String ontId, + public ResponseBean delUserAddress(@RequestParam("ont_id") @Pattern(regexp = "did:ont:[A-Za-z0-9]{34}", message = "Incorrect ONT ID format") String ontId, @RequestBody JSONObject jsonObject) { log.info("###{}.{} begin...ontId:{}", CLASS_NAME, Helper.currentMethod(), ontId); checkToken(ontId); @@ -122,8 +126,8 @@ public ResponseBean delUserAddress(@RequestParam("ont_id") String ontId, @ApiImplicitParams({@ApiImplicitParam(paramType = "header", dataType = "String", name = "ONT_EXP_TOKEN", value = "login token", required = true)}) @ApiOperation(value = "Update user information") @PostMapping - public ResponseBean updateUser(@RequestParam("ont_id") String ontId, - @RequestBody User user) { + public ResponseBean updateUser(@RequestParam("ont_id") @Pattern(regexp = "did:ont:[A-Za-z0-9]{34}", message = "Incorrect ONT ID format") String ontId, + @RequestBody @Validated User user) { log.info("###{}.{} begin...ontId:{}", CLASS_NAME, Helper.currentMethod(), ontId); checkToken(ontId); user.setOntId(ontId); diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/User.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/User.java index 8a3c9e63..922ac0cb 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/User.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/User.java @@ -10,6 +10,7 @@ import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; +import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; import java.util.Date; @@ -35,6 +36,7 @@ public class User { /** * 邮箱 */ + @NotEmpty @Pattern(regexp = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$", message = "email format error") private String email; diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/UserAddress.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/UserAddress.java index bab8fa74..06eb0a2f 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/UserAddress.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/model/dao/UserAddress.java @@ -4,7 +4,14 @@ import lombok.Builder; import lombok.NoArgsConstructor; -import javax.persistence.*; +import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Pattern; @Builder @AllArgsConstructor @@ -24,6 +31,8 @@ public class UserAddress { /** * 地址 */ + @NotEmpty + @Pattern(regexp = "A[A-Za-z0-9]{33}") private String address; /** @@ -34,6 +43,8 @@ public class UserAddress { /** * 监听策略。0:不监听 1:监听所有入金出金,2:只监听入金 3:只监听出金 */ + @Min(0) + @Max(3) private Integer strategy; /** diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java index b755aada..70ebf8e7 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java @@ -202,7 +202,7 @@ public ResponseBean queryUserAddresses(String ontId) { @Override public ResponseBean addOrUpdateUserAddresses(List userAddressList, String ontId) { - if (userAddressList.size() > 5) { + if (userAddressList.size() > paramsConfig.oneUserAddressCountLimit) { //normal response can refresh token return Helper.errorResult(ErrorInfo.ADDRESS_TOOMANY, false); } From 9a7861be57292e26c4b210e85c610297e2880edd Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Thu, 2 Apr 2020 19:08:23 +0800 Subject: [PATCH 32/40] queryLoginUserInfo api return normal response --- .../java/com/github/ontio/service/impl/UserServiceImpl.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java index 70ebf8e7..68cdbd3e 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/UserServiceImpl.java @@ -7,7 +7,6 @@ import com.github.ontio.core.asset.Sig; import com.github.ontio.core.transaction.Transaction; import com.github.ontio.crypto.Digest; -import com.github.ontio.exception.ExplorerException; import com.github.ontio.mapper.AddressBlacklistMapper; import com.github.ontio.mapper.UserAddressMapper; import com.github.ontio.mapper.UserMapper; @@ -119,9 +118,9 @@ private QrCodeDto generateQrCode(String qrCodeId) { public ResponseBean queryLoginUserInfo(String qrCodeId) { String token = redisTemplate.opsForValue().get(String.format(RedisKey.USERLOGIN_QRCODEID, qrCodeId)); if (token == null) { - throw new ExplorerException(ErrorInfo.QRCODE_EXPIRED); + return Helper.successResult(ErrorInfo.QRCODE_EXPIRED.code()); } else if ("".equals(token)) { - throw new ExplorerException(ErrorInfo.NO_LOGIN_USERINFO); + return Helper.successResult(ErrorInfo.NO_LOGIN_USERINFO.code()); } String ontId = JwtUtil.getClaim(token, ConstantParam.JWT_LOGINID).asString(); User user = userMapper.selectByPrimaryKey(ontId); From 17ef1b667a9de4a4829a0bafe31a37a4a3f95b8a Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Thu, 2 Apr 2020 19:12:04 +0800 Subject: [PATCH 33/40] tbl_oep5_tx_detail table add index --- .../resources/db/migration/V1.48__tbl_oep5_tx_detail_index.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 back-end-projects/Explorer/src/main/resources/db/migration/V1.48__tbl_oep5_tx_detail_index.sql diff --git a/back-end-projects/Explorer/src/main/resources/db/migration/V1.48__tbl_oep5_tx_detail_index.sql b/back-end-projects/Explorer/src/main/resources/db/migration/V1.48__tbl_oep5_tx_detail_index.sql new file mode 100644 index 00000000..7ffc4e31 --- /dev/null +++ b/back-end-projects/Explorer/src/main/resources/db/migration/V1.48__tbl_oep5_tx_detail_index.sql @@ -0,0 +1 @@ +CREATE INDEX idx_called_contract_hash_tx_hash ON tbl_oep5_tx_detail(`called_contract_hash`, `tx_hash`); From e2c0b705d39545f08eeac436a492b69158b7c23f Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Thu, 2 Apr 2020 19:27:35 +0800 Subject: [PATCH 34/40] fix param format bug --- .../src/main/java/com/github/ontio/config/ParamsConfig.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java index f9240eb9..827d0931 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/config/ParamsConfig.java @@ -157,7 +157,7 @@ public String getContractHash(String token) { public String loginQrCodeUrl; - @Value("${oneUser.address.count.limit") - public int oneUserAddressCountLimit; + @Value("${oneUser.address.count.limit}") + public Integer oneUserAddressCountLimit; } \ No newline at end of file From d4b46fe8cdc2edfc69c94fe66333b7b992317d2f Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Thu, 2 Apr 2020 19:27:50 +0800 Subject: [PATCH 35/40] add Access-Control-Allow-Headers --- .../com/github/ontio/SimpleCORSFilter.java | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/SimpleCORSFilter.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/SimpleCORSFilter.java index 7078e561..42c16153 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/SimpleCORSFilter.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/SimpleCORSFilter.java @@ -19,6 +19,7 @@ package com.github.ontio; +import com.github.ontio.util.ConstantParam; import org.springframework.stereotype.Component; import javax.servlet.*; @@ -29,26 +30,26 @@ @Component public class SimpleCORSFilter implements Filter { - public void doFilter(ServletRequest req, ServletResponse res, + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { - HttpServletResponse response = (HttpServletResponse) res; - HttpServletRequest request = (HttpServletRequest) req; - String origin = request.getHeader("Origin"); - response.setHeader("Access-Control-Allow-Origin", "*"); - response.setHeader("Access-Control-Allow-Credentials", "true"); - response.setHeader("Access-Control-Allow-Methods", - "POST, PUT, GET, OPTIONS, DELETE"); - response.setHeader("Access-Control-Max-Age", "3600"); - response.setHeader( - "Access-Control-Allow-Headers", - "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With"); - chain.doFilter(req, res); - } - - public void init(FilterConfig filterConfig) { - } - - public void destroy() { - } + HttpServletResponse response = (HttpServletResponse) res; + HttpServletRequest request = (HttpServletRequest) req; + String origin = request.getHeader("Origin"); + response.setHeader("Access-Control-Allow-Origin", "*"); + response.setHeader("Access-Control-Allow-Credentials", "true"); + response.setHeader("Access-Control-Allow-Methods", + "POST, PUT, GET, OPTIONS, DELETE"); + response.setHeader("Access-Control-Max-Age", "3600"); + response.setHeader( + "Access-Control-Allow-Headers", + "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With, " + ConstantParam.HTTPHEADER_TOKEN); + chain.doFilter(req, res); + } + + public void init(FilterConfig filterConfig) { + } + + public void destroy() { + } } \ No newline at end of file From 727e211e8064b9d0b9f049728faaa084348723d8 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Thu, 2 Apr 2020 20:14:27 +0800 Subject: [PATCH 36/40] add Access-Control-Expose-Headers --- .../src/main/java/com/github/ontio/SimpleCORSFilter.java | 3 ++- .../src/main/java/com/github/ontio/util/ConstantParam.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/SimpleCORSFilter.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/SimpleCORSFilter.java index 42c16153..52bf059c 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/SimpleCORSFilter.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/SimpleCORSFilter.java @@ -42,7 +42,8 @@ public void doFilter(ServletRequest req, ServletResponse res, response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader( "Access-Control-Allow-Headers", - "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With, " + ConstantParam.HTTPHEADER_TOKEN); + "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With"); + response.setHeader("Access-Control-Expose-Headers", ConstantParam.HTTPHEADER_TOKEN); chain.doFilter(req, res); } diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/util/ConstantParam.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/util/ConstantParam.java index a538fe2d..debc22f0 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/util/ConstantParam.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/util/ConstantParam.java @@ -172,7 +172,7 @@ public class ConstantParam { public static final String CONTRACTHASH_ONT = "0100000000000000000000000000000000000000"; - public static final String HTTPHEADER_TOKEN = "ONT_EXP_TOKEN"; + public static final String HTTPHEADER_TOKEN = "ont_exp_token"; public static final String JWT_LOGINID = "loginId"; From 44aeb9ba7dd4be429d56f198d5f60c0328baaa9f Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Thu, 2 Apr 2020 21:19:04 +0800 Subject: [PATCH 37/40] update Access-Control-Allow-Headers --- .../src/main/java/com/github/ontio/SimpleCORSFilter.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/SimpleCORSFilter.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/SimpleCORSFilter.java index 52bf059c..3a06d42f 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/SimpleCORSFilter.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/SimpleCORSFilter.java @@ -41,8 +41,7 @@ public void doFilter(ServletRequest req, ServletResponse res, "POST, PUT, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader( - "Access-Control-Allow-Headers", - "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With"); + "Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers")); response.setHeader("Access-Control-Expose-Headers", ConstantParam.HTTPHEADER_TOKEN); chain.doFilter(req, res); } From c193a1d4a4de190d044491cfa1afd126c54394f7 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Fri, 3 Apr 2020 11:34:50 +0800 Subject: [PATCH 38/40] update email template --- .../java/com/github/ontio/txPush/EmailService.java | 7 ++++--- .../com/github/ontio/txPush/model/PushEmailDto.java | 11 ++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/EmailService.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/EmailService.java index b28c7e82..d73d0242 100644 --- a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/EmailService.java +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/EmailService.java @@ -92,12 +92,13 @@ public void sendTransferTxInfoEmail(PushEmailDto pushEmailDto) { private String convertVerificationCode(PushEmailDto pushEmailDto) { JSONObject sub = new JSONObject(); + sub.put("%ontId%", Arrays.asList(pushEmailDto.getOntId())); sub.put("%address%", Arrays.asList(pushEmailDto.getUserAddress())); - sub.put("%des%", Arrays.asList(pushEmailDto.getTxDes())); + sub.put("%fromAddress%", Arrays.asList(pushEmailDto.getFromAddress())); sub.put("%hash%", Arrays.asList(pushEmailDto.getTxHash())); - sub.put("%assetname%", Arrays.asList(pushEmailDto.getAssetName())); + sub.put("%assetName%", Arrays.asList(pushEmailDto.getAssetName())); sub.put("%time%", Arrays.asList(pushEmailDto.getTime())); - sub.put("%taddress%", Arrays.asList(pushEmailDto.getTAddress())); + sub.put("%toAddress%", Arrays.asList(pushEmailDto.getToAddress())); sub.put("%amount%", Arrays.asList(pushEmailDto.getAmount())); JSONObject ret = new JSONObject(); diff --git a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushEmailDto.java b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushEmailDto.java index 4ee8f5c1..cd336418 100644 --- a/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushEmailDto.java +++ b/back-end-projects/OntSynHandler/src/main/java/com/github/ontio/txPush/model/PushEmailDto.java @@ -29,14 +29,15 @@ public class PushEmailDto { private String assetName; private String amount; private String time; - private String tAddress; + private String toAddress; + private String fromAddress; public static final String DEPOSIT = "deposit"; public static final String WITHDRAW = "withdraw"; - private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public static PushEmailDto buildDto(PushUserAddressInfoDto pushUserAddressInfoDto, TxDetail txDetail, String txDes) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); PushEmailDtoBuilder builder = PushEmailDto.builder() .email(pushUserAddressInfoDto.getEmail()) .userName(pushUserAddressInfoDto.getUserName()) @@ -44,15 +45,15 @@ public static PushEmailDto buildDto(PushUserAddressInfoDto pushUserAddressInfoDt .txHash(txDetail.getTxHash()) .amount(txDetail.getAmount().stripTrailingZeros().toPlainString()) .time(sdf.format(new Date(txDetail.getTxTime() * 1000L))) - .assetName(txDetail.getAssetName()); + .assetName(txDetail.getAssetName()) + .fromAddress(txDetail.getFromAddress()) + .toAddress(txDetail.getToAddress()); if (DEPOSIT.equals(txDes)) { return builder.userAddress(txDetail.getToAddress()) - .tAddress(txDetail.getFromAddress()) .txDes(DEPOSIT) .build(); } else { return builder.userAddress(txDetail.getFromAddress()) - .tAddress(txDetail.getToAddress()) .txDes(WITHDRAW) .build(); } From 855e96a32986ad952c8d76c618ed24bf7c233c61 Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Fri, 3 Apr 2020 14:36:20 +0800 Subject: [PATCH 39/40] order by tokenId --- .../java/com/github/ontio/service/impl/TokenServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/TokenServiceImpl.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/TokenServiceImpl.java index 4687c361..18bd9a7a 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/TokenServiceImpl.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/TokenServiceImpl.java @@ -218,7 +218,7 @@ public ResponseBean queryOepLogos(String contractHash, int pageSize, int pageNum Example example = new Example(OepLogo.class); example.and() .andEqualTo("contractHash", contractHash); - example.orderBy("createTime").desc(); + example.orderBy("tokenId").asc(); List oepLogos = oepLogoMapper.selectByExample(example); Long total = ((Page) oepLogos).getTotal(); PageResponseBean responseBean = new PageResponseBean(oepLogos, total.intValue()); From 8429a15383c51b60fe41d8610fbb112b8d4c9a5e Mon Sep 17 00:00:00 2001 From: zzsZhou <18217008370@163.com> Date: Fri, 3 Apr 2020 14:56:18 +0800 Subject: [PATCH 40/40] order by id desc --- .../java/com/github/ontio/service/impl/TokenServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/TokenServiceImpl.java b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/TokenServiceImpl.java index 18bd9a7a..30654914 100644 --- a/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/TokenServiceImpl.java +++ b/back-end-projects/Explorer/src/main/java/com/github/ontio/service/impl/TokenServiceImpl.java @@ -218,7 +218,7 @@ public ResponseBean queryOepLogos(String contractHash, int pageSize, int pageNum Example example = new Example(OepLogo.class); example.and() .andEqualTo("contractHash", contractHash); - example.orderBy("tokenId").asc(); + example.orderBy("id").desc(); List oepLogos = oepLogoMapper.selectByExample(example); Long total = ((Page) oepLogos).getTotal(); PageResponseBean responseBean = new PageResponseBean(oepLogos, total.intValue());