|
| 1 | +# Delete Name |
| 2 | + |
| 3 | +## Msg |
| 4 | + |
| 5 | +Now it is time to define the `Msg` for deleting names and add it to the `./x/nameservice/types/msgs.go` file. This code is very similar to `SetName`: |
| 6 | + |
| 7 | +```go |
| 8 | +// MsgDeleteName defines a DeleteName message |
| 9 | +type MsgDeleteName struct { |
| 10 | + Name string `json:"name"` |
| 11 | + Owner sdk.AccAddress `json:"owner"` |
| 12 | +} |
| 13 | + |
| 14 | +// NewMsgDeleteName is a constructor function for MsgDeleteName |
| 15 | +func NewMsgDeleteName(name string, owner sdk.AccAddress) MsgDeleteName { |
| 16 | + return MsgDeleteName{ |
| 17 | + Name: name, |
| 18 | + Owner: owner, |
| 19 | + } |
| 20 | +} |
| 21 | + |
| 22 | +// Route should return the name of the module |
| 23 | +func (msg MsgDeleteName) Route() string { return RouterKey } |
| 24 | + |
| 25 | +// Type should return the action |
| 26 | +func (msg MsgDeleteName) Type() string { return "delete_name" } |
| 27 | + |
| 28 | +// ValidateBasic runs stateless checks on the message |
| 29 | +func (msg MsgDeleteName) ValidateBasic() sdk.Error { |
| 30 | + if msg.Owner.Empty() { |
| 31 | + return sdk.ErrInvalidAddress(msg.Owner.String()) |
| 32 | + } |
| 33 | + if len(msg.Name) == 0 { |
| 34 | + return sdk.ErrUnknownRequest("Name cannot be empty") |
| 35 | + } |
| 36 | + return nil |
| 37 | +} |
| 38 | + |
| 39 | +// GetSignBytes encodes the message for signing |
| 40 | +func (msg MsgDeleteName) GetSignBytes() []byte { |
| 41 | + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(msg)) |
| 42 | +} |
| 43 | + |
| 44 | +// GetSigners defines whose signature is required |
| 45 | +func (msg MsgDeleteName) GetSigners() []sdk.AccAddress { |
| 46 | + return []sdk.AccAddress{msg.Owner} |
| 47 | +} |
| 48 | +``` |
| 49 | + |
| 50 | +Next, in the `./x/nameservice/handler.go` file, add the `MsgDeleteName` handler to the module router: |
| 51 | + |
| 52 | +```go |
| 53 | +// NewHandler returns a handler for "nameservice" type messages. |
| 54 | +func NewHandler(keeper Keeper) sdk.Handler { |
| 55 | + return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { |
| 56 | + switch msg := msg.(type) { |
| 57 | + case MsgSetName: |
| 58 | + return handleMsgSetName(ctx, keeper, msg) |
| 59 | + case MsgBuyName: |
| 60 | + return handleMsgBuyName(ctx, keeper, msg) |
| 61 | + case MsgDeleteName: |
| 62 | + return handleMsgDeleteName(ctx, keeper, msg) |
| 63 | + default: |
| 64 | + errMsg := fmt.Sprintf("Unrecognized nameservice Msg type: %v", msg.Type()) |
| 65 | + return sdk.ErrUnknownRequest(errMsg).Result() |
| 66 | + } |
| 67 | + } |
| 68 | +} |
| 69 | +``` |
| 70 | + |
| 71 | +Finally, define the `DeleteName` `handler` function which performs the state transitions triggered by the message. Keep in mind that at this point the message has had its `ValidateBasic` function run so there has been some input verification. However, `ValidateBasic` cannot query application state. Validation logic that is dependent on network state (e.g. account balances) should be performed in the `handler` function. |
| 72 | + |
| 73 | +```go |
| 74 | +// Handle a message to delete name |
| 75 | +func handleMsgDeleteName(ctx sdk.Context, keeper Keeper, msg MsgDeleteName) sdk.Result { |
| 76 | + if !keeper.IsNamePresent(ctx, msg.Name) { |
| 77 | + return types.ErrNameDoesNotExist(types.DefaultCodespace).Result() |
| 78 | + } |
| 79 | + if !msg.Owner.Equals(keeper.GetOwner(ctx, msg.Name)) { |
| 80 | + return sdk.ErrUnauthorized("Incorrect Owner").Result() |
| 81 | + } |
| 82 | + keeper.DeleteWhois(ctx, msg.Name) |
| 83 | + return sdk.Result{} |
| 84 | +} |
| 85 | +``` |
| 86 | + |
| 87 | +First check to see if the name currently exists in the store. If not, throw an error and return that to the user. Then check to see if the `Msg` sender is actually the owner of the name (`keeper.GetOwner`). If so, they can delete the name by calling the function on the `Keeper`. If not, throw an error and return that to the user. |
| 88 | + |
| 89 | +### Now that you have your `Msgs` and `Handlers` defined it's time to learn about making the data from these transactions [available for querying](queriers.md)! |
0 commit comments