Skip to content

Commit

Permalink
feat: get private key from keystore (#4)
Browse files Browse the repository at this point in the history
* decrypt private key

* update config parser

* resolve keyfile path

* update readme
  • Loading branch information
iczc authored Aug 9, 2021
1 parent b0530cd commit 86634f3
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 28 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
## Quick Start
```bash
docker build -t eth-faucet .
docker run -d -p 8080:8080 -v $(pwd)/config.yml:/app/config.yml eth-faucet
docker run -d -p 8080:8080 -v `pwd`/config.yml:/app/config.yml eth-faucet
```
48 changes: 38 additions & 10 deletions cmd/server.go
Original file line number Diff line number Diff line change
@@ -1,42 +1,70 @@
package cmd

import (
"crypto/ecdsa"
"flag"
"fmt"
"os"
"os/signal"

"github.com/ethereum/go-ethereum/crypto"
"github.com/spf13/viper"

"github.com/chainflag/eth-faucet/internal"
"github.com/chainflag/eth-faucet/internal/pkg"
"github.com/chainflag/eth-faucet/internal/chain"
)

type config struct {
Provider string
Payout int
QueueCap int
PrivateKey *ecdsa.PrivateKey
}

var port int

func init() {
flag.IntVar(&port, "port", 8080, "listen port")
flag.Parse()
}

func initConfig() *viper.Viper {
func initConfig() *config {
v := viper.New()
v.SetConfigFile("./config.yml")
if err := v.ReadInConfig(); err != nil {
panic(err)
panic(fmt.Errorf("Fatal error config file: %v \n", err))
}

return v
privateKey, err := func(walletConf map[string]string) (*ecdsa.PrivateKey, error) {
if walletConf["privkey"] != "" {
return crypto.HexToECDSA(walletConf["privkey"])
}

keyfile, err := chain.ResolveKeyfilePath(walletConf["keystore"])
if err != nil {
panic(err)
}

return chain.DecryptPrivateKey(keyfile, walletConf["password"])
}(v.GetStringMapString("wallet"))

if err != nil {
panic(fmt.Errorf("Failed to parse private key: %v \n", err))
}

return &config{
Provider: v.GetString("provider"),
Payout: v.GetInt("payout"),
QueueCap: v.GetInt("queuecap"),
PrivateKey: privateKey,
}
}

func Execute() {
conf := initConfig()
provider := conf.GetString("provider")
privKey := conf.GetString("privkey")
queueCap := conf.GetInt("queuecap")

faucet := internal.NewFaucet(pkg.NewTxBuilder(provider, privKey, nil), queueCap)
faucet := internal.NewFaucet(chain.NewTxBuilder(conf.Provider, conf.PrivateKey, nil), conf.QueueCap)
defer faucet.Close()
faucet.SetPayoutEther(int64(conf.GetInt("payout")))
faucet.SetPayoutEther(conf.Payout)
go faucet.Run()

server := internal.NewServer(faucet)
Expand Down
8 changes: 6 additions & 2 deletions config.yml.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
provider : "https://ropsten.infura.io/"
privkey : ""
provider : "http://geth:8545"
payout : 1
queuecap : 100

wallet:
privkey: ""
keystore: "./keystore"
password: "secret"
52 changes: 52 additions & 0 deletions internal/chain/keystore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package chain

import (
"crypto/ecdsa"
"errors"
"io/ioutil"
"os"
"path/filepath"
"strings"

"github.com/ethereum/go-ethereum/accounts/keystore"
)

func DecryptPrivateKey(keyfile, password string) (*ecdsa.PrivateKey, error) {
jsonBytes, err := ioutil.ReadFile(keyfile)
if err != nil {
return nil, err
}

key, err := keystore.DecryptKey(jsonBytes, password)
if err != nil {
return nil, err
}

return key.PrivateKey, nil
}

func ResolveKeyfilePath(keydir string) (string, error) {
keydir, _ = filepath.Abs(keydir)
fileInfo, err := os.Stat(keydir)
if err != nil {
return "", err
}
if !fileInfo.IsDir() {
return keydir, nil
}

files, err := ioutil.ReadDir(keydir)
if err != nil {
return "", err
}
for _, file := range files {
if file.IsDir() {
continue
}
if strings.HasPrefix(file.Name(), "UTC") {
return filepath.Join(keydir, file.Name()), nil
}
}

return "", errors.New("keystore file not found ")
}
13 changes: 4 additions & 9 deletions internal/pkg/transaction.go → internal/chain/transaction.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package pkg
package chain

import (
"context"
Expand All @@ -12,7 +12,7 @@ import (
)

type ITxBuilder interface {
FromAddress() common.Address
Sender() common.Address
Transfer(ctx context.Context, to string, value *big.Int) (string, error)
}

Expand All @@ -23,17 +23,12 @@ type TxBuilder struct {
fromAddress common.Address
}

func NewTxBuilder(provider, privateKeyHex string, chainID *big.Int) ITxBuilder {
func NewTxBuilder(provider string, privateKey *ecdsa.PrivateKey, chainID *big.Int) ITxBuilder {
client, err := ethclient.Dial(provider)
if err != nil {
panic(err)
}

privateKey, err := crypto.HexToECDSA(privateKeyHex)
if err != nil {
panic(err)
}

if chainID == nil {
chainID, err = client.ChainID(context.Background())
if err != nil {
Expand All @@ -49,7 +44,7 @@ func NewTxBuilder(provider, privateKeyHex string, chainID *big.Int) ITxBuilder {
}
}

func (b *TxBuilder) FromAddress() common.Address {
func (b *TxBuilder) Sender() common.Address {
return b.fromAddress
}

Expand Down
11 changes: 6 additions & 5 deletions internal/faucet.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import (

log "github.com/sirupsen/logrus"

"github.com/chainflag/eth-faucet/internal/pkg"
"github.com/chainflag/eth-faucet/internal/chain"
)

type faucet struct {
pkg.ITxBuilder
chain.ITxBuilder
payout *big.Int
queue chan string
}

func NewFaucet(builder pkg.ITxBuilder, queueCap int) *faucet {
func NewFaucet(builder chain.ITxBuilder, queueCap int) *faucet {
return &faucet{
ITxBuilder: builder,
queue: make(chan string, queueCap),
Expand All @@ -39,8 +39,9 @@ func (f faucet) GetPayoutWei() *big.Int {
return f.payout
}

func (f *faucet) SetPayoutEther(amount int64) {
payoutWei := new(big.Int).Mul(big.NewInt(amount), new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil))
func (f *faucet) SetPayoutEther(amount int) {
ether := new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)
payoutWei := new(big.Int).Mul(big.NewInt(int64(amount)), ether)
f.payout = payoutWei
}

Expand Down
2 changes: 1 addition & 1 deletion internal/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func (s server) handleInfo() http.HandlerFunc {

w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(infoResp{
Account: s.faucet.FromAddress().String(),
Account: s.faucet.Sender().String(),
Payout: s.faucet.GetPayoutWei().String(),
})
}
Expand Down
Empty file added keystore/.gitkeep
Empty file.

0 comments on commit 86634f3

Please sign in to comment.