github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/crypto/keys/wif.go (about) 1 package keys 2 3 import ( 4 "bytes" 5 "fmt" 6 7 "github.com/nspcc-dev/neo-go/pkg/encoding/base58" 8 "github.com/nspcc-dev/neo-go/pkg/util/slice" 9 ) 10 11 const ( 12 // WIFVersion is the version used to decode and encode WIF keys. 13 WIFVersion = 0x80 14 ) 15 16 // WIF represents a wallet import format. 17 type WIF struct { 18 // Version of the wallet import format. Default to 0x80. 19 Version byte 20 21 // Bool to determine if the WIF is compressed or not. 22 Compressed bool 23 24 // A reference to the PrivateKey which this WIF is created from. 25 PrivateKey *PrivateKey 26 27 // A string representation of the WIF. 28 S string 29 } 30 31 // WIFEncode encodes the given private key into a WIF string. 32 func WIFEncode(key []byte, version byte, compressed bool) (s string, err error) { 33 if version == 0x00 { 34 version = WIFVersion 35 } 36 if len(key) != 32 { 37 return s, fmt.Errorf("invalid private key length: %d", len(key)) 38 } 39 40 buf := new(bytes.Buffer) 41 buf.WriteByte(version) 42 buf.Write(key) 43 if compressed { 44 buf.WriteByte(0x01) 45 } 46 47 s = base58.CheckEncode(buf.Bytes()) 48 return 49 } 50 51 // WIFDecode decodes the given WIF string into a WIF struct. 52 func WIFDecode(wif string, version byte) (*WIF, error) { 53 b, err := base58.CheckDecode(wif) 54 if err != nil { 55 return nil, err 56 } 57 defer slice.Clean(b) 58 59 if version == 0x00 { 60 version = WIFVersion 61 } 62 w := &WIF{ 63 Version: version, 64 S: wif, 65 } 66 switch len(b) { 67 case 33: // OK, uncompressed public key. 68 case 34: // OK, compressed public key. 69 // Check the compression flag. 70 if b[33] != 0x01 { 71 return nil, fmt.Errorf("invalid compression flag %d expecting %d", b[33], 0x01) 72 } 73 w.Compressed = true 74 default: 75 return nil, fmt.Errorf("invalid WIF length %d, expecting 33 or 34", len(b)) 76 } 77 78 if b[0] != version { 79 return nil, fmt.Errorf("invalid WIF version got %d, expected %d", b[0], version) 80 } 81 82 // Derive the PrivateKey. 83 w.PrivateKey, err = NewPrivateKeyFromBytes(b[1:33]) 84 if err != nil { 85 return nil, err 86 } 87 88 return w, nil 89 }