xiaoyong931011
2020-11-20 4c4d1e52ee25f9d77c132144521df6694cd8e63e
20201120
23 files added
7 files modified
2069 ■■■■■ changed files
src/main/java/com/xcong/excoin/common/contants/WalletConstants.java 16 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/common/system/controller/LoginController.java 24 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/common/system/dao/WalletDetailDao.java 36 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/common/system/dao/WtTokenDao.java 28 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/common/system/dao/WtWalletDao.java 39 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/common/system/dao/WtWordDao.java 10 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/common/system/dto/OutCenterRegisterDto.java 20 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/common/system/entity/WtBlock.java 68 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/common/system/entity/WtToken.java 57 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/common/system/entity/WtWallet.java 51 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/common/system/entity/WtWalletDetail.java 53 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/common/system/vo/LoginVo.java 26 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/configurations/security/TokenFilter.java 39 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/member/entity/MemberEntity.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/member/service/MemberService.java 7 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/member/service/impl/MemberServiceImpl.java 355 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/utils/AddressRsaUtil.java 19 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/utils/DES.java 48 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/utils/DESUtil.java 71 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/utils/MD5Util.java 55 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/utils/RSAUtils.java 234 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/utils/ToolUtil.java 362 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/utils/UUIDUtil.java 20 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/utils/WordsUtil.java 11 ●●●●● patch | view | raw | blame | history
src/main/resources/i18n/messages_en_US.properties 4 ●●●● patch | view | raw | blame | history
src/main/resources/i18n/messages_zh_CN.properties 5 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/member/WalletDetailDao.xml 135 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/member/WtTokenDao.xml 117 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/member/WtWalletMapper.xml 146 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/member/WtWordDao.xml 9 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/common/contants/WalletConstants.java
New file
@@ -0,0 +1,16 @@
package com.xcong.excoin.common.contants;
public class WalletConstants {
    public static final String ADDRESS_PREFIX =  "ROC";
    /**
     *  是否是主币
     */
    public static final Integer IS_MAIN = 1;
    /**
     *  是否是本位币
     */
    public static final Integer IS_MAIN_BASIC = -1;
}
src/main/java/com/xcong/excoin/common/system/controller/LoginController.java
@@ -15,13 +15,19 @@
import com.xcong.excoin.common.response.Result;
import com.xcong.excoin.common.system.bean.LoginUserBean;
import com.xcong.excoin.common.system.dto.LoginDto;
import com.xcong.excoin.common.system.dto.OutCenterRegisterDto;
import com.xcong.excoin.common.system.dto.RegisterDto;
import com.xcong.excoin.common.system.entity.WtWallet;
import com.xcong.excoin.common.system.vo.LoginVo;
import com.xcong.excoin.configurations.properties.ApplicationProperties;
import com.xcong.excoin.configurations.properties.SecurityProperties;
import com.xcong.excoin.modules.member.service.MemberService;
import com.xcong.excoin.utils.RedisUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@@ -117,5 +123,23 @@
    public Result register(@RequestBody @Validated RegisterDto registerDto) {
        return memberservice.register(registerDto);
    }
    @ApiOperation(value = "创建接口", notes = "创建接口")
    @PostMapping(value = "/registerOutCenter")
    @ApiResponses({
        @ApiResponse(code = 200,message = "OK",response = LoginVo.class),
    })
    public Result registerOutCenter(@RequestBody @Validated OutCenterRegisterDto outCenterRegisterDto) {
        return memberservice.registerOutCenter(outCenterRegisterDto);
    }
    @ApiOperation(value = "导入接口", notes = "导入接口")
    @PostMapping(value = "/loginOutCenter")
    @ApiResponses({
        @ApiResponse(code = 200,message = "OK",response = LoginVo.class),
    })
    public Result recovery(@RequestBody WtWallet wallet) {
        return memberservice.recovery(wallet);
    }
}
src/main/java/com/xcong/excoin/common/system/dao/WalletDetailDao.java
New file
@@ -0,0 +1,36 @@
package com.xcong.excoin.common.system.dao;
import java.math.BigDecimal;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import com.xcong.excoin.common.system.entity.WtWalletDetail;
/**
 * @description 钱包表
 * @author admin
 * @date 2020-09-17 14:31
 */
@Mapper
public interface WalletDetailDao {
     int insert(@Param("item") WtWalletDetail wtWalletDetail);
       int batchInsert(@Param("list") List<WtWalletDetail> wtWalletDetailList);
     int updateByModel(@Param("record") WtWalletDetail wtWalletDetail);
     int deleteByIds(@Param("list") List<String> list);
     int deleteById(String id);
     List<WtWalletDetail> selectByModel( WtWalletDetail wtWalletDetail);
     WtWalletDetail  selectById(String id);
    WtWalletDetail selectByAddressAndSymbol(@Param("address")String address,@Param("symbol")String symbol);
    void updateWalletBalance(@Param("id") Long id, @Param("balance") BigDecimal balance);
}
src/main/java/com/xcong/excoin/common/system/dao/WtTokenDao.java
New file
@@ -0,0 +1,28 @@
package com.xcong.excoin.common.system.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import com.xcong.excoin.common.system.entity.WtToken;
@Mapper
public interface WtTokenDao {
     int insert(@Param("item") WtToken wtToken);
       int batchInsert(@Param("list") List<WtToken> wtTokenList);
     int updateByModel(@Param("record") WtToken wtToken);
     int deleteById(Integer id);
     WtToken  selectById(Integer id);
     WtToken  selectBySymbol(String symbol);
     List<WtToken>  selectAllToken();
     WtToken  selectMainToken();
}
src/main/java/com/xcong/excoin/common/system/dao/WtWalletDao.java
New file
@@ -0,0 +1,39 @@
package com.xcong.excoin.common.system.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import com.xcong.excoin.common.system.entity.WtWallet;
@Mapper
public interface WtWalletDao {
     int insert(@Param("item") WtWallet wtWallet);
       int batchInsert(@Param("list") List<WtWallet> wtWalletList);
     int updateByModel(@Param("record") WtWallet wtWallet);
     int deleteByIds(@Param("list") List<String> list);
     int deleteById(String address);
     int clearTerminalId(String address);
     int deleteTerminal(String terminalId);
     WtWallet  selectById(String address);
    /**
     * 只有name信息
     * @param address
     * @return
     */
    WtWallet  selectSimpleById(String address);
    WtWallet  selectSimpleByTerminalId(String terminalId);
    WtWallet selectByMnemonicWords(String mnemonicWords);
}
src/main/java/com/xcong/excoin/common/system/dao/WtWordDao.java
New file
@@ -0,0 +1,10 @@
package com.xcong.excoin.common.system.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface WtWordDao {
    List<String> selectAllWords();
}
src/main/java/com/xcong/excoin/common/system/dto/OutCenterRegisterDto.java
New file
@@ -0,0 +1,20 @@
package com.xcong.excoin.common.system.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "OutCenterRegisterDto", description = "注册接口参数类")
public class OutCenterRegisterDto {
    @ApiModelProperty(value = "推荐人Uid", example = "rxadr3")
    private String refererId;
    @ApiModelProperty(value = "资金交易密码", example = "1qazwsx")
    private String password;
    @ApiModelProperty(value = "钱包名称", example = "qwer")
    private String walletName;
    @ApiModelProperty(value = "终端ID", example = "21220sdsf")
    private String terminalId;
}
src/main/java/com/xcong/excoin/common/system/entity/WtBlock.java
New file
@@ -0,0 +1,68 @@
package com.xcong.excoin.common.system.entity;
import java.math.BigDecimal;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
 * @description 区块信息表
 * @author admin
 * @date 2020-09-17 14:31
 */
@Data
@TableName("wt_block")
public class WtBlock {
    /**
     * 主键
     */
    private String  id;
    /**
     * 区块高度
     */
    private Long  block;
    /**
     * 累计交易
     */
    private Long  totalTransaction;
    /**
     * 更新时间
     */
    private Date updateTime;
    /**
     * 流通总量
     */
    private BigDecimal totalAmount;
    /**
     * 持币地址数
     */
    private Integer  holdCount;
    /**
     * 平均出块速度
     */
    private Integer  blockAvg;
    /**
     * 超级节点
     */
    private Integer  superNode;
}
src/main/java/com/xcong/excoin/common/system/entity/WtToken.java
New file
@@ -0,0 +1,57 @@
package com.xcong.excoin.common.system.entity;
import java.math.BigDecimal;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
/**
 * @description 代币表
 * @author admin
 * @date 2020-09-17 14:31
 */
@Data
@TableName("wt_token")
public class WtToken {
    /**
     * 主键
     */
    private Integer  id;
    /**
     * 币种:NEK,MUSD
     */
    private String  symbol;
    /**
     * USDT汇率
     */
    private BigDecimal price;
    /**
     * 是否主币(0:否 1:是)
     */
    private Integer  main;
    /**
     *  手续费(按主币收取)
     */
    private BigDecimal fee;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;
    private BigDecimal amount;
    private String contractAddress;
    private String symbolName;
}
src/main/java/com/xcong/excoin/common/system/entity/WtWallet.java
New file
@@ -0,0 +1,51 @@
package com.xcong.excoin.common.system.entity;
import java.util.List;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("wt_wallet")
public class WtWallet {
    /**
     * 主键
     */
    private String  address;
    /**
     * 私钥
     */
    private String  privateKey;
    /**
     * 助记词 12个单词逗号隔开
     */
    private String  mnemonicWords;
    /**
     * 密码:通过助记词导入后重置
     */
    private String  password;
    /**
     * 钱包名称
     */
    private String  walletName;
    /**
     * 终端ID
     */
    private String  terminalId;
    @TableField(exist = false)
    private List<String> mnemonicWordList;
}
src/main/java/com/xcong/excoin/common/system/entity/WtWalletDetail.java
New file
@@ -0,0 +1,53 @@
package com.xcong.excoin.common.system.entity;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
 * @description 钱包表
 * @author admin
 * @date 2020-09-17 14:31
 */
@Data
@TableName("wt_wallet_detail")
public class WtWalletDetail {
    /**
     * 主键
     */
    private Long  id;
    /**
     * 主地址
     */
    private String  address;
    /**
     * 币种
     */
    private String  symbol;
    /**
     * 余额
     */
    private BigDecimal balance;
    /**
     * 主钱包 0:否 1:是
     */
    private Integer main;
    /**
     * 是否显示 0显示 1不显示
     */
    private Integer isShow;
}
src/main/java/com/xcong/excoin/common/system/vo/LoginVo.java
New file
@@ -0,0 +1,26 @@
package com.xcong.excoin.common.system.vo;
import java.util.List;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "LoginVo", description = "注册返回")
public class LoginVo {
    @ApiModelProperty(value = "助记词")
    private List<String> mnemonicWordList;
    @ApiModelProperty(value = "地址")
    /**
     * 主键
     */
    private String  address;
    @ApiModelProperty(value = "地址MD5")
    private String  addressMd;
}
src/main/java/com/xcong/excoin/configurations/security/TokenFilter.java
@@ -55,9 +55,9 @@
                String redisKey = "";
                // 根据user-agent判断pc端还是app端
                if (LoginUserUtils.isBrowser(request)) {
                    redisKey = AppContants.PC_LOGIN_PREFIX + token;
                    redisKey = token;
                } else {
                    redisKey = AppContants.APP_LOGIN_PREFIX + token;
                    redisKey = token;
                }
                String loginStr = (String) redisUtils.get(redisKey);
@@ -65,7 +65,6 @@
                    MemberEntity loginUser = JSONObject.parseObject(loginStr, MemberEntity.class);
                    Authentication authentication = new UsernamePasswordAuthenticationToken(loginUser, token, new ArrayList<>());
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                    redisUtils.expire(redisKey, 36000);
                } else {
                    log.info("token无法查询:{}", token);
                    SecurityContextHolder.clearContext();
@@ -80,6 +79,40 @@
        }
        filterChain.doFilter(servletRequest, servletResponse);
    }
    /**
     * 解析前端传来的token,md5加密后的地址_/api_设备iD
     *
     * @param request
     * @return
     */
    private String resolveTokenOutCenter(HttpServletRequest request) {
        try {
            String bearerToken = request.getHeader(AppContants.TOKEN_HEADER);
            //获取请求的完整路径
            StringBuffer requestURL = request.getRequestURL();
            if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(AppContants.TOKEN_START_WITH)) {
                // 去掉令牌前缀
                String rsaToken = bearerToken.replace(AppContants.TOKEN_START_WITH, "");
                RSA rsa = new RSA(securityProperties.getPrivateKey(), null);
                String[] tokens = StrUtil.split(rsa.decryptStr(rsaToken, KeyType.PrivateKey), "_");
                if (StrUtil.isNotEmpty(requestURL) && requestURL.toString().contains(tokens[1])) {
                    return tokens[0];
                } else {
//                    log.info("前面token为{}", tokens[0]);
//                    log.info("时间为:{}, 当前时间为:{}", tokens[1], System.currentTimeMillis());
                    return AppContants.TIME_OUT;
                }
            }
//            log.info("bearerToken---->{}", bearerToken);
        } catch (Exception e) {
            log.error("#解析token异常#", e);
            return null;
        }
        return null;
    }
    /**
     * 解析前端传来的token,先去掉Bearer,在rsa解密得到token_time,返回token,并判断time与当前是否在5s内
src/main/java/com/xcong/excoin/modules/member/entity/MemberEntity.java
@@ -94,6 +94,10 @@
     * 交易密码
     */
    private String tradePassword;
    /**
     * 钱包地址
     */
    private String address;
    /**
     * 交易密码时效性设置
src/main/java/com/xcong/excoin/modules/member/service/MemberService.java
@@ -4,7 +4,9 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.xcong.excoin.common.response.Result;
import com.xcong.excoin.common.system.dto.OutCenterRegisterDto;
import com.xcong.excoin.common.system.dto.RegisterDto;
import com.xcong.excoin.common.system.entity.WtWallet;
import com.xcong.excoin.modules.member.entity.MemberEntity;
import com.xcong.excoin.modules.member.parameter.dto.MemberAddCoinAddressDto;
import com.xcong.excoin.modules.member.parameter.dto.MemberAuthenticationDto;
@@ -90,5 +92,10 @@
    public Result getPcVersionInfo();
    public Result registerOutCenter(OutCenterRegisterDto outCenterRegisterDto);
    public Result recovery(WtWallet wallet);
}
src/main/java/com/xcong/excoin/modules/member/service/impl/MemberServiceImpl.java
@@ -5,14 +5,27 @@
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xcong.excoin.common.LoginUserUtils;
import com.xcong.excoin.common.contants.AppContants;
import com.xcong.excoin.common.contants.WalletConstants;
import com.xcong.excoin.common.enumerates.CoinTypeEnum;
import com.xcong.excoin.common.enumerates.SymbolEnum;
import com.xcong.excoin.common.response.Result;
import com.xcong.excoin.common.system.dao.WalletDetailDao;
import com.xcong.excoin.common.system.dao.WtTokenDao;
import com.xcong.excoin.common.system.dao.WtWalletDao;
import com.xcong.excoin.common.system.dao.WtWordDao;
import com.xcong.excoin.common.system.dto.OutCenterRegisterDto;
import com.xcong.excoin.common.system.dto.RegisterDto;
import com.xcong.excoin.common.system.entity.WtToken;
import com.xcong.excoin.common.system.entity.WtWallet;
import com.xcong.excoin.common.system.entity.WtWalletDetail;
import com.xcong.excoin.common.system.service.CommonService;
import com.xcong.excoin.common.system.vo.LoginVo;
import com.xcong.excoin.modules.coin.dao.MemberAccountMoneyChangeDao;
import com.xcong.excoin.modules.coin.entity.MemberAccountMoneyChange;
import com.xcong.excoin.modules.member.dao.*;
@@ -35,12 +48,18 @@
import com.xcong.excoin.modules.platform.dao.PlatformSymbolsCoinDao;
import com.xcong.excoin.modules.platform.entity.PlatformFeeSettingEntity;
import com.xcong.excoin.modules.platform.entity.PlatformSymbolsCoinEntity;
import com.xcong.excoin.utils.MD5Util;
import com.xcong.excoin.utils.MessageSourceUtils;
import com.xcong.excoin.utils.RedisUtils;
import com.xcong.excoin.utils.ShareCodeUtil;
import com.xcong.excoin.utils.ThreadPoolUtils;
import com.xcong.excoin.utils.ToolUtil;
import com.xcong.excoin.utils.UUIDUtil;
import com.xcong.excoin.utils.WordsUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
@@ -51,6 +70,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.annotation.Resource;
import javax.validation.Valid;
@@ -112,7 +132,18 @@
    @Resource
    private MemberWalletContractSimulateDao memberWalletContractSimulateDao;
    @Resource
    private WtWalletDao wtWalletDao;
    @Resource
    private WtWordDao wtWordDao;
    @Resource
    private WtTokenDao wtTokenDao;
    @Resource
    private WalletDetailDao walletDetailDao;
    @Transactional()
    @Override
    public Result register(RegisterDto registerDto) {
@@ -1020,6 +1051,330 @@
        }
        return Result.ok(arrayList);
    }
    @Transactional()
    @Override
    public Result registerOutCenter(OutCenterRegisterDto outCenterRegisterDto) {
        LoginVo loginVo = new LoginVo();
        log.info("钱包初始化");
        /**
         * 钱包初始化
         */
        // 创建钱包需要先清除这个设备之前的钱包
        //wtWalletDao.deleteTerminal(outCenterRegisterDto.getTerminalId());
        WtWallet wtWallet = new WtWallet();
        wtWallet.setWalletName(outCenterRegisterDto.getWalletName());
        wtWallet.setTerminalId(outCenterRegisterDto.getTerminalId());
        wtWallet.setPassword(MD5Util.strToMD5(outCenterRegisterDto.getPassword()));
        // 校验钱包名和密码
        // 得到助记词
        List<String> words = getWords();
        wtWallet.setMnemonicWordList(words);
        loginVo.setMnemonicWordList(words);
        if(CollectionUtils.isEmpty(words)){
            // 报错 不能生成钱包
            return Result.fail(MessageSourceUtils.getString("login_init"));
        }
        // 创建钱包
       // 生成钱包地址和私钥 34 52   42 64
        // 公链钱包地址36位  私钥 46
        String randomID = UUIDUtil.getRandomID();
        String address = WalletConstants.ADDRESS_PREFIX+randomID;
        String privateKey = (UUIDUtil.getRandomID()+UUIDUtil.getRandomID()).substring(0,46);
        wtWallet.setAddress(address);
        loginVo.setAddress(address);
        String strToMD5 = MD5Util.strToMD5(address);
        loginVo.setAddressMd(strToMD5);
        wtWallet.setPrivateKey(privateKey);
        wtWallet.setMnemonicWords(ToolUtil.listToString(words,","));
        wtWalletDao.insert(wtWallet);
        // 同时需要创建各个token
        List<WtToken> wtTokens = wtTokenDao.selectAllToken();
        List<WtWalletDetail> wtWalletDetails = new ArrayList<>();
        WtWalletDetail wtWalletDetail = null;
        if(CollectionUtils.isNotEmpty(wtTokens)){
            for(WtToken token : wtTokens){
                wtWalletDetail = new WtWalletDetail();
                String symbol = token.getSymbol();
                wtWalletDetail.setAddress(address);
                wtWalletDetail.setBalance(BigDecimal.ZERO);
                wtWalletDetail.setSymbol(symbol);
                wtWalletDetail.setMain(token.getMain());
                wtWalletDetail.setIsShow(0);
                wtWalletDetails.add(wtWalletDetail);
            }
            walletDetailDao.batchInsert(wtWalletDetails);
        }
        // 置空敏感信息
        wtWallet.setTerminalId(null);
        wtWallet.setPassword(null);
        wtWallet.setPrivateKey(null);
        // 查询是否存在该账号用户
//        MemberEntity member = memberDao.selectMemberInfoByAccount(registerDto.getAccount());
//        if (member != null) {
//            return Result.fail("账号已存在");
//        }
//        boolean isTrue = commonservice.verifyCode(registerDto.getAccount(), registerDto.getCode());
//        if (!isTrue) {
//            return Result.fail(MessageSourceUtils.getString("common_verify_code"));
//        }
        log.info("用户初始化");
        /**
         * 用户初始化
         */
        MemberEntity member = new MemberEntity();
        member.setAddress(address);
        member.setPassword(SecureUtil.md5(outCenterRegisterDto.getPassword()));
        member.setTradePassword(SecureUtil.md5(outCenterRegisterDto.getPassword()));
        // 判断账号类型
//        if (MemberEntity.ACCOUNT_TYPE_PHONE.equals(registerDto.getType())) {
//            member.setPhone(registerDto.getAccount());
//        } else if (MemberEntity.ACCOUNT_TYPE_EMAIL.equals(registerDto.getType())) {
//            member.setEmail(registerDto.getAccount());
//        } else {
//            return Result.fail("账号类型错误");
//        }
        // 判断是否拥有推荐人,若为空则默认系统
//        if (StrUtil.isBlank(registerDto.getRefererId())) {
//            registerDto.setRefererId(AppContants.SYSTEM_REFERER);
//        }
//        if (!AppContants.SYSTEM_REFERER.equals(outCenterRegisterDto.getRefererId())) {
//            MemberEntity isExist = memberDao.selectMemberInfoByInviteId(outCenterRegisterDto.getRefererId());
//            if (isExist != null) {
//                member.setRefererId(outCenterRegisterDto.getRefererId());
//            }
//        }
        member.setAccountStatus(MemberEntity.ACCOUNT_STATUS_ENABLE);
        member.setAccountType(MemberEntity.ACCOUNT_TYPE_NORMAL);
        member.setAgentLevel(MemberEntity.ACCOUNT_AGENT_LEVEL);
        member.setCertifyStatus(MemberEntity.CERTIFY_STATUS_UN_SUBMIT);
        member.setIsForce(1);
        member.setIsProfit(0);
        memberDao.insert(member);
        MemberSettingEntity memberSettingEntity = new MemberSettingEntity();
        memberSettingEntity.setSpread(BigDecimal.ONE);
        memberSettingEntity.setClosingSpread(BigDecimal.valueOf(5));
        memberSettingEntity.setForceParam(BigDecimal.valueOf(0.0030));
        memberSettingEntity.setMemberId(member.getId());
        memberSettingDao.insert(memberSettingEntity);
        String inviteId = ShareCodeUtil.toSerialCode(member.getId());
        member.setInviteId(inviteId);
//        boolean flag = false;
//        String parentId = member.getRefererId();
//        String ids = "";
//        while (!flag && StringUtils.isNotBlank(parentId)) {
//            ids += ("," + parentId);
//            MemberEntity parentMember = memberDao.selectMemberInfoByInviteId(parentId);
//            if (parentMember == null) {
//                break;
//            }
//            parentId = parentMember.getRefererId();
//            if(StringUtils.isBlank(parentId)){
//                break;
//            }
//            if (parentMember.getRefererId().equals(parentMember.getInviteId())) {
//                flag = true;
//            }
//        }
//        member.setRefererIds(ids);
        memberDao.updateById(member);
        //初始化合约钱包
        MemberWalletContractEntity walletContract = new MemberWalletContractEntity();
        walletContract.setMemberId(member.getId());
        walletContract.setAvailableBalance(AppContants.INIT_MONEY);
        walletContract.setFrozenBalance(AppContants.INIT_MONEY);
        walletContract.setTotalBalance(AppContants.INIT_MONEY);
        walletContract.setBorrowedFund(AppContants.INIT_MONEY);
        walletContract.setWalletCode(CoinTypeEnum.USDT.name());
        memberWalletContractDao.insert(walletContract);
        MemberWalletContractSimulateEntity walletContractSimulate = new MemberWalletContractSimulateEntity();
        walletContractSimulate.setMemberId(member.getId());
        walletContractSimulate.setAvailableBalance(new BigDecimal(AppContants.INIT_SIMULATE_MONEY));
        walletContractSimulate.setTotalBalance(new BigDecimal(AppContants.INIT_SIMULATE_MONEY));
        walletContractSimulate.setFrozenBalance(AppContants.INIT_MONEY);
        walletContractSimulate.setBorrowedFund(AppContants.INIT_MONEY);
        walletContractSimulate.setWalletCode(CoinTypeEnum.USDT.name());
        memberWalletContractSimulateDao.insert(walletContractSimulate);
        // 初始化币币钱包
        for (CoinTypeEnum coinTypeEnum : CoinTypeEnum.values()) {
            MemberWalletCoinEntity walletCoin = new MemberWalletCoinEntity();
            walletCoin.setWalletCode(coinTypeEnum.name());
            walletCoin.setMemberId(member.getId());
            walletCoin.setAvailableBalance(AppContants.INIT_MONEY);
            walletCoin.setFrozenBalance(AppContants.INIT_MONEY);
            walletCoin.setTotalBalance(AppContants.INIT_MONEY);
            walletCoin.setBorrowedFund(AppContants.INIT_MONEY);
            memberWalletCoinDao.insert(walletCoin);
        }
        // 初始化代理佣金钱包
        MemberWalletAgentEntity walletAgent = new MemberWalletAgentEntity();
        walletAgent.setMemberId(member.getId());
        walletAgent.setWalletCode(CoinTypeEnum.USDT.name());
        memberWalletAgentDao.insert(walletAgent);
        // 初始化杠杆
        for (SymbolEnum symbolEnum : SymbolEnum.values()) {
            MemberLevelRateEntity levelRate = new MemberLevelRateEntity();
            levelRate.setMemberId(member.getId());
            levelRate.setSymbol(symbolEnum.getValue());
            memberLevelRateDao.insert(levelRate);
        }
        //加密地址为key,member为value
        redisUtils.set(strToMD5, JSONObject.toJSONString(member));
        return Result.ok(loginVo);
    }
    public  List<String> getWords(){
        if(CollectionUtils.isEmpty(WordsUtil.words_list)){
            WordsUtil.words_list = wtWordDao.selectAllWords();
        }
        // 随机得12个单词
        if(CollectionUtils.isEmpty(WordsUtil.words_list)){
            throw new RuntimeException("error");
        }
        int size = WordsUtil.words_list.size();
        Random random = new Random();
        // 获得12个单词
        List<String> zjc = new ArrayList<>(12);
        boolean loop = true;
        while (loop){
            int randInt = random.nextInt(size - 1);
            // 根据得到的随机数去取
            String s = WordsUtil.words_list.get(randInt);
            if(!zjc.contains(s)){
                zjc.add(s);
            }
            if(zjc.size()>=12){
                loop = false;
            }
        }
        return zjc;
    }
    @Transactional
    @Override
    public Result recovery(WtWallet wallet) {
        LoginVo loginVo = new LoginVo();
        /**
         * 判断钱包是否存在
         */
        List<String> mnemonicWordList = wallet.getMnemonicWordList();
        if(CollectionUtils.isEmpty(mnemonicWordList)){
            return Result.fail(MessageSourceUtils.getString("login_recovery_001"));
        }
        String mnemonicWords = ToolUtil.listToString(mnemonicWordList, ",");
        WtWallet wtWallet = wtWalletDao.selectByMnemonicWords(mnemonicWords);
        if(wtWallet==null){
            return Result.fail(MessageSourceUtils.getString("login_recovery_002"));
        }
        /**
         * 通过地址获取该用户是否存在
         */
        String address = wtWallet.getAddress();
        String strToMD5 = MD5Util.strToMD5(address);
        loginVo.setAddress(address);
        loginVo.setAddressMd(strToMD5);
        Wrapper<MemberEntity> queryWrapperOrepool = new QueryWrapper<>();
        ((QueryWrapper<MemberEntity>) queryWrapperOrepool).eq("address", address);
        MemberEntity memberEntity = memberDao.selectOne(queryWrapperOrepool);
        if(ObjectUtil.isEmpty(memberEntity)) {
            log.info("用户初始化");
            /**
             * 用户初始化
             */
            MemberEntity member = new MemberEntity();
            member.setAddress(address);
            member.setPassword(MD5Util.strToMD5(wallet.getPassword()));
            member.setTradePassword(MD5Util.strToMD5(wallet.getPassword()));
            member.setAccountStatus(MemberEntity.ACCOUNT_STATUS_ENABLE);
            member.setAccountType(MemberEntity.ACCOUNT_TYPE_NORMAL);
            member.setAgentLevel(MemberEntity.ACCOUNT_AGENT_LEVEL);
            member.setCertifyStatus(MemberEntity.CERTIFY_STATUS_UN_SUBMIT);
            member.setIsForce(1);
            member.setIsProfit(0);
            memberDao.insert(member);
            MemberSettingEntity memberSettingEntity = new MemberSettingEntity();
            memberSettingEntity.setSpread(BigDecimal.ONE);
            memberSettingEntity.setClosingSpread(BigDecimal.valueOf(5));
            memberSettingEntity.setForceParam(BigDecimal.valueOf(0.0030));
            memberSettingEntity.setMemberId(member.getId());
            memberSettingDao.insert(memberSettingEntity);
            String inviteId = ShareCodeUtil.toSerialCode(member.getId());
            member.setInviteId(inviteId);
            memberDao.updateById(member);
            //初始化合约钱包
            MemberWalletContractEntity walletContract = new MemberWalletContractEntity();
            walletContract.setMemberId(member.getId());
            walletContract.setAvailableBalance(AppContants.INIT_MONEY);
            walletContract.setFrozenBalance(AppContants.INIT_MONEY);
            walletContract.setTotalBalance(AppContants.INIT_MONEY);
            walletContract.setBorrowedFund(AppContants.INIT_MONEY);
            walletContract.setWalletCode(CoinTypeEnum.USDT.name());
            memberWalletContractDao.insert(walletContract);
            MemberWalletContractSimulateEntity walletContractSimulate = new MemberWalletContractSimulateEntity();
            walletContractSimulate.setMemberId(member.getId());
            walletContractSimulate.setAvailableBalance(new BigDecimal(AppContants.INIT_SIMULATE_MONEY));
            walletContractSimulate.setTotalBalance(new BigDecimal(AppContants.INIT_SIMULATE_MONEY));
            walletContractSimulate.setFrozenBalance(AppContants.INIT_MONEY);
            walletContractSimulate.setBorrowedFund(AppContants.INIT_MONEY);
            walletContractSimulate.setWalletCode(CoinTypeEnum.USDT.name());
            memberWalletContractSimulateDao.insert(walletContractSimulate);
            // 初始化币币钱包
            for (CoinTypeEnum coinTypeEnum : CoinTypeEnum.values()) {
                MemberWalletCoinEntity walletCoin = new MemberWalletCoinEntity();
                walletCoin.setWalletCode(coinTypeEnum.name());
                walletCoin.setMemberId(member.getId());
                walletCoin.setAvailableBalance(AppContants.INIT_MONEY);
                walletCoin.setFrozenBalance(AppContants.INIT_MONEY);
                walletCoin.setTotalBalance(AppContants.INIT_MONEY);
                walletCoin.setBorrowedFund(AppContants.INIT_MONEY);
                memberWalletCoinDao.insert(walletCoin);
            }
            // 初始化代理佣金钱包
            MemberWalletAgentEntity walletAgent = new MemberWalletAgentEntity();
            walletAgent.setMemberId(member.getId());
            walletAgent.setWalletCode(CoinTypeEnum.USDT.name());
            memberWalletAgentDao.insert(walletAgent);
            // 初始化杠杆
            for (SymbolEnum symbolEnum : SymbolEnum.values()) {
                MemberLevelRateEntity levelRate = new MemberLevelRateEntity();
                levelRate.setMemberId(member.getId());
                levelRate.setSymbol(symbolEnum.getValue());
                memberLevelRateDao.insert(levelRate);
            }
            //加密地址为key,member为value
            redisUtils.set(strToMD5, JSONObject.toJSONString(member));
        }else {
            redisUtils.set(strToMD5, JSONObject.toJSONString(memberEntity));
        }
        return Result.ok(loginVo);
    }
}
src/main/java/com/xcong/excoin/utils/AddressRsaUtil.java
New file
@@ -0,0 +1,19 @@
package com.xcong.excoin.utils;
public class AddressRsaUtil {
    public final static String private_key = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJPg33yoN16c8Lfl7KpQ8N87R6c3HLpOZ/4Se1+xTNK3c+a6RL3VzpVqKF0zFax6O+MDzOK+PiYPD3K4+KjleSKckO3cm5kDRmjgEkpiEeMwYVrpdixyXCzlkt1bLVauj89GNLWwaydiqVypkXoLnqpcmomnjPFbq7e28AEWBHdTAgMBAAECgYBDlFrN3xoetN4VTJARbZgGjFK8iiUoxzgjFlMnciFHkur2oF1V2+XixnbX0Maw4dOIdW4mmQZR4kQPC5Unqmbmxf+TOcoHY42o3T4a2DIeG6LSlB3/AZ+z+Ht3xs8TcSkHeWzk5GRfgDFkLIeZmT9FCjctLDZmXd4/eitals03YQJBANJ6ZuSSP2iY4WDlC+4PlQysMRFsDw+y2PMV6du9ssTjtk+LOxD/xiHU5n6pnr40ylzbpEuNi8EBphlObS+glrsCQQCz3H7sKWkUMshQXKXpFeTIvIM1mK3GPBODlForQJM+NCtnwqyu9xl7oTCoy97rWSuqpOZA58z1jdVM6vX02rRJAkEAjpq16fmYkpK6aP7m9VWDZAGqgSZYkgdX7GMVfndpjvLFi+FGlL7nC/cGcB0WW8LCtOVvzGzLmmo2koDLg3BnjwJARc6ihE5eNjSvgmEzE5Anx7FCy56Cc5oFiOAfTwI1I8NjxVXNZ+sHvPAGzryxvG5TgFuX8kEFT5jI3J2k8G+h4QJBALkpNsc0jj7lrFY6vVd9ZNjHPB5Yo0PgZI+WGXNMzm+EmTLc9cOsE82rQQ2K4u4vMGYZ3PyKaBrw7xBj5PsKEcI=";
    public final static String public_key = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCT4N98qDdenPC35eyqUPDfO0enNxy6Tmf+EntfsUzSt3PmukS91c6VaihdMxWsejvjA8zivj4mDw9yuPio5XkinJDt3JuZA0Zo4BJKYhHjMGFa6XYsclws5ZLdWy1Wro/PRjS1sGsnYqlcqZF6C56qXJqJp4zxW6u3tvABFgR3UwIDAQAB";
    public static String decryptByPrivateKey(String encryptAddress){
        byte[] bytes = new byte[0];
        try {
            bytes = RSAUtils.decryptByPrivateKey(encryptAddress, private_key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String s = new String(bytes);
        return s;
    }
}
src/main/java/com/xcong/excoin/utils/DES.java
New file
@@ -0,0 +1,48 @@
package com.xcong.excoin.utils;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
public class DES {
    static String string = "DES";
    public static void main(String[] args) {
        DES.jdkDES();
    }
    public static void jdkDES() {
        try {
            // 生成key//返回生成指定算法密钥的KeyGenerator对象
            KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
            keyGenerator.init(56);//初始化此密钥生成器,使其具有确定的密钥大小
            SecretKey secretKey = keyGenerator.generateKey();//生成一个密钥
            byte[] bs = secretKey.getEncoded();
            // key转换
            DESKeySpec desKeySpec = new DESKeySpec(bs); //实例化DES密钥规则
            SecretKeyFactory factory = SecretKeyFactory.getInstance("DES"); //实例化密钥工厂
            Key convertSecretKey = factory.generateSecret(desKeySpec); //生成密钥
            // 加密
            Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey);
            byte[] result = cipher.doFinal(string.getBytes());
            System.out.println("jdk des encrypt:" + DESUtil.byteToHex(result));
            // 解密
            cipher.init(Cipher.DECRYPT_MODE, convertSecretKey);
            result = cipher.doFinal(result);
            System.out.println("jdk des decrypt:" + new String(result));
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }
}
src/main/java/com/xcong/excoin/utils/DESUtil.java
New file
@@ -0,0 +1,71 @@
package com.xcong.excoin.utils;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Formatter;
public class DESUtil {
    /*
     * 生成密钥
     */
    public static byte[] initKey() throws Exception{
        KeyGenerator keyGen = KeyGenerator.getInstance("DES");
        keyGen.init(56);
        SecretKey secretKey = keyGen.generateKey();
        return secretKey.getEncoded();
    }
    /*
     * DES 加密
     */
    public static byte[] encrypt(byte[] data, byte[] key) throws Exception{
        SecretKey secretKey = new SecretKeySpec(key, "DES");
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] cipherBytes = cipher.doFinal(data);
        return cipherBytes;
    }
    /*
     * DES 解密
     */
    public static byte[] decrypt(byte[] data, byte[] key) throws Exception{
        SecretKey secretKey = new SecretKeySpec(key, "DES");
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] plainBytes = cipher.doFinal(data);
        return plainBytes;
    }
    public static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }
    //Test
    public static void main(String[] args) throws Exception {
//        byte[] desKey = DESUtil.initKey();
//        String da = UUIDUtil.getRandomID();
//        System.out.println("DES KEY : " + byteToHex(desKey));
//        byte[] desResult = DESUtil.encrypt(da.getBytes(), desKey);
//        System.out.println(da + ">>>DES 加密结果>>>" + byteToHex(desResult));
//
//        byte[] desPlain = DESUtil.decrypt(desResult, desKey);
//        System.out.println(da+ ">>>DES 解密结果>>>" + new String(desPlain));
        System.out.println("b68edd21786c4d4816284e2ad6d6291aaf4091cd3a0fc7898f4aa52153d730a32bf17f803a91ffde".length());
    }
}
src/main/java/com/xcong/excoin/utils/MD5Util.java
New file
@@ -0,0 +1,55 @@
package com.xcong.excoin.utils;
import java.security.MessageDigest;
/**
 * MD5工具类
 *
 * @author jiangyouyao
 * @email 512061637@qq.com
 * @date 2019年2月25日
 */
public class MD5Util {
    public static String bytesToHex(byte[] bytes) {
        StringBuffer md5str = new StringBuffer();
        // 把数组每一字节换成16进制连成md5字符串
        int digital;
        for (int i = 0; i < bytes.length; i++) {
            digital = bytes[i];
            if (digital < 0) {
                digital += 256;
            }
            if (digital < 16) {
                md5str.append("0");
            }
            md5str.append(Integer.toHexString(digital));
        }
        return md5str.toString();
    }
    public static String bytesToMD5(byte[] input) {
        String md5str = null;
        try {
            // 创建一个提供信息摘要算法的对象,初始化为md5算法对象
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 计算后获得字节数组
            byte[] buff = md.digest(input);
            // 把数组每一字节换成16进制连成md5字符串
            md5str = bytesToHex(buff);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return md5str;
    }
    public static String strToMD5(String str) {
        byte[] input = str.getBytes();
        return bytesToMD5(input);
    }
}
src/main/java/com/xcong/excoin/utils/RSAUtils.java
New file
@@ -0,0 +1,234 @@
package com.xcong.excoin.utils;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
/**
 * @author JIANGYOUYAO
 * @email 935090232@qq.com
 * @date 2018年5月13日
 */
public class RSAUtils {
    public static final String KEY_ALGORITHM = "RSA";
    public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
    private static final String PUBLIC_KEY = "RSAPublicKey";
    private static final String PRIVATE_KEY = "RSAPrivateKey";
    public static byte[] decryptBASE64(String key) {
        return Base64.decodeBase64(key);
    }
    public static String encryptBASE64(byte[] bytes) {
        return Base64.encodeBase64String(bytes);
    }
    /**
     * 用私钥对信息生成数字签名
     *
     * @param data
     *            加密数据
     * @param privateKey
     *            私钥
     * @return
     * @throws Exception
     */
    public static String sign(byte[] data, String privateKey) throws Exception {
        // 解密由base64编码的私钥
        byte[] keyBytes = decryptBASE64(privateKey);
        // 构造PKCS8EncodedKeySpec对象
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        // KEY_ALGORITHM 指定的加密算法
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        // 取私钥匙对象
        PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
        // 用私钥对信息生成数字签名
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initSign(priKey);
        signature.update(data);
        return encryptBASE64(signature.sign());
    }
    /**
     * 校验数字签名
     *
     * @param data
     *            加密数据
     * @param publicKey
     *            公钥
     * @param sign
     *            数字签名
     * @return 校验成功返回true 失败返回false
     * @throws Exception
     */
    public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
        // 解密由base64编码的公钥
        byte[] keyBytes = decryptBASE64(publicKey);
        // 构造X509EncodedKeySpec对象
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        // KEY_ALGORITHM 指定的加密算法
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        // 取公钥匙对象
        PublicKey pubKey = keyFactory.generatePublic(keySpec);
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initVerify(pubKey);
        signature.update(data);
        // 验证签名是否正常
        return signature.verify(decryptBASE64(sign));
    }
    public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {
        // 对密钥解密
        byte[] keyBytes = decryptBASE64(key);
        // 取得私钥
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        // 对数据解密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }
    /**
     * 解密<br>
     * 用私钥解密
     *
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] decryptByPrivateKey(String data, String key) throws Exception {
        return decryptByPrivateKey(decryptBASE64(data), key);
    }
    /**
     * 解密<br>
     * 用公钥解密
     *
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception {
        // 对密钥解密
        byte[] keyBytes = decryptBASE64(key);
        // 取得公钥
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key publicKey = keyFactory.generatePublic(x509KeySpec);
        // 对数据解密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }
    /**
     * 加密<br>
     * 用公钥加密
     *
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] encryptByPublicKey(String data, String key) throws Exception {
        // 对公钥解密
        byte[] keyBytes = decryptBASE64(key);
        // 取得公钥
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key publicKey = keyFactory.generatePublic(x509KeySpec);
        // 对数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(data.getBytes());
    }
    /**
     * 加密<br>
     * 用私钥加密
     *
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception {
        // 对密钥解密
        byte[] keyBytes = decryptBASE64(key);
        // 取得私钥
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        // 对数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }
    /**
     * 取得私钥
     *
     * @param keyMap
     * @return
     * @throws Exception
     */
    public static String getPrivateKey(Map<String, Key> keyMap) throws Exception {
        Key key = (Key) keyMap.get(PRIVATE_KEY);
        return encryptBASE64(key.getEncoded());
    }
    /**
     * 取得公钥
     *
     * @param keyMap
     * @return
     * @throws Exception
     */
    public static String getPublicKey(Map<String, Key> keyMap) throws Exception {
        Key key = keyMap.get(PUBLIC_KEY);
        return encryptBASE64(key.getEncoded());
    }
    /**
     * 初始化密钥
     *
     * @return
     * @throws Exception
     */
    public static Map<String, Key> initKey() throws Exception {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        keyPairGen.initialize(1024);
        KeyPair keyPair = keyPairGen.generateKeyPair();
        Map<String, Key> keyMap = new HashMap<>(2);
        // 公钥
        keyMap.put(PUBLIC_KEY, keyPair.getPublic());
        // 私钥
        keyMap.put(PRIVATE_KEY, keyPair.getPrivate());
        return keyMap;
    }
    public static void main(String[] args) throws Exception {
        Map<String, Key> stringKeyMap = initKey();
        String publicKey = getPublicKey(stringKeyMap);
        System.out.println("公钥:"+publicKey);
        String privateKey = getPrivateKey(stringKeyMap);
        System.out.println("私钥:"+privateKey);
        byte[] bytes = encryptByPublicKey("111112323",publicKey);
        String s = encryptBASE64(bytes);
        System.out.println("加密后的:"+s);
        // 解密
        byte[] bytes1 = decryptByPrivateKey(s, privateKey);
        String s1 = new String(bytes1);
        System.out.println(s1);
    }
}
src/main/java/com/xcong/excoin/utils/ToolUtil.java
New file
@@ -0,0 +1,362 @@
package com.xcong.excoin.utils;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
/**
 * 工具类
 * @add 20190828 添加时间转换方法
 * @author 敢超
 *
 */
public class ToolUtil {
    private static Logger log = LoggerFactory.getLogger(ToolUtil.class);
    /*
     * 字符串正则匹配方法(用于匹配字符串是否包含指定字符串)
     */
    public static boolean stringFilter(String string, String regex) {
        Pattern p = Pattern.compile(regex);
        return p.matcher(string).matches();
    }
    /**
     * 将http传过来的数据转化成实体
     *
     * @param request
     * @param clazz
     * @return
     */
    public static <T> T getHttpRequestParams(HttpServletRequest request, Class<T> clazz) {
        T bean = null;
        try {
            bean = clazz.newInstance();
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                String methodName = method.getName();
                if (methodName.startsWith("set")) {
                    String key = methodName.substring(3);
                    key = key.substring(0, 1).toLowerCase() + key.substring(1);
                    String value = request.getParameter(key);
                    if (value != null) {
                        method.invoke(bean, value);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bean;
    }
    /**
     * 实体转json字符串
     * @param obj
     * @return
     */
    public static String objToJson(Object obj) {
        return JSONObject.toJSONString(obj);
    }
    /**
     * json字符串转对象
     * @param json  json格式的字符串
     * @param clazz
     * @return
     */
    public static <T> T jsonToObject(String json, Class<T> clazz) {
        //    return new Gson().fromJson(json, clazz);
        return JSONObject.parseObject(json,clazz);
    }
    /**
     * json转list对象
     * @param json
     * @param clazz
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> List<T> jsonToList(String json,Class<?> clazz){
        return (List<T>) JSONObject.parseArray(json, clazz);
    }
    /**
     * map 对象转bean对象 用于统一处理接口输入参数
     * @param map
     * @param clazz
     * @param isUpper Map的key值是否为大写类型 ture: USER_ID,false:userId
     * @return
     */
    public static <T> T mapToBean(Map map, Class<T> clazz, boolean isUpper) {
        T t = null;
        try {
            t = clazz.newInstance();
            BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                if (map.containsKey(key)) {
                    Object value = map.get(key);
                    Method setter = property.getWriteMethod();
                    if(setter != null && value != null){
                        if(value.getClass().equals(setter.getParameterTypes()[0])){
                            setter.invoke(t, value);
                        }else if(Date.class.equals(setter.getParameterTypes()[0]) && Number.class.isAssignableFrom(value.getClass())){
                            setter.invoke(t,new Date(((Number)value).longValue()));
                        }else {
                            log.warn("【mapToBean】"+key+" 类型不匹配,没有转化");
                        }
                    }else {
                        log.warn("【mapToBean】"+key+" 不存在写入方法,或值不存在,没有转化");
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return t;
    }
    /**
     *    实体bean 转换成map
     * @param object
     * @param <T>
     * @return
     */
    public static <T> Map beanToMap(T object){
        Map map = new HashMap();
        BeanInfo beanInfo = null;
        try {
            beanInfo = Introspector.getBeanInfo(object.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                if("class".equals(key)){
                    continue;
                }
                Object temp = property.getReadMethod().invoke(object);
                if(temp != null){
                    map.put(key,temp);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            map = null;
        }
        return map;
    }
    /**
     * 大写字母转小写
     * @param str USER_ID 转小写 userId
     * @return
     */
    public static String strToLowerCase(String str) {
        String s1 = str.toLowerCase();
        if (s1.indexOf("_") != -1) {
            StringBuffer sb = new StringBuffer();
            String[] strs = s1.split("_");
            for (String temp : strs) {
                if (sb.length() == 0) {
                    sb.append(temp);
                } else {
                    char[] cs = temp.toCharArray();
                    cs[0] -= 32;
                    sb.append(String.valueOf(cs));
                }
            }
            s1 = sb.toString();
        }
        return s1;
    }
    /**
     * list对象转换成Map<String,T>
     * @param list 对象
     * @param name 作为map的key的 属性
     * @return
     */
    public static <T> Map<String, T> listToMap(List<T> list, String name) {
        HashMap<String, T> map = new HashMap<>();
        if(CollectionUtils.isNotEmpty(list)){
            try {
                if(Map.class.isAssignableFrom(list.get(0).getClass())){
                    for(T object : list){
                        Map temp = (Map) object;
                        String key = (String) temp.get(name);
                        map.put(key,object);
                    }
                }else {
                    char[] cs = name.toCharArray();
                    cs[0] -= 32;
                    String getMethod = "get" + String.valueOf(cs);
                    Method method = list.get(0).getClass().getMethod(getMethod);
                    for (T object : list) {
                        String str = (String) method.invoke(object);
                        map.put(str, object);
                    }
                }
            } catch (Exception e) {
                log.error("listToMap 数据转换出错!");
                e.printStackTrace();
            }
        }
        return map;
    }
    /**
     * 打印异常堆栈
     * @param e
     * @return
     */
    public static String printExceptionDetail(Exception e){
        String result = "";
        StringWriter sw = null;
        PrintWriter pw = null;
        try {
            sw = new StringWriter();
            pw =  new PrintWriter(sw);
            //将出错的栈信息输出到printWriter中
            e.printStackTrace(pw);
            pw.flush();
            sw.flush();
            result = sw.toString();
        } finally {
            if (sw != null) {
                try {
                    sw.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (pw != null) {
                pw.close();
            }
        }
        return result;
    }
    /**
     * 复制bean属性
     * @param source
     * @param type
     * @param <T>
     * @return
     */
    public static <T> T copyBeanProperties(Object source,Class<T> type){
        T t = null;
        try {
            t = type.newInstance();
            PropertyUtils.copyProperties(t,source);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return t;
    }
    /**
     * 模拟oracle数据库的decode
     * @param source
     * @param match 比配参数,参数个数必须是2的倍数,没有匹配到直接返回原字符串
     * @return
     */
    public static String decodeStr(String source,String... match){
        if(source == null){
            return null;
        }
        if(match == null || match.length%2 != 0){
            throw new RuntimeException("ToolUtil.decodeStr的match参数错误");
        }
        for(int i = 0;i < match.length;i++){
            if(source.equals(match[i])){
                return match[i+1];
            }
            i++;
        }
        return source;
    }
    /**
     * 根据属性,获取get方法
     * @param ob 对象
     * @param name 属性名
     * @return
     * @throws Exception
     */
    public static Object getGetMethod(Object ob , String name)throws Exception{
        Method[] m = ob.getClass().getMethods();
        for(int i = 0;i < m.length;i++){
            if(("get"+name).toLowerCase().equals(m[i].getName().toLowerCase())){
                return m[i].invoke(ob);
            }
        }
        return null;
    }
    /**
     * 获取格式化后的时间
     * @param date
     * @param pattern
     * @return
     */
    public static String getStringDate(Date date,String pattern){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        return simpleDateFormat.format(date);
    }
    /**
     * 去除字符串的前后空格
     * @author zhangheng
     * @date 2020-04-23
     * @param param
     * @return java.lang.String
     */
    public static String trimString(String param){
        if(StringUtils.isBlank(param)){
            return null;
        }
        return param.trim();
    }
    public static String listToString(List<String> list,String sep){
        if(CollectionUtils.isEmpty(list)){
            return null;
        }
        int size = list.size();
        StringBuilder builder = new StringBuilder();
        for(int i=0;i<size;i++){
            if(i==0){
                builder.append(list.get(i));
            }else{
                builder.append(sep+list.get(i));
            }
        }
        return builder.toString();
    }
}
src/main/java/com/xcong/excoin/utils/UUIDUtil.java
New file
@@ -0,0 +1,20 @@
package com.xcong.excoin.utils;
import java.util.UUID;
public class UUIDUtil {
    /**
     * 获取一个32位的随机字符串
     *
     * @author JIANGYOUYAO
     * @email 935090232@qq.com
     * @date 2017年11月30日
     * @return
     */
    public static String getRandomID() {
        return UUID.randomUUID().toString().replace("-", "");
    }
}
src/main/java/com/xcong/excoin/utils/WordsUtil.java
New file
@@ -0,0 +1,11 @@
package com.xcong.excoin.utils;
import java.util.ArrayList;
import java.util.List;
/**
 *  助记词
 */
public class WordsUtil {
    public static List<String> words_list = new ArrayList<>();
}
src/main/resources/i18n/messages_en_US.properties
@@ -241,3 +241,7 @@
submit_repeat=Do not repeat submission
login_init=Cannot generate Wallet
login_recovery_001=Please input mnemonics
login_recovery_002=Mnemonic errors
login_recovery_003=Import succeeded
src/main/resources/i18n/messages_zh_CN.properties
@@ -240,3 +240,8 @@
cancellation_fail=撤销失败
submit_repeat=请勿重复提交
login_init=不能生成钱包
login_recovery_001=请输入助记词
login_recovery_002=助记词错误
login_recovery_003=导入成功
src/main/resources/mapper/member/WalletDetailDao.xml
New file
@@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xcong.excoin.common.system.dao.WalletDetailDao">
    <!-- 定义WtWalletDetail 的复杂关联map -->
    <resultMap type="com.xcong.excoin.common.system.entity.WtWalletDetail" id="WtWalletDetailMap">
        <id property="id" column="id"/>
        <result property="address" column="address"/>
        <result property="symbol" column="symbol"/>
        <result property="balance" column="balance"/>
        <result property="show" column="show"/>
    </resultMap>
    <!-- 字段sql -->
    <sql id="columns">
            id,
            address,
            symbol,
            balance,
            main,
            is_show
    </sql>
    <!-- 属性sql -->
    <sql id="propertys">
            #{item.id},
            #{item.address},
            #{item.symbol},
            #{item.balance},
            #{item.main},
            #{item.isShow}
    </sql>
    <!--  插入方法   -->
    <insert id="insert" parameterType="com.xcong.excoin.common.system.entity.WtWalletDetail"
            useGeneratedKeys="true" keyProperty="item.id">
        INSERT INTO wt_wallet_detail (
        <include refid="columns"></include>
        )
        VALUES (
        <include refid="propertys"></include>
        )
    </insert>
    <!--  批量插入   -->
    <insert id="batchInsert" parameterType="java.util.List">
        INSERT INTO wt_wallet_detail (
        <include refid="columns"></include>
        )
        VALUES
        <foreach collection="list" item="item" index="index" separator=",">(
            <include refid="propertys"></include>
            )
        </foreach>
    </insert>
    <!--  根据对象更新 部分更新   -->
    <update id="updateByModel" parameterType="String">
        UPDATE wt_wallet_detail
        <set>
            <if test="record.address != null and record.address != '' ">
                address = #{record.address},
            </if>
            <if test="record.symbol != null and record.symbol != '' ">
                symbol = #{record.symbol},
            </if>
            <if test="record.balance != null ">
                balance = #{record.balance},
            </if>
            <if test="record.isShow != null ">
                is_show = #{record.isShow},
            </if>
        </set>
        WHERE id=#{record.id}
    </update>
    <!-- 批量删除 -->
    <delete id="deleteByIds" parameterType="java.util.List">
        delete from wt_wallet_detail where id in
        <foreach collection="list" index="index" item="item" open="("
                 separator="," close=")">
            #{item}
        </foreach>
    </delete>
    <!-- 根据id删除-->
    <delete id="deleteById" parameterType="String">
        DELETE FROM wt_wallet_detail
        where  id=#{id}
    </delete>
    <!-- 根据id查询-->
    <select id="selectById" resultMap="WtWalletDetailMap">
        select
        <include refid="columns"></include>
        from wt_wallet_detail
        where id=#{id}
    </select>
    <select id="selectByAddressAndSymbol" resultMap="WtWalletDetailMap">
        select
        <include refid="columns"></include>
        from wt_wallet_detail
        where address=#{address} and symbol = #{symbol}
    </select>
    <!-- 根据对象查询-->
    <select id="selectByModel" resultMap="WtWalletDetailMap">
        select
        <include refid="columns"></include>
        from wt_wallet_detail
        <where>
           <if test="address !=null and address != ''">
               and address = #{address}
           </if>
           <if test="symbol !=null and symbol != ''">
               and symbol = #{symbol}
           </if>
        </where>
        order by main desc
    </select>
    <update id="updateWalletBalance" parameterType="map">
        update wt_wallet_detail set balance = balance + #{balance} where id = #{id}
    </update>
</mapper>
src/main/resources/mapper/member/WtTokenDao.xml
New file
@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xcong.excoin.common.system.dao.WtTokenDao">
    <!-- 定义WtToken 的复杂关联map -->
    <!-- 字段sql -->
    <sql id="columns">
            id,
            symbol,
            price,
            main,
            fee,
            create_time,
            amount,
            contract_address,
            symbol_name
    </sql>
    <!-- 属性sql -->
    <sql id="propertys">
            #{item.id},
            #{item.symbol},
            #{item.price},
            #{item.main},
            #{item.fee},
            #{item.createTime},
            #{item.amount},
            #{item.contractAddress},
            #{item.symbolName}
    </sql>
    <!--  插入方法   -->
    <insert id="insert" parameterType="com.xcong.excoin.common.system.entity.WtBlock"
            useGeneratedKeys="true" keyProperty="item.id">
        INSERT INTO wt_token (
        <include refid="columns"></include>
        )
        VALUES (
        <include refid="propertys"></include>
        )
    </insert>
    <!--  批量插入   -->
    <insert id="batchInsert" parameterType="java.util.List">
        INSERT INTO wt_token (
        <include refid="columns"></include>
        )
        VALUES
        <foreach collection="list" item="item" index="index" separator=",">(
            <include refid="propertys"></include>
            )
        </foreach>
    </insert>
    <!--  根据对象更新 部分更新   -->
    <update id="updateByModel" parameterType="Integer">
        UPDATE wt_token
        <set>
            <if test="record.symbol != null and record.symbol != '' ">
                symbol = #{record.symbol},
            </if>
            <if test="record.price != null ">
                price = #{record.price},
            </if>
            <if test="record.main != null ">
                main = #{record.main},
            </if>
        </set>
        WHERE id=#{record.id}
    </update>
    <!-- 根据id删除-->
    <delete id="deleteById" parameterType="Integer">
        DELETE FROM wt_token
        where  id=#{id}
    </delete>
    <!-- 根据id查询-->
    <select id="selectById" resultType="com.xcong.excoin.common.system.entity.WtToken">
        select
        <include refid="columns"></include>
        from wt_token
        where id=#{id}
    </select>
    <select id="selectBySymbol" resultType="com.xcong.excoin.common.system.entity.WtToken">
        select
        <include refid="columns"></include>
        from wt_token
        where symbol =#{symbol}
    </select>
    <select id="selectAllToken" resultType="com.xcong.excoin.common.system.entity.WtToken">
        select
        <include refid="columns"></include>
        from wt_token
    </select>
    <select id="selectMainToken" resultType="com.xcong.excoin.common.system.entity.WtToken">
        select
        <include refid="columns"></include>
        from wt_token where main = 1
    </select>
</mapper>
src/main/resources/mapper/member/WtWalletMapper.xml
New file
@@ -0,0 +1,146 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xcong.excoin.common.system.dao.WtWalletDao">
    <!-- 定义WtWallet 的复杂关联map -->
    <resultMap type="com.xcong.excoin.common.system.entity.WtWallet" id="WtWalletMap">
            <result property="privateKey" column="private_key" />
            <result property="mnemonicWords" column="mnemonic_words" />
            <result property="password" column="password" />
            <result property="walletName" column="wallet_name" />
            <result property="terminalId" column="terminal_Id" />
    </resultMap>
    <!-- 字段sql -->
    <sql id="columns">
            address,
            private_key,
            mnemonic_words,
            password,
            wallet_name,
            terminal_Id
    </sql>
    <sql id="simpleColumns">
            address,
            wallet_name
    </sql>
    <!-- 属性sql -->
    <sql id="propertys">
            #{item.address},
            #{item.privateKey},
            #{item.mnemonicWords},
            #{item.password},
            #{item.walletName},
            #{item.terminalId}
    </sql>
    <!--  插入方法   -->
    <insert id="insert" parameterType="com.xcong.excoin.common.system.entity.WtWallet"
        useGeneratedKeys="true" keyProperty="item.address">
        INSERT INTO wt_wallet (
             <include refid="columns"></include>
        )
        VALUES (
         <include refid="propertys"></include>
    )
    </insert>
    <!--  批量插入   -->
    <insert id="batchInsert" parameterType="java.util.List">
        INSERT INTO wt_wallet (
        <include refid="columns"></include>
        )
    VALUES
    <foreach collection="list" item="item" index="index" separator=",">(
        <include refid="propertys"></include>
    )</foreach>
    </insert>
    <!--  根据对象更新 部分更新   -->
    <update id="updateByModel" parameterType="String">
        UPDATE wt_wallet
        <set>
            <if test="record.password != null and record.password != '' ">
                password  = #{record.password},
            </if>
            <if test="record.walletName != null and record.walletName != '' ">
                wallet_name  = #{record.walletName},
            </if>
            <if test="record.terminalId != null and record.terminalId != '' ">
                terminal_Id  = #{record.terminalId},
            </if>
        </set>
        WHERE address=#{record.address}
    </update>
    <!-- 批量删除 -->
    <delete id="deleteByIds" parameterType="java.util.List">
        delete from wt_wallet where  address in
        <foreach collection="list" index="index" item="item" open="("
            separator="," close=")">
            #{item}
        </foreach>
    </delete>
    <!-- 根据id删除-->
    <delete id="deleteById" parameterType="String">
        DELETE FROM wt_wallet
        where  address=#{address}
    </delete>
    <!-- 根据id查询-->
    <select id="selectById" resultMap="WtWalletMap">
        select
        <include refid="columns" ></include>
        from wt_wallet
        where  address=#{address}
    </select>
    <select id="selectSimpleById" resultMap="WtWalletMap">
        select
        <include refid="simpleColumns" ></include>
        from wt_wallet
        where  address=#{address}
    </select>
    <select id="selectSimpleByTerminalId" resultMap="WtWalletMap">
        select
        <include refid="simpleColumns" ></include>
        from wt_wallet
        where  terminal_Id=#{terminalId}
        limit 1
    </select>
    <select id="selectByMnemonicWords" resultMap="WtWalletMap">
        select
            address,
            mnemonic_words,
            wallet_name,
            terminal_Id
        from wt_wallet
        where  mnemonic_words=#{mnemonic_words}
    </select>
    <update id="clearTerminalId" parameterType="string">
        update wt_wallet set   terminal_id = null where address = #{address}
    </update>
    <update id="deleteTerminal" parameterType="string">
        update wt_wallet set   terminal_Id = null where terminal_id = #{terminalId}
    </update>
</mapper>
src/main/resources/mapper/member/WtWordDao.xml
New file
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xcong.excoin.common.system.dao.WtWordDao">
    <select id="selectAllWords"  resultType="String">
       select word from wt_word
    </select>
</mapper>