Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ioctl] Build did register command line into new ioctl #3583

Merged
merged 24 commits into from
Sep 7, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ffeba83
[ioctl] build did command line into new ioctl
LuckyPigeon Aug 3, 2022
dcdc832
[ioctl] build did register command line into new ioctl
LuckyPigeon Aug 4, 2022
25c88be
replace use & short with client interface
LuckyPigeon Aug 4, 2022
e6ad871
build unittest to cover the modification
LuckyPigeon Aug 4, 2022
6ef5818
update short description
LuckyPigeon Aug 4, 2022
b6eab00
align all abi methods
LuckyPigeon Aug 4, 2022
21e6d98
check result
LuckyPigeon Aug 4, 2022
aa594df
check did unittest result
LuckyPigeon Aug 4, 2022
47d1d4f
check abi errors
LuckyPigeon Aug 5, 2022
f3127fe
Merge branch 'master' into dev_did_register
LuckyPigeon Aug 9, 2022
09f6c0b
Merge branch 'master' into dev_did_register
LuckyPigeon Aug 10, 2022
3dc7c11
Merge branch 'master' into dev_did_register
LuckyPigeon Aug 13, 2022
e4b5ed8
Merge branch 'master' into dev_did_register
LuckyPigeon Aug 16, 2022
85641bb
Merge branch 'master' into dev_did_register
LuckyPigeon Aug 19, 2022
f0ff2c7
Merge branch 'master' into dev_did_register
millken Aug 22, 2022
f27ab0a
Merge branch 'master' into dev_did_register
LuckyPigeon Aug 23, 2022
62ca4fb
Merge branch 'master' into dev_did_register
LuckyPigeon Aug 23, 2022
435fb35
Merge branch 'master' into dev_did_register
LuckyPigeon Aug 29, 2022
ba3e430
Merge branch 'master' into dev_did_register
LuckyPigeon Sep 5, 2022
8a15dc0
Merge branch 'master' into dev_did_register
huof6829 Sep 6, 2022
e527441
fix cmd flag of action.Execute
huof6829 Sep 6, 2022
48c1f2f
Merge branch 'master' into dev_did_register
huof6829 Sep 7, 2022
31894f5
format
huof6829 Sep 7, 2022
5292388
Merge branch 'master' into dev_did_register
Liuhaai Sep 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions ioctl/newcmd/did/did.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) 2022 IoTeX Foundation
// This is an alpha (internal) release and is not suitable for production. This source code is provided 'as is' and no
// warranties are given as to title or non-infringement, merchantability or fitness for purpose and, to the extent
// permitted by law, all liability for your use of the code is disclaimed. This source code is governed by Apache
// License 2.0 that can be found in the LICENSE file.

package did

import (
"github.com/iotexproject/iotex-core/ioctl"
"github.com/iotexproject/iotex-core/ioctl/config"
LuckyPigeon marked this conversation as resolved.
Show resolved Hide resolved
"github.com/spf13/cobra"
)

// Multi-language support
var (
_dIDCmdShorts = map[config.Language]string{
config.English: "DID command",
LuckyPigeon marked this conversation as resolved.
Show resolved Hide resolved
config.Chinese: "DID command",
LuckyPigeon marked this conversation as resolved.
Show resolved Hide resolved
}
)

// NewDidCmd represents the did command
func NewDidCmd(client ioctl.Client) *cobra.Command {
short, _ := client.SelectTranslation(_dIDCmdShorts)

LuckyPigeon marked this conversation as resolved.
Show resolved Hide resolved
cmd := &cobra.Command{
Use: "did",
Short: short,
}

client.SetEndpointWithFlag(cmd.PersistentFlags().StringVar)
client.SetInsecureWithFlag(cmd.PersistentFlags().BoolVar)
return cmd
}
32 changes: 32 additions & 0 deletions ioctl/newcmd/did/did_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) 2022 IoTeX Foundation
// This is an alpha (internal) release and is not suitable for production. This source code is provided 'as is' and no
// warranties are given as to title or non-infringement, merchantability or fitness for purpose and, to the extent
// permitted by law, all liability for your use of the code is disclaimed. This source code is governed by Apache
// License 2.0 that can be found in the LICENSE file.

package did

import (
"testing"

"github.com/golang/mock/gomock"
"github.com/iotexproject/iotex-core/ioctl/config"
"github.com/iotexproject/iotex-core/ioctl/util"
"github.com/iotexproject/iotex-core/test/mock/mock_ioctlclient"
LuckyPigeon marked this conversation as resolved.
Show resolved Hide resolved
"github.com/stretchr/testify/require"
)

func TestNewDidCmd(t *testing.T) {
require := require.New(t)
ctrl := gomock.NewController(t)
defer ctrl.Finish()
client := mock_ioctlclient.NewMockClient(ctrl)

client.EXPECT().SelectTranslation(gomock.Any()).Return("mockTranslationString", config.English).AnyTimes()
client.EXPECT().SetEndpointWithFlag(gomock.Any()).Do(func(_ func(*string, string, string, string)) {})
client.EXPECT().SetInsecureWithFlag(gomock.Any()).Do(func(_ func(*bool, string, bool, string)) {})

cmd := NewDidCmd(client)
_, err := util.ExecuteCmd(cmd)
LuckyPigeon marked this conversation as resolved.
Show resolved Hide resolved
require.NoError(err)
}
84 changes: 84 additions & 0 deletions ioctl/newcmd/did/didregister.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright (c) 2022 IoTeX Foundation
// This is an alpha (internal) release and is not suitable for production. This source code is provided 'as is' and no
// warranties are given as to title or non-infringement, merchantability or fitness for purpose and, to the extent
// permitted by law, all liability for your use of the code is disclaimed. This source code is governed by Apache
// License 2.0 that can be found in the LICENSE file.

package did

import (
"encoding/hex"
"math/big"
"strings"

"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/pkg/errors"
"github.com/spf13/cobra"

"github.com/iotexproject/iotex-core/ioctl"
"github.com/iotexproject/iotex-core/ioctl/config"
"github.com/iotexproject/iotex-core/ioctl/newcmd/action"
)

const (
_registerDIDName = "registerDID"
_getHashName = "getHash"
_getURIName = "getURI"
_updateDIDName = "updateDID"
_deregisterDIDName = "deregisterDID"
// DIDABI is the did abi
DIDABI = `[{"constant": false,"inputs": [],"name": "deregisterDID","outputs": [],"payable": false,"stateMutability": "nonpayable","type": "function"},{"constant": true,"inputs": [{"internalType": "bytes","name": "did","type": "bytes"}],"name": "getHash","outputs": [{"internalType": "bytes32","name": "","type": "bytes32"}],"payable": false,"stateMutability": "view","type": "function"}, {"constant": true,"inputs": [{"internalType": "bytes","name": "did","type": "bytes"}],"name": "getURI","outputs": [{"internalType": "bytes","name": "","type": "bytes"}],"payable": false,"stateMutability": "view","type": "function"},{"constant": false,"inputs": [{"internalType": "bytes32","name": "h","type": "bytes32"},{"internalType": "bytes","name": "uri","type": "bytes"}],"name": "registerDID","outputs": [],"payable": false,"stateMutability": "nonpayable","type": "function"},{"constant": false,"inputs": [{"internalType": "bytes32","name": "h","type": "bytes32"},{"internalType": "bytes","name": "uri","type": "bytes"}],"name": "updateDID","outputs": [],"payable": false,"stateMutability": "nonpayable","type": "function"}]`
LuckyPigeon marked this conversation as resolved.
Show resolved Hide resolved
)

// Multi-language support
var (
_registerCmdUses = map[config.Language]string{
config.English: "register (CONTRACT_ADDRESS|ALIAS) hash uri",
config.Chinese: "register (合约地址|别名) hash uri",
}
_registerCmdShorts = map[config.Language]string{
config.English: "Register DID on IoTeX blockchain",
config.Chinese: "Register 在IoTeX链上注册DID",
}
)

// NewDidRegisterCmd represents the did register command
func NewDidRegisterCmd(client ioctl.Client) *cobra.Command {
use, _ := client.SelectTranslation(_registerCmdUses)
short, _ := client.SelectTranslation(_registerCmdShorts)

cmd := &cobra.Command{
Use: use,
Short: short,
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true
contract, err := client.Address(args[0])
if err != nil {
return errors.Wrap(err, "failed to get contract address")
}

hashSlice, err := hex.DecodeString(args[1])
if err != nil {
return errors.Wrap(err, "failed to decode data")
}
var hashArray [32]byte
copy(hashArray[:], hashSlice)
abi, err := abi.JSON(strings.NewReader(DIDABI))
if err != nil {
return errors.Wrap(err, "falied to parse abi")
}
_, exist := abi.Methods[_registerDIDName]
if !exist {
return errors.New("method is not found")
}
bytecode, err := abi.Pack(_registerDIDName, hashArray, []byte(args[2]))
LuckyPigeon marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return errors.Wrap(err, "invalid bytecode")
}
return action.Execute(client, cmd, contract, big.NewInt(0), bytecode)
},
}
action.RegisterWriteCommand(client, cmd)
LuckyPigeon marked this conversation as resolved.
Show resolved Hide resolved
return cmd
}
83 changes: 83 additions & 0 deletions ioctl/newcmd/did/didregister_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright (c) 2022 IoTeX Foundation
// This is an alpha (internal) release and is not suitable for production. This source code is provided 'as is' and no
// warranties are given as to title or non-infringement, merchantability or fitness for purpose and, to the extent
// permitted by law, all liability for your use of the code is disclaimed. This source code is governed by Apache
// License 2.0 that can be found in the LICENSE file.

package did

import (
"testing"

"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/golang/mock/gomock"
"github.com/iotexproject/iotex-address/address"
"github.com/iotexproject/iotex-core/ioctl/config"
"github.com/iotexproject/iotex-core/ioctl/util"
"github.com/iotexproject/iotex-core/test/mock/mock_ioctlclient"
LuckyPigeon marked this conversation as resolved.
Show resolved Hide resolved
"github.com/iotexproject/iotex-proto/golang/iotexapi"
"github.com/iotexproject/iotex-proto/golang/iotexapi/mock_iotexapi"
"github.com/iotexproject/iotex-proto/golang/iotextypes"
"github.com/pkg/errors"
"github.com/stretchr/testify/require"
)

func TestNewJwtSignCmd(t *testing.T) {
LuckyPigeon marked this conversation as resolved.
Show resolved Hide resolved
require := require.New(t)
ctrl := gomock.NewController(t)
defer ctrl.Finish()
client := mock_ioctlclient.NewMockClient(ctrl)
apiServiceClient := mock_iotexapi.NewMockAPIServiceClient(ctrl)
payload := "0a10080118a08d062202313062040a023130124104dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b1a4161e219c2c5d5987f8a9efa33e8df0cde9d5541689fff05784cdc24f12e9d9ee8283a5aa720f494b949535b7969c07633dfb68c4ef9359eb16edb9abc6ebfadc801"

ks := keystore.NewKeyStore(t.TempDir(), 2, 1)
acc, err := ks.NewAccount("")
require.NoError(err)
accAddr, err := address.FromBytes(acc.Address.Bytes())
require.NoError(err)

client.EXPECT().SelectTranslation(gomock.Any()).Return("did", config.English).AnyTimes()
client.EXPECT().Address(gomock.Any()).Return(accAddr.String(), nil).Times(3)
client.EXPECT().Alias(gomock.Any()).Return("producer", nil).AnyTimes()
client.EXPECT().APIServiceClient().Return(apiServiceClient, nil).AnyTimes()
client.EXPECT().IsCryptoSm2().Return(false).Times(3)
client.EXPECT().ReadSecret().Return("", nil).Times(1)
client.EXPECT().AddressWithDefaultIfNotExist(gomock.Any()).Return(accAddr.String(), nil).Times(1)
client.EXPECT().NewKeyStore().Return(ks).Times(2)
client.EXPECT().AskToConfirm(gomock.Any()).Return(true, nil).Times(1)
client.EXPECT().Config().Return(config.Config{
Explorer: "iotexscan",
Endpoint: "testnet1",
}).Times(2)

accountResp := &iotexapi.GetAccountResponse{
AccountMeta: &iotextypes.AccountMeta{
IsContract: false,
PendingNonce: 10,
Balance: "100000000000000000000",
},
}
chainMetaResp := &iotexapi.GetChainMetaResponse{
ChainMeta: &iotextypes.ChainMeta{
ChainID: 0,
},
}
sendActionResp := &iotexapi.SendActionResponse{}
apiServiceClient.EXPECT().GetAccount(gomock.Any(), gomock.Any()).Return(accountResp, nil).Times(2)
apiServiceClient.EXPECT().GetChainMeta(gomock.Any(), gomock.Any()).Return(chainMetaResp, nil).Times(1)
apiServiceClient.EXPECT().SendAction(gomock.Any(), gomock.Any()).Return(sendActionResp, nil).Times(1)

t.Run("did register", func(t *testing.T) {
cmd := NewDidRegisterCmd(client)
_, err := util.ExecuteCmd(cmd, accAddr.String(), payload, "test", "--signer", accAddr.String())
LuckyPigeon marked this conversation as resolved.
Show resolved Hide resolved
require.NoError(err)
})

t.Run("failed to decode data", func(t *testing.T) {
expectedErr := errors.New("failed to decode data")

cmd := NewDidRegisterCmd(client)
_, err := util.ExecuteCmd(cmd, accAddr.String(), "test", "test", "--signer", accAddr.String())
require.Contains(err.Error(), expectedErr.Error())
})
}