encoding/gob: type not registered for interface: elliptic.p256Curve
func (w *Data) SaveFile() {
var content bytes.Buffer
gob.Register(elliptic.P256())
encoder := gob.NewEncoder(&content)
if err := encoder.Encode(w); err != nil {
log.Panic(err)
}
fmt.Println(content)
}
Error
gob: type not registered for interface: elliptic.p256Curve
What version of Go are you using (go version)?
$ go version 1.19.3
A runnable example would be very helpful; without more context, I can't tell much about what's supposed to happen. What did you expect to happen?
elliptic.P256 is a function, not an interface, so registering it is meaningless. If anything, you want to register elliptic.Curve, I think.
However, @dr2chase is right: without a complete runnable example with import statements and main function, it's hard to diagnose any problem.
https://www.softwaretestinghelp.com/how-to-write-good-bug-report/
type Wallet struct {
PrivateKey *ecdsa.PrivateKey
PublicKey *ecdsa.PublicKey
WalletAddress string
}
type Wallets struct {
Wallets map[string]*Wallet
}
I want to encode the type Wallets struct data and store it in a data.gob file.
Here is my code
func (w *Wallets) SaveFile() {
var content bytes.Buffer
gob.Register(elliptic.P256())
encoder := gob.NewEncoder(&content)
if err := encoder.Encode(w); err != nil {
log.Panic(err)
}
fmt.Println(content)
}
The gob package failed to encode as it is showing the error gob: type not registered for interface: elliptic.p256Curve
How can I encode a type Wallets struct that contents Wallets mapping (string->Wallet) ?
gob package is not working and I'm not able to find any working solution.
I get a different error from this: "gob: type elliptic.p256Curve has no exported fields". https://go.dev/play/p/koZfJIH_lOl
However, the same code works in 1.18. The discrepancy is due to elliptic.p256Curve switching from embedding *elliptic.CurveParams in 1.18 to embedding elliptic.nistCurve in 1.19. Evidently, this was technically a breaking change.
As an unexported type, this change was one allowed by the stdlib.
Note that crypto/elliptic has specialized functions for marshaling and unmarshaling key data, you should be using those rather than on hidden implementation details.
Closing as unfortunate, but working as intended.
Is there no equivalent substitute in the latest version?
Is there no equivalent substitute in the latest version?
No!
Maybe this would help. I was getting the same issue because I wanna encode a Wallets structure (that uses this interface of P256 Elliptic Curve) with a buffer and this gob.NewEncoder.
What I did to work me, it's change the way that I was trying to encode this structure. So I encode the structure with json.Marshal instead of the bytes.Buffer and this gob.NewEncoder.
Old Code (With troubles)
func (ws *Wallets) SaveFile() {
var content bytes.Buffer
gob.Register(elliptic.P256())
encoder := gob.NewEncoder(&content)
err := encoder.Encode(ws) // HERE WAS THE PROBLEM
if err != nil {
log.Panic(err)
}
err = ioutil.WriteFile(walletFile, content.Bytes(), 0644)
if err != nil {
log.Panic(err)
}
}
New Code (Working)
func (ws *Wallets) SaveFile() {
jsonData, err := json.Marshal(ws)
handlers.HandleErrors(err)
err = ioutil.WriteFile(walletFile, jsonData, 0544)
handlers.HandleErrors(err)
}
Helpers Module
package handlers
import "log"
func HandleErrors(err error) {
if err != nil {
log.Panic(err)
}
}
in addition to the previous answer we should apply some more code as well. @rwiteshbera @facundocarballo
// wallet.go
func (w Wallet) MarshalJSON() ([]byte, error) {
mapStringAny := map[string]any{
"PrivateKey": map[string]any{
"D": w.PrivateKey.D,
"PublicKey": map[string]any{
"X": w.PrivateKey.PublicKey.X,
"Y": w.PrivateKey.PublicKey.Y,
},
"X": w.PrivateKey.X,
"Y": w.PrivateKey.Y,
},
"PublicKey": w.PublicKey,
}
return json.Marshal(mapStringAny)
}