github.com/iotexproject/iotex-core@v1.14.1-rc1/ioctl/newcmd/did/didgenerate.go (about) 1 // Copyright (c) 2022 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package did 7 8 import ( 9 "crypto/sha256" 10 "encoding/hex" 11 "encoding/json" 12 13 "github.com/pkg/errors" 14 "github.com/spf13/cobra" 15 16 "github.com/iotexproject/iotex-core/ioctl" 17 "github.com/iotexproject/iotex-core/ioctl/config" 18 "github.com/iotexproject/iotex-core/ioctl/newcmd/account" 19 "github.com/iotexproject/iotex-core/ioctl/newcmd/action" 20 "github.com/iotexproject/iotex-core/pkg/util/addrutil" 21 ) 22 23 // Multi-language support 24 var ( 25 _generateCmdShorts = map[config.Language]string{ 26 config.English: "Generate DID document using private key from wallet", 27 config.Chinese: "用钱包中的私钥产生DID document", 28 } 29 _generateCmdUses = map[config.Language]string{ 30 config.English: "generate [-s SIGNER]", 31 config.Chinese: "generate [-s 签署人]", 32 } 33 ) 34 35 // NewDidGenerateCmd represents the did generate command 36 func NewDidGenerateCmd(client ioctl.Client) *cobra.Command { 37 use, _ := client.SelectTranslation(_generateCmdUses) 38 short, _ := client.SelectTranslation(_generateCmdShorts) 39 40 cmd := &cobra.Command{ 41 Use: use, 42 Short: short, 43 Args: cobra.ExactArgs(0), 44 RunE: func(cmd *cobra.Command, args []string) error { 45 cmd.SilenceUsage = true 46 signer, err := cmd.Flags().GetString("signer") 47 if err != nil { 48 return errors.Wrap(err, "failed to get flag signer") 49 } 50 addr, err := action.Signer(client, signer) 51 if err != nil { 52 return errors.Wrap(err, "failed to get signer addr") 53 } 54 cmd.Printf("Enter password #%s:\n", addr) 55 password, err := client.ReadSecret() 56 if err != nil { 57 return errors.Wrap(err, "failed to get password") 58 } 59 pri, err := account.PrivateKeyFromSigner(client, cmd, addr, password) 60 if err != nil { 61 return errors.Wrap(err, "failed to get private key from signer") 62 } 63 doc := newDIDDoc() 64 ethAddress, err := addrutil.IoAddrToEvmAddr(addr) 65 if err != nil { 66 return errors.Wrap(err, "failed to convert IoTeX address to EVM address") 67 } 68 doc.ID = DIDPrefix + ethAddress.String() 69 authentication := authenticationStruct{ 70 ID: doc.ID + DIDOwner, 71 Type: DIDAuthType, 72 Controller: doc.ID, 73 } 74 uncompressed := pri.PublicKey().Bytes() 75 if len(uncompressed) == 33 && (uncompressed[0] == 2 || uncompressed[0] == 3) { 76 authentication.PublicKeyHex = hex.EncodeToString(uncompressed) 77 } else if len(uncompressed) == 65 && uncompressed[0] == 4 { 78 lastNum := uncompressed[64] 79 authentication.PublicKeyHex = hex.EncodeToString(uncompressed[1:33]) 80 if lastNum%2 == 0 { 81 authentication.PublicKeyHex = "02" + authentication.PublicKeyHex 82 } else { 83 authentication.PublicKeyHex = "03" + authentication.PublicKeyHex 84 } 85 } else { 86 return errors.New("invalid public key") 87 } 88 89 doc.Authentication = append(doc.Authentication, authentication) 90 msg, err := json.MarshalIndent(doc, "", " ") 91 if err != nil { 92 return err 93 } 94 95 sum := sha256.Sum256(msg) 96 cmd.Printf("%s\n\nThe hex encoded SHA256 hash of the DID doc is:%s\n", string(msg), hex.EncodeToString(sum[:])) 97 return nil 98 }, 99 } 100 action.RegisterWriteCommand(client, cmd) 101 return cmd 102 }