go+solidity+mysql+html共享经济-校园租借项目-go与solidity交互,封装solidity中的方法

144 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1、配置:

//私钥何账户文件二选一
const(
chainID = 8565 
gasLimit = 3000000
//fileKeystore     = "UTC--2022-03-17T08-08-40.600466800Z--59b0f8a34d8f0dd0e0eef44d02cef0c12fffb9de"    //账户文件
Prikey = "***************************"//你的私钥
privateKey       = "111"           //账户文件密码  
ShareFishAddress = "0x7D1672baDeA4825c4B8fFD938fFD29457D6aF6ae" //合约地址
)

2、封装client、Transactor等

//获取client
func GetClient() (*ethclient.Client, error) {
   client, err := ethclient.Dial("http://127.0.0.1:7545") //私链
   //client, err := ethclient.Dial("https://rinkeby.etherscan.io") //测试链
   if err != nil {
      log.Fatal(err)
   }
   defer client.Close()
   return client, nil
}

//只写实例 获取UserCaller对象
func HaveUserWrite(client *ethclient.Client) (*Agreement.UserTransactor, error) {
   ins, err := Agreement.NewUserTransactor(common.HexToAddress(ShareFishAddress), client)
   if err != nil {
      log.Fatal(err)
   }
   return ins, err
}

// 获取合约对象
func GetAddress(client *ethclient.Client) (*Agreement.User, error) {
   contract, err := Agreement.NewUser(common.HexToAddress(ShareFishAddress), client)
   if err != nil {
      log.Fatal(err)
   }
   fmt.Println("faucet:", contract)
   return contract, err
}

//只读实例 获取UserCaller对象
func HaveUserRead(client *ethclient.Client) (*Agreement.UserCaller, error) {
   contract, err := Agreement.NewUserCaller(common.HexToAddress(ShareFishAddress), client)
   if err != nil {
      log.Fatal(err)
   }
   return contract, err
}

//获取Opts对象
func Getopts() *bind.TransactOpts {
   privateKey := GetPrivateKey()
   opts := bind.NewKeyedTransactor(privateKey)
   fmt.Println("opts:", opts)
   return opts
}

//获取私钥
func GetPrivateKey() *ecdsa.PrivateKey {
   privateKey, err := crypto.HexToECDSA(Prikey)
   if err != nil {
      panic(err)
   }
   return privateKey
}

//获取gas价格
func GetgasPrice(client *ethclient.Client) (*big.Int, error) {
   gasPrice, err := client.SuggestGasPrice(context.Background())

   if err != nil {
      return big.NewInt(0), err
   } else {
      fmt.Println("gasPrice", gasPrice)
      return gasPrice, nil
   }

}

func GetMsgOpts(privateKey *ecdsa.PrivateKey) *bind.TransactOpts {
   opts := bind.NewKeyedTransactor(privateKey) //此方法即将弃用
   fmt.Println("opts:", opts)
   return opts
}

3、调用配置,封装方法

//封装登录方法
func LoginMethod(client *ethclient.Client, contract *Agreement.User, Address common.Address, privateKey *ecdsa.PrivateKey) (*types.Transaction, error) {
   opts := GetMsgOpts(privateKey)
   res, err := contract.Login(opts, Address)

   fmt.Println("login:", res)
   opts.GasLimit = gasLimit
   opts.GasPrice, err = GetgasPrice(client)
   if err != nil {
      log.Fatal(err)
   }
   return res, nil
}

4、账户文件登录

//登录
func login(c *gin.Context) {
   //fmt.Println("login")
   //初始化client
   client, err := config.GetClient()
   if err != nil {
      fmt.Println(err)
      respError(c, err)
      return
   }
   //初始化合约地址
   contract, err := config.GetAddress(client)
   if err != nil {
      respError(c, err)
      return
   }

   _, f, err := c.Request.FormFile("log_addr")
   if err != nil {
      fmt.Println(err)
      respError(c, err)
      return
   }
   //获取前端密码
   password := c.PostForm("log_passwd")

   keyjson, errs := ioutil.ReadFile("./keystore/" + f.Filename)
   fmt.Println("keyjson:", string(keyjson))
   if errs != nil {
      respError(c, err)
      return
   }
   unlockedKey, errors := keystore.DecryptKey(keyjson, password)
   fmt.Println("unlock:", unlockedKey)
   if errors != nil {
      respError(c, err)
      fmt.Println(errors)
      return
   }
   privKey = unlockedKey.PrivateKey
   fmt.Println("pri", privKey)
   comAddr := unlockedKey.Address
   LoginUser = comAddr
   Addr_owner = LoginUser.Hex()
   data, err := config.LoginMethod(client, contract, comAddr, privKey)
   addr := comAddr.Hex()
   userImg, err := contract.GetUserImg(nil, comAddr)
   Userimg = userImg
   if data != nil && unlockedKey != nil {
      c.Redirect(http.StatusFound, "/index")
      fmt.Println("addr", addr)
      fmt.Println("data", data)
   } else {
      //respOK(c,"无法用给定的密码解密密钥")
      c.Redirect(http.StatusFound, "/login")

   }
}  

5、私钥登录方法

//私钥登录
func privateLogin(c *gin.Context) {
   fmt.Println("ok")
   //初始化client
   client, err := config.GetClient()
   if err != nil {
      fmt.Println(err)
      respError(c, err)
      return
   }
   //初始化合约地址
   contract, err := config.GetAddress(client)
   if err != nil {
      respError(c, err)
      return
   }

   privateKeyStr := c.PostForm("log_privateKey")
   fmt.Println("str", privateKeyStr)
   if err != nil {
      fmt.Println(err)
      respError(c, err)
      return
   }

   privKey, _ = crypto.HexToECDSA(privateKeyStr)
   fmt.Println("prikey", privKey)
   if privKey == nil {

      c.Redirect(http.StatusFound, "/login")

   } else {
      comAddr := crypto.PubkeyToAddress(privKey.PublicKey)
      fmt.Println("comaddr", comAddr)
      LoginUser = comAddr
      Addr_owner = LoginUser.Hex()
      data, err := config.LoginMethod(client, contract, comAddr, privKey)
      fmt.Println(data)
      if err != nil {
         return
      }
      addr := comAddr.Hex()
      userImg, err := contract.GetUserImg(nil, comAddr)
      Userimg = userImg
      if data != nil {
         c.Redirect(http.StatusFound, "/index")
      } else {
         c.Redirect(http.StatusFound, "/login")
      }
      //respOK(c,data)
      fmt.Println("addr", addr)
      fmt.Println("data", data)
   }
}