util.go 2.37 KB
package utils

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"example.com/m/log"
	"fmt"
	"github.com/ethereum/go-ethereum/accounts/keystore"
	"github.com/ethereum/go-ethereum/crypto"
	"io/ioutil"
	"math/big"
	"os"
)

const KEYPATH_PWD = "keystore"

func GenerateRandomNumber(privateKey *ecdsa.PrivateKey, length int64) *big.Int {
	// 生成一个随机数
	randNum, err := rand.Int(rand.Reader, elliptic.P256().Params().N)
	if err != nil {
		log.Error("Error generating random number:", err)
	}
	randNum.Mod(randNum, big.NewInt(length))
	log.Info("Generating random number:", randNum)
	return randNum
}

func GetPrv() (*ecdsa.PrivateKey, error) {
	if _, err := os.Stat(KEYPATH_PWD); os.IsNotExist(err) {
		//log.Info("Keystore not found. Generating a new one...")
		// 生成私钥
		privateKey, err := generatePrivateKey()
		if err != nil {
			log.Error("Error generating private key:", err)
			return nil, err
		}
		// 保存私钥到 keystore 文件
		err = savePrivateKey(privateKey)
		if err != nil {
			log.Error("Error saving private key:", err)
			return nil, err
		}
		//log.Info("Keystore generated successfully.")
		return privateKey, nil
	} else {
		//log.Info("Keystore found. Reading private key...")
		// 读取私钥
		privateKey, err := readPrivateKey()
		if err != nil || privateKey == nil {
			log.Error("Error reading private key:", err)
			return nil, err
		}
		//log.Info("Private key read successfully:", privateKey)
		return privateKey, nil
	}
}

func generatePrivateKey() (*ecdsa.PrivateKey, error) {
	return crypto.GenerateKey()
}

func savePrivateKey(privateKey *ecdsa.PrivateKey) error {
	ks := keystore.NewKeyStore(KEYPATH_PWD, keystore.StandardScryptN, keystore.StandardScryptP)
	account, err := ks.ImportECDSA(privateKey, KEYPATH_PWD)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(account.Address.Hex())
	return nil
}

func readPrivateKey() (*ecdsa.PrivateKey, error) {
	file, err := ioutil.ReadDir(KEYPATH_PWD)
	if err != nil {
		return nil, err
	}
	for _, info := range file {
		keystoreFile := fmt.Sprintf("%s%s%s", KEYPATH_PWD, "/", info.Name())
		jsonBytes, err := ioutil.ReadFile(keystoreFile)
		if err != nil {
			log.Error("import ecdsa keystore error: ", err)
			continue
		}
		key, err := keystore.DecryptKey(jsonBytes, KEYPATH_PWD)
		if err != nil {
			log.Error("keystore decrypt key failed:", err)
			continue
		}
		return key.PrivateKey, nil
	}
	return nil, nil
}