1、调整gas费浮动比例为90%

This commit is contained in:
2025-05-17 09:10:14 +08:00
parent 38a5acface
commit 8113868cc0
19 changed files with 397 additions and 23 deletions

View File

@ -43,7 +43,7 @@ func (e WmTransferItem) GetPage(c *gin.Context) {
} }
p := actions.GetPermissionFromContext(c) p := actions.GetPermissionFromContext(c)
list := make([]models.WmTransferItem, 0) list := make([]dto.WmTransferItemResp, 0)
var count int64 var count int64
err = s.GetPage(&req, p, &list, &count) err = s.GetPage(&req, p, &list, &count)
@ -262,3 +262,23 @@ func (e WmTransferItem) GetAutoTransferLogPage(c *gin.Context) {
} }
e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功") e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
} }
// 清除自动转账
func (e WmTransferItem) ClearAutoLog(c *gin.Context) {
s := service.WmTransferItem{}
err := e.MakeContext(c).
MakeOrm().
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
err = s.ClearAutoLog()
if err != nil {
e.Error(500, err, fmt.Sprintf("清除自动转账日志失败,\r\n失败信息 %s", err.Error()))
return
}
e.OK(nil, "清除成功")
}

View File

@ -174,3 +174,49 @@ func (e WmWalletInfo) ClearAll(c *gin.Context) {
} }
e.OK(nil, "清空成功") e.OK(nil, "清空成功")
} }
// 根据excel导入钱包信息
func (e WmWalletInfo) ExcelImport(c *gin.Context) {
s := service.WmWalletInfo{}
err := e.MakeContext(c).
MakeOrm().
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
errs := s.ExcelImport(c)
e.OK(strings.Join(errs, "<br/>"), "创建成功")
}
// UpdateRemark 更新备注信息
func (e WmWalletInfo) UpdateRemark(c *gin.Context) {
s := service.WmWalletInfo{}
req := dto.WmWalletInfoBatchUpdateReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
// 设置更新人
req.SetUpdateBy(user.GetUserId(c))
err = s.BatchUpdateRemark(&req)
if err != nil {
e.Error(500, err, fmt.Sprintf("更新备注信息失败,\r\n失败信息 %s", err.Error()))
return
}
e.OK(nil, "更新成功")
}

View File

@ -17,6 +17,8 @@ type WmTransfer struct {
Sucess int `json:"sucess" gorm:"-"` Sucess int `json:"sucess" gorm:"-"`
Fail int `json:"fail" gorm:"-"` Fail int `json:"fail" gorm:"-"`
Pending int `json:"pending" gorm:"-"` Pending int `json:"pending" gorm:"-"`
NetworkName string `json:"networkName" gorm:"-"`
TokenName string `json:"tokenName" gorm:"-"`
models.ModelTime models.ModelTime
models.ControlBy models.ControlBy
} }

View File

@ -12,6 +12,7 @@ type WmWalletInfo struct {
PrivateKey string `json:"privateKey" gorm:"type:varchar(50);comment:钱包私钥"` PrivateKey string `json:"privateKey" gorm:"type:varchar(50);comment:钱包私钥"`
Address string `json:"address" gorm:"type:varchar(50);comment:钱包地址"` Address string `json:"address" gorm:"type:varchar(50);comment:钱包地址"`
UsdcAmount decimal.Decimal `json:"usdcAmount" gorm:"type:decimal(18,8);comment:USDC余额"` UsdcAmount decimal.Decimal `json:"usdcAmount" gorm:"type:decimal(18,8);comment:USDC余额"`
Remark string `json:"remark" gorm:"type:varchar(255);comment:备注信息"`
models.ModelTime models.ModelTime
models.ControlBy models.ControlBy
} }

View File

@ -24,6 +24,7 @@ func registerWmTransferItemRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJW
r.PUT("/:id", actions.PermissionAction(), api.Update) r.PUT("/:id", actions.PermissionAction(), api.Update)
r.DELETE("", api.Delete) r.DELETE("", api.Delete)
r.DELETE("/clear", api.ClearAutoLog)
r.GET("/export", actions.PermissionAction(), api.Export) r.GET("/export", actions.PermissionAction(), api.Export)
r.GET("/export-auto-log", actions.PermissionAction(), api.ExportAutoLog) r.GET("/export-auto-log", actions.PermissionAction(), api.ExportAutoLog)
r.GET("/auto-log", actions.PermissionAction(), api.GetAutoTransferLogPage) r.GET("/auto-log", actions.PermissionAction(), api.GetAutoTransferLogPage)

View File

@ -24,5 +24,8 @@ func registerWmWalletInfoRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTM
// r.PUT("/:id", actions.PermissionAction(), api.Update) // r.PUT("/:id", actions.PermissionAction(), api.Update)
r.DELETE("", api.Delete) r.DELETE("", api.Delete)
r.DELETE("clear", api.ClearAll) r.DELETE("clear", api.ClearAll)
r.POST("/excel-import", api.ExcelImport) //根据excel导入数据
r.PUT("/batch", api.UpdateRemark) //批量更新备注
} }
} }

View File

@ -13,6 +13,7 @@ type WmTokenGetPageReq struct {
dto.Pagination `search:"-"` dto.Pagination `search:"-"`
NetworkId string `form:"networkId" search:"type:contains;column:network_id;table:wm_token" comment:"网络id"` NetworkId string `form:"networkId" search:"type:contains;column:network_id;table:wm_token" comment:"网络id"`
TokenName string `form:"tokenName" search:"type:contains;column:token_name;table:wm_token" comment:"代币名称"` TokenName string `form:"tokenName" search:"type:contains;column:token_name;table:wm_token" comment:"代币名称"`
TransType int `form:"transType" search:"-" comment:"转账类型 1-百分比 2-实际金额"`
WmTokenOrder WmTokenOrder
} }

View File

@ -2,9 +2,11 @@ package dto
import ( import (
"errors" "errors"
"fmt"
"go-admin/app/admin/models" "go-admin/app/admin/models"
"go-admin/common/dto" "go-admin/common/dto"
common "go-admin/common/models" common "go-admin/common/models"
"go-admin/utils/ethtransferhelper"
"strings" "strings"
"github.com/shopspring/decimal" "github.com/shopspring/decimal"
@ -105,6 +107,12 @@ func (s *WmTransferInsertReq) Valid() error {
} }
} }
for _, content := range contents {
if !ethtransferhelper.IsValidAddress(content) {
return fmt.Errorf("%s 地址格式错误", content)
}
}
return nil return nil
} }

View File

@ -17,7 +17,10 @@ type WmTransferItemGetPageReq struct {
type WmTransferItemAutoLogPageReq struct { type WmTransferItemAutoLogPageReq struct {
dto.Pagination `search:"-"` dto.Pagination `search:"-"`
NetworkId int `form:"networkId" search:"type:exact;column:network_id;table:wm_transfer_item"` NetworkId int `form:"networkId" search:"type:exact;column:network_id;table:wm_transfer_item"`
StartAmount float64 `form:"startAmount" search:"-"`
EndAmount float64 `form:"endAmount" search:"-"`
Status int `form:"status" search:"-"`
WmTransferItemOrder WmTransferItemOrder
} }
@ -146,6 +149,8 @@ type WmTransferItemExportReq struct {
} }
type WmTransferItemExportData struct { type WmTransferItemExportData struct {
NetworkName string `json:"networkName" excel:"网络名称"`
TokenName string `json:"tokenName" excel:"代币名称"`
PrivateKey string `json:"privateKey" excel:"私钥"` PrivateKey string `json:"privateKey" excel:"私钥"`
TokenAddress string `json:"tokenAddress" excel:"代币地址"` TokenAddress string `json:"tokenAddress" excel:"代币地址"`
FromAddress string `json:"fromAddress" excel:"来源地址"` FromAddress string `json:"fromAddress" excel:"来源地址"`

View File

@ -10,7 +10,7 @@ import (
type WmWalletInfoGetPageReq struct { type WmWalletInfoGetPageReq struct {
dto.Pagination `search:"-"` dto.Pagination `search:"-"`
PrivateKey string `form:"privateKey" search:"type:exact;column:private_key;table:wm_wallet_info" comment:"钱包私钥"` PrivateKey string `form:"privateKey" search:"-" comment:"钱包私钥"`
WmWalletInfoOrder WmWalletInfoOrder
} }
@ -30,7 +30,8 @@ func (m *WmWalletInfoGetPageReq) GetNeedSearch() interface{} {
} }
type WmWalletInfoBatchInsertReq struct { type WmWalletInfoBatchInsertReq struct {
Keys string `json:"keys"` Keys string `json:"keys"`
Remark string `json:"remark"`
common.ControlBy common.ControlBy
} }
@ -103,3 +104,14 @@ type WmWalletInfoDeleteReq struct {
func (s *WmWalletInfoDeleteReq) GetId() interface{} { func (s *WmWalletInfoDeleteReq) GetId() interface{} {
return s.Ids return s.Ids
} }
type WmWalletExcelImportReq struct {
PrivateKey string `json:"privateKey" excel:"钱包私钥"`
Remark string `json:"remark" excel:"备注"`
}
type WmWalletInfoBatchUpdateReq struct {
Ids []int `json:"ids" form:"ids"`
Remark string `json:"remark" form:"remark"`
common.ControlBy
}

View File

@ -25,13 +25,18 @@ type WmToken struct {
func (e *WmToken) GetPage(c *dto.WmTokenGetPageReq, p *actions.DataPermission, list *[]models.WmToken, count *int64) error { func (e *WmToken) GetPage(c *dto.WmTokenGetPageReq, p *actions.DataPermission, list *[]models.WmToken, count *int64) error {
var err error var err error
var data models.WmToken var data models.WmToken
query := e.Orm.Model(&data).
err = e.Orm.Model(&data).
Scopes( Scopes(
cDto.MakeCondition(c.GetNeedSearch()), cDto.MakeCondition(c.GetNeedSearch()),
cDto.Paginate(c.GetPageSize(), c.GetPageIndex()), cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
actions.Permission(data.TableName(), p), actions.Permission(data.TableName(), p),
). )
if c.TransType > 0 {
query.Where("trans_type = ?", c.TransType)
}
err = query.
Find(list).Limit(-1).Offset(-1). Find(list).Limit(-1).Offset(-1).
Count(count).Error Count(count).Error
if err != nil { if err != nil {

View File

@ -56,6 +56,10 @@ func (e *WmTransfer) GetPage(c *dto.WmTransferGetPageReq, p *actions.DataPermiss
} }
itemData, _ := e.GetItemData(transferIds) itemData, _ := e.GetItemData(transferIds)
networkService := WmNetwork{Service: e.Service}
networks, _ := networkService.GetAll()
tokenService := WmToken{Service: e.Service}
tokens, _ := tokenService.GetAll()
for i := range *list { for i := range *list {
var total int var total int
@ -74,6 +78,20 @@ func (e *WmTransfer) GetPage(c *dto.WmTransferGetPageReq, p *actions.DataPermiss
} }
} }
for _, network := range networks {
if network.Id == (*list)[i].NetworkId {
(*list)[i].NetworkName = network.NetworkName
break
}
}
for _, token := range tokens {
if token.NetworkId == (*list)[i].NetworkId && token.TokenAddress == (*list)[i].TokenAddress {
(*list)[i].TokenName = token.TokenName
break
}
}
(*list)[i].Total = total (*list)[i].Total = total
} }
@ -196,6 +214,7 @@ func (e *WmTransfer) Insert(c *dto.WmTransferInsertReq) error {
caches[i].TransferId = data.Id caches[i].TransferId = data.Id
caches[i].IsAuto = 2 caches[i].IsAuto = 2
caches[i].TokenAddress = c.TokenAddress caches[i].TokenAddress = c.TokenAddress
caches[i].Decimals = token.Decimals
} }
if err := tx.CreateInBatches(&caches, 100).Error; err != nil { if err := tx.CreateInBatches(&caches, 100).Error; err != nil {
@ -226,7 +245,7 @@ func (e *WmTransfer) getPrivateKeyAmount(privateKey, tokenAddress string, decima
return amount, errors.New("连接区块链失败") return amount, errors.New("连接区块链失败")
} }
amount, err = ethbalanceofhelper.GetERC20Balance(client, tokenAddress, accountAddress.String(), decimals) amount, err = ethbalanceofhelper.GetBalance(client, tokenAddress, accountAddress.String(), decimals)
if err != nil { if err != nil {
return amount, errors.New("查询主账号余额失败") return amount, errors.New("查询主账号余额失败")
@ -372,11 +391,11 @@ func (e *WmTransfer) CheckHashStatus() error {
// 清理数据 // 清理数据
func (e *WmTransfer) ClearAll() error { func (e *WmTransfer) ClearAll() error {
err := e.Orm.Transaction(func(tx *gorm.DB) error { err := e.Orm.Transaction(func(tx *gorm.DB) error {
if err1 := tx.Exec("truncate table wm_transfer_item").Error; err1 != nil { if err1 := tx.Exec("delete from wm_transfer_item where is_auto = 2").Error; err1 != nil {
return err1 return err1
} }
if err2 := tx.Exec("truncate table wm_transfer").Error; err2 != nil { if err2 := tx.Exec("delete from wm_transfer ").Error; err2 != nil {
return err2 return err2
} }

View File

@ -21,9 +21,10 @@ type WmTransferItem struct {
} }
// GetPage 获取WmTransferItem列表 // GetPage 获取WmTransferItem列表
func (e *WmTransferItem) GetPage(c *dto.WmTransferItemGetPageReq, p *actions.DataPermission, list *[]models.WmTransferItem, count *int64) error { func (e *WmTransferItem) GetPage(c *dto.WmTransferItemGetPageReq, p *actions.DataPermission, list *[]dto.WmTransferItemResp, count *int64) error {
var err error var err error
var data models.WmTransferItem var data models.WmTransferItem
var datas []models.WmTransferItem
err = e.Orm.Model(&data). err = e.Orm.Model(&data).
Scopes( Scopes(
@ -31,15 +32,48 @@ func (e *WmTransferItem) GetPage(c *dto.WmTransferItemGetPageReq, p *actions.Dat
cDto.Paginate(c.GetPageSize(), c.GetPageIndex()), cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
actions.Permission(data.TableName(), p), actions.Permission(data.TableName(), p),
). ).
Find(list).Limit(-1).Offset(-1). Find(&datas).Limit(-1).Offset(-1).
Count(count).Error Count(count).Error
if err != nil { if err != nil {
e.Log.Errorf("WmTransferItemService GetPage error:%s \r\n", err) e.Log.Errorf("WmTransferItemService GetPage error:%s \r\n", err)
return err return err
} }
for i := 0; i < len(*list); i++ { networkService := WmNetwork{Service: e.Service}
(*list)[i].PrivateKey = stringhelper.DesensitizeWalletAddress(aeshelper.AesEcbDecrypt((*list)[i].PrivateKey)) networks, _ := networkService.GetAll()
tokenService := WmToken{Service: e.Service}
tokens, _ := tokenService.GetAll()
for i := 0; i < len(datas); i++ {
item := dto.WmTransferItemResp{}
item.Id = datas[i].Id
item.PrivateKey = stringhelper.DesensitizeWalletAddress(aeshelper.AesEcbDecrypt(datas[i].PrivateKey))
item.FromAddress = datas[i].FromAddress
item.ToAddress = datas[i].ToAddress
item.TokenAddress = datas[i].TokenAddress
item.Amount = datas[i].Amount
item.Status = datas[i].Status
item.Remark = datas[i].Remark
item.Type = datas[i].Type
item.TypeValue = datas[i].TypeValue
item.Hash = datas[i].Hash
item.CreateAt = datas[i].CreatedAt
for _, network := range networks {
if network.Id == datas[i].NetworkId {
item.NetworkName = network.NetworkName
break
}
}
for _, token := range tokens {
if token.NetworkId == datas[i].NetworkId && token.TokenAddress == datas[i].TokenAddress {
item.TokenName = token.TokenName
break
}
}
*list = append(*list, item)
} }
return nil return nil
@ -50,9 +84,22 @@ func (e *WmTransferItem) GetAutoTransferLogPage(c *dto.WmTransferItemAutoLogPage
var err error var err error
var data models.WmTransferItem var data models.WmTransferItem
var datas []models.WmTransferItem var datas []models.WmTransferItem
query := e.Orm.Model(&data).
Where("is_auto = 1")
err = e.Orm.Model(&data). if c.StartAmount >= 0 {
Where("is_auto = 1"). query.Where("amount >=?", c.StartAmount)
}
if c.EndAmount > 0 {
query.Where("amount <=?", c.EndAmount)
}
if c.Status > 0 {
query.Where("status =?", c.Status)
}
err = query.
Scopes( Scopes(
cDto.MakeCondition(c.GetNeedSearch()), cDto.MakeCondition(c.GetNeedSearch()),
cDto.Paginate(c.GetPageSize(), c.GetPageIndex()), cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
@ -111,8 +158,21 @@ func (e *WmTransferItem) ExportAutoLog(req *dto.WmTransferItemAutoLogPageReq, c
var err error var err error
var data models.WmTransferItem var data models.WmTransferItem
exportDatas := make([]dto.WmTransferItemResp, 0) exportDatas := make([]dto.WmTransferItemResp, 0)
query := e.Orm.Model(&data)
err = e.Orm.Model(&data). if req.StartAmount >= 0 {
query.Where("amount >=?", req.StartAmount)
}
if req.EndAmount > 0 {
query.Where("amount <=?", req.EndAmount)
}
if req.Status > 0 {
query.Where("status =?", req.Status)
}
err = query.
Where("is_auto = 1"). Where("is_auto = 1").
Scopes( Scopes(
cDto.MakeCondition(req.GetNeedSearch()), cDto.MakeCondition(req.GetNeedSearch()),
@ -259,6 +319,11 @@ func (e *WmTransferItem) ExportExcel(req *dto.WmTransferItemExportReq, p *action
return err return err
} }
networkService := WmNetwork{Service: e.Service}
networks, _ := networkService.GetAll()
tokenService := WmToken{Service: e.Service}
tokens, _ := tokenService.GetAll()
for i := 0; i < len(datas); i++ { for i := 0; i < len(datas); i++ {
(datas)[i].PrivateKey = stringhelper.DesensitizeWalletAddress(aeshelper.AesEcbDecrypt((datas)[i].PrivateKey)) (datas)[i].PrivateKey = stringhelper.DesensitizeWalletAddress(aeshelper.AesEcbDecrypt((datas)[i].PrivateKey))
exportData := dto.WmTransferItemExportData{ exportData := dto.WmTransferItemExportData{
@ -281,6 +346,21 @@ func (e *WmTransferItem) ExportExcel(req *dto.WmTransferItemExportReq, p *action
default: default:
exportData.Status = "默认" exportData.Status = "默认"
} }
for _, network := range networks {
if network.Id == datas[i].NetworkId {
exportData.NetworkName = network.NetworkName
break
}
}
for _, token := range tokens {
if token.NetworkId == datas[i].NetworkId && token.TokenAddress == datas[i].TokenAddress {
exportData.TokenName = token.TokenName
break
}
}
exportDatas = append(exportDatas, exportData) exportDatas = append(exportDatas, exportData)
} }
@ -290,3 +370,13 @@ func (e *WmTransferItem) ExportExcel(req *dto.WmTransferItemExportReq, p *action
return excelhelper.ExportExcel(c, "转账明细", exportDatas, []string{}) return excelhelper.ExportExcel(c, "转账明细", exportDatas, []string{})
} }
// 批量删除自动转账日志
func (e *WmTransferItem) ClearAutoLog() error {
if err := e.Orm.Where("is_auto=1").Unscoped().Delete(&models.WmTransferItem{}).Error; err != nil {
e.Log.Errorf("Service ClearAutoLog error:%s \r\n", err)
return err
}
return nil
}

View File

@ -4,6 +4,7 @@ import (
"errors" "errors"
"strings" "strings"
"github.com/gin-gonic/gin"
"github.com/go-admin-team/go-admin-core/sdk/service" "github.com/go-admin-team/go-admin-core/sdk/service"
"github.com/shopspring/decimal" "github.com/shopspring/decimal"
"gorm.io/gorm" "gorm.io/gorm"
@ -16,6 +17,7 @@ import (
"go-admin/utils/aeshelper" "go-admin/utils/aeshelper"
"go-admin/utils/ethbalanceofhelper" "go-admin/utils/ethbalanceofhelper"
"go-admin/utils/ethtransferhelper" "go-admin/utils/ethtransferhelper"
"go-admin/utils/excelhelper"
"go-admin/utils/stringhelper" "go-admin/utils/stringhelper"
) )
@ -27,8 +29,13 @@ type WmWalletInfo struct {
func (e *WmWalletInfo) GetPage(c *dto.WmWalletInfoGetPageReq, p *actions.DataPermission, list *[]models.WmWalletInfo, count *int64) error { func (e *WmWalletInfo) GetPage(c *dto.WmWalletInfoGetPageReq, p *actions.DataPermission, list *[]models.WmWalletInfo, count *int64) error {
var err error var err error
var data models.WmWalletInfo var data models.WmWalletInfo
query := e.Orm.Model(&data)
if c.PrivateKey != "" {
key := aeshelper.AesEcbDecrypt(c.PrivateKey)
query.Where("private_key =?", key)
}
err = e.Orm.Model(&data). err = query.
Scopes( Scopes(
cDto.MakeCondition(c.GetNeedSearch()), cDto.MakeCondition(c.GetNeedSearch()),
cDto.Paginate(c.GetPageSize(), c.GetPageIndex()), cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
@ -174,7 +181,7 @@ func (e *WmWalletInfo) ScheduledTask() error {
} }
for i := range datas { for i := range datas {
amount, err := ethbalanceofhelper.GetERC20Balance(client, token.TokenAddress, datas[i].Address, token.Decimals) amount, err := ethbalanceofhelper.GetBalance(client, token.TokenAddress, datas[i].Address, token.Decimals)
if err != nil { if err != nil {
e.Log.Errorf("GetERC20Balance error:%s", err) e.Log.Errorf("GetERC20Balance error:%s", err)
@ -245,3 +252,65 @@ func (e *WmWalletInfo) ClearAll() error {
return err return err
} }
// 根据excel导入数据
func (e *WmWalletInfo) ExcelImport(c *gin.Context) []string {
dataRows, headers, err := excelhelper.GetExcelContent(c)
errors := []string{}
if err != nil {
errors = append(errors, err.Error())
return errors
}
datas, err := excelhelper.MapExcelToStruct[dto.WmWalletExcelImportReq](dataRows, headers)
if err != nil {
errors = append(errors, err.Error())
return errors
}
// entitys := make([]models.WmWalletInfo, 0)
var count int64
for _, data := range datas {
privateKey := strings.ReplaceAll(data.PrivateKey, " ", "")
if privateKey == "" {
continue
}
_, address, _ := ethtransferhelper.GetAddressFromPrivateKey(privateKey)
entity := models.WmWalletInfo{
PrivateKey: aeshelper.AesEcbEncrypt(privateKey),
Address: address.String(),
Remark: data.Remark,
}
if err := e.Orm.Model(entity).Where("private_key =?", entity.PrivateKey).Count(&count).Error; err != nil {
e.Log.Errorf("db error:%s", err)
}
if count == 0 {
if err := e.Orm.Create(&entity).Error; err != nil {
e.Log.Errorf("db error:%s", err)
errors = append(errors, err.Error())
}
}
// entitys = append(entitys, entity)
}
// if len(entitys) > 0 {
// if err := e.Orm.CreateInBatches(entitys, 100).Error; err != nil {
// e.Log.Errorf("定时转账保存数据库失败 error:%s", err)
// return err
// }
// }
return errors
}
// 批量修改备注
func (e *WmWalletInfo) BatchUpdateRemark(req *dto.WmWalletInfoBatchUpdateReq) error {
if err := e.Orm.Model(&models.WmWalletInfo{}).Where("id in ?", req.Ids).Update("remark", req.Remark).Error; err != nil {
return err
}
return nil
}

Binary file not shown.

View File

@ -36,6 +36,30 @@ const erc20ABI = `[
} }
]` ]`
// GetBalance 查询 余额并转换为正常单位 (使用 decimal)
func GetBalance(client *ethclient.Client, tokenAddress, accountAddress string, decimals int) (decimal.Decimal, error) {
switch tokenAddress {
case "0":
return GetEthBalance(client, accountAddress, decimals)
default:
return GetERC20Balance(client, tokenAddress, accountAddress, decimals)
}
}
// GetEthBalance 查询以太坊余额并转换为正常单位 (使用 decimal)
func GetEthBalance(client *ethclient.Client, accountAddress string, decimals int) (decimal.Decimal, error) {
account := common.HexToAddress(accountAddress)
balance, err := client.BalanceAt(context.Background(), account, nil)
if err != nil {
return decimal.Zero, fmt.Errorf("查询余额失败 err:%v", err)
}
balanceDecimal := decimal.NewFromBigInt(balance, 0) // Create decimal from big.Int
decimalFactor := decimal.NewFromInt(10).Pow(decimal.NewFromInt(int64(decimals)))
readableBalance := balanceDecimal.Div(decimalFactor)
return readableBalance, nil
}
// GetERC20Balance 查询 ERC-20 代币余额并转换为正常单位 (使用 decimal) // GetERC20Balance 查询 ERC-20 代币余额并转换为正常单位 (使用 decimal)
// tokenAddress: 代币合约地址 // tokenAddress: 代币合约地址
// accountAddress: 账户地址 // accountAddress: 账户地址

View File

@ -0,0 +1,25 @@
package ethbalanceofhelper
import (
"fmt"
"testing"
)
func TestBalanceOfHelper(t *testing.T) {
api := "https://stylish-cool-fire.ethereum-sepolia.quiknode.pro/17572db4c091accfa5dc6faa0c60a805e5173459"
proxy := "http://127.0.0.1:7890"
client, err := EthClientWithProxy(api, proxy)
if err != nil {
t.Error(err)
}
address := "0x5079a681a2a2344f4da79a21e187d6ed075ba90a"
balance, err := GetBalance(client, "0", address, 18)
if err != nil {
t.Error(err)
}
fmt.Println("余额:", balance)
}

View File

@ -28,7 +28,7 @@ func TransferErc20(
tokenAmount decimal.Decimal, tokenAmount decimal.Decimal,
tokenDecimals uint8) (*types.Transaction, error) { tokenDecimals uint8) (*types.Transaction, error) {
switch tokenAddress { switch tokenAddress {
case "": case "0":
return TransferEth(client, fromPrivateKey, toAddress, tokenAmount) return TransferEth(client, fromPrivateKey, toAddress, tokenAmount)
default: default:
return TransferErc20Token(client, fromPrivateKey, tokenAddress, toAddress, tokenAmount, tokenDecimals) return TransferErc20Token(client, fromPrivateKey, tokenAddress, toAddress, tokenAmount, tokenDecimals)
@ -81,7 +81,7 @@ func TransferEth(client *ethclient.Client, fromPrivateKey string, toAddress stri
} }
// 9. (预估gas+基础费用)*1.1 作为 GasLimit // 9. (预估gas+基础费用)*1.1 作为 GasLimit
gasLimit = (gasLimit + 21000) * 12 / 10 // 增加 20% gasLimit = (gasLimit + 21000) * 19 / 10 // 增加 90%
if gasLimit < 23000 { if gasLimit < 23000 {
gasLimit = 23000 // 最小 Gas 限制 gasLimit = 23000 // 最小 Gas 限制
} }
@ -182,7 +182,7 @@ func TransferErc20Token(
} }
// 9. (预估gas+基础费用)*1.1 作为 GasLimit // 9. (预估gas+基础费用)*1.1 作为 GasLimit
gasLimit = (gasLimit + 21000) * 12 / 10 // 增加 20% gasLimit = (gasLimit + 21000) * 19 / 10 // 增加 90%
if gasLimit < 23000 { if gasLimit < 23000 {
gasLimit = 23000 // 最小 Gas 限制 gasLimit = 23000 // 最小 Gas 限制
} }
@ -274,5 +274,5 @@ func IsValidAddress(address string) bool {
} }
checksumAddress := common.HexToAddress(address).String() checksumAddress := common.HexToAddress(address).String()
return address == checksumAddress return strings.EqualFold(address, checksumAddress)
} }

View File

@ -167,3 +167,46 @@ func MapExcelToStruct[T any](rows [][]string, headers []string) ([]T, error) {
return results, nil return results, nil
} }
// 获取上传文件的数据
func GetExcelContent(c *gin.Context) (dataRows [][]string, headers []string, err error) {
// 获取上传的文件
file, err := c.FormFile("file")
if err != nil {
err = errors.New("文件上传失败")
return
}
// 打开上传的文件
src, err := file.Open()
if err != nil {
err = errors.New("文件打开失败")
return
}
defer src.Close()
// 使用 excelize 读取 Excel 文件
xlFile, err := excelize.OpenReader(src)
if err != nil {
err = errors.New("读取 Excel 文件失败")
return
}
sheetName := xlFile.GetSheetName(0)
// 假设读取第一个工作表中的数据
rows, err := xlFile.GetRows(sheetName)
if err != nil {
err = errors.New("读取 Excel 行数据失败")
return
}
if len(rows) < 1 {
err = errors.New("没有数据内容")
return
}
headers = rows[0] // First row is the header
dataRows = rows[1:]
return
}