github.com/fff-chain/go-fff@v0.0.0-20220726032732-1c84420b8a99/global_config/wallet/wallet.go (about) 1 package wallet 2 3 import ( 4 "context" 5 "crypto/ecdsa" 6 "github.com/fff-chain/go-fff/accounts/abi/bind" 7 "github.com/fff-chain/go-fff/common" 8 "github.com/fff-chain/go-fff/common/hexutil" 9 math2 "github.com/fff-chain/go-fff/common/math" 10 "github.com/fff-chain/go-fff/core/types" 11 "github.com/fff-chain/go-fff/crypto" 12 "github.com/fff-chain/go-fff/ethclient" 13 "github.com/fff-chain/go-fff/global_config" 14 "github.com/fff-chain/go-fff/global_config/token" 15 "log" 16 "math/big" 17 "time" 18 ) 19 20 var WEI = math2.BigPow(10, 9) 21 22 type Wallet struct { 23 CurrClient *ethclient.Client 24 RpcUrl string 25 RpcUrl2 string 26 } 27 28 func Init(RpcUrl string, RpcUrl2 string) *Wallet { 29 newl := new(Wallet) 30 newl.RpcUrl = RpcUrl 31 newl.RpcUrl2 = RpcUrl2 32 client, err := ethclient.Dial(RpcUrl) 33 if err != nil || GetClientChainId(client) == 0 { 34 log.Println("无法连接", RpcUrl, err, "等待五秒后重连") 35 time.Sleep(time.Second * 5) 36 client, err := ethclient.Dial(RpcUrl2) 37 if err != nil || GetClientChainId(client) == 0 { 38 log.Println("无法连接", RpcUrl2, err, "等待五秒后重连") 39 time.Sleep(time.Second * 5) 40 return Init(RpcUrl, RpcUrl2) 41 } else { 42 newl.CurrClient = client 43 return newl 44 } 45 } else { 46 newl.CurrClient = client 47 return newl 48 } 49 } 50 func (this *Wallet) ReInit() { 51 for { 52 client, err := ethclient.Dial(this.RpcUrl) 53 if err != nil || GetClientChainId(client) == 0 { 54 log.Println("无法连接", this.RpcUrl, err, "等待五秒后重连") 55 time.Sleep(time.Second * 5) 56 client, err := ethclient.Dial(this.RpcUrl2) 57 if err != nil || GetClientChainId(client) == 0 { 58 log.Println("无法连接", this.RpcUrl2, err, "等待五秒后重连") 59 time.Sleep(time.Second * 5) 60 } else { 61 this.CurrClient = client 62 return 63 } 64 } else { 65 this.CurrClient = client 66 return 67 } 68 } 69 70 } 71 func GetClientChainId(c *ethclient.Client) int64 { 72 if c == nil { 73 return 0 74 } 75 76 chainIdInt, err := c.ChainID(context.Background()) 77 if err != nil { 78 log.Println(err) 79 return 0 80 } 81 return chainIdInt.Int64() 82 } 83 func (this *Wallet) GetMiniBalance() float64 { 84 gasLimit := uint64(21000) 85 86 gasPrice, err2 := this.CurrClient.SuggestGasPrice(context.Background()) 87 88 if err2 != nil { 89 gasPrice = big.NewInt(100) 90 } 91 count := new(big.Int).Mul(big.NewInt(int64(gasLimit)), gasPrice) 92 return global_config.WeiToEth(count) 93 94 } 95 func FloatToWei(f float64) *big.Int { 96 97 weiCount := 18 98 99 beth := math2.BigPow(10, int64(weiCount)) 100 101 rs := new(big.Float).Mul(big.NewFloat(f), new(big.Float).SetInt(beth)) 102 103 w := big.NewInt(0) 104 105 rs.Int(w) 106 107 return w 108 109 } 110 func NewAddress() (pri string, pub string) { 111 privateKey, err := crypto.GenerateKey() 112 if err != nil { 113 log.Println(err) 114 return "", "" 115 } 116 privateKeyBytes := crypto.FromECDSA(privateKey) 117 key := hexutil.Encode(privateKeyBytes)[2:] 118 return key, GetPublicAddressFromKey(key) 119 } 120 121 func GetPublicAddressFromKey(userKey string) string { 122 priKeyECD, err := crypto.HexToECDSA(userKey) 123 if err != nil { 124 log.Println("私钥异常") 125 return "" 126 } 127 128 publicKeyECDSA, ok := priKeyECD.Public().(*ecdsa.PublicKey) 129 if !ok { 130 log.Println("cannot assert type: publicKey is not of type *ecdsa.PublicKey") 131 return "" 132 } 133 address := crypto.PubkeyToAddress(*publicKeyECDSA).Hex() 134 if err != nil { 135 log.Println("私钥异常") 136 return "" 137 } 138 139 return address 140 141 } 142 func (this *Wallet) GetTokenBalance(tokenAddress string, own string) *big.Int { 143 144 transtBnB, err := token.NewBEP20TokenCaller(common.HexToAddress(tokenAddress), this.CurrClient) 145 if err != nil { 146 return nil 147 } 148 currBnb, err := transtBnB.BalanceOf(nil, common.HexToAddress(own)) 149 if err != nil { 150 return nil 151 } 152 return currBnb 153 154 } 155 func (this *Wallet) TransferToken(pri string, tokenAddress string, toAddress string, count *big.Int) string { 156 transt, err := token.NewBEP20TokenTransactor(common.HexToAddress(tokenAddress), this.CurrClient) 157 158 if err == nil { 159 priKeyECD, err := crypto.HexToECDSA(pri) 160 161 if err != nil { 162 log.Println("私钥异常") 163 return "" 164 } 165 chianId, err := this.CurrClient.ChainID(context.Background()) 166 if err != nil { 167 log.Println("节点chianId异常", err) 168 return "" 169 } 170 param, err := bind.NewKeyedTransactorWithChainID(priKeyECD, chianId) 171 if err != nil { 172 log.Println("节点Transactor异常", err) 173 return "" 174 } 175 param.GasPrice, err = this.CurrClient.SuggestGasPrice(context.Background()) 176 if err != nil { 177 log.Println("GAS异常", err) 178 } 179 180 if param.GasPrice == nil { 181 param.GasPrice = big.NewInt(1000000000) 182 } 183 184 if param.GasPrice.Cmp(big.NewInt(1000000000)) < 0 { 185 param.GasPrice = big.NewInt(1000000000) 186 } 187 log.Println("当前gas:", param.GasPrice) 188 189 param.GasLimit = uint64(8000000) 190 nonce, err := this.CurrClient.PendingNonceAt(context.Background(), common.HexToAddress(GetPublicAddressFromKey(pri))) 191 if err != nil { 192 log.Println("节点异常") 193 return "" 194 } 195 param.Nonce = big.NewInt(int64(nonce)) 196 197 ts, err := transt.Transfer(param, common.HexToAddress(toAddress), count) //转账代币 198 199 if err != nil { 200 log.Println("转账代币异常") 201 return "" 202 } 203 return ts.Hash().Hex() 204 205 } else { 206 log.Println("节点异常") 207 return "" 208 } 209 } 210 func (this *Wallet) Transfer(privateKey string, toAddress string, count *big.Int, transData string, gasP int64) string { 211 212 if this.CurrClient == nil { 213 return "" 214 } 215 216 priviteKey, err := crypto.HexToECDSA(privateKey) 217 218 publicAddress := GetPublicAddressFromKey(privateKey) 219 220 if len(publicAddress) == 0 { 221 return "" 222 } 223 224 if err != nil { 225 log.Println("chanid err", err) 226 return "" 227 } 228 229 nonce, err := this.CurrClient.PendingNonceAt(context.Background(), common.HexToAddress(publicAddress)) 230 if err != nil { 231 log.Println("err", err) 232 return "" 233 } 234 gasLimit := uint64(21000) 235 236 gasPrice, err2 := this.CurrClient.SuggestGasPrice(context.Background()) 237 238 if err2 != nil { 239 log.Println("err", err2) 240 return "" 241 } 242 243 if gasP > 0 { 244 gasPrice = new(big.Int).Mul(big.NewInt(int64(gasP)), math2.BigPow(10, 9)) 245 } 246 247 count = new(big.Int).Sub(count, new(big.Int).Mul(big.NewInt(int64(gasLimit)), gasPrice)) 248 data := []byte(transData) 249 250 newTrans := types.NewTransaction(nonce, common.HexToAddress(toAddress), count, gasLimit, gasPrice, data) 251 252 chainID, err := this.CurrClient.ChainID(context.Background()) 253 if err != nil { 254 log.Println("chanid err", err) 255 return "" 256 } 257 258 signer := types.NewEIP155Signer(chainID) 259 260 signTx, err := types.SignTx(newTrans, signer, priviteKey) 261 262 if err != nil { 263 log.Println("sign err", err) 264 return "" 265 } 266 267 errTrans := this.CurrClient.SendTransaction(context.Background(), signTx) 268 269 if errTrans != nil { 270 log.Println("err", errTrans) 271 272 return "" 273 } 274 return signTx.Hash().String() 275 } 276 func (this *Wallet) GetBalance(address string) *big.Int { 277 if this.CurrClient == nil { 278 return nil 279 } 280 b, err := this.CurrClient.BalanceAt(context.Background(), common.HexToAddress(address), nil) 281 282 if err != nil || b == nil { 283 return nil 284 } 285 return b 286 287 } 288 func (this *Wallet) GetChainId() int64 { 289 chainID, err := this.CurrClient.NetworkID(context.Background()) 290 if err != nil { 291 log.Println("chanid err", err) 292 return 0 293 } 294 return chainID.Int64() 295 296 } 297 func (this *Wallet) GetCurrGas() int64 { 298 if this.CurrClient == nil { 299 return 0 300 } 301 302 gasPrice, err2 := this.CurrClient.SuggestGasPrice(context.Background()) 303 if err2 != nil { 304 log.Println(err2) 305 return 0 306 } 307 gasInt := new(big.Int).Quo(gasPrice, WEI) 308 return gasInt.Int64() 309 310 }