1
This commit is contained in:
		
							
								
								
									
										9
									
								
								abis/ethereumabi/usdc.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								abis/ethereumabi/usdc.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| package ethereumabi | ||||
|  | ||||
| import "go-admin/abis" | ||||
|  | ||||
| var USDCErc20 = abis.TokenABI{ | ||||
| 	Address:     "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", | ||||
| 	TestAddress: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238", | ||||
| 	Decimals:    6, | ||||
| } | ||||
							
								
								
									
										10
									
								
								abis/token.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								abis/token.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| package abis | ||||
|  | ||||
| type TokenABI struct { | ||||
| 	//token 合约地址 | ||||
| 	Address string | ||||
| 	//测试网地址 | ||||
| 	TestAddress string | ||||
| 	//token 最小单位位数 | ||||
| 	Decimals int | ||||
| } | ||||
							
								
								
									
										193
									
								
								app/admin/apis/wm_transfer.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								app/admin/apis/wm_transfer.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,193 @@ | ||||
| package apis | ||||
|  | ||||
| import ( | ||||
|     "fmt" | ||||
|  | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk/api" | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user" | ||||
| 	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response" | ||||
|  | ||||
| 	"go-admin/app/admin/models" | ||||
| 	"go-admin/app/admin/service" | ||||
| 	"go-admin/app/admin/service/dto" | ||||
| 	"go-admin/common/actions" | ||||
| ) | ||||
|  | ||||
| type WmTransfer struct { | ||||
| 	api.Api | ||||
| } | ||||
|  | ||||
| // GetPage 获取批量转账任务列表 | ||||
| // @Summary 获取批量转账任务列表 | ||||
| // @Description 获取批量转账任务列表 | ||||
| // @Tags 批量转账任务 | ||||
| // @Param type query int64 false "类型 0-百分比 1-实际金额" | ||||
| // @Param transferType query int64 false "转账类型 0-批量转出 1-批量汇总" | ||||
| // @Param pageSize query int false "页条数" | ||||
| // @Param pageIndex query int false "页码" | ||||
| // @Success 200 {object} response.Response{data=response.Page{list=[]models.WmTransfer}} "{"code": 200, "data": [...]}" | ||||
| // @Router /api/v1/wm-transfer [get] | ||||
| // @Security Bearer | ||||
| func (e WmTransfer) GetPage(c *gin.Context) { | ||||
|     req := dto.WmTransferGetPageReq{} | ||||
|     s := service.WmTransfer{} | ||||
|     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 | ||||
|    	} | ||||
|  | ||||
| 	p := actions.GetPermissionFromContext(c) | ||||
| 	list := make([]models.WmTransfer, 0) | ||||
| 	var count int64 | ||||
|  | ||||
| 	err = s.GetPage(&req, p, &list, &count) | ||||
| 	if err != nil { | ||||
| 		e.Error(500, err, fmt.Sprintf("获取批量转账任务失败,\r\n失败信息 %s", err.Error())) | ||||
|         return | ||||
| 	} | ||||
|  | ||||
| 	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功") | ||||
| } | ||||
|  | ||||
| // Get 获取批量转账任务 | ||||
| // @Summary 获取批量转账任务 | ||||
| // @Description 获取批量转账任务 | ||||
| // @Tags 批量转账任务 | ||||
| // @Param id path int false "id" | ||||
| // @Success 200 {object} response.Response{data=models.WmTransfer} "{"code": 200, "data": [...]}" | ||||
| // @Router /api/v1/wm-transfer/{id} [get] | ||||
| // @Security Bearer | ||||
| func (e WmTransfer) Get(c *gin.Context) { | ||||
| 	req := dto.WmTransferGetReq{} | ||||
| 	s := service.WmTransfer{} | ||||
|     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 | ||||
| 	} | ||||
| 	var object models.WmTransfer | ||||
|  | ||||
| 	p := actions.GetPermissionFromContext(c) | ||||
| 	err = s.Get(&req, p, &object) | ||||
| 	if err != nil { | ||||
| 		e.Error(500, err, fmt.Sprintf("获取批量转账任务失败,\r\n失败信息 %s", err.Error())) | ||||
|         return | ||||
| 	} | ||||
|  | ||||
| 	e.OK( object, "查询成功") | ||||
| } | ||||
|  | ||||
| // Insert 创建批量转账任务 | ||||
| // @Summary 创建批量转账任务 | ||||
| // @Description 创建批量转账任务 | ||||
| // @Tags 批量转账任务 | ||||
| // @Accept application/json | ||||
| // @Product application/json | ||||
| // @Param data body dto.WmTransferInsertReq true "data" | ||||
| // @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}" | ||||
| // @Router /api/v1/wm-transfer [post] | ||||
| // @Security Bearer | ||||
| func (e WmTransfer) Insert(c *gin.Context) { | ||||
|     req := dto.WmTransferInsertReq{} | ||||
|     s := service.WmTransfer{} | ||||
|     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.SetCreateBy(user.GetUserId(c)) | ||||
|  | ||||
| 	err = s.Insert(&req) | ||||
| 	if err != nil { | ||||
| 		e.Error(500, err, fmt.Sprintf("创建批量转账任务失败,\r\n失败信息 %s", err.Error())) | ||||
|         return | ||||
| 	} | ||||
|  | ||||
| 	e.OK(req.GetId(), "创建成功") | ||||
| } | ||||
|  | ||||
| // Update 修改批量转账任务 | ||||
| // @Summary 修改批量转账任务 | ||||
| // @Description 修改批量转账任务 | ||||
| // @Tags 批量转账任务 | ||||
| // @Accept application/json | ||||
| // @Product application/json | ||||
| // @Param id path int true "id" | ||||
| // @Param data body dto.WmTransferUpdateReq true "body" | ||||
| // @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}" | ||||
| // @Router /api/v1/wm-transfer/{id} [put] | ||||
| // @Security Bearer | ||||
| func (e WmTransfer) Update(c *gin.Context) { | ||||
|     req := dto.WmTransferUpdateReq{} | ||||
|     s := service.WmTransfer{} | ||||
|     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)) | ||||
| 	p := actions.GetPermissionFromContext(c) | ||||
|  | ||||
| 	err = s.Update(&req, p) | ||||
| 	if err != nil { | ||||
| 		e.Error(500, err, fmt.Sprintf("修改批量转账任务失败,\r\n失败信息 %s", err.Error())) | ||||
|         return | ||||
| 	} | ||||
| 	e.OK( req.GetId(), "修改成功") | ||||
| } | ||||
|  | ||||
| // Delete 删除批量转账任务 | ||||
| // @Summary 删除批量转账任务 | ||||
| // @Description 删除批量转账任务 | ||||
| // @Tags 批量转账任务 | ||||
| // @Param data body dto.WmTransferDeleteReq true "body" | ||||
| // @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}" | ||||
| // @Router /api/v1/wm-transfer [delete] | ||||
| // @Security Bearer | ||||
| func (e WmTransfer) Delete(c *gin.Context) { | ||||
|     s := service.WmTransfer{} | ||||
|     req := dto.WmTransferDeleteReq{} | ||||
|     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)) | ||||
| 	p := actions.GetPermissionFromContext(c) | ||||
|  | ||||
| 	err = s.Remove(&req, p) | ||||
| 	if err != nil { | ||||
| 		e.Error(500, err, fmt.Sprintf("删除批量转账任务失败,\r\n失败信息 %s", err.Error())) | ||||
|         return | ||||
| 	} | ||||
| 	e.OK( req.GetId(), "删除成功") | ||||
| } | ||||
							
								
								
									
										191
									
								
								app/admin/apis/wm_transfer_item.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								app/admin/apis/wm_transfer_item.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,191 @@ | ||||
| package apis | ||||
|  | ||||
| import ( | ||||
|     "fmt" | ||||
|  | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk/api" | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user" | ||||
| 	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response" | ||||
|  | ||||
| 	"go-admin/app/admin/models" | ||||
| 	"go-admin/app/admin/service" | ||||
| 	"go-admin/app/admin/service/dto" | ||||
| 	"go-admin/common/actions" | ||||
| ) | ||||
|  | ||||
| type WmTransferItem struct { | ||||
| 	api.Api | ||||
| } | ||||
|  | ||||
| // GetPage 获取批量转账明细列表 | ||||
| // @Summary 获取批量转账明细列表 | ||||
| // @Description 获取批量转账明细列表 | ||||
| // @Tags 批量转账明细 | ||||
| // @Param pageSize query int false "页条数" | ||||
| // @Param pageIndex query int false "页码" | ||||
| // @Success 200 {object} response.Response{data=response.Page{list=[]models.WmTransferItem}} "{"code": 200, "data": [...]}" | ||||
| // @Router /api/v1/wm-transfer-item [get] | ||||
| // @Security Bearer | ||||
| func (e WmTransferItem) GetPage(c *gin.Context) { | ||||
|     req := dto.WmTransferItemGetPageReq{} | ||||
|     s := service.WmTransferItem{} | ||||
|     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 | ||||
|    	} | ||||
|  | ||||
| 	p := actions.GetPermissionFromContext(c) | ||||
| 	list := make([]models.WmTransferItem, 0) | ||||
| 	var count int64 | ||||
|  | ||||
| 	err = s.GetPage(&req, p, &list, &count) | ||||
| 	if err != nil { | ||||
| 		e.Error(500, err, fmt.Sprintf("获取批量转账明细失败,\r\n失败信息 %s", err.Error())) | ||||
|         return | ||||
| 	} | ||||
|  | ||||
| 	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功") | ||||
| } | ||||
|  | ||||
| // Get 获取批量转账明细 | ||||
| // @Summary 获取批量转账明细 | ||||
| // @Description 获取批量转账明细 | ||||
| // @Tags 批量转账明细 | ||||
| // @Param id path int false "id" | ||||
| // @Success 200 {object} response.Response{data=models.WmTransferItem} "{"code": 200, "data": [...]}" | ||||
| // @Router /api/v1/wm-transfer-item/{id} [get] | ||||
| // @Security Bearer | ||||
| func (e WmTransferItem) Get(c *gin.Context) { | ||||
| 	req := dto.WmTransferItemGetReq{} | ||||
| 	s := service.WmTransferItem{} | ||||
|     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 | ||||
| 	} | ||||
| 	var object models.WmTransferItem | ||||
|  | ||||
| 	p := actions.GetPermissionFromContext(c) | ||||
| 	err = s.Get(&req, p, &object) | ||||
| 	if err != nil { | ||||
| 		e.Error(500, err, fmt.Sprintf("获取批量转账明细失败,\r\n失败信息 %s", err.Error())) | ||||
|         return | ||||
| 	} | ||||
|  | ||||
| 	e.OK( object, "查询成功") | ||||
| } | ||||
|  | ||||
| // Insert 创建批量转账明细 | ||||
| // @Summary 创建批量转账明细 | ||||
| // @Description 创建批量转账明细 | ||||
| // @Tags 批量转账明细 | ||||
| // @Accept application/json | ||||
| // @Product application/json | ||||
| // @Param data body dto.WmTransferItemInsertReq true "data" | ||||
| // @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}" | ||||
| // @Router /api/v1/wm-transfer-item [post] | ||||
| // @Security Bearer | ||||
| func (e WmTransferItem) Insert(c *gin.Context) { | ||||
|     req := dto.WmTransferItemInsertReq{} | ||||
|     s := service.WmTransferItem{} | ||||
|     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.SetCreateBy(user.GetUserId(c)) | ||||
|  | ||||
| 	err = s.Insert(&req) | ||||
| 	if err != nil { | ||||
| 		e.Error(500, err, fmt.Sprintf("创建批量转账明细失败,\r\n失败信息 %s", err.Error())) | ||||
|         return | ||||
| 	} | ||||
|  | ||||
| 	e.OK(req.GetId(), "创建成功") | ||||
| } | ||||
|  | ||||
| // Update 修改批量转账明细 | ||||
| // @Summary 修改批量转账明细 | ||||
| // @Description 修改批量转账明细 | ||||
| // @Tags 批量转账明细 | ||||
| // @Accept application/json | ||||
| // @Product application/json | ||||
| // @Param id path int true "id" | ||||
| // @Param data body dto.WmTransferItemUpdateReq true "body" | ||||
| // @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}" | ||||
| // @Router /api/v1/wm-transfer-item/{id} [put] | ||||
| // @Security Bearer | ||||
| func (e WmTransferItem) Update(c *gin.Context) { | ||||
|     req := dto.WmTransferItemUpdateReq{} | ||||
|     s := service.WmTransferItem{} | ||||
|     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)) | ||||
| 	p := actions.GetPermissionFromContext(c) | ||||
|  | ||||
| 	err = s.Update(&req, p) | ||||
| 	if err != nil { | ||||
| 		e.Error(500, err, fmt.Sprintf("修改批量转账明细失败,\r\n失败信息 %s", err.Error())) | ||||
|         return | ||||
| 	} | ||||
| 	e.OK( req.GetId(), "修改成功") | ||||
| } | ||||
|  | ||||
| // Delete 删除批量转账明细 | ||||
| // @Summary 删除批量转账明细 | ||||
| // @Description 删除批量转账明细 | ||||
| // @Tags 批量转账明细 | ||||
| // @Param data body dto.WmTransferItemDeleteReq true "body" | ||||
| // @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}" | ||||
| // @Router /api/v1/wm-transfer-item [delete] | ||||
| // @Security Bearer | ||||
| func (e WmTransferItem) Delete(c *gin.Context) { | ||||
|     s := service.WmTransferItem{} | ||||
|     req := dto.WmTransferItemDeleteReq{} | ||||
|     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)) | ||||
| 	p := actions.GetPermissionFromContext(c) | ||||
|  | ||||
| 	err = s.Remove(&req, p) | ||||
| 	if err != nil { | ||||
| 		e.Error(500, err, fmt.Sprintf("删除批量转账明细失败,\r\n失败信息 %s", err.Error())) | ||||
|         return | ||||
| 	} | ||||
| 	e.OK( req.GetId(), "删除成功") | ||||
| } | ||||
							
								
								
									
										154
									
								
								app/admin/apis/wm_wallet_info.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								app/admin/apis/wm_wallet_info.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,154 @@ | ||||
| package apis | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk/api" | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user" | ||||
| 	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response" | ||||
|  | ||||
| 	"go-admin/app/admin/models" | ||||
| 	"go-admin/app/admin/service" | ||||
| 	"go-admin/app/admin/service/dto" | ||||
| 	"go-admin/common/actions" | ||||
| ) | ||||
|  | ||||
| type WmWalletInfo struct { | ||||
| 	api.Api | ||||
| } | ||||
|  | ||||
| // GetPage 获取钱包信息列表 | ||||
| // @Summary 获取钱包信息列表 | ||||
| // @Description 获取钱包信息列表 | ||||
| // @Tags 钱包信息 | ||||
| // @Param privateKey query string false "钱包私钥" | ||||
| // @Param pageSize query int false "页条数" | ||||
| // @Param pageIndex query int false "页码" | ||||
| // @Success 200 {object} response.Response{data=response.Page{list=[]models.WmWalletInfo}} "{"code": 200, "data": [...]}" | ||||
| // @Router /api/v1/wm-wallet-info [get] | ||||
| // @Security Bearer | ||||
| func (e WmWalletInfo) GetPage(c *gin.Context) { | ||||
| 	req := dto.WmWalletInfoGetPageReq{} | ||||
| 	s := service.WmWalletInfo{} | ||||
| 	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 | ||||
| 	} | ||||
|  | ||||
| 	p := actions.GetPermissionFromContext(c) | ||||
| 	list := make([]models.WmWalletInfo, 0) | ||||
| 	var count int64 | ||||
|  | ||||
| 	err = s.GetPage(&req, p, &list, &count) | ||||
| 	if err != nil { | ||||
| 		e.Error(500, err, fmt.Sprintf("获取钱包信息失败,\r\n失败信息 %s", err.Error())) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功") | ||||
| } | ||||
|  | ||||
| // Get 获取钱包信息 | ||||
| // @Summary 获取钱包信息 | ||||
| // @Description 获取钱包信息 | ||||
| // @Tags 钱包信息 | ||||
| // @Param id path int false "id" | ||||
| // @Success 200 {object} response.Response{data=models.WmWalletInfo} "{"code": 200, "data": [...]}" | ||||
| // @Router /api/v1/wm-wallet-info/{id} [get] | ||||
| // @Security Bearer | ||||
| func (e WmWalletInfo) Get(c *gin.Context) { | ||||
| 	req := dto.WmWalletInfoGetReq{} | ||||
| 	s := service.WmWalletInfo{} | ||||
| 	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 | ||||
| 	} | ||||
| 	var object models.WmWalletInfo | ||||
|  | ||||
| 	p := actions.GetPermissionFromContext(c) | ||||
| 	err = s.Get(&req, p, &object) | ||||
| 	if err != nil { | ||||
| 		e.Error(500, err, fmt.Sprintf("获取钱包信息失败,\r\n失败信息 %s", err.Error())) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	e.OK(object, "查询成功") | ||||
| } | ||||
|  | ||||
| // Insert 创建钱包信息 | ||||
| // @Summary 创建钱包信息 | ||||
| // @Description 创建钱包信息 | ||||
| // @Tags 钱包信息 | ||||
| // @Accept application/json | ||||
| // @Product application/json | ||||
| // @Param data body dto.WmWalletInfoInsertReq true "data" | ||||
| // @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}" | ||||
| // @Router /api/v1/wm-wallet-info [post] | ||||
| // @Security Bearer | ||||
| func (e WmWalletInfo) Insert(c *gin.Context) { | ||||
| 	req := dto.WmWalletInfoBatchInsertReq{} | ||||
| 	s := service.WmWalletInfo{} | ||||
| 	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.SetCreateBy(user.GetUserId(c)) | ||||
|  | ||||
| 	errs := s.Insert(&req) | ||||
|  | ||||
| 	e.OK(strings.Join(errs, "<br/>"), "创建成功") | ||||
| } | ||||
|  | ||||
| // Delete 删除钱包信息 | ||||
| // @Summary 删除钱包信息 | ||||
| // @Description 删除钱包信息 | ||||
| // @Tags 钱包信息 | ||||
| // @Param data body dto.WmWalletInfoDeleteReq true "body" | ||||
| // @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}" | ||||
| // @Router /api/v1/wm-wallet-info [delete] | ||||
| // @Security Bearer | ||||
| func (e WmWalletInfo) Delete(c *gin.Context) { | ||||
| 	s := service.WmWalletInfo{} | ||||
| 	req := dto.WmWalletInfoDeleteReq{} | ||||
| 	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)) | ||||
| 	p := actions.GetPermissionFromContext(c) | ||||
|  | ||||
| 	err = s.Remove(&req, p) | ||||
| 	if err != nil { | ||||
| 		e.Error(500, err, fmt.Sprintf("删除钱包信息失败,\r\n失败信息 %s", err.Error())) | ||||
| 		return | ||||
| 	} | ||||
| 	e.OK(req.GetId(), "删除成功") | ||||
| } | ||||
							
								
								
									
										31
									
								
								app/admin/models/wm_transfer.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								app/admin/models/wm_transfer.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| package models | ||||
|  | ||||
| import ( | ||||
|  | ||||
| 	"go-admin/common/models" | ||||
|  | ||||
| ) | ||||
|  | ||||
| type WmTransfer struct { | ||||
|     models.Model | ||||
|      | ||||
|     Type int64 `json:"type" gorm:"type:tinyint;comment:类型 0-百分比 1-实际金额"`  | ||||
|     TransferType int64 `json:"transferType" gorm:"type:tinyint;comment:转账类型 0-批量转出 1-批量汇总"`  | ||||
|     Status int64 `json:"status" gorm:"type:tinyint;comment:状态"`  | ||||
|     Remark string `json:"remark" gorm:"type:varchar(255);comment:备注信息"`  | ||||
|     models.ModelTime | ||||
|     models.ControlBy | ||||
| } | ||||
|  | ||||
| func (WmTransfer) TableName() string { | ||||
|     return "wm_transfer" | ||||
| } | ||||
|  | ||||
| func (e *WmTransfer) Generate() models.ActiveRecord { | ||||
| 	o := *e | ||||
| 	return &o | ||||
| } | ||||
|  | ||||
| func (e *WmTransfer) GetId() interface{} { | ||||
| 	return e.Id | ||||
| } | ||||
							
								
								
									
										34
									
								
								app/admin/models/wm_transfer_item.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								app/admin/models/wm_transfer_item.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| package models | ||||
|  | ||||
| import ( | ||||
|  | ||||
| 	"go-admin/common/models" | ||||
|  | ||||
| ) | ||||
|  | ||||
| type WmTransferItem struct { | ||||
|     models.Model | ||||
|      | ||||
|     TokenAddress string `json:"tokenAddress" gorm:"type:varchar(50);comment:代币地址"`  | ||||
|     FromAddress string `json:"fromAddress" gorm:"type:varchar(50);comment:来源地址"`  | ||||
|     ToAddress string `json:"toAddress" gorm:"type:varchar(50);comment:目标地址"`  | ||||
|     Amount string `json:"amount" gorm:"type:decimal(18,8);comment:代币数量"`  | ||||
|     Type string `json:"type" gorm:"type:tinyint;comment:类型 0-主账号百分比 1-实际数量"`  | ||||
|     TypeValue string `json:"typeValue" gorm:"type:decimal(18,8);comment:操作类型值"`  | ||||
|     PrivateKey string `json:"privateKey" gorm:"type:varchar(255);comment:私钥"`  | ||||
|     models.ModelTime | ||||
|     models.ControlBy | ||||
| } | ||||
|  | ||||
| func (WmTransferItem) TableName() string { | ||||
|     return "wm_transfer_item" | ||||
| } | ||||
|  | ||||
| func (e *WmTransferItem) Generate() models.ActiveRecord { | ||||
| 	o := *e | ||||
| 	return &o | ||||
| } | ||||
|  | ||||
| func (e *WmTransferItem) GetId() interface{} { | ||||
| 	return e.Id | ||||
| } | ||||
							
								
								
									
										30
									
								
								app/admin/models/wm_wallet_info.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								app/admin/models/wm_wallet_info.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| package models | ||||
|  | ||||
| import ( | ||||
| 	"go-admin/common/models" | ||||
|  | ||||
| 	"github.com/shopspring/decimal" | ||||
| ) | ||||
|  | ||||
| type WmWalletInfo struct { | ||||
| 	models.Model | ||||
|  | ||||
| 	PrivateKey string          `json:"privateKey" 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余额"` | ||||
| 	models.ModelTime | ||||
| 	models.ControlBy | ||||
| } | ||||
|  | ||||
| func (WmWalletInfo) TableName() string { | ||||
| 	return "wm_wallet_info" | ||||
| } | ||||
|  | ||||
| func (e *WmWalletInfo) Generate() models.ActiveRecord { | ||||
| 	o := *e | ||||
| 	return &o | ||||
| } | ||||
|  | ||||
| func (e *WmWalletInfo) GetId() interface{} { | ||||
| 	return e.Id | ||||
| } | ||||
							
								
								
									
										27
									
								
								app/admin/router/wm_transfer.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/admin/router/wm_transfer.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| package router | ||||
|  | ||||
| import ( | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth" | ||||
|  | ||||
| 	"go-admin/app/admin/apis" | ||||
| 	"go-admin/common/middleware" | ||||
| 	"go-admin/common/actions" | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	routerCheckRole = append(routerCheckRole, registerWmTransferRouter) | ||||
| } | ||||
|  | ||||
| // registerWmTransferRouter | ||||
| func registerWmTransferRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { | ||||
| 	api := apis.WmTransfer{} | ||||
| 	r := v1.Group("/wm-transfer").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()) | ||||
| 	{ | ||||
| 		r.GET("", actions.PermissionAction(), api.GetPage) | ||||
| 		r.GET("/:id", actions.PermissionAction(), api.Get) | ||||
| 		r.POST("", api.Insert) | ||||
| 		r.PUT("/:id", actions.PermissionAction(), api.Update) | ||||
| 		r.DELETE("", api.Delete) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										27
									
								
								app/admin/router/wm_transfer_item.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/admin/router/wm_transfer_item.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| package router | ||||
|  | ||||
| import ( | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth" | ||||
|  | ||||
| 	"go-admin/app/admin/apis" | ||||
| 	"go-admin/common/middleware" | ||||
| 	"go-admin/common/actions" | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	routerCheckRole = append(routerCheckRole, registerWmTransferItemRouter) | ||||
| } | ||||
|  | ||||
| // registerWmTransferItemRouter | ||||
| func registerWmTransferItemRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { | ||||
| 	api := apis.WmTransferItem{} | ||||
| 	r := v1.Group("/wm-transfer-item").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()) | ||||
| 	{ | ||||
| 		r.GET("", actions.PermissionAction(), api.GetPage) | ||||
| 		r.GET("/:id", actions.PermissionAction(), api.Get) | ||||
| 		r.POST("", api.Insert) | ||||
| 		r.PUT("/:id", actions.PermissionAction(), api.Update) | ||||
| 		r.DELETE("", api.Delete) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										27
									
								
								app/admin/router/wm_wallet_info.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/admin/router/wm_wallet_info.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| package router | ||||
|  | ||||
| import ( | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth" | ||||
|  | ||||
| 	"go-admin/app/admin/apis" | ||||
| 	"go-admin/common/actions" | ||||
| 	"go-admin/common/middleware" | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	routerCheckRole = append(routerCheckRole, registerWmWalletInfoRouter) | ||||
| } | ||||
|  | ||||
| // registerWmWalletInfoRouter | ||||
| func registerWmWalletInfoRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { | ||||
| 	api := apis.WmWalletInfo{} | ||||
| 	r := v1.Group("/wm-wallet-info").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()) | ||||
| 	{ | ||||
| 		r.GET("", actions.PermissionAction(), api.GetPage) | ||||
| 		r.GET("/:id", actions.PermissionAction(), api.Get) | ||||
| 		r.POST("", api.Insert) | ||||
| 		// r.PUT("/:id", actions.PermissionAction(), api.Update) | ||||
| 		r.DELETE("", api.Delete) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										98
									
								
								app/admin/service/dto/wm_transfer.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								app/admin/service/dto/wm_transfer.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,98 @@ | ||||
| package dto | ||||
|  | ||||
| import ( | ||||
|  | ||||
| 	"go-admin/app/admin/models" | ||||
| 	"go-admin/common/dto" | ||||
| 	common "go-admin/common/models" | ||||
| ) | ||||
|  | ||||
| type WmTransferGetPageReq struct { | ||||
| 	dto.Pagination     `search:"-"` | ||||
|     Type int64 `form:"type"  search:"type:exact;column:type;table:wm_transfer" comment:"类型 0-百分比 1-实际金额"` | ||||
|     TransferType int64 `form:"transferType"  search:"type:exact;column:transfer_type;table:wm_transfer" comment:"转账类型 0-批量转出 1-批量汇总"` | ||||
|     WmTransferOrder | ||||
| } | ||||
|  | ||||
| type WmTransferOrder struct { | ||||
|     Id string `form:"idOrder"  search:"type:order;column:id;table:wm_transfer"` | ||||
|     Type string `form:"typeOrder"  search:"type:order;column:type;table:wm_transfer"` | ||||
|     TransferType string `form:"transferTypeOrder"  search:"type:order;column:transfer_type;table:wm_transfer"` | ||||
|     Status string `form:"statusOrder"  search:"type:order;column:status;table:wm_transfer"` | ||||
|     Remark string `form:"remarkOrder"  search:"type:order;column:remark;table:wm_transfer"` | ||||
|     CreateBy string `form:"createByOrder"  search:"type:order;column:create_by;table:wm_transfer"` | ||||
|     UpdateBy string `form:"updateByOrder"  search:"type:order;column:update_by;table:wm_transfer"` | ||||
|     CreatedAt string `form:"createdAtOrder"  search:"type:order;column:created_at;table:wm_transfer"` | ||||
|     UpdatedAt string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:wm_transfer"` | ||||
|     DeletedAt string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:wm_transfer"` | ||||
|      | ||||
| } | ||||
|  | ||||
| func (m *WmTransferGetPageReq) GetNeedSearch() interface{} { | ||||
| 	return *m | ||||
| } | ||||
|  | ||||
| type WmTransferInsertReq struct { | ||||
|     Id int `json:"-" comment:"主键id"` // 主键id | ||||
|     Type int64 `json:"type" comment:"类型 0-百分比 1-实际金额"` | ||||
|     TransferType int64 `json:"transferType" comment:"转账类型 0-批量转出 1-批量汇总"` | ||||
|     Status int64 `json:"status" comment:"状态"` | ||||
|     Remark string `json:"remark" comment:"备注信息"` | ||||
|     common.ControlBy | ||||
| } | ||||
|  | ||||
| func (s *WmTransferInsertReq) Generate(model *models.WmTransfer)  { | ||||
|     if s.Id == 0 { | ||||
|         model.Model = common.Model{ Id: s.Id } | ||||
|     } | ||||
|     model.Type = s.Type | ||||
|     model.TransferType = s.TransferType | ||||
|     model.Status = s.Status | ||||
|     model.Remark = s.Remark | ||||
|     model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 | ||||
| } | ||||
|  | ||||
| func (s *WmTransferInsertReq) GetId() interface{} { | ||||
| 	return s.Id | ||||
| } | ||||
|  | ||||
| type WmTransferUpdateReq struct { | ||||
|     Id int `uri:"id" comment:"主键id"` // 主键id | ||||
|     Type int64 `json:"type" comment:"类型 0-百分比 1-实际金额"` | ||||
|     TransferType int64 `json:"transferType" comment:"转账类型 0-批量转出 1-批量汇总"` | ||||
|     Status int64 `json:"status" comment:"状态"` | ||||
|     Remark string `json:"remark" comment:"备注信息"` | ||||
|     common.ControlBy | ||||
| } | ||||
|  | ||||
| func (s *WmTransferUpdateReq) Generate(model *models.WmTransfer)  { | ||||
|     if s.Id == 0 { | ||||
|         model.Model = common.Model{ Id: s.Id } | ||||
|     } | ||||
|     model.Type = s.Type | ||||
|     model.TransferType = s.TransferType | ||||
|     model.Status = s.Status | ||||
|     model.Remark = s.Remark | ||||
|     model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 | ||||
| } | ||||
|  | ||||
| func (s *WmTransferUpdateReq) GetId() interface{} { | ||||
| 	return s.Id | ||||
| } | ||||
|  | ||||
| // WmTransferGetReq 功能获取请求参数 | ||||
| type WmTransferGetReq struct { | ||||
|      Id int `uri:"id"` | ||||
| } | ||||
| func (s *WmTransferGetReq) GetId() interface{} { | ||||
| 	return s.Id | ||||
| } | ||||
|  | ||||
| // WmTransferDeleteReq 功能删除请求参数 | ||||
| type WmTransferDeleteReq struct { | ||||
| 	Ids []int `json:"ids"` | ||||
| } | ||||
|  | ||||
| func (s *WmTransferDeleteReq) GetId() interface{} { | ||||
| 	return s.Ids | ||||
| } | ||||
							
								
								
									
										111
									
								
								app/admin/service/dto/wm_transfer_item.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								app/admin/service/dto/wm_transfer_item.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,111 @@ | ||||
| package dto | ||||
|  | ||||
| import ( | ||||
|  | ||||
| 	"go-admin/app/admin/models" | ||||
| 	"go-admin/common/dto" | ||||
| 	common "go-admin/common/models" | ||||
| ) | ||||
|  | ||||
| type WmTransferItemGetPageReq struct { | ||||
| 	dto.Pagination     `search:"-"` | ||||
|     WmTransferItemOrder | ||||
| } | ||||
|  | ||||
| type WmTransferItemOrder struct { | ||||
|     Id string `form:"idOrder"  search:"type:order;column:id;table:wm_transfer_item"` | ||||
|     TokenAddress string `form:"tokenAddressOrder"  search:"type:order;column:token_address;table:wm_transfer_item"` | ||||
|     FromAddress string `form:"fromAddressOrder"  search:"type:order;column:from_address;table:wm_transfer_item"` | ||||
|     ToAddress string `form:"toAddressOrder"  search:"type:order;column:to_address;table:wm_transfer_item"` | ||||
|     Amount string `form:"amountOrder"  search:"type:order;column:amount;table:wm_transfer_item"` | ||||
|     Type string `form:"typeOrder"  search:"type:order;column:type;table:wm_transfer_item"` | ||||
|     TypeValue string `form:"typeValueOrder"  search:"type:order;column:type_value;table:wm_transfer_item"` | ||||
|     PrivateKey string `form:"privateKeyOrder"  search:"type:order;column:private_key;table:wm_transfer_item"` | ||||
|     CreateBy string `form:"createByOrder"  search:"type:order;column:create_by;table:wm_transfer_item"` | ||||
|     UpdateBy string `form:"updateByOrder"  search:"type:order;column:update_by;table:wm_transfer_item"` | ||||
|     CreatedAt string `form:"createdAtOrder"  search:"type:order;column:created_at;table:wm_transfer_item"` | ||||
|     UpdatedAt string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:wm_transfer_item"` | ||||
|     DeletedAt string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:wm_transfer_item"` | ||||
|      | ||||
| } | ||||
|  | ||||
| func (m *WmTransferItemGetPageReq) GetNeedSearch() interface{} { | ||||
| 	return *m | ||||
| } | ||||
|  | ||||
| type WmTransferItemInsertReq struct { | ||||
|     Id int `json:"-" comment:"主键id"` // 主键id | ||||
|     TokenAddress string `json:"tokenAddress" comment:"代币地址"` | ||||
|     FromAddress string `json:"fromAddress" comment:"来源地址"` | ||||
|     ToAddress string `json:"toAddress" comment:"目标地址"` | ||||
|     Amount string `json:"amount" comment:"代币数量"` | ||||
|     Type string `json:"type" comment:"类型 0-主账号百分比 1-实际数量"` | ||||
|     TypeValue string `json:"typeValue" comment:"操作类型值"` | ||||
|     PrivateKey string `json:"privateKey" comment:"私钥"` | ||||
|     common.ControlBy | ||||
| } | ||||
|  | ||||
| func (s *WmTransferItemInsertReq) Generate(model *models.WmTransferItem)  { | ||||
|     if s.Id == 0 { | ||||
|         model.Model = common.Model{ Id: s.Id } | ||||
|     } | ||||
|     model.TokenAddress = s.TokenAddress | ||||
|     model.FromAddress = s.FromAddress | ||||
|     model.ToAddress = s.ToAddress | ||||
|     model.Amount = s.Amount | ||||
|     model.Type = s.Type | ||||
|     model.TypeValue = s.TypeValue | ||||
|     model.PrivateKey = s.PrivateKey | ||||
|     model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 | ||||
| } | ||||
|  | ||||
| func (s *WmTransferItemInsertReq) GetId() interface{} { | ||||
| 	return s.Id | ||||
| } | ||||
|  | ||||
| type WmTransferItemUpdateReq struct { | ||||
|     Id int `uri:"id" comment:"主键id"` // 主键id | ||||
|     TokenAddress string `json:"tokenAddress" comment:"代币地址"` | ||||
|     FromAddress string `json:"fromAddress" comment:"来源地址"` | ||||
|     ToAddress string `json:"toAddress" comment:"目标地址"` | ||||
|     Amount string `json:"amount" comment:"代币数量"` | ||||
|     Type string `json:"type" comment:"类型 0-主账号百分比 1-实际数量"` | ||||
|     TypeValue string `json:"typeValue" comment:"操作类型值"` | ||||
|     PrivateKey string `json:"privateKey" comment:"私钥"` | ||||
|     common.ControlBy | ||||
| } | ||||
|  | ||||
| func (s *WmTransferItemUpdateReq) Generate(model *models.WmTransferItem)  { | ||||
|     if s.Id == 0 { | ||||
|         model.Model = common.Model{ Id: s.Id } | ||||
|     } | ||||
|     model.TokenAddress = s.TokenAddress | ||||
|     model.FromAddress = s.FromAddress | ||||
|     model.ToAddress = s.ToAddress | ||||
|     model.Amount = s.Amount | ||||
|     model.Type = s.Type | ||||
|     model.TypeValue = s.TypeValue | ||||
|     model.PrivateKey = s.PrivateKey | ||||
|     model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 | ||||
| } | ||||
|  | ||||
| func (s *WmTransferItemUpdateReq) GetId() interface{} { | ||||
| 	return s.Id | ||||
| } | ||||
|  | ||||
| // WmTransferItemGetReq 功能获取请求参数 | ||||
| type WmTransferItemGetReq struct { | ||||
|      Id int `uri:"id"` | ||||
| } | ||||
| func (s *WmTransferItemGetReq) GetId() interface{} { | ||||
| 	return s.Id | ||||
| } | ||||
|  | ||||
| // WmTransferItemDeleteReq 功能删除请求参数 | ||||
| type WmTransferItemDeleteReq struct { | ||||
| 	Ids []int `json:"ids"` | ||||
| } | ||||
|  | ||||
| func (s *WmTransferItemDeleteReq) GetId() interface{} { | ||||
| 	return s.Ids | ||||
| } | ||||
							
								
								
									
										105
									
								
								app/admin/service/dto/wm_wallet_info.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								app/admin/service/dto/wm_wallet_info.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,105 @@ | ||||
| package dto | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"go-admin/app/admin/models" | ||||
| 	"go-admin/common/dto" | ||||
| 	common "go-admin/common/models" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| type WmWalletInfoGetPageReq struct { | ||||
| 	dto.Pagination `search:"-"` | ||||
| 	PrivateKey     string `form:"privateKey"  search:"type:exact;column:private_key;table:wm_wallet_info" comment:"钱包私钥"` | ||||
| 	WmWalletInfoOrder | ||||
| } | ||||
|  | ||||
| type WmWalletInfoOrder struct { | ||||
| 	Id         string `form:"idOrder"  search:"type:order;column:id;table:wm_wallet_info"` | ||||
| 	PrivateKey string `form:"privateKeyOrder"  search:"type:order;column:private_key;table:wm_wallet_info"` | ||||
| 	Address    string `form:"addressOrder"  search:"type:order;column:address;table:wm_wallet_info"` | ||||
| 	CreateBy   string `form:"createByOrder"  search:"type:order;column:create_by;table:wm_wallet_info"` | ||||
| 	UpdateBy   string `form:"updateByOrder"  search:"type:order;column:update_by;table:wm_wallet_info"` | ||||
| 	CreatedAt  string `form:"createdAtOrder"  search:"type:order;column:created_at;table:wm_wallet_info"` | ||||
| 	UpdatedAt  string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:wm_wallet_info"` | ||||
| 	DeletedAt  string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:wm_wallet_info"` | ||||
| } | ||||
|  | ||||
| func (m *WmWalletInfoGetPageReq) GetNeedSearch() interface{} { | ||||
| 	return *m | ||||
| } | ||||
|  | ||||
| type WmWalletInfoBatchInsertReq struct { | ||||
| 	Keys string `json:"keys"` | ||||
| 	common.ControlBy | ||||
| } | ||||
|  | ||||
| func (s *WmWalletInfoBatchInsertReq) Valid() error { | ||||
| 	s.Keys = strings.ReplaceAll(s.Keys, " ", "") | ||||
| 	s.Keys = strings.ReplaceAll(s.Keys, ",", "\n") | ||||
| 	s.Keys = strings.ReplaceAll(s.Keys, ",", "\n") | ||||
|  | ||||
| 	if s.Keys == "" { | ||||
| 		return errors.New("请至少输入一条数据") | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type WmWalletInfoInsertReq struct { | ||||
| 	Id         int    `json:"-" comment:"主键Id"` // 主键Id | ||||
| 	PrivateKey string `json:"privateKey" comment:"钱包私钥"` | ||||
| 	Address    string `json:"address" comment:"钱包地址"` | ||||
| 	common.ControlBy | ||||
| } | ||||
|  | ||||
| func (s *WmWalletInfoInsertReq) Generate(model *models.WmWalletInfo) { | ||||
| 	if s.Id == 0 { | ||||
| 		model.Model = common.Model{Id: s.Id} | ||||
| 	} | ||||
| 	model.PrivateKey = s.PrivateKey | ||||
| 	model.Address = s.Address | ||||
| 	model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 | ||||
| } | ||||
|  | ||||
| func (s *WmWalletInfoInsertReq) GetId() interface{} { | ||||
| 	return s.Id | ||||
| } | ||||
|  | ||||
| type WmWalletInfoUpdateReq struct { | ||||
| 	Id         int    `uri:"id" comment:"主键Id"` // 主键Id | ||||
| 	PrivateKey string `json:"privateKey" comment:"钱包私钥"` | ||||
| 	Address    string `json:"address" comment:"钱包地址"` | ||||
| 	common.ControlBy | ||||
| } | ||||
|  | ||||
| func (s *WmWalletInfoUpdateReq) Generate(model *models.WmWalletInfo) { | ||||
| 	if s.Id == 0 { | ||||
| 		model.Model = common.Model{Id: s.Id} | ||||
| 	} | ||||
| 	model.PrivateKey = s.PrivateKey | ||||
| 	model.Address = s.Address | ||||
| 	model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 | ||||
| } | ||||
|  | ||||
| func (s *WmWalletInfoUpdateReq) GetId() interface{} { | ||||
| 	return s.Id | ||||
| } | ||||
|  | ||||
| // WmWalletInfoGetReq 功能获取请求参数 | ||||
| type WmWalletInfoGetReq struct { | ||||
| 	Id int `uri:"id"` | ||||
| } | ||||
|  | ||||
| func (s *WmWalletInfoGetReq) GetId() interface{} { | ||||
| 	return s.Id | ||||
| } | ||||
|  | ||||
| // WmWalletInfoDeleteReq 功能删除请求参数 | ||||
| type WmWalletInfoDeleteReq struct { | ||||
| 	Ids []int `json:"ids"` | ||||
| } | ||||
|  | ||||
| func (s *WmWalletInfoDeleteReq) GetId() interface{} { | ||||
| 	return s.Ids | ||||
| } | ||||
							
								
								
									
										109
									
								
								app/admin/service/wm_transfer.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								app/admin/service/wm_transfer.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | ||||
| package service | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
|  | ||||
|     "github.com/go-admin-team/go-admin-core/sdk/service" | ||||
| 	"gorm.io/gorm" | ||||
|  | ||||
| 	"go-admin/app/admin/models" | ||||
| 	"go-admin/app/admin/service/dto" | ||||
| 	"go-admin/common/actions" | ||||
| 	cDto "go-admin/common/dto" | ||||
| ) | ||||
|  | ||||
| type WmTransfer struct { | ||||
| 	service.Service | ||||
| } | ||||
|  | ||||
| // GetPage 获取WmTransfer列表 | ||||
| func (e *WmTransfer) GetPage(c *dto.WmTransferGetPageReq, p *actions.DataPermission, list *[]models.WmTransfer, count *int64) error { | ||||
| 	var err error | ||||
| 	var data models.WmTransfer | ||||
|  | ||||
| 	err = e.Orm.Model(&data). | ||||
| 		Scopes( | ||||
| 			cDto.MakeCondition(c.GetNeedSearch()), | ||||
| 			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()), | ||||
| 			actions.Permission(data.TableName(), p), | ||||
| 		). | ||||
| 		Find(list).Limit(-1).Offset(-1). | ||||
| 		Count(count).Error | ||||
| 	if err != nil { | ||||
| 		e.Log.Errorf("WmTransferService GetPage error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Get 获取WmTransfer对象 | ||||
| func (e *WmTransfer) Get(d *dto.WmTransferGetReq, p *actions.DataPermission, model *models.WmTransfer) error { | ||||
| 	var data models.WmTransfer | ||||
|  | ||||
| 	err := e.Orm.Model(&data). | ||||
| 		Scopes( | ||||
| 			actions.Permission(data.TableName(), p), | ||||
| 		). | ||||
| 		First(model, d.GetId()).Error | ||||
| 	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { | ||||
| 		err = errors.New("查看对象不存在或无权查看") | ||||
| 		e.Log.Errorf("Service GetWmTransfer error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		e.Log.Errorf("db error:%s", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Insert 创建WmTransfer对象 | ||||
| func (e *WmTransfer) Insert(c *dto.WmTransferInsertReq) error { | ||||
|     var err error | ||||
|     var data models.WmTransfer | ||||
|     c.Generate(&data) | ||||
| 	err = e.Orm.Create(&data).Error | ||||
| 	if err != nil { | ||||
| 		e.Log.Errorf("WmTransferService Insert error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Update 修改WmTransfer对象 | ||||
| func (e *WmTransfer) Update(c *dto.WmTransferUpdateReq, p *actions.DataPermission) error { | ||||
|     var err error | ||||
|     var data = models.WmTransfer{} | ||||
|     e.Orm.Scopes( | ||||
|             actions.Permission(data.TableName(), p), | ||||
|         ).First(&data, c.GetId()) | ||||
|     c.Generate(&data) | ||||
|  | ||||
|     db := e.Orm.Save(&data) | ||||
|     if err = db.Error; err != nil { | ||||
|         e.Log.Errorf("WmTransferService Save error:%s \r\n", err) | ||||
|         return err | ||||
|     } | ||||
|     if db.RowsAffected == 0 { | ||||
|         return errors.New("无权更新该数据") | ||||
|     } | ||||
|     return nil | ||||
| } | ||||
|  | ||||
| // Remove 删除WmTransfer | ||||
| func (e *WmTransfer) Remove(d *dto.WmTransferDeleteReq, p *actions.DataPermission) error { | ||||
| 	var data models.WmTransfer | ||||
|  | ||||
| 	db := e.Orm.Model(&data). | ||||
| 		Scopes( | ||||
| 			actions.Permission(data.TableName(), p), | ||||
| 		).Delete(&data, d.GetId()) | ||||
| 	if err := db.Error; err != nil { | ||||
|         e.Log.Errorf("Service RemoveWmTransfer error:%s \r\n", err) | ||||
|         return err | ||||
|     } | ||||
|     if db.RowsAffected == 0 { | ||||
|         return errors.New("无权删除该数据") | ||||
|     } | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										109
									
								
								app/admin/service/wm_transfer_item.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								app/admin/service/wm_transfer_item.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | ||||
| package service | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
|  | ||||
|     "github.com/go-admin-team/go-admin-core/sdk/service" | ||||
| 	"gorm.io/gorm" | ||||
|  | ||||
| 	"go-admin/app/admin/models" | ||||
| 	"go-admin/app/admin/service/dto" | ||||
| 	"go-admin/common/actions" | ||||
| 	cDto "go-admin/common/dto" | ||||
| ) | ||||
|  | ||||
| type WmTransferItem struct { | ||||
| 	service.Service | ||||
| } | ||||
|  | ||||
| // GetPage 获取WmTransferItem列表 | ||||
| func (e *WmTransferItem) GetPage(c *dto.WmTransferItemGetPageReq, p *actions.DataPermission, list *[]models.WmTransferItem, count *int64) error { | ||||
| 	var err error | ||||
| 	var data models.WmTransferItem | ||||
|  | ||||
| 	err = e.Orm.Model(&data). | ||||
| 		Scopes( | ||||
| 			cDto.MakeCondition(c.GetNeedSearch()), | ||||
| 			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()), | ||||
| 			actions.Permission(data.TableName(), p), | ||||
| 		). | ||||
| 		Find(list).Limit(-1).Offset(-1). | ||||
| 		Count(count).Error | ||||
| 	if err != nil { | ||||
| 		e.Log.Errorf("WmTransferItemService GetPage error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Get 获取WmTransferItem对象 | ||||
| func (e *WmTransferItem) Get(d *dto.WmTransferItemGetReq, p *actions.DataPermission, model *models.WmTransferItem) error { | ||||
| 	var data models.WmTransferItem | ||||
|  | ||||
| 	err := e.Orm.Model(&data). | ||||
| 		Scopes( | ||||
| 			actions.Permission(data.TableName(), p), | ||||
| 		). | ||||
| 		First(model, d.GetId()).Error | ||||
| 	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { | ||||
| 		err = errors.New("查看对象不存在或无权查看") | ||||
| 		e.Log.Errorf("Service GetWmTransferItem error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		e.Log.Errorf("db error:%s", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Insert 创建WmTransferItem对象 | ||||
| func (e *WmTransferItem) Insert(c *dto.WmTransferItemInsertReq) error { | ||||
|     var err error | ||||
|     var data models.WmTransferItem | ||||
|     c.Generate(&data) | ||||
| 	err = e.Orm.Create(&data).Error | ||||
| 	if err != nil { | ||||
| 		e.Log.Errorf("WmTransferItemService Insert error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Update 修改WmTransferItem对象 | ||||
| func (e *WmTransferItem) Update(c *dto.WmTransferItemUpdateReq, p *actions.DataPermission) error { | ||||
|     var err error | ||||
|     var data = models.WmTransferItem{} | ||||
|     e.Orm.Scopes( | ||||
|             actions.Permission(data.TableName(), p), | ||||
|         ).First(&data, c.GetId()) | ||||
|     c.Generate(&data) | ||||
|  | ||||
|     db := e.Orm.Save(&data) | ||||
|     if err = db.Error; err != nil { | ||||
|         e.Log.Errorf("WmTransferItemService Save error:%s \r\n", err) | ||||
|         return err | ||||
|     } | ||||
|     if db.RowsAffected == 0 { | ||||
|         return errors.New("无权更新该数据") | ||||
|     } | ||||
|     return nil | ||||
| } | ||||
|  | ||||
| // Remove 删除WmTransferItem | ||||
| func (e *WmTransferItem) Remove(d *dto.WmTransferItemDeleteReq, p *actions.DataPermission) error { | ||||
| 	var data models.WmTransferItem | ||||
|  | ||||
| 	db := e.Orm.Model(&data). | ||||
| 		Scopes( | ||||
| 			actions.Permission(data.TableName(), p), | ||||
| 		).Delete(&data, d.GetId()) | ||||
| 	if err := db.Error; err != nil { | ||||
|         e.Log.Errorf("Service RemoveWmTransferItem error:%s \r\n", err) | ||||
|         return err | ||||
|     } | ||||
|     if db.RowsAffected == 0 { | ||||
|         return errors.New("无权删除该数据") | ||||
|     } | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										174
									
								
								app/admin/service/wm_wallet_info.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								app/admin/service/wm_wallet_info.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,174 @@ | ||||
| package service | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk/service" | ||||
| 	"gorm.io/gorm" | ||||
|  | ||||
| 	"go-admin/abis/ethereumabi" | ||||
| 	"go-admin/app/admin/models" | ||||
| 	"go-admin/app/admin/service/dto" | ||||
| 	"go-admin/common/actions" | ||||
| 	cDto "go-admin/common/dto" | ||||
| 	"go-admin/config" | ||||
| 	"go-admin/utils/aeshelper" | ||||
| 	"go-admin/utils/ethbalanceofhelper" | ||||
| 	"go-admin/utils/ethtransferhelper" | ||||
| 	"go-admin/utils/stringhelper" | ||||
| ) | ||||
|  | ||||
| type WmWalletInfo struct { | ||||
| 	service.Service | ||||
| } | ||||
|  | ||||
| // GetPage 获取WmWalletInfo列表 | ||||
| func (e *WmWalletInfo) GetPage(c *dto.WmWalletInfoGetPageReq, p *actions.DataPermission, list *[]models.WmWalletInfo, count *int64) error { | ||||
| 	var err error | ||||
| 	var data models.WmWalletInfo | ||||
|  | ||||
| 	err = e.Orm.Model(&data). | ||||
| 		Scopes( | ||||
| 			cDto.MakeCondition(c.GetNeedSearch()), | ||||
| 			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()), | ||||
| 			actions.Permission(data.TableName(), p), | ||||
| 		). | ||||
| 		Find(list).Limit(-1).Offset(-1). | ||||
| 		Count(count).Error | ||||
| 	if err != nil { | ||||
| 		e.Log.Errorf("WmWalletInfoService GetPage error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	for i := 0; i < len(*list); i++ { | ||||
| 		(*list)[i].PrivateKey = stringhelper.DesensitizeWalletAddress(aeshelper.AesEcbDecrypt((*list)[i].PrivateKey)) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Get 获取WmWalletInfo对象 | ||||
| func (e *WmWalletInfo) Get(d *dto.WmWalletInfoGetReq, p *actions.DataPermission, model *models.WmWalletInfo) error { | ||||
| 	var data models.WmWalletInfo | ||||
|  | ||||
| 	err := e.Orm.Model(&data). | ||||
| 		Scopes( | ||||
| 			actions.Permission(data.TableName(), p), | ||||
| 		). | ||||
| 		First(model, d.GetId()).Error | ||||
| 	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { | ||||
| 		err = errors.New("查看对象不存在或无权查看") | ||||
| 		e.Log.Errorf("Service GetWmWalletInfo error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		e.Log.Errorf("db error:%s", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Insert 创建WmWalletInfo对象 | ||||
| func (e *WmWalletInfo) Insert(c *dto.WmWalletInfoBatchInsertReq) []string { | ||||
| 	errs := []string{} | ||||
| 	var count int64 | ||||
| 	keys := strings.Split(c.Keys, "\n") | ||||
|  | ||||
| 	for _, key := range keys { | ||||
| 		if key == "" { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		var data models.WmWalletInfo | ||||
| 		data.PrivateKey = aeshelper.AesEcbEncrypt(key) | ||||
| 		_, address, _ := ethtransferhelper.GetAddressFromPrivateKey(key) | ||||
| 		data.Address = address.String() | ||||
|  | ||||
| 		if err := e.Orm.Model(data).Where("private_key =?", data.PrivateKey).Count(&count).Error; err != nil { | ||||
| 			e.Log.Errorf("db error:%s", err) | ||||
| 		} | ||||
|  | ||||
| 		if count == 0 { | ||||
| 			if err := e.Orm.Create(&data).Error; err != nil { | ||||
| 				e.Log.Errorf("db error:%s", err) | ||||
| 				errs = append(errs, key) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return errs | ||||
| } | ||||
|  | ||||
| // Update 修改WmWalletInfo对象 | ||||
| func (e *WmWalletInfo) Update(c *dto.WmWalletInfoUpdateReq, p *actions.DataPermission) error { | ||||
| 	var err error | ||||
| 	var data = models.WmWalletInfo{} | ||||
| 	e.Orm.Scopes( | ||||
| 		actions.Permission(data.TableName(), p), | ||||
| 	).First(&data, c.GetId()) | ||||
| 	c.Generate(&data) | ||||
|  | ||||
| 	db := e.Orm.Save(&data) | ||||
| 	if err = db.Error; err != nil { | ||||
| 		e.Log.Errorf("WmWalletInfoService Save error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	if db.RowsAffected == 0 { | ||||
| 		return errors.New("无权更新该数据") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Remove 删除WmWalletInfo | ||||
| func (e *WmWalletInfo) Remove(d *dto.WmWalletInfoDeleteReq, p *actions.DataPermission) error { | ||||
| 	var data models.WmWalletInfo | ||||
|  | ||||
| 	db := e.Orm.Model(&data). | ||||
| 		Scopes( | ||||
| 			actions.Permission(data.TableName(), p), | ||||
| 		).Delete(&data, d.GetId()) | ||||
| 	if err := db.Error; err != nil { | ||||
| 		e.Log.Errorf("Service RemoveWmWalletInfo error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	if db.RowsAffected == 0 { | ||||
| 		return errors.New("无权删除该数据") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // ScheduledTask 定时任务 | ||||
| func (e *WmWalletInfo) ScheduledTask() error { | ||||
| 	var datas []models.WmWalletInfo | ||||
|  | ||||
| 	if err := e.Orm.Model(models.WmWalletInfo{}).Find(&datas).Error; err != nil { | ||||
| 		e.Log.Errorf("db error:%s", err) | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	client, err := ethbalanceofhelper.EthClientWithProxy(config.ExtConfig.ApiEndpoint, config.ExtConfig.ProxyUrl) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		e.Log.Errorf("ethclient error:%s", err) | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	for i := range datas { | ||||
| 		amount, err := ethbalanceofhelper.GetERC20Balance(client, ethereumabi.USDCErc20, datas[i].Address) | ||||
|  | ||||
| 		if err != nil { | ||||
| 			e.Log.Errorf("GetERC20Balance error:%s", err) | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		datas[i].UsdcAmount = amount | ||||
|  | ||||
| 		if err := e.Orm.Model(&datas[i]).Update("usdc_amount", amount).Error; err != nil { | ||||
| 			e.Log.Errorf("db error:%s", err) | ||||
| 			continue | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										31
									
								
								app/jobs/transfer_job.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								app/jobs/transfer_job.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| package jobs | ||||
|  | ||||
| import ( | ||||
| 	"go-admin/app/admin/service" | ||||
|  | ||||
| 	"github.com/go-admin-team/go-admin-core/logger" | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk" | ||||
| 	"gorm.io/gorm" | ||||
| ) | ||||
|  | ||||
| type TransferJob struct{} | ||||
|  | ||||
| // 定期转账 | ||||
| func (t TransferJob) Exec(arg interface{}) error { | ||||
| 	walletService := service.WmWalletInfo{} | ||||
| 	walletService.Orm = getDefaultDb() | ||||
| 	walletService.Log = logger.NewHelper(logger.DefaultLogger) | ||||
|  | ||||
| 	return walletService.ScheduledTask() | ||||
| } | ||||
|  | ||||
| func getDefaultDb() *gorm.DB { | ||||
| 	dbs := sdk.Runtime.GetDb() | ||||
| 	var db *gorm.DB | ||||
|  | ||||
| 	for _, item := range dbs { | ||||
| 		db = item | ||||
| 		break | ||||
| 	} | ||||
| 	return db | ||||
| } | ||||
							
								
								
									
										23
									
								
								app/jobs/transfer_job_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								app/jobs/transfer_job_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| package jobs | ||||
|  | ||||
| import ( | ||||
| 	"go-admin/config" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk" | ||||
| 	"gorm.io/driver/mysql" | ||||
| 	"gorm.io/gorm" | ||||
| ) | ||||
|  | ||||
| func TestTransferJob(t *testing.T) { | ||||
| 	dsn := "root:123456@tcp(127.0.0.1:3306)/eth_transfer?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms" | ||||
| 	db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{}) | ||||
| 	sdk.Runtime.SetDb("default", db) | ||||
|  | ||||
| 	config.ExtConfig.ApiEndpoint = "https://stylish-cool-fire.ethereum-sepolia.quiknode.pro/17572db4c091accfa5dc6faa0c60a805e5173459" | ||||
| 	config.ExtConfig.ProxyUrl = "http://127.0.0.1:7890" | ||||
|  | ||||
| 	job := TransferJob{} | ||||
|  | ||||
| 	job.Exec(nil) | ||||
| } | ||||
| @ -3,12 +3,17 @@ package config | ||||
| var ExtConfig Extend | ||||
|  | ||||
| // Extend 扩展配置 | ||||
| // | ||||
| //	extend: | ||||
| //	  demo: | ||||
| //	    name: demo-name | ||||
| // | ||||
| // 使用方法: config.ExtConfig......即可!! | ||||
| type Extend struct { | ||||
| 	AMap AMap // 这里配置对应配置文件的结构即可 | ||||
|  | ||||
| 	ApiEndpoint string //rpc api地址 | ||||
| 	ProxyUrl    string //代理地址 | ||||
| } | ||||
|  | ||||
| type AMap struct { | ||||
|  | ||||
| @ -5,7 +5,7 @@ settings: | ||||
|     # 服务器ip,默认使用 0.0.0.0 | ||||
|     host: 0.0.0.0 | ||||
|     # 服务名称 | ||||
|     name: testApp | ||||
|     name: ethTransfer | ||||
|     # 端口号 | ||||
|     port: 8000 # 服务端口号 | ||||
|     readtimeout: 1 | ||||
| @ -23,7 +23,7 @@ settings: | ||||
|     enableddb: false | ||||
|   jwt: | ||||
|     # token 密钥,生产环境时及的修改 | ||||
|     secret: go-admin | ||||
|     secret: eth-transfer-admin | ||||
|     # token 过期时间 单位:秒 | ||||
|     timeout: 3600 | ||||
|   database: | ||||
| @ -31,7 +31,7 @@ settings: | ||||
|     # sqlserver: sqlserver://用户名:密码@地址?database=数据库名 | ||||
|     driver: mysql | ||||
|     # 数据库连接字符串 mysql 缺省信息 charset=utf8&parseTime=True&loc=Local&timeout=1000ms | ||||
|     source: user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8&parseTime=True&loc=Local&timeout=1000ms | ||||
|     source: root:123456@tcp(127.0.0.1:3306)/eth_transfer?charset=utf8&parseTime=True&loc=Local&timeout=1000ms | ||||
| #  databases: | ||||
| #    'locaohost:8000': | ||||
| #      driver: mysql | ||||
| @ -42,17 +42,19 @@ settings: | ||||
| #            - user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8&parseTime=True&loc=Local&timeout=1000ms | ||||
|   gen: | ||||
|     # 代码生成读取的数据库名称 | ||||
|     dbname: dbname | ||||
|     dbname: eth_transfer | ||||
|     # 代码生成是使用前端代码存放位置,需要指定到src文件夹,相对路径 | ||||
|     frontpath: ../go-admin-ui/src | ||||
|   extend: # 扩展项使用说明 | ||||
|     demo: | ||||
|       name: data | ||||
|      | ||||
|     apiEndpoint: https://stylish-cool-fire.ethereum-sepolia.quiknode.pro/17572db4c091accfa5dc6faa0c60a805e5173459 | ||||
|   cache: | ||||
| #    redis: | ||||
| #      addr: 127.0.0.1:6379 | ||||
| #      password: xxxxxx | ||||
| #      db: 2 | ||||
|     redis: | ||||
|      addr: 127.0.0.1:6379 | ||||
|      password: '' | ||||
|      db: 15 | ||||
|     # key存在即可 | ||||
|     memory: ''  | ||||
|   queue: | ||||
|  | ||||
							
								
								
									
										92
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										92
									
								
								go.mod
									
									
									
									
									
								
							| @ -1,6 +1,8 @@ | ||||
| module go-admin | ||||
|  | ||||
| go 1.18 | ||||
| go 1.23.0 | ||||
|  | ||||
| toolchain go1.24.2 | ||||
|  | ||||
| require ( | ||||
| 	github.com/alibaba/sentinel-golang v1.0.4 | ||||
| @ -9,6 +11,7 @@ require ( | ||||
| 	github.com/bitly/go-simplejson v0.5.0 | ||||
| 	github.com/bytedance/go-tagexpr/v2 v2.7.12 | ||||
| 	github.com/casbin/casbin/v2 v2.51.2 | ||||
| 	github.com/ethereum/go-ethereum v1.15.11 | ||||
| 	github.com/gin-gonic/gin v1.9.1 | ||||
| 	github.com/go-admin-team/go-admin-core v1.4.1-0.20220809101213-21187928f7d9 | ||||
| 	github.com/go-admin-team/go-admin-core/sdk v1.4.1-0.20220809101213-21187928f7d9 | ||||
| @ -17,16 +20,16 @@ require ( | ||||
| 	github.com/mssola/user_agent v0.5.2 | ||||
| 	github.com/opentracing/opentracing-go v1.1.0 | ||||
| 	github.com/pkg/errors v0.9.1 | ||||
| 	github.com/prometheus/client_golang v1.11.1 | ||||
| 	github.com/prometheus/client_golang v1.12.0 | ||||
| 	github.com/qiniu/go-sdk/v7 v7.11.1 | ||||
| 	github.com/robfig/cron/v3 v3.0.1 | ||||
| 	github.com/shirou/gopsutil/v3 v3.22.1 | ||||
| 	github.com/spf13/cobra v1.0.0 | ||||
| 	github.com/spf13/cobra v1.8.1 | ||||
| 	github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a | ||||
| 	github.com/swaggo/gin-swagger v1.5.0 | ||||
| 	github.com/swaggo/swag v1.8.3 | ||||
| 	github.com/unrolled/secure v1.0.8 | ||||
| 	golang.org/x/crypto v0.9.0 | ||||
| 	golang.org/x/crypto v0.38.0 | ||||
| 	gorm.io/driver/mysql v1.3.5 | ||||
| 	gorm.io/driver/postgres v1.3.8 | ||||
| 	gorm.io/driver/sqlite v1.3.6 | ||||
| @ -38,26 +41,41 @@ require ( | ||||
| 	github.com/BurntSushi/toml v0.3.1 // indirect | ||||
| 	github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect | ||||
| 	github.com/KyleBanks/depth v1.2.1 // indirect | ||||
| 	github.com/Microsoft/go-winio v0.6.2 // indirect | ||||
| 	github.com/PuerkitoBio/purell v1.1.1 // indirect | ||||
| 	github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect | ||||
| 	github.com/StackExchange/wmi v1.2.1 // indirect | ||||
| 	github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect | ||||
| 	github.com/beorn7/perks v1.0.1 // indirect | ||||
| 	github.com/bits-and-blooms/bitset v1.20.0 // indirect | ||||
| 	github.com/bsm/redislock v0.5.0 // indirect | ||||
| 	github.com/bytedance/sonic v1.9.1 // indirect | ||||
| 	github.com/casbin/redis-watcher/v2 v2.0.0-20220614104201-0e70bf2be930 // indirect | ||||
| 	github.com/cespare/xxhash/v2 v2.1.2 // indirect | ||||
| 	github.com/cespare/xxhash/v2 v2.3.0 // indirect | ||||
| 	github.com/chanxuehong/rand v0.0.0-20201110082127-2f19a1bdd973 // indirect | ||||
| 	github.com/chanxuehong/wechat v0.0.0-20201110083048-0180211b69fd // indirect | ||||
| 	github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect | ||||
| 	github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect | ||||
| 	github.com/consensys/bavard v0.1.27 // indirect | ||||
| 	github.com/consensys/gnark-crypto v0.16.0 // indirect | ||||
| 	github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect | ||||
| 	github.com/crate-crypto/go-eth-kzg v1.3.0 // indirect | ||||
| 	github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect | ||||
| 	github.com/deckarep/golang-set/v2 v2.6.0 // indirect | ||||
| 	github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect | ||||
| 	github.com/denisenkom/go-mssqldb v0.12.0 // indirect | ||||
| 	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect | ||||
| 	github.com/fatih/color v1.9.0 // indirect | ||||
| 	github.com/fsnotify/fsnotify v1.4.9 // indirect | ||||
| 	github.com/ethereum/c-kzg-4844/v2 v2.1.0 // indirect | ||||
| 	github.com/ethereum/go-verkle v0.2.2 // indirect | ||||
| 	github.com/fatih/color v1.16.0 // indirect | ||||
| 	github.com/forgoer/openssl v1.6.0 // indirect | ||||
| 	github.com/fsnotify/fsnotify v1.6.0 // indirect | ||||
| 	github.com/gabriel-vasile/mimetype v1.4.2 // indirect | ||||
| 	github.com/ghodss/yaml v1.0.0 // indirect | ||||
| 	github.com/gin-contrib/sse v0.1.0 // indirect | ||||
| 	github.com/git-chglog/git-chglog v0.0.0-20190611050339-63a4e637021f // indirect | ||||
| 	github.com/go-admin-team/go-admin-core/plugins/logger/zap v0.0.0-20210610020726-2db73adb505d // indirect | ||||
| 	github.com/go-admin-team/gorm-adapter/v3 v3.7.8-0.20220809100335-eaf9f67b3d21 // indirect | ||||
| 	github.com/go-ole/go-ole v1.2.6 // indirect | ||||
| 	github.com/go-ole/go-ole v1.3.0 // indirect | ||||
| 	github.com/go-openapi/jsonpointer v0.19.5 // indirect | ||||
| 	github.com/go-openapi/jsonreference v0.19.6 // indirect | ||||
| 	github.com/go-openapi/spec v0.20.4 // indirect | ||||
| @ -68,17 +86,19 @@ require ( | ||||
| 	github.com/go-redis/redis/v7 v7.4.0 // indirect | ||||
| 	github.com/go-redis/redis/v8 v8.11.5 // indirect | ||||
| 	github.com/go-sql-driver/mysql v1.6.0 // indirect | ||||
| 	github.com/golang-jwt/jwt/v4 v4.4.2 // indirect | ||||
| 	github.com/goccy/go-json v0.10.4 // indirect | ||||
| 	github.com/golang-jwt/jwt/v4 v4.5.1 // indirect | ||||
| 	github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect | ||||
| 	github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188 // indirect | ||||
| 	github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect | ||||
| 	github.com/golang/protobuf v1.5.0 // indirect | ||||
| 	github.com/golang/snappy v0.0.1 // indirect | ||||
| 	github.com/golang/protobuf v1.5.4 // indirect | ||||
| 	github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect | ||||
| 	github.com/gorilla/websocket v1.4.2 // indirect | ||||
| 	github.com/henrylee2cn/ameda v1.4.10 // indirect | ||||
| 	github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8 // indirect | ||||
| 	github.com/holiman/uint256 v1.3.2 // indirect | ||||
| 	github.com/imdario/mergo v0.3.9 // indirect | ||||
| 	github.com/inconshreveable/mousetrap v1.0.0 // indirect | ||||
| 	github.com/inconshreveable/mousetrap v1.1.0 // indirect | ||||
| 	github.com/jackc/chunkreader/v2 v2.0.1 // indirect | ||||
| 	github.com/jackc/pgconn v1.12.1 // indirect | ||||
| 	github.com/jackc/pgio v1.0.0 // indirect | ||||
| @ -92,52 +112,60 @@ require ( | ||||
| 	github.com/josharian/intern v1.0.0 // indirect | ||||
| 	github.com/json-iterator/go v1.1.12 // indirect | ||||
| 	github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect | ||||
| 	github.com/klauspost/cpuid/v2 v2.2.4 // indirect | ||||
| 	github.com/leodido/go-urn v1.2.4 // indirect | ||||
| 	github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect | ||||
| 	github.com/mailru/easyjson v0.7.6 // indirect | ||||
| 	github.com/mattn/go-colorable v0.1.7 // indirect | ||||
| 	github.com/mattn/go-isatty v0.0.19 // indirect | ||||
| 	github.com/mattn/go-colorable v0.1.13 // indirect | ||||
| 	github.com/mattn/go-isatty v0.0.20 // indirect | ||||
| 	github.com/mattn/go-sqlite3 v1.14.12 // indirect | ||||
| 	github.com/mattn/goveralls v0.0.2 // indirect | ||||
| 	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect | ||||
| 	github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect | ||||
| 	github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect | ||||
| 	github.com/mmcloughlin/addchain v0.4.0 // indirect | ||||
| 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | ||||
| 	github.com/modern-go/reflect2 v1.0.2 // indirect | ||||
| 	github.com/mojocn/base64Captcha v1.3.1 // indirect | ||||
| 	github.com/nsqio/go-nsq v1.0.8 // indirect | ||||
| 	github.com/nyaruka/phonenumbers v1.0.55 // indirect | ||||
| 	github.com/pelletier/go-toml/v2 v2.0.8 // indirect | ||||
| 	github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect | ||||
| 	github.com/prometheus/client_model v0.2.0 // indirect | ||||
| 	github.com/prometheus/common v0.26.0 // indirect | ||||
| 	github.com/prometheus/procfs v0.6.0 // indirect | ||||
| 	github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a // indirect | ||||
| 	github.com/prometheus/common v0.32.1 // indirect | ||||
| 	github.com/prometheus/procfs v0.7.3 // indirect | ||||
| 	github.com/robinjoseph08/redisqueue/v2 v2.1.0 // indirect | ||||
| 	github.com/russross/blackfriday/v2 v2.0.1 // indirect | ||||
| 	github.com/russross/blackfriday/v2 v2.1.0 // indirect | ||||
| 	github.com/shamsher31/goimgext v1.0.0 // indirect | ||||
| 	github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect | ||||
| 	github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect | ||||
| 	github.com/shopspring/decimal v1.4.0 // indirect | ||||
| 	github.com/spf13/cast v1.3.1 // indirect | ||||
| 	github.com/spf13/pflag v1.0.3 // indirect | ||||
| 	github.com/tklauser/go-sysconf v0.3.9 // indirect | ||||
| 	github.com/tklauser/numcpus v0.3.0 // indirect | ||||
| 	github.com/spf13/pflag v1.0.5 // indirect | ||||
| 	github.com/supranational/blst v0.3.14 // indirect | ||||
| 	github.com/tklauser/go-sysconf v0.3.12 // indirect | ||||
| 	github.com/tklauser/numcpus v0.6.1 // indirect | ||||
| 	github.com/tsuyoshiwada/go-gitcmd v0.0.0-20180205145712-5f1f5f9475df // indirect | ||||
| 	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect | ||||
| 	github.com/ugorji/go/codec v1.2.11 // indirect | ||||
| 	github.com/urfave/cli v1.22.1 // indirect | ||||
| 	github.com/yusufpapurcu/wmi v1.2.2 // indirect | ||||
| 	go.uber.org/atomic v1.6.0 // indirect | ||||
| 	go.uber.org/multierr v1.5.0 // indirect | ||||
| 	go.uber.org/zap v1.15.0 // indirect | ||||
| 	golang.org/x/arch v0.3.0 // indirect | ||||
| 	golang.org/x/image v0.1.0 // indirect | ||||
| 	golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect | ||||
| 	golang.org/x/net v0.10.0 // indirect | ||||
| 	golang.org/x/sync v0.1.0 // indirect | ||||
| 	golang.org/x/sys v0.8.0 // indirect | ||||
| 	golang.org/x/text v0.9.0 // indirect | ||||
| 	golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect | ||||
| 	golang.org/x/tools v0.6.0 // indirect | ||||
| 	google.golang.org/protobuf v1.30.0 // indirect | ||||
| 	golang.org/x/net v0.36.0 // indirect | ||||
| 	golang.org/x/sync v0.14.0 // indirect | ||||
| 	golang.org/x/sys v0.33.0 // indirect | ||||
| 	golang.org/x/text v0.25.0 // indirect | ||||
| 	golang.org/x/time v0.9.0 // indirect | ||||
| 	golang.org/x/tools v0.29.0 // indirect | ||||
| 	google.golang.org/protobuf v1.34.2 // indirect | ||||
| 	gopkg.in/AlecAivazis/survey.v1 v1.8.5 // indirect | ||||
| 	gopkg.in/kyokomi/emoji.v1 v1.5.1 // indirect | ||||
| 	gopkg.in/yaml.v2 v2.4.0 // indirect | ||||
| 	gopkg.in/yaml.v3 v3.0.1 // indirect | ||||
| 	gorm.io/plugin/dbresolver v1.2.2 // indirect | ||||
| 	rsc.io/tmplfunc v0.0.3 // indirect | ||||
| ) | ||||
|  | ||||
| //replace ( | ||||
|  | ||||
							
								
								
									
										1
									
								
								static/abis/usdc.abi
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								static/abis/usdc.abi
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| [{"constant":false,"inputs":[{"name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newImplementation","type":"address"},{"name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newAdmin","type":"address"}],"name":"changeAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_implementation","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"previousAdmin","type":"address"},{"indexed":false,"name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"implementation","type":"address"}],"name":"Upgraded","type":"event"}] | ||||
							
								
								
									
										596
									
								
								static/abis/usdc.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										596
									
								
								static/abis/usdc.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,596 @@ | ||||
| // Code generated - DO NOT EDIT. | ||||
| // This file is a generated binding and any manual changes will be lost. | ||||
|  | ||||
| package usdc | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"math/big" | ||||
| 	"strings" | ||||
|  | ||||
| 	ethereum "github.com/ethereum/go-ethereum" | ||||
| 	"github.com/ethereum/go-ethereum/accounts/abi" | ||||
| 	"github.com/ethereum/go-ethereum/accounts/abi/bind" | ||||
| 	"github.com/ethereum/go-ethereum/common" | ||||
| 	"github.com/ethereum/go-ethereum/core/types" | ||||
| 	"github.com/ethereum/go-ethereum/event" | ||||
| ) | ||||
|  | ||||
| // Reference imports to suppress errors if they are not otherwise used. | ||||
| var ( | ||||
| 	_ = errors.New | ||||
| 	_ = big.NewInt | ||||
| 	_ = strings.NewReader | ||||
| 	_ = ethereum.NotFound | ||||
| 	_ = bind.Bind | ||||
| 	_ = common.Big1 | ||||
| 	_ = types.BloomLookup | ||||
| 	_ = event.NewSubscription | ||||
| 	_ = abi.ConvertType | ||||
| ) | ||||
|  | ||||
| // UsdcMetaData contains all meta data concerning the Usdc contract. | ||||
| var UsdcMetaData = &bind.MetaData{ | ||||
| 	ABI: "[{\"constant\":false,\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_implementation\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"}]", | ||||
| } | ||||
|  | ||||
| // UsdcABI is the input ABI used to generate the binding from. | ||||
| // Deprecated: Use UsdcMetaData.ABI instead. | ||||
| var UsdcABI = UsdcMetaData.ABI | ||||
|  | ||||
| // Usdc is an auto generated Go binding around an Ethereum contract. | ||||
| type Usdc struct { | ||||
| 	UsdcCaller     // Read-only binding to the contract | ||||
| 	UsdcTransactor // Write-only binding to the contract | ||||
| 	UsdcFilterer   // Log filterer for contract events | ||||
| } | ||||
|  | ||||
| // UsdcCaller is an auto generated read-only Go binding around an Ethereum contract. | ||||
| type UsdcCaller struct { | ||||
| 	contract *bind.BoundContract // Generic contract wrapper for the low level calls | ||||
| } | ||||
|  | ||||
| // UsdcTransactor is an auto generated write-only Go binding around an Ethereum contract. | ||||
| type UsdcTransactor struct { | ||||
| 	contract *bind.BoundContract // Generic contract wrapper for the low level calls | ||||
| } | ||||
|  | ||||
| // UsdcFilterer is an auto generated log filtering Go binding around an Ethereum contract events. | ||||
| type UsdcFilterer struct { | ||||
| 	contract *bind.BoundContract // Generic contract wrapper for the low level calls | ||||
| } | ||||
|  | ||||
| // UsdcSession is an auto generated Go binding around an Ethereum contract, | ||||
| // with pre-set call and transact options. | ||||
| type UsdcSession struct { | ||||
| 	Contract     *Usdc             // Generic contract binding to set the session for | ||||
| 	CallOpts     bind.CallOpts     // Call options to use throughout this session | ||||
| 	TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session | ||||
| } | ||||
|  | ||||
| // UsdcCallerSession is an auto generated read-only Go binding around an Ethereum contract, | ||||
| // with pre-set call options. | ||||
| type UsdcCallerSession struct { | ||||
| 	Contract *UsdcCaller   // Generic contract caller binding to set the session for | ||||
| 	CallOpts bind.CallOpts // Call options to use throughout this session | ||||
| } | ||||
|  | ||||
| // UsdcTransactorSession is an auto generated write-only Go binding around an Ethereum contract, | ||||
| // with pre-set transact options. | ||||
| type UsdcTransactorSession struct { | ||||
| 	Contract     *UsdcTransactor   // Generic contract transactor binding to set the session for | ||||
| 	TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session | ||||
| } | ||||
|  | ||||
| // UsdcRaw is an auto generated low-level Go binding around an Ethereum contract. | ||||
| type UsdcRaw struct { | ||||
| 	Contract *Usdc // Generic contract binding to access the raw methods on | ||||
| } | ||||
|  | ||||
| // UsdcCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. | ||||
| type UsdcCallerRaw struct { | ||||
| 	Contract *UsdcCaller // Generic read-only contract binding to access the raw methods on | ||||
| } | ||||
|  | ||||
| // UsdcTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. | ||||
| type UsdcTransactorRaw struct { | ||||
| 	Contract *UsdcTransactor // Generic write-only contract binding to access the raw methods on | ||||
| } | ||||
|  | ||||
| // NewUsdc creates a new instance of Usdc, bound to a specific deployed contract. | ||||
| func NewUsdc(address common.Address, backend bind.ContractBackend) (*Usdc, error) { | ||||
| 	contract, err := bindUsdc(address, backend, backend, backend) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &Usdc{UsdcCaller: UsdcCaller{contract: contract}, UsdcTransactor: UsdcTransactor{contract: contract}, UsdcFilterer: UsdcFilterer{contract: contract}}, nil | ||||
| } | ||||
|  | ||||
| // NewUsdcCaller creates a new read-only instance of Usdc, bound to a specific deployed contract. | ||||
| func NewUsdcCaller(address common.Address, caller bind.ContractCaller) (*UsdcCaller, error) { | ||||
| 	contract, err := bindUsdc(address, caller, nil, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &UsdcCaller{contract: contract}, nil | ||||
| } | ||||
|  | ||||
| // NewUsdcTransactor creates a new write-only instance of Usdc, bound to a specific deployed contract. | ||||
| func NewUsdcTransactor(address common.Address, transactor bind.ContractTransactor) (*UsdcTransactor, error) { | ||||
| 	contract, err := bindUsdc(address, nil, transactor, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &UsdcTransactor{contract: contract}, nil | ||||
| } | ||||
|  | ||||
| // NewUsdcFilterer creates a new log filterer instance of Usdc, bound to a specific deployed contract. | ||||
| func NewUsdcFilterer(address common.Address, filterer bind.ContractFilterer) (*UsdcFilterer, error) { | ||||
| 	contract, err := bindUsdc(address, nil, nil, filterer) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &UsdcFilterer{contract: contract}, nil | ||||
| } | ||||
|  | ||||
| // bindUsdc binds a generic wrapper to an already deployed contract. | ||||
| func bindUsdc(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { | ||||
| 	parsed, err := UsdcMetaData.GetAbi() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil | ||||
| } | ||||
|  | ||||
| // Call invokes the (constant) contract method with params as input values and | ||||
| // sets the output to result. The result type might be a single field for simple | ||||
| // returns, a slice of interfaces for anonymous returns and a struct for named | ||||
| // returns. | ||||
| func (_Usdc *UsdcRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { | ||||
| 	return _Usdc.Contract.UsdcCaller.contract.Call(opts, result, method, params...) | ||||
| } | ||||
|  | ||||
| // Transfer initiates a plain transaction to move funds to the contract, calling | ||||
| // its default method if one is available. | ||||
| func (_Usdc *UsdcRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { | ||||
| 	return _Usdc.Contract.UsdcTransactor.contract.Transfer(opts) | ||||
| } | ||||
|  | ||||
| // Transact invokes the (paid) contract method with params as input values. | ||||
| func (_Usdc *UsdcRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { | ||||
| 	return _Usdc.Contract.UsdcTransactor.contract.Transact(opts, method, params...) | ||||
| } | ||||
|  | ||||
| // Call invokes the (constant) contract method with params as input values and | ||||
| // sets the output to result. The result type might be a single field for simple | ||||
| // returns, a slice of interfaces for anonymous returns and a struct for named | ||||
| // returns. | ||||
| func (_Usdc *UsdcCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { | ||||
| 	return _Usdc.Contract.contract.Call(opts, result, method, params...) | ||||
| } | ||||
|  | ||||
| // Transfer initiates a plain transaction to move funds to the contract, calling | ||||
| // its default method if one is available. | ||||
| func (_Usdc *UsdcTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { | ||||
| 	return _Usdc.Contract.contract.Transfer(opts) | ||||
| } | ||||
|  | ||||
| // Transact invokes the (paid) contract method with params as input values. | ||||
| func (_Usdc *UsdcTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { | ||||
| 	return _Usdc.Contract.contract.Transact(opts, method, params...) | ||||
| } | ||||
|  | ||||
| // Admin is a free data retrieval call binding the contract method 0xf851a440. | ||||
| // | ||||
| // Solidity: function admin() view returns(address) | ||||
| func (_Usdc *UsdcCaller) Admin(opts *bind.CallOpts) (common.Address, error) { | ||||
| 	var out []interface{} | ||||
| 	err := _Usdc.contract.Call(opts, &out, "admin") | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return *new(common.Address), err | ||||
| 	} | ||||
|  | ||||
| 	out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) | ||||
|  | ||||
| 	return out0, err | ||||
|  | ||||
| } | ||||
|  | ||||
| // Admin is a free data retrieval call binding the contract method 0xf851a440. | ||||
| // | ||||
| // Solidity: function admin() view returns(address) | ||||
| func (_Usdc *UsdcSession) Admin() (common.Address, error) { | ||||
| 	return _Usdc.Contract.Admin(&_Usdc.CallOpts) | ||||
| } | ||||
|  | ||||
| // Admin is a free data retrieval call binding the contract method 0xf851a440. | ||||
| // | ||||
| // Solidity: function admin() view returns(address) | ||||
| func (_Usdc *UsdcCallerSession) Admin() (common.Address, error) { | ||||
| 	return _Usdc.Contract.Admin(&_Usdc.CallOpts) | ||||
| } | ||||
|  | ||||
| // Implementation is a free data retrieval call binding the contract method 0x5c60da1b. | ||||
| // | ||||
| // Solidity: function implementation() view returns(address) | ||||
| func (_Usdc *UsdcCaller) Implementation(opts *bind.CallOpts) (common.Address, error) { | ||||
| 	var out []interface{} | ||||
| 	err := _Usdc.contract.Call(opts, &out, "implementation") | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return *new(common.Address), err | ||||
| 	} | ||||
|  | ||||
| 	out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) | ||||
|  | ||||
| 	return out0, err | ||||
|  | ||||
| } | ||||
|  | ||||
| // Implementation is a free data retrieval call binding the contract method 0x5c60da1b. | ||||
| // | ||||
| // Solidity: function implementation() view returns(address) | ||||
| func (_Usdc *UsdcSession) Implementation() (common.Address, error) { | ||||
| 	return _Usdc.Contract.Implementation(&_Usdc.CallOpts) | ||||
| } | ||||
|  | ||||
| // Implementation is a free data retrieval call binding the contract method 0x5c60da1b. | ||||
| // | ||||
| // Solidity: function implementation() view returns(address) | ||||
| func (_Usdc *UsdcCallerSession) Implementation() (common.Address, error) { | ||||
| 	return _Usdc.Contract.Implementation(&_Usdc.CallOpts) | ||||
| } | ||||
|  | ||||
| // ChangeAdmin is a paid mutator transaction binding the contract method 0x8f283970. | ||||
| // | ||||
| // Solidity: function changeAdmin(address newAdmin) returns() | ||||
| func (_Usdc *UsdcTransactor) ChangeAdmin(opts *bind.TransactOpts, newAdmin common.Address) (*types.Transaction, error) { | ||||
| 	return _Usdc.contract.Transact(opts, "changeAdmin", newAdmin) | ||||
| } | ||||
|  | ||||
| // ChangeAdmin is a paid mutator transaction binding the contract method 0x8f283970. | ||||
| // | ||||
| // Solidity: function changeAdmin(address newAdmin) returns() | ||||
| func (_Usdc *UsdcSession) ChangeAdmin(newAdmin common.Address) (*types.Transaction, error) { | ||||
| 	return _Usdc.Contract.ChangeAdmin(&_Usdc.TransactOpts, newAdmin) | ||||
| } | ||||
|  | ||||
| // ChangeAdmin is a paid mutator transaction binding the contract method 0x8f283970. | ||||
| // | ||||
| // Solidity: function changeAdmin(address newAdmin) returns() | ||||
| func (_Usdc *UsdcTransactorSession) ChangeAdmin(newAdmin common.Address) (*types.Transaction, error) { | ||||
| 	return _Usdc.Contract.ChangeAdmin(&_Usdc.TransactOpts, newAdmin) | ||||
| } | ||||
|  | ||||
| // UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. | ||||
| // | ||||
| // Solidity: function upgradeTo(address newImplementation) returns() | ||||
| func (_Usdc *UsdcTransactor) UpgradeTo(opts *bind.TransactOpts, newImplementation common.Address) (*types.Transaction, error) { | ||||
| 	return _Usdc.contract.Transact(opts, "upgradeTo", newImplementation) | ||||
| } | ||||
|  | ||||
| // UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. | ||||
| // | ||||
| // Solidity: function upgradeTo(address newImplementation) returns() | ||||
| func (_Usdc *UsdcSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { | ||||
| 	return _Usdc.Contract.UpgradeTo(&_Usdc.TransactOpts, newImplementation) | ||||
| } | ||||
|  | ||||
| // UpgradeTo is a paid mutator transaction binding the contract method 0x3659cfe6. | ||||
| // | ||||
| // Solidity: function upgradeTo(address newImplementation) returns() | ||||
| func (_Usdc *UsdcTransactorSession) UpgradeTo(newImplementation common.Address) (*types.Transaction, error) { | ||||
| 	return _Usdc.Contract.UpgradeTo(&_Usdc.TransactOpts, newImplementation) | ||||
| } | ||||
|  | ||||
| // UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. | ||||
| // | ||||
| // Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() | ||||
| func (_Usdc *UsdcTransactor) UpgradeToAndCall(opts *bind.TransactOpts, newImplementation common.Address, data []byte) (*types.Transaction, error) { | ||||
| 	return _Usdc.contract.Transact(opts, "upgradeToAndCall", newImplementation, data) | ||||
| } | ||||
|  | ||||
| // UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. | ||||
| // | ||||
| // Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() | ||||
| func (_Usdc *UsdcSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { | ||||
| 	return _Usdc.Contract.UpgradeToAndCall(&_Usdc.TransactOpts, newImplementation, data) | ||||
| } | ||||
|  | ||||
| // UpgradeToAndCall is a paid mutator transaction binding the contract method 0x4f1ef286. | ||||
| // | ||||
| // Solidity: function upgradeToAndCall(address newImplementation, bytes data) payable returns() | ||||
| func (_Usdc *UsdcTransactorSession) UpgradeToAndCall(newImplementation common.Address, data []byte) (*types.Transaction, error) { | ||||
| 	return _Usdc.Contract.UpgradeToAndCall(&_Usdc.TransactOpts, newImplementation, data) | ||||
| } | ||||
|  | ||||
| // Fallback is a paid mutator transaction binding the contract fallback function. | ||||
| // | ||||
| // Solidity: fallback() payable returns() | ||||
| func (_Usdc *UsdcTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { | ||||
| 	return _Usdc.contract.RawTransact(opts, calldata) | ||||
| } | ||||
|  | ||||
| // Fallback is a paid mutator transaction binding the contract fallback function. | ||||
| // | ||||
| // Solidity: fallback() payable returns() | ||||
| func (_Usdc *UsdcSession) Fallback(calldata []byte) (*types.Transaction, error) { | ||||
| 	return _Usdc.Contract.Fallback(&_Usdc.TransactOpts, calldata) | ||||
| } | ||||
|  | ||||
| // Fallback is a paid mutator transaction binding the contract fallback function. | ||||
| // | ||||
| // Solidity: fallback() payable returns() | ||||
| func (_Usdc *UsdcTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { | ||||
| 	return _Usdc.Contract.Fallback(&_Usdc.TransactOpts, calldata) | ||||
| } | ||||
|  | ||||
| // UsdcAdminChangedIterator is returned from FilterAdminChanged and is used to iterate over the raw logs and unpacked data for AdminChanged events raised by the Usdc contract. | ||||
| type UsdcAdminChangedIterator struct { | ||||
| 	Event *UsdcAdminChanged // Event containing the contract specifics and raw log | ||||
|  | ||||
| 	contract *bind.BoundContract // Generic contract to use for unpacking event data | ||||
| 	event    string              // Event name to use for unpacking event data | ||||
|  | ||||
| 	logs chan types.Log        // Log channel receiving the found contract events | ||||
| 	sub  ethereum.Subscription // Subscription for errors, completion and termination | ||||
| 	done bool                  // Whether the subscription completed delivering logs | ||||
| 	fail error                 // Occurred error to stop iteration | ||||
| } | ||||
|  | ||||
| // Next advances the iterator to the subsequent event, returning whether there | ||||
| // are any more events found. In case of a retrieval or parsing error, false is | ||||
| // returned and Error() can be queried for the exact failure. | ||||
| func (it *UsdcAdminChangedIterator) Next() bool { | ||||
| 	// If the iterator failed, stop iterating | ||||
| 	if it.fail != nil { | ||||
| 		return false | ||||
| 	} | ||||
| 	// If the iterator completed, deliver directly whatever's available | ||||
| 	if it.done { | ||||
| 		select { | ||||
| 		case log := <-it.logs: | ||||
| 			it.Event = new(UsdcAdminChanged) | ||||
| 			if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { | ||||
| 				it.fail = err | ||||
| 				return false | ||||
| 			} | ||||
| 			it.Event.Raw = log | ||||
| 			return true | ||||
|  | ||||
| 		default: | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	// Iterator still in progress, wait for either a data or an error event | ||||
| 	select { | ||||
| 	case log := <-it.logs: | ||||
| 		it.Event = new(UsdcAdminChanged) | ||||
| 		if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { | ||||
| 			it.fail = err | ||||
| 			return false | ||||
| 		} | ||||
| 		it.Event.Raw = log | ||||
| 		return true | ||||
|  | ||||
| 	case err := <-it.sub.Err(): | ||||
| 		it.done = true | ||||
| 		it.fail = err | ||||
| 		return it.Next() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Error returns any retrieval or parsing error occurred during filtering. | ||||
| func (it *UsdcAdminChangedIterator) Error() error { | ||||
| 	return it.fail | ||||
| } | ||||
|  | ||||
| // Close terminates the iteration process, releasing any pending underlying | ||||
| // resources. | ||||
| func (it *UsdcAdminChangedIterator) Close() error { | ||||
| 	it.sub.Unsubscribe() | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // UsdcAdminChanged represents a AdminChanged event raised by the Usdc contract. | ||||
| type UsdcAdminChanged struct { | ||||
| 	PreviousAdmin common.Address | ||||
| 	NewAdmin      common.Address | ||||
| 	Raw           types.Log // Blockchain specific contextual infos | ||||
| } | ||||
|  | ||||
| // FilterAdminChanged is a free log retrieval operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. | ||||
| // | ||||
| // Solidity: event AdminChanged(address previousAdmin, address newAdmin) | ||||
| func (_Usdc *UsdcFilterer) FilterAdminChanged(opts *bind.FilterOpts) (*UsdcAdminChangedIterator, error) { | ||||
|  | ||||
| 	logs, sub, err := _Usdc.contract.FilterLogs(opts, "AdminChanged") | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &UsdcAdminChangedIterator{contract: _Usdc.contract, event: "AdminChanged", logs: logs, sub: sub}, nil | ||||
| } | ||||
|  | ||||
| // WatchAdminChanged is a free log subscription operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. | ||||
| // | ||||
| // Solidity: event AdminChanged(address previousAdmin, address newAdmin) | ||||
| func (_Usdc *UsdcFilterer) WatchAdminChanged(opts *bind.WatchOpts, sink chan<- *UsdcAdminChanged) (event.Subscription, error) { | ||||
|  | ||||
| 	logs, sub, err := _Usdc.contract.WatchLogs(opts, "AdminChanged") | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return event.NewSubscription(func(quit <-chan struct{}) error { | ||||
| 		defer sub.Unsubscribe() | ||||
| 		for { | ||||
| 			select { | ||||
| 			case log := <-logs: | ||||
| 				// New log arrived, parse the event and forward to the user | ||||
| 				event := new(UsdcAdminChanged) | ||||
| 				if err := _Usdc.contract.UnpackLog(event, "AdminChanged", log); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 				event.Raw = log | ||||
|  | ||||
| 				select { | ||||
| 				case sink <- event: | ||||
| 				case err := <-sub.Err(): | ||||
| 					return err | ||||
| 				case <-quit: | ||||
| 					return nil | ||||
| 				} | ||||
| 			case err := <-sub.Err(): | ||||
| 				return err | ||||
| 			case <-quit: | ||||
| 				return nil | ||||
| 			} | ||||
| 		} | ||||
| 	}), nil | ||||
| } | ||||
|  | ||||
| // ParseAdminChanged is a log parse operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. | ||||
| // | ||||
| // Solidity: event AdminChanged(address previousAdmin, address newAdmin) | ||||
| func (_Usdc *UsdcFilterer) ParseAdminChanged(log types.Log) (*UsdcAdminChanged, error) { | ||||
| 	event := new(UsdcAdminChanged) | ||||
| 	if err := _Usdc.contract.UnpackLog(event, "AdminChanged", log); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	event.Raw = log | ||||
| 	return event, nil | ||||
| } | ||||
|  | ||||
| // UsdcUpgradedIterator is returned from FilterUpgraded and is used to iterate over the raw logs and unpacked data for Upgraded events raised by the Usdc contract. | ||||
| type UsdcUpgradedIterator struct { | ||||
| 	Event *UsdcUpgraded // Event containing the contract specifics and raw log | ||||
|  | ||||
| 	contract *bind.BoundContract // Generic contract to use for unpacking event data | ||||
| 	event    string              // Event name to use for unpacking event data | ||||
|  | ||||
| 	logs chan types.Log        // Log channel receiving the found contract events | ||||
| 	sub  ethereum.Subscription // Subscription for errors, completion and termination | ||||
| 	done bool                  // Whether the subscription completed delivering logs | ||||
| 	fail error                 // Occurred error to stop iteration | ||||
| } | ||||
|  | ||||
| // Next advances the iterator to the subsequent event, returning whether there | ||||
| // are any more events found. In case of a retrieval or parsing error, false is | ||||
| // returned and Error() can be queried for the exact failure. | ||||
| func (it *UsdcUpgradedIterator) Next() bool { | ||||
| 	// If the iterator failed, stop iterating | ||||
| 	if it.fail != nil { | ||||
| 		return false | ||||
| 	} | ||||
| 	// If the iterator completed, deliver directly whatever's available | ||||
| 	if it.done { | ||||
| 		select { | ||||
| 		case log := <-it.logs: | ||||
| 			it.Event = new(UsdcUpgraded) | ||||
| 			if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { | ||||
| 				it.fail = err | ||||
| 				return false | ||||
| 			} | ||||
| 			it.Event.Raw = log | ||||
| 			return true | ||||
|  | ||||
| 		default: | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	// Iterator still in progress, wait for either a data or an error event | ||||
| 	select { | ||||
| 	case log := <-it.logs: | ||||
| 		it.Event = new(UsdcUpgraded) | ||||
| 		if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { | ||||
| 			it.fail = err | ||||
| 			return false | ||||
| 		} | ||||
| 		it.Event.Raw = log | ||||
| 		return true | ||||
|  | ||||
| 	case err := <-it.sub.Err(): | ||||
| 		it.done = true | ||||
| 		it.fail = err | ||||
| 		return it.Next() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Error returns any retrieval or parsing error occurred during filtering. | ||||
| func (it *UsdcUpgradedIterator) Error() error { | ||||
| 	return it.fail | ||||
| } | ||||
|  | ||||
| // Close terminates the iteration process, releasing any pending underlying | ||||
| // resources. | ||||
| func (it *UsdcUpgradedIterator) Close() error { | ||||
| 	it.sub.Unsubscribe() | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // UsdcUpgraded represents a Upgraded event raised by the Usdc contract. | ||||
| type UsdcUpgraded struct { | ||||
| 	Implementation common.Address | ||||
| 	Raw            types.Log // Blockchain specific contextual infos | ||||
| } | ||||
|  | ||||
| // FilterUpgraded is a free log retrieval operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. | ||||
| // | ||||
| // Solidity: event Upgraded(address implementation) | ||||
| func (_Usdc *UsdcFilterer) FilterUpgraded(opts *bind.FilterOpts) (*UsdcUpgradedIterator, error) { | ||||
|  | ||||
| 	logs, sub, err := _Usdc.contract.FilterLogs(opts, "Upgraded") | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &UsdcUpgradedIterator{contract: _Usdc.contract, event: "Upgraded", logs: logs, sub: sub}, nil | ||||
| } | ||||
|  | ||||
| // WatchUpgraded is a free log subscription operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. | ||||
| // | ||||
| // Solidity: event Upgraded(address implementation) | ||||
| func (_Usdc *UsdcFilterer) WatchUpgraded(opts *bind.WatchOpts, sink chan<- *UsdcUpgraded) (event.Subscription, error) { | ||||
|  | ||||
| 	logs, sub, err := _Usdc.contract.WatchLogs(opts, "Upgraded") | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return event.NewSubscription(func(quit <-chan struct{}) error { | ||||
| 		defer sub.Unsubscribe() | ||||
| 		for { | ||||
| 			select { | ||||
| 			case log := <-logs: | ||||
| 				// New log arrived, parse the event and forward to the user | ||||
| 				event := new(UsdcUpgraded) | ||||
| 				if err := _Usdc.contract.UnpackLog(event, "Upgraded", log); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 				event.Raw = log | ||||
|  | ||||
| 				select { | ||||
| 				case sink <- event: | ||||
| 				case err := <-sub.Err(): | ||||
| 					return err | ||||
| 				case <-quit: | ||||
| 					return nil | ||||
| 				} | ||||
| 			case err := <-sub.Err(): | ||||
| 				return err | ||||
| 			case <-quit: | ||||
| 				return nil | ||||
| 			} | ||||
| 		} | ||||
| 	}), nil | ||||
| } | ||||
|  | ||||
| // ParseUpgraded is a log parse operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. | ||||
| // | ||||
| // Solidity: event Upgraded(address implementation) | ||||
| func (_Usdc *UsdcFilterer) ParseUpgraded(log types.Log) (*UsdcUpgraded, error) { | ||||
| 	event := new(UsdcUpgraded) | ||||
| 	if err := _Usdc.contract.UnpackLog(event, "Upgraded", log); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	event.Raw = log | ||||
| 	return event, nil | ||||
| } | ||||
							
								
								
									
										88
									
								
								utils/aeshelper/aes256.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								utils/aeshelper/aes256.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,88 @@ | ||||
| package aeshelper | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"crypto/aes" | ||||
| 	"crypto/cipher" | ||||
| 	"crypto/md5" | ||||
| 	"crypto/rand" | ||||
| 	"encoding/base64" | ||||
| 	"io" | ||||
| ) | ||||
|  | ||||
| // Encrypt text with the passphrase | ||||
| func Encrypt(text string, passphrase string) string { | ||||
| 	salt := make([]byte, 8) | ||||
| 	if _, err := io.ReadFull(rand.Reader, salt); err != nil { | ||||
| 		panic(err.Error()) | ||||
| 	} | ||||
|  | ||||
| 	key, iv := DeriveKeyAndIv(passphrase, string(salt)) | ||||
|  | ||||
| 	block, err := aes.NewCipher([]byte(key)) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
|  | ||||
| 	pad := PKCS7Padding([]byte(text), block.BlockSize()) | ||||
| 	ecb := cipher.NewCBCEncrypter(block, []byte(iv)) | ||||
| 	encrypted := make([]byte, len(pad)) | ||||
| 	ecb.CryptBlocks(encrypted, pad) | ||||
|  | ||||
| 	return base64.StdEncoding.EncodeToString([]byte("Salted__" + string(salt) + string(encrypted))) | ||||
| } | ||||
|  | ||||
| // Decrypt encrypted text with the passphrase | ||||
| func Decrypt(encrypted string, passphrase string) string { | ||||
| 	ct, _ := base64.StdEncoding.DecodeString(encrypted) | ||||
| 	if len(ct) < 16 || string(ct[:8]) != "Salted__" { | ||||
| 		return "" | ||||
| 	} | ||||
|  | ||||
| 	salt := ct[8:16] | ||||
| 	ct = ct[16:] | ||||
| 	key, iv := DeriveKeyAndIv(passphrase, string(salt)) | ||||
|  | ||||
| 	block, err := aes.NewCipher([]byte(key)) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
|  | ||||
| 	cbc := cipher.NewCBCDecrypter(block, []byte(iv)) | ||||
| 	dst := make([]byte, len(ct)) | ||||
| 	cbc.CryptBlocks(dst, ct) | ||||
|  | ||||
| 	return string(PKCS7Trimming(dst)) | ||||
| } | ||||
|  | ||||
| // PKCS7Padding PKCS7Padding | ||||
| func PKCS7Padding(ciphertext []byte, blockSize int) []byte { | ||||
| 	padding := blockSize - len(ciphertext)%blockSize | ||||
| 	padtext := bytes.Repeat([]byte{byte(padding)}, padding) | ||||
| 	return append(ciphertext, padtext...) | ||||
| } | ||||
|  | ||||
| // PKCS7Trimming PKCS7Trimming | ||||
| func PKCS7Trimming(encrypt []byte) []byte { | ||||
| 	padding := encrypt[len(encrypt)-1] | ||||
| 	return encrypt[:len(encrypt)-int(padding)] | ||||
| } | ||||
|  | ||||
| // DeriveKeyAndIv DeriveKeyAndIv | ||||
| func DeriveKeyAndIv(passphrase string, salt string) (string, string) { | ||||
| 	salted := "" | ||||
| 	dI := "" | ||||
|  | ||||
| 	for len(salted) < 48 { | ||||
| 		md := md5.New() | ||||
| 		md.Write([]byte(dI + passphrase + salt)) | ||||
| 		dM := md.Sum(nil) | ||||
| 		dI = string(dM[:16]) | ||||
| 		salted = salted + dI | ||||
| 	} | ||||
|  | ||||
| 	key := salted[0:32] | ||||
| 	iv := salted[32:48] | ||||
|  | ||||
| 	return key, iv | ||||
| } | ||||
							
								
								
									
										108
									
								
								utils/aeshelper/aeshelper.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								utils/aeshelper/aeshelper.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,108 @@ | ||||
| package aeshelper | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"crypto/aes" | ||||
| 	"crypto/cipher" | ||||
| 	"encoding/base64" | ||||
| 	"encoding/hex" | ||||
|  | ||||
| 	"github.com/forgoer/openssl" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	sKey        = "ptQJqRKyICCTeo6w" // "dde4b1f8a9e6b814" | ||||
| 	ivParameter = "O3vZvOJSxQDP9hKT" // "dde4b1f8a9e6b814" | ||||
|  | ||||
| ) | ||||
|  | ||||
| // PswEncrypt 加密 | ||||
| func PswEncrypt(src string) (string, error) { | ||||
| 	key := []byte(sKey) | ||||
| 	iv := []byte(ivParameter) | ||||
| 	result, err := Aes128Encrypt([]byte(src), key, iv) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	return base64.RawStdEncoding.EncodeToString(result), nil | ||||
| } | ||||
|  | ||||
| // PswDecrypt 解密 | ||||
| func PswDecrypt(src string) (string, error) { | ||||
| 	key := []byte(sKey) | ||||
| 	iv := []byte(ivParameter) | ||||
| 	var result []byte | ||||
| 	var err error | ||||
| 	result, err = base64.StdEncoding.DecodeString(src) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	origData, err := Aes128Decrypt(result, key, iv) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	return string(origData), nil | ||||
| } | ||||
|  | ||||
| func Aes128Encrypt(origData, key []byte, IV []byte) ([]byte, error) { | ||||
| 	if key == nil || len(key) != 16 { | ||||
| 		return nil, nil | ||||
| 	} | ||||
| 	if IV != nil && len(IV) != 16 { | ||||
| 		return nil, nil | ||||
| 	} | ||||
| 	block, err := aes.NewCipher(key) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	blockSize := block.BlockSize() | ||||
| 	origData = PKCS5Padding(origData, blockSize) | ||||
| 	blockMode := cipher.NewCBCEncrypter(block, IV[:blockSize]) | ||||
| 	crypted := make([]byte, len(origData)) | ||||
| 	// 根据CryptBlocks方法的说明,如下方式初始化crypted也可以 | ||||
| 	blockMode.CryptBlocks(crypted, origData) | ||||
| 	return crypted, nil | ||||
| } | ||||
| func Aes128Decrypt(crypted, key []byte, IV []byte) ([]byte, error) { | ||||
| 	if key == nil || len(key) != 16 { | ||||
| 		return nil, nil | ||||
| 	} | ||||
| 	if IV != nil && len(IV) != 16 { | ||||
| 		return nil, nil | ||||
| 	} | ||||
| 	block, err := aes.NewCipher(key) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	blockSize := block.BlockSize() | ||||
| 	blockMode := cipher.NewCBCDecrypter(block, IV[:blockSize]) | ||||
| 	origData := make([]byte, len(crypted)) | ||||
| 	blockMode.CryptBlocks(origData, crypted) | ||||
| 	origData = PKCS5UnPadding(origData) | ||||
| 	return origData, nil | ||||
| } | ||||
| func PKCS5Padding(ciphertext []byte, blockSize int) []byte { | ||||
| 	padding := blockSize - len(ciphertext)%blockSize | ||||
| 	padtext := bytes.Repeat([]byte{byte(padding)}, padding) | ||||
| 	return append(ciphertext, padtext...) | ||||
| } | ||||
| func PKCS5UnPadding(origData []byte) []byte { | ||||
| 	length := len(origData) | ||||
| 	// 去掉最后一个字节 unpadding 次 | ||||
| 	unpadding := int(origData[length-1]) | ||||
| 	return origData[:(length - unpadding)] | ||||
| } | ||||
|  | ||||
| // 密码加密 | ||||
| func AesEcbEncrypt(origData string) string { | ||||
| 	//加密 | ||||
| 	dst, _ := openssl.AesECBEncrypt([]byte(origData), []byte(sKey), openssl.PKCS7_PADDING) | ||||
| 	return hex.EncodeToString(dst) | ||||
| } | ||||
|  | ||||
| // 密码解密 | ||||
| func AesEcbDecrypt(origData string) string { | ||||
| 	value, _ := hex.DecodeString(origData) | ||||
| 	dst, _ := openssl.AesECBDecrypt(value, []byte(sKey), openssl.PKCS7_PADDING) | ||||
| 	return string(dst) | ||||
| } | ||||
							
								
								
									
										65
									
								
								utils/aeshelper/aeshelper_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								utils/aeshelper/aeshelper_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,65 @@ | ||||
| package aeshelper | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"testing" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // 测试加密解密 | ||||
| func Test_EnDe(t *testing.T) { | ||||
| 	a := `asg` | ||||
| 	b := Encrypt(a, `code_verify_success`) | ||||
| 	c := Decrypt(b, `code_verify_success`) | ||||
| 	fmt.Println(`原始为`, a) | ||||
| 	fmt.Println(`加密后`, b) | ||||
| 	fmt.Println(`解密后`, c) | ||||
| } | ||||
| func TestAesEcbEncrypt(t *testing.T) { | ||||
| 	//aes := AesEcbEncrypt("123456") | ||||
| 	aes := AesEcbEncrypt(fmt.Sprintf("%v_%v", time.Now().Unix(), 1332355333)) | ||||
| 	dst := AesEcbDecrypt(aes) | ||||
| 	fmt.Println(aes) | ||||
| 	fmt.Println(dst) | ||||
| } | ||||
|  | ||||
| // TODO:需要加密的接口 | ||||
| /** | ||||
| 1.合约下单接口            /api/futures/trade/order | ||||
| 2.合约撤单              /api/futures/trade/cancelorder | ||||
| 3.调整保证金           /api/futures/trade/adjustmargin | ||||
| 4.变换逐全仓模式       /api/futures/trade/marginType | ||||
| 5.更改持仓模式(方向)   /api/futures/trade/positionSide/dual | ||||
| 6.资产划转          /api/futures/transfer | ||||
| */ | ||||
| func TestAesEcbEncryptOrder(t *testing.T) { | ||||
| 	data := addFutOrderReq{ | ||||
| 		OrderType:     1, | ||||
| 		BuyType:       3, | ||||
| 		TriggerDecide: 3, | ||||
| 		IsReduce:      2, | ||||
| 		Coin:          "asdf", | ||||
| 		Price:         "333.23", | ||||
| 		Num:           "23.20", | ||||
| 		TriggerPrice:  "1.023", | ||||
| 		PositionSide:  "long", | ||||
| 	} | ||||
| 	b, _ := json.Marshal(data) | ||||
| 	aes := AesEcbEncrypt(string(b)) | ||||
| 	dst := AesEcbDecrypt(aes) | ||||
| 	fmt.Println(aes) | ||||
| 	fmt.Println(dst) | ||||
| } | ||||
|  | ||||
| type addFutOrderReq struct { | ||||
| 	OrderType     int    `json:"order_type"`     // 订单类型:1限价,2限价止盈止损,3市价,4市价止盈止损,5强平委托(就是限价委托) | ||||
| 	BuyType       int    `json:"buy_type"`       // 买卖类型:1买,2卖 | ||||
| 	TriggerDecide int    `json:"trigger_decide"` // 触发条件 1按最新成交价格算,2按标记价格算 | ||||
| 	IsReduce      int    `json:"is_reduce"`      // 1是只减仓位(点击仓位列表中的平仓按钮),0正常 | ||||
| 	Coin          string `json:"coin"`           // 交易币 | ||||
| 	Price         string `json:"price"`          // 下单价格(限价+止盈止损时,该字段必填) | ||||
| 	Num           string `json:"num"`            // 下单数量(市价时该字段必填) | ||||
| 	TriggerPrice  string `json:"trigger_price"`  // 触发价格 | ||||
| 	PositionSide  string `json:"position_side"`  // 持仓方向,单向持仓模式下可填both;在双向持仓模式下必填,且仅可选择 long 或 short | ||||
| } | ||||
							
								
								
									
										94
									
								
								utils/aeshelper/aesoldhelper/aesoldhelper.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								utils/aeshelper/aesoldhelper/aesoldhelper.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,94 @@ | ||||
| package aesoldhelper | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"crypto/aes" | ||||
| 	"crypto/cipher" | ||||
| 	"crypto/rand" | ||||
| 	"encoding/base64" | ||||
| 	"errors" | ||||
| 	"io" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| func addBase64Padding(value string) string { | ||||
| 	m := len(value) % 4 | ||||
| 	if m != 0 { | ||||
| 		value += strings.Repeat("=", 4-m) | ||||
| 	} | ||||
|  | ||||
| 	return value | ||||
| } | ||||
|  | ||||
| func removeBase64Padding(value string) string { | ||||
| 	return strings.Replace(value, "=", "", -1) | ||||
| } | ||||
|  | ||||
| // Pad Pad | ||||
| func Pad(src []byte) []byte { | ||||
| 	padding := aes.BlockSize - len(src)%aes.BlockSize | ||||
| 	padtext := bytes.Repeat([]byte{byte(padding)}, padding) | ||||
| 	return append(src, padtext...) | ||||
| } | ||||
|  | ||||
| // Unpad Unpad | ||||
| func Unpad(src []byte) ([]byte, error) { | ||||
| 	length := len(src) | ||||
| 	unpadding := int(src[length-1]) | ||||
|  | ||||
| 	if unpadding > length { | ||||
| 		return nil, errors.New("unpad error. This could happen when incorrect encryption key is used") | ||||
| 	} | ||||
|  | ||||
| 	return src[:(length - unpadding)], nil | ||||
| } | ||||
|  | ||||
| // AesEncrypt AesEncrypt | ||||
| func AesEncrypt(key []byte, text string) (string, error) { | ||||
| 	block, err := aes.NewCipher(key) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	msg := Pad([]byte(text)) | ||||
| 	ciphertext := make([]byte, aes.BlockSize+len(msg)) | ||||
| 	iv := ciphertext[:aes.BlockSize] | ||||
| 	if _, err := io.ReadFull(rand.Reader, iv); err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	cfb := cipher.NewCFBEncrypter(block, iv) | ||||
| 	cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(msg)) | ||||
| 	finalMsg := removeBase64Padding(base64.URLEncoding.EncodeToString(ciphertext)) | ||||
| 	return finalMsg, nil | ||||
| } | ||||
|  | ||||
| // AesDecrypt AesDecrypt | ||||
| func AesDecrypt(key []byte, text string) (string, error) { | ||||
| 	block, err := aes.NewCipher(key) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	decodedMsg, err := base64.URLEncoding.DecodeString(addBase64Padding(text)) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	if (len(decodedMsg) % aes.BlockSize) != 0 { | ||||
| 		return "", errors.New("blocksize must be multipe of decoded message length") | ||||
| 	} | ||||
|  | ||||
| 	iv := decodedMsg[:aes.BlockSize] | ||||
| 	msg := decodedMsg[aes.BlockSize:] | ||||
|  | ||||
| 	cfb := cipher.NewCFBDecrypter(block, iv) | ||||
| 	cfb.XORKeyStream(msg, msg) | ||||
|  | ||||
| 	unpadMsg, err := Unpad(msg) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	return string(unpadMsg), nil | ||||
| } | ||||
							
								
								
									
										19
									
								
								utils/aeshelper/apikey.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								utils/aeshelper/apikey.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| package aeshelper | ||||
|  | ||||
| var ( | ||||
| 	apiaeskey = "9jxFTkydwCJsmIA1TUrv" | ||||
| ) | ||||
|  | ||||
| // EncryptApi 加密apikey | ||||
| func EncryptApi(apikey, secretkey string) (apikeyen, secrekeyen string) { | ||||
| 	apikeyen = Encrypt(apikey, apiaeskey) | ||||
| 	secrekeyen = Encrypt(secretkey, apiaeskey) | ||||
| 	return apikeyen, secrekeyen | ||||
| } | ||||
|  | ||||
| // DecryptApi 解密apikey | ||||
| func DecryptApi(apikeyen, secrekeyen string) (apikey, secrekey string) { | ||||
| 	apikey = Decrypt(apikeyen, apiaeskey) | ||||
| 	secrekey = Decrypt(secrekeyen, apiaeskey) | ||||
| 	return apikey, secrekey | ||||
| } | ||||
							
								
								
									
										113
									
								
								utils/ethbalanceofhelper/baalanceof_helper.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								utils/ethbalanceofhelper/baalanceof_helper.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,113 @@ | ||||
| package ethbalanceofhelper | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"go-admin/abis" | ||||
| 	"math/big" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/ethereum/go-ethereum" | ||||
| 	"github.com/ethereum/go-ethereum/accounts/abi" | ||||
| 	"github.com/ethereum/go-ethereum/common" | ||||
| 	"github.com/ethereum/go-ethereum/ethclient" | ||||
| 	"github.com/ethereum/go-ethereum/rpc" | ||||
| 	"github.com/shopspring/decimal" | ||||
| ) | ||||
|  | ||||
| // ERC-20 代币合约 ABI (部分,只包含 balanceOf) | ||||
| // ERC-20 代币合约 ABI (部分,只包含 balanceOf 和 decimals) | ||||
| const erc20ABI = `[ | ||||
|     { | ||||
|         "constant": true, | ||||
|         "inputs": [ { "name": "_owner", "type": "address" } ], | ||||
|         "name": "balanceOf", | ||||
|         "outputs": [ { "name": "balance", "type": "uint256" } ], | ||||
|         "type": "function" | ||||
|     }, | ||||
|     { | ||||
|         "constant": true, | ||||
|         "inputs": [], | ||||
|         "name": "decimals", | ||||
|         "outputs": [ { "name": "", "type": "uint8" } ], | ||||
|         "type": "function" | ||||
|     } | ||||
| ]` | ||||
|  | ||||
| // GetERC20Balance 查询 ERC-20 代币余额并转换为正常单位 (使用 decimal) | ||||
| func GetERC20Balance(client *ethclient.Client, tokenAbi abis.TokenABI, accountAddress string) (decimal.Decimal, error) { | ||||
| 	// 1. 解析 ABI | ||||
| 	contractABI, err := abi.JSON(strings.NewReader(erc20ABI)) | ||||
| 	if err != nil { | ||||
| 		return decimal.Zero, fmt.Errorf("解析 ABI 失败: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	// 2. 构造 balanceOf 函数调用数据 | ||||
| 	balanceOfCallData, err := contractABI.Pack("balanceOf", common.HexToAddress(accountAddress)) | ||||
| 	if err != nil { | ||||
| 		return decimal.Zero, fmt.Errorf("构造 balanceOf 调用数据失败: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	address := common.HexToAddress(tokenAbi.TestAddress) | ||||
| 	// 3. 执行 balanceOf 调用 | ||||
| 	balanceResult, err := client.CallContract(context.Background(), ethereum.CallMsg{ | ||||
| 		To:   &address, | ||||
| 		Data: balanceOfCallData, | ||||
| 	}, nil) | ||||
| 	if err != nil { | ||||
| 		return decimal.Zero, fmt.Errorf("调用 balanceOf 失败: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	// 4. 解析 balanceOf 结果 | ||||
| 	unpackedBalance, err := contractABI.Unpack("balanceOf", balanceResult) | ||||
| 	if err != nil { | ||||
| 		return decimal.Zero, fmt.Errorf("解析 balanceOf 结果失败: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	balance, ok := unpackedBalance[0].(*big.Int) | ||||
| 	if !ok { | ||||
| 		return decimal.Zero, errors.New("解析 balanceOf 结果为 *big.Int 失败") | ||||
| 	} | ||||
|  | ||||
| 	// 8. 转换为正常单位 (使用 decimal) | ||||
| 	balanceDecimal := decimal.NewFromBigInt(balance, 0) // Create decimal from big.Int | ||||
| 	decimalFactor := decimal.NewFromInt(10).Pow(decimal.NewFromInt(int64(tokenAbi.Decimals))) | ||||
| 	readableBalance := balanceDecimal.Div(decimalFactor) | ||||
|  | ||||
| 	return readableBalance, nil | ||||
| } | ||||
|  | ||||
| // 初始化以太坊客户端连接代理 | ||||
| func EthClientWithProxy(rawURL string, proxyURL string) (*ethclient.Client, error) { | ||||
| 	u, err := url.Parse(rawURL) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("invalid URL: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	if proxyURL == "" { | ||||
| 		return ethclient.Dial(rawURL) | ||||
| 	} | ||||
|  | ||||
| 	proxy, err := url.Parse(proxyURL) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("invalid proxy URL: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	httpClient := &http.Client{ | ||||
| 		Transport: &http.Transport{ | ||||
| 			Proxy: http.ProxyURL(proxy), | ||||
| 		}, | ||||
| 	} | ||||
| 	dialOptions := []rpc.ClientOption{ | ||||
| 		rpc.WithHTTPClient(httpClient), | ||||
| 	} | ||||
| 	rpcClient, err := rpc.DialOptions(context.Background(), u.String(), dialOptions...) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to dial RPC client with options: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	return ethclient.NewClient(rpcClient), nil | ||||
| } | ||||
							
								
								
									
										175
									
								
								utils/ethtransferhelper/transfer_helper.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								utils/ethtransferhelper/transfer_helper.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,175 @@ | ||||
| package ethtransferhelper | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"crypto/ecdsa" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"math/big" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/ethereum/go-ethereum" | ||||
| 	"github.com/ethereum/go-ethereum/common" | ||||
| 	"github.com/ethereum/go-ethereum/core/types" | ||||
| 	"github.com/ethereum/go-ethereum/crypto" | ||||
| 	"github.com/ethereum/go-ethereum/ethclient" | ||||
| 	"golang.org/x/crypto/sha3" | ||||
| ) | ||||
|  | ||||
| // transferErc20Token 发送 ERC-20 代币交易。 | ||||
| // tokenAmount: 要发送的代币数量 (例如,1.0 代表 1 个代币)。 | ||||
| // fromPrivateKey: 发送者的私钥。 | ||||
| // tokenAddress: ERC-20 代币的合约地址。 | ||||
| // toAddress: 接收者的地址。 | ||||
| // tokenDecimals: 代币的小数位数 (例如,USDC 是 6,很多其他代币是 18)。 | ||||
| func transferErc20Token( | ||||
| 	client *ethclient.Client, | ||||
| 	fromPrivateKey string, | ||||
| 	tokenAddress string, | ||||
| 	toAddress string, | ||||
| 	tokenAmount float64, | ||||
| 	tokenDecimals uint8, | ||||
| ) (*types.Transaction, error) { | ||||
| 	// 1. 解析私钥 | ||||
| 	privateKey, fromAddressCommon, err := GetAddressFromPrivateKey(fromPrivateKey) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	// 3. 获取发送者的 nonce(交易序号) | ||||
| 	nonce, err := client.PendingNonceAt(context.Background(), fromAddressCommon) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("获取 nonce 失败: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	// 4. 设置交易的 value (对于代币转账,value 是 0) | ||||
| 	value := big.NewInt(0) // 不发送 ETH | ||||
|  | ||||
| 	// 5. 获取 Gas 价格 | ||||
| 	gasPrice, err := client.SuggestGasPrice(context.Background()) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("获取 Gas 价格失败: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	// 6. 将地址字符串转换为 common.Address 类型 | ||||
| 	toAddressCommon := common.HexToAddress(toAddress) | ||||
| 	tokenAddressCommon := common.HexToAddress(tokenAddress) | ||||
|  | ||||
| 	// 7. 构造 ERC-20 transfer 函数的调用数据 | ||||
| 	// 7.1  函数签名:transfer(address,uint256) | ||||
| 	transferFnSignature := []byte("transfer(address,uint256)") | ||||
| 	hash := sha3.New256() | ||||
| 	hash.Write(transferFnSignature) | ||||
| 	methodID := hash.Sum(nil)[:4] // 取前 4 个字节作为方法 ID | ||||
|  | ||||
| 	// 7.2  填充接收者地址和转账金额 | ||||
| 	paddedAddress := common.LeftPadBytes(toAddressCommon.Bytes(), 32) | ||||
| 	// 7.3  将代币数量转换为最小单位 | ||||
| 	amountBigInt, err := convertTokenAmountToBigInt(tokenAmount, tokenDecimals) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("转换代币数量失败: %w", err) | ||||
| 	} | ||||
| 	paddedAmount := common.LeftPadBytes(amountBigInt.Bytes(), 32) | ||||
|  | ||||
| 	// 7.4  拼接调用数据 | ||||
| 	var data []byte | ||||
| 	data = append(data, methodID...) | ||||
| 	data = append(data, paddedAddress...) | ||||
| 	data = append(data, paddedAmount...) | ||||
|  | ||||
| 	// 8. 估算 Gas 消耗 | ||||
| 	gasLimit, err := client.EstimateGas(context.Background(), ethereum.CallMsg{ | ||||
| 		From: fromAddressCommon, | ||||
| 		To:   &tokenAddressCommon, | ||||
| 		Data: data, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("估算 Gas 消耗失败: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	// 9. 增加 Gas 限制的安全边际 | ||||
| 	gasLimit = gasLimit * 11 / 10 // 增加 10% | ||||
| 	if gasLimit < 23000 { | ||||
| 		gasLimit = 23000 // 最小 Gas 限制 | ||||
| 	} | ||||
|  | ||||
| 	// 10. 创建交易 | ||||
| 	tx := types.NewTransaction(nonce, tokenAddressCommon, value, gasLimit, gasPrice, data) | ||||
|  | ||||
| 	// 11. 获取链 ID | ||||
| 	chainID, err := client.NetworkID(context.Background()) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("获取链 ID 失败: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	// 12. 签名交易 | ||||
| 	signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), privateKey) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("签名交易失败: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	// 13. 发送交易 | ||||
| 	err = client.SendTransaction(context.Background(), signedTx) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("发送交易失败: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	return signedTx, nil | ||||
| } | ||||
|  | ||||
| // getAddressFromPrivateKey 从私钥获取公钥和地址。 | ||||
| func GetAddressFromPrivateKey(fromPrivateKey string) (*ecdsa.PrivateKey, common.Address, error) { | ||||
| 	// 1. 移除 "0x" 前缀(如果存在) | ||||
| 	if strings.HasPrefix(fromPrivateKey, "0x") { | ||||
| 		fromPrivateKey = fromPrivateKey[2:] | ||||
| 	} | ||||
|  | ||||
| 	privateKey, err := crypto.HexToECDSA(fromPrivateKey) | ||||
| 	if err != nil { | ||||
| 		return nil, common.Address{}, fmt.Errorf("解析私钥失败: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	// 2. 从私钥获取公钥和发送者地址 | ||||
| 	publicKey := privateKey.Public() | ||||
| 	publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) | ||||
| 	if !ok { | ||||
| 		return nil, common.Address{}, errors.New("无法将公钥转换为 ECDSA 类型") | ||||
| 	} | ||||
| 	fromAddressCommon := crypto.PubkeyToAddress(*publicKeyECDSA) | ||||
| 	return privateKey, fromAddressCommon, nil | ||||
| } | ||||
|  | ||||
| // convertTokenAmountToBigInt 将代币数量 (例如,1.0) 转换为最小单位的整数表示 (例如,USDC 的 1000000)。 | ||||
| func convertTokenAmountToBigInt(tokenAmount float64, tokenDecimals uint8) (*big.Int, error) { | ||||
| 	// 1. 使用最大精度格式化浮点数 | ||||
| 	amountStr := fmt.Sprintf("%.18f", tokenAmount) // 使用最大精度 | ||||
|  | ||||
| 	// 2. 找到小数点的位置 | ||||
| 	decimalPointIndex := strings.Index(amountStr, ".") | ||||
|  | ||||
| 	// 3. 如果没有小数点,则添加足够的 0 | ||||
| 	if decimalPointIndex == -1 { | ||||
| 		amountStr += "." + strings.Repeat("0", int(tokenDecimals)) | ||||
| 	} else { | ||||
| 		// 4. 计算需要填充的 0 的数量 | ||||
| 		paddingNeeded := int(tokenDecimals) - (len(amountStr) - decimalPointIndex - 1) | ||||
|  | ||||
| 		// 5. 填充 0 或截断多余的小数位 | ||||
| 		if paddingNeeded > 0 { | ||||
| 			amountStr += strings.Repeat("0", paddingNeeded) | ||||
| 		} else if paddingNeeded < 0 { | ||||
| 			amountStr = amountStr[:decimalPointIndex+int(tokenDecimals)+1] | ||||
| 		} | ||||
| 		// 6. 移除小数点 | ||||
| 		amountStr = strings.ReplaceAll(amountStr, ".", "") | ||||
| 	} | ||||
|  | ||||
| 	// 7. 将字符串转换为 big.Int | ||||
| 	amountBigInt := new(big.Int) | ||||
| 	amountBigInt, ok := amountBigInt.SetString(amountStr, 10) | ||||
| 	if !ok { | ||||
| 		return nil, fmt.Errorf("将金额字符串转换为 big.Int 失败: %s", amountStr) | ||||
| 	} | ||||
|  | ||||
| 	return amountBigInt, nil | ||||
| } | ||||
							
								
								
									
										9
									
								
								utils/stringhelper/address_helper.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								utils/stringhelper/address_helper.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| package stringhelper | ||||
|  | ||||
| func DesensitizeWalletAddress(address string) string { | ||||
| 	if len(address) < 10 { // 更严格的长度检查 | ||||
| 		return "0x...invalid" | ||||
| 	} | ||||
|  | ||||
| 	return address[:6] + "..." + address[len(address)-4:] | ||||
| } | ||||
		Reference in New Issue
	
	Block a user