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][ws][#5] project device sub commands to support interaction with ws contracts #4283

Merged
merged 8 commits into from
May 30, 2024
55 changes: 55 additions & 0 deletions ioctl/cmd/ws/wsdevice.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package ws

import (
"bytes"
_ "embed" // used to embed contract abi

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

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

var (
_flagDevicesUsages = map[config.Language]string{
config.English: "device address for the project, separate multiple addresses with commas",
config.Chinese: "该project的设备地址,多个地址用逗号分割",
}
)

var wsProjectDeviceCmd = &cobra.Command{
Use: "device",
Short: config.TranslateInLang(map[config.Language]string{
config.English: "w3bstream device management",
config.Chinese: "w3bstream device 节点管理",
}, config.UILanguage),
}

var (
//go:embed contracts/abis/ProjectDevice.json
projectDeviceJSON []byte
projectDeviceAddress string
projectDeviceABI abi.ABI
)

const (
funcDevicesApprove = "approve"
funcDevicesUnapprove = "unapprove"
funcDevicesApproved = "approved"
)

const (
eventOnApprove = "Approve"
eventOnUnapprove = "Unapprove"
)

func init() {
var err error
projectDeviceABI, err = abi.JSON(bytes.NewReader(projectDeviceJSON))
if err != nil {
panic(err)
}
projectDeviceAddress = config.ReadConfig.WsProjectDevicesContract

WsCmd.AddCommand(wsProjectDeviceCmd)
}
91 changes: 91 additions & 0 deletions ioctl/cmd/ws/wsdeviceapprove.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package ws

import (
"fmt"
"math/big"
"strings"

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

"github.com/iotexproject/iotex-address/address"
"github.com/iotexproject/iotex-core/ioctl/cmd/ws/contracts"
"github.com/iotexproject/iotex-core/ioctl/config"
"github.com/iotexproject/iotex-core/ioctl/output"
)

var (
// wsProjectDeviceApprove represents approve device to send message to w3bstream project command
wsProjectDeviceApprove = &cobra.Command{
Use: "approve",
Short: config.TranslateInLang(wsProjectDeviceApproveShorts, config.UILanguage),
RunE: func(cmd *cobra.Command, args []string) error {
projectID, err := cmd.Flags().GetUint64("project-id")
if err != nil {
return errors.Wrap(err, "failed to get flag project-id")
}
devices, err := cmd.Flags().GetString("devices")
if err != nil {
return errors.Wrap(err, "failed to get flag devices")
}

out, err := approveProjectDevice(projectID, devices)
if err != nil {
return output.PrintError(err)
}
output.PrintResult(out)
return nil
},
}

wsProjectDeviceApproveShorts = map[config.Language]string{
config.English: "approve devices for w3bstream project",
config.Chinese: "授权w3bstream项目的设备",
}
)

func init() {
wsProjectDeviceApprove.Flags().Uint64P("project-id", "", 0, config.TranslateInLang(_flagProjectIDUsages, config.UILanguage))
wsProjectDeviceApprove.Flags().StringP("devices", "", "", config.TranslateInLang(_flagDevicesUsages, config.UILanguage))

_ = wsProjectDeviceApprove.MarkFlagRequired("project-id")
_ = wsProjectDeviceApprove.MarkFlagRequired("devices")

wsProjectDeviceCmd.AddCommand(wsProjectDeviceApprove)
}

func approveProjectDevice(projectID uint64, devices string) (string, error) {
deviceArr := []string{devices}
if strings.Contains(devices, ",") {
deviceArr = strings.Split(devices, ",")
}

deviceAddress := make([]common.Address, len(deviceArr))
for _, device := range deviceArr {
addr, err := address.FromString(device)
if err != nil {
return "", errors.Wrapf(err, "invalid device address: %s", device)
}
deviceAddress = append(deviceAddress, common.BytesToAddress(addr.Bytes()))
}

caller, err := NewContractCaller(projectDeviceABI, projectDeviceAddress)
if err != nil {
return "", errors.Wrap(err, "failed to create contract caller")
}

value := new(contracts.ProjectDeviceApprove)
result := NewContractResult(&projectDeviceABI, eventOnApprove, value)
if _, err = caller.CallAndRetrieveResult(funcDevicesApprove, []any{
big.NewInt(int64(projectID)),
deviceAddress,
}, result); err != nil {
return "", errors.Wrap(err, "failed to read contract")
}
if _, err = result.Result(); err != nil {
return "", err
}

return fmt.Sprintf("approve %d device", len(deviceAddress)), nil
}
93 changes: 93 additions & 0 deletions ioctl/cmd/ws/wsdeviceapproved.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package ws

import (
"math/big"

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

"github.com/iotexproject/iotex-address/address"
"github.com/iotexproject/iotex-core/ioctl/config"
"github.com/iotexproject/iotex-core/ioctl/output"
)

var (
// wsProjectDeviceApproved represents unapprove device to send message to w3bstream project command
wsProjectDeviceApproved = &cobra.Command{
Use: "approved",
Short: config.TranslateInLang(wsProjectDeviceApprovedShorts, config.UILanguage),
RunE: func(cmd *cobra.Command, args []string) error {
projectID, err := cmd.Flags().GetUint64("project-id")
if err != nil {
return errors.Wrap(err, "failed to get flag project-id")
}
device, err := cmd.Flags().GetString("device")
if err != nil {
return errors.Wrap(err, "failed to get flag devices")
}

out, err := approvedProjectDevice(projectID, device)
if err != nil {
return output.PrintError(err)
}
output.PrintResult(output.JSONString(out))
return nil
},
}

wsProjectDeviceApprovedShorts = map[config.Language]string{
config.English: "approved devices for w3bstream project",
config.Chinese: "查询是否授权w3bstream项目的设备",
}

_flagDeviceUsages = map[config.Language]string{
config.English: "device address for the project",
config.Chinese: "该project的设备地址",
}
)

func init() {
wsProjectDeviceApproved.Flags().Uint64P("project-id", "", 0, config.TranslateInLang(_flagProjectIDUsages, config.UILanguage))
wsProjectDeviceApproved.Flags().StringP("device", "", "", config.TranslateInLang(_flagDeviceUsages, config.UILanguage))

_ = wsProjectDeviceApproved.MarkFlagRequired("project-id")
_ = wsProjectDeviceApproved.MarkFlagRequired("device")

wsProjectDeviceCmd.AddCommand(wsProjectDeviceApproved)
}

func approvedProjectDevice(projectID uint64, device string) (any, error) {
addr, err := address.FromString(device)
if err != nil {
return nil, errors.Wrapf(err, "invalid device address: %s", device)
}
deviceAddress := common.BytesToAddress(addr.Bytes())

caller, err := NewContractCaller(projectDeviceABI, projectDeviceAddress)
if err != nil {
return nil, errors.Wrap(err, "failed to create contract caller")
}

result := NewContractResult(&projectDeviceABI, funcDevicesApproved, new(bool))
if err = caller.Read(funcDevicesApproved, []any{
big.NewInt(int64(projectID)),
deviceAddress,
}, result); err != nil {
return nil, errors.Wrap(err, "failed to read contract")
}
approved, err := result.Result()
if err != nil {
return nil, err
}

return &struct {
ProjectID uint64 `json:"projectID"`
Device string `json:"device"`
Approved bool `json:"approved"`
}{
ProjectID: projectID,
Device: device,
Approved: *(approved.(*bool)),
}, nil
}
91 changes: 91 additions & 0 deletions ioctl/cmd/ws/wsdeviceunapprove.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package ws

import (
"fmt"
"math/big"
"strings"

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

"github.com/iotexproject/iotex-address/address"
"github.com/iotexproject/iotex-core/ioctl/cmd/ws/contracts"
"github.com/iotexproject/iotex-core/ioctl/config"
"github.com/iotexproject/iotex-core/ioctl/output"
)

var (
// wsProjectDeviceUnapprove represents unapprove device to send message to w3bstream project command
wsProjectDeviceUnapprove = &cobra.Command{
Use: "unapprove",
Short: config.TranslateInLang(wsProjectDeviceUnapproveShorts, config.UILanguage),
RunE: func(cmd *cobra.Command, args []string) error {
projectID, err := cmd.Flags().GetUint64("project-id")
if err != nil {
return errors.Wrap(err, "failed to get flag project-id")
}
devices, err := cmd.Flags().GetString("devices")
if err != nil {
return errors.Wrap(err, "failed to get flag devices")
}

out, err := unapproveProjectDevice(projectID, devices)
if err != nil {
return output.PrintError(err)
}
output.PrintResult(out)
return nil
},
}

wsProjectDeviceUnapproveShorts = map[config.Language]string{
config.English: "unapprove devices for w3bstream project",
config.Chinese: "取消授权w3bstream项目的设备",
}
)

func init() {
wsProjectDeviceUnapprove.Flags().Uint64P("project-id", "", 0, config.TranslateInLang(_flagProjectIDUsages, config.UILanguage))
wsProjectDeviceUnapprove.Flags().StringP("devices", "", "", config.TranslateInLang(_flagDevicesUsages, config.UILanguage))

_ = wsProjectDeviceUnapprove.MarkFlagRequired("project-id")
_ = wsProjectDeviceUnapprove.MarkFlagRequired("devices")

wsProjectDeviceCmd.AddCommand(wsProjectDeviceUnapprove)
}

func unapproveProjectDevice(projectID uint64, devices string) (string, error) {
deviceArr := []string{devices}
if strings.Contains(devices, ",") {
deviceArr = strings.Split(devices, ",")
}

deviceAddress := make([]common.Address, len(deviceArr))
for _, device := range deviceArr {
addr, err := address.FromString(device)
if err != nil {
return "", errors.Wrapf(err, "invalid device address: %s", device)
}
deviceAddress = append(deviceAddress, common.BytesToAddress(addr.Bytes()))
}

caller, err := NewContractCaller(projectDeviceABI, projectDeviceAddress)
if err != nil {
return "", errors.Wrap(err, "failed to create contract caller")
}

value := new(contracts.ProjectDeviceUnapprove)
result := NewContractResult(&projectDeviceABI, eventOnUnapprove, value)
if _, err = caller.CallAndRetrieveResult(funcDevicesUnapprove, []any{
big.NewInt(int64(projectID)),
deviceAddress,
}, result); err != nil {
return "", errors.Wrap(err, "failed to read contract")
}
if _, err = result.Result(); err != nil {
return "", err
}

return fmt.Sprintf("unapprove %d device", len(deviceAddress)), nil
}
Loading