Skip to content

Commit 5284acc

Browse files
committed
feat(add keystore logic): add keystore logic
add keystore logic
1 parent ff42d0c commit 5284acc

File tree

8 files changed

+96
-3
lines changed

8 files changed

+96
-3
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ go.work.sum
2323

2424
# env file
2525
.env
26-
bin
26+
bin
27+
wallet

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,18 @@ build-client:
66
build-wallet:
77
@CGO_ENABLED=0 GOOS=linux go build -o bin/go-wallet learn/go-wallet/go-wallet.go
88

9+
build-keystore:
10+
@CGO_ENABLED=0 GOOS=linux go build -o bin/go-keystore learn/go-keystore/go-keystore.go
11+
912
run-client: build-client
1013
@./bin/go-client
1114

1215
run-wallet: build-wallet
1316
@./bin/go-wallet
1417

18+
run-keystore: build-keystore
19+
@./bin/go-keystore
20+
1521
coverage:
1622
@go test -v -cover ./...
1723

README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,40 @@ func main() {
111111
// address
112112
fmt.Println(crypto.PubkeyToAddress(pvk.PublicKey).Hex())
113113
}
114+
```
115+
116+
## wallet (keystore) concept
117+
118+
![wallet-keystore-concept](wallet-keystore-concept.png)
119+
120+
1. Generate keystore with password
121+
```golang
122+
func GenerateKeyStore() {
123+
// generate keystore
124+
key := keystore.NewKeyStore("./wallet", keystore.StandardScryptN, keystore.StandardScryptP)
125+
account, err := key.NewAccount(config.AppConfig.KeyStorePassword)
126+
if err != nil {
127+
log.Fatal(err)
128+
}
129+
fmt.Println(account.Address)
130+
}
131+
```
132+
2. Read key from keystore with password
133+
```golang
134+
func ReadKeyFromKeyStore() {
135+
b, err := os.ReadFile(fmt.Sprintf("%s/%s", "./wallet", config.AppConfig.KeyStorefile))
136+
if err != nil {
137+
log.Fatal(err)
138+
}
139+
key, err := keystore.DecryptKey(b, config.AppConfig.KeyStorePassword)
140+
if err != nil {
141+
log.Fatal(err)
142+
}
143+
pData := crypto.FromECDSA(key.PrivateKey)
144+
fmt.Println("private key:", hexutil.Encode(pData))
145+
pubData := crypto.FromECDSAPub(&key.PrivateKey.PublicKey)
146+
fmt.Println("public key:", hexutil.Encode(pubData))
147+
address := crypto.PubkeyToAddress(key.PrivateKey.PublicKey).Hex()
148+
fmt.Println("address:", address)
149+
}
114150
```

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ require (
1616
github.com/ethereum/go-ethereum v1.14.5 // indirect
1717
github.com/fsnotify/fsnotify v1.7.0 // indirect
1818
github.com/go-ole/go-ole v1.3.0 // indirect
19+
github.com/google/uuid v1.4.0 // indirect
1920
github.com/gorilla/websocket v1.4.2 // indirect
2021
github.com/hashicorp/hcl v1.0.0 // indirect
2122
github.com/holiman/uint256 v1.2.4 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiU
2929
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
3030
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
3131
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
32+
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
33+
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
3234
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
3335
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
3436
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=

internal/config/config.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import (
77
)
88

99
type Config struct {
10-
EthJsonRpcURL string `mapstructure:"ETH_JSON_RPC_URL"`
11-
EthAddress string `mapstructure:"ETH_ADDRESS"`
10+
EthJsonRpcURL string `mapstructure:"ETH_JSON_RPC_URL"`
11+
EthAddress string `mapstructure:"ETH_ADDRESS"`
12+
KeyStorePassword string `mapstructure:"KEY_STORE_PASSWORD"`
13+
KeyStorefile string `mapstructure:"KEY_STORE_FILE"`
1214
}
1315

1416
var AppConfig *Config
@@ -21,6 +23,8 @@ func init() {
2123
v.AutomaticEnv()
2224
failOnError(v.BindEnv("ETH_JSON_RPC_URL"), "fail on Bind ETH_JSON_RPC_URL")
2325
failOnError(v.BindEnv("ETH_ADDRESS"), "fail on Bind ETH_ADDRESS")
26+
failOnError(v.BindEnv("KEY_STORE_PASSWORD"), "fail on Bind KEY_STORE_PASSWORD")
27+
failOnError(v.BindEnv("KEY_STORE_FILE"), "fail on Bind KEY_STORE_FILE")
2428
err := v.ReadInConfig()
2529
if err != nil {
2630
log.Println("load from environment variable")

learn/go-keystore/go-keystore.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"os"
7+
8+
"github.com/ethereum/go-ethereum/accounts/keystore"
9+
"github.com/ethereum/go-ethereum/common/hexutil"
10+
"github.com/ethereum/go-ethereum/crypto"
11+
"github.com/leetcode-golang-classroom/golang-ethereum-sample/internal/config"
12+
)
13+
14+
func main() {
15+
ReadKeyFromKeyStore()
16+
}
17+
18+
func GenerateKeyStore() {
19+
// generate keystore
20+
key := keystore.NewKeyStore("./wallet", keystore.StandardScryptN, keystore.StandardScryptP)
21+
account, err := key.NewAccount(config.AppConfig.KeyStorePassword)
22+
if err != nil {
23+
log.Fatal(err)
24+
}
25+
fmt.Println(account.Address)
26+
}
27+
28+
func ReadKeyFromKeyStore() {
29+
b, err := os.ReadFile(fmt.Sprintf("%s/%s", "./wallet", config.AppConfig.KeyStorefile))
30+
if err != nil {
31+
log.Fatal(err)
32+
}
33+
key, err := keystore.DecryptKey(b, config.AppConfig.KeyStorePassword)
34+
if err != nil {
35+
log.Fatal(err)
36+
}
37+
pData := crypto.FromECDSA(key.PrivateKey)
38+
fmt.Println("private key:", hexutil.Encode(pData))
39+
pubData := crypto.FromECDSAPub(&key.PrivateKey.PublicKey)
40+
fmt.Println("public key:", hexutil.Encode(pubData))
41+
address := crypto.PubkeyToAddress(key.PrivateKey.PublicKey).Hex()
42+
fmt.Println("address:", address)
43+
}

wallet-keystore-concept.png

570 KB
Loading

0 commit comments

Comments
 (0)