Skip to content

Commit

Permalink
Emit owner event before CW721 transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
codchen committed Nov 14, 2024
1 parent c72030c commit 7b9d051
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 9 deletions.
49 changes: 49 additions & 0 deletions x/wasm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"context"
"encoding/binary"
"encoding/json"
"fmt"
"math"
"path/filepath"
Expand Down Expand Up @@ -371,6 +372,7 @@ func (k Keeper) execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller
// prepare querier
querier := k.newQueryHandler(ctx, contractAddress)
gas := k.runtimeGasForContract(ctx)
k.emitCW721OwnerBeforeTransferIfApplicable(ctx, contractAddress, msg)
res, gasUsed, execErr := k.wasmVM.Execute(codeInfo.CodeHash, env, info, msg, prefixStore, cosmwasmAPI, querier, k.gasMeter(ctx), gas, costJSONDeserialization)
k.consumeRuntimeGas(ctx, gasUsed)
if execErr != nil {
Expand Down Expand Up @@ -1072,6 +1074,53 @@ func (k Keeper) newQueryHandler(ctx sdk.Context, contractAddress sdk.AccAddress)
return NewQueryHandler(ctx, k.wasmVMQueryHandler, contractAddress, k.gasRegister)
}

func (k Keeper) emitCW721OwnerBeforeTransferIfApplicable(ctx sdk.Context, contractAddress sdk.AccAddress, msg []byte) {
parsedMsg := map[string]json.RawMessage{}
if err := json.Unmarshal(msg, &parsedMsg); err != nil {
return
}
subMsg, ok := parsedMsg["transfer_nft"]
if !ok {
subMsg, ok = parsedMsg["send_nft"]
}
if !ok {
subMsg, ok = parsedMsg["burn"]
}
if !ok {
return
}
parsedSubMsg := map[string]json.RawMessage{}
if err := json.Unmarshal(subMsg, &parsedSubMsg); err != nil {
return
}
if tokenBz, ok := parsedSubMsg["token_id"]; ok && len(tokenBz) > 2 {
tokenID := string(tokenBz[1 : len(tokenBz)-1])
ownerQuery := map[string]interface{}{"owner_of": map[string]string{
"token_id": tokenID,
}}
ownerQueryBz, err := json.Marshal(ownerQuery)
if err != nil {
return
}
resBz, err := k.QuerySmart(ctx.WithGasMeter(sdk.NewInfiniteGasMeterWithMultiplier(ctx)), contractAddress, ownerQueryBz)
if err != nil {
return
}
res := map[string]json.RawMessage{}
if err := json.Unmarshal(resBz, &res); err != nil {
return
}
if ownerBz, ok := res["owner"]; ok && len(ownerBz) > 2 {
ctx.EventManager().EmitEvent(sdk.NewEvent(
types.EventTypeCW721PreTransferOwner,
sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddress.String()),
sdk.NewAttribute(types.AttributeKeyTokenId, tokenID),
sdk.NewAttribute(types.AttributeKeyOwner, string(ownerBz[1:len(ownerBz)-1])),
))
}
}
}

// MultipliedGasMeter wraps the GasMeter from context and multiplies all reads by out defined multiplier
type MultipliedGasMeter struct {
originalMeter sdk.GasMeter
Expand Down
21 changes: 12 additions & 9 deletions x/wasm/types/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ const (
// CustomContractEventPrefix contracts can create custom events. To not mix them with other system events they got the `wasm-` prefix.
CustomContractEventPrefix = "wasm-"

EventTypeStoreCode = "store_code"
EventTypeInstantiate = "instantiate"
EventTypeExecute = "execute"
EventTypeMigrate = "migrate"
EventTypePinCode = "pin_code"
EventTypeUnpinCode = "unpin_code"
EventTypeSudo = "sudo"
EventTypeReply = "reply"
EventTypeGovContractResult = "gov_contract_result"
EventTypeStoreCode = "store_code"
EventTypeInstantiate = "instantiate"
EventTypeExecute = "execute"
EventTypeMigrate = "migrate"
EventTypePinCode = "pin_code"
EventTypeUnpinCode = "unpin_code"
EventTypeSudo = "sudo"
EventTypeReply = "reply"
EventTypeGovContractResult = "gov_contract_result"
EventTypeCW721PreTransferOwner = "cw721_pretransfer_owner"
)

// event attributes returned from contract execution
Expand All @@ -25,4 +26,6 @@ const (
AttributeKeyCodeID = "code_id"
AttributeKeyResultDataHex = "result"
AttributeKeyFeature = "feature"
AttributeKeyTokenId = "token_id"
AttributeKeyOwner = "owner"
)

0 comments on commit 7b9d051

Please sign in to comment.