Skip to content

Commit

Permalink
native: call onNEP11Transfer for NEP-11 transfers
Browse files Browse the repository at this point in the history
  • Loading branch information
roman-khimov committed Feb 5, 2021
1 parent a442e15 commit cd9b344
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 2 deletions.
21 changes: 19 additions & 2 deletions pkg/core/interop_system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,13 +340,20 @@ func getTestContractState(bc *Blockchain) (*state.Contract, *state.Contract) {
emit.Syscall(w.BinWriter, interopnames.SystemStorageGetContext)
emit.Syscall(w.BinWriter, interopnames.SystemStorageGet)
emit.Opcodes(w.BinWriter, opcode.RET)
onPaymentOff := w.Len()
onNEP17PaymentOff := w.Len()
emit.Syscall(w.BinWriter, interopnames.SystemRuntimeGetCallingScriptHash)
emit.Int(w.BinWriter, 4)
emit.Opcodes(w.BinWriter, opcode.PACK)
emit.String(w.BinWriter, "LastPayment")
emit.Syscall(w.BinWriter, interopnames.SystemRuntimeNotify)
emit.Opcodes(w.BinWriter, opcode.RET)
onNEP11PaymentOff := w.Len()
emit.Syscall(w.BinWriter, interopnames.SystemRuntimeGetCallingScriptHash)
emit.Int(w.BinWriter, 4)
emit.Opcodes(w.BinWriter, opcode.PACK)
emit.String(w.BinWriter, "LostPayment")
emit.Syscall(w.BinWriter, interopnames.SystemRuntimeNotify)
emit.Opcodes(w.BinWriter, opcode.RET)
update3Off := w.Len()
emit.Int(w.BinWriter, 3)
emit.Opcodes(w.BinWriter, opcode.JMP, 2+1)
Expand Down Expand Up @@ -455,9 +462,19 @@ func getTestContractState(bc *Blockchain) (*state.Contract, *state.Contract) {
},
ReturnType: smartcontract.VoidType,
},
{
Name: manifest.MethodOnNEP11Payment,
Offset: onNEP11PaymentOff,
Parameters: []manifest.Parameter{
manifest.NewParameter("from", smartcontract.Hash160Type),
manifest.NewParameter("amount", smartcontract.IntegerType),
manifest.NewParameter("tokenid", smartcontract.ByteArrayType),
},
ReturnType: smartcontract.VoidType,
},
{
Name: manifest.MethodOnNEP17Payment,
Offset: onPaymentOff,
Offset: onNEP17PaymentOff,
Parameters: []manifest.Parameter{
manifest.NewParameter("from", smartcontract.Hash160Type),
manifest.NewParameter("amount", smartcontract.IntegerType),
Expand Down
21 changes: 21 additions & 0 deletions pkg/core/native/nonfungible.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/nspcc-dev/neo-go/pkg/core/dao"
"github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/core/interop/contract"
"github.com/nspcc-dev/neo-go/pkg/core/interop/runtime"
istorage "github.com/nspcc-dev/neo-go/pkg/core/interop/storage"
"github.com/nspcc-dev/neo-go/pkg/core/state"
Expand Down Expand Up @@ -277,6 +278,26 @@ func (n *nonfungible) postTransfer(ic *interop.Context, from, to *util.Uint160,
}),
}
ic.Notifications = append(ic.Notifications, ne)
if to == nil {
return
}
cs, err := ic.GetContract(*to)
if err != nil {
return
}

fromArg := stackitem.Item(stackitem.Null{})
if from != nil {
fromArg = stackitem.NewByteArray((*from).BytesBE())
}
args := []stackitem.Item{
fromArg,
stackitem.NewBigInteger(intOne),
stackitem.NewByteArray(tokenID),
}
if err := contract.CallFromNative(ic, n.Hash, cs, manifest.MethodOnNEP11Payment, args, false); err != nil {
panic(err)
}
}

func (n *nonfungible) burn(ic *interop.Context, tokenID []byte) {
Expand Down
10 changes: 10 additions & 0 deletions pkg/core/native_name_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,16 @@ func TestTransfer(t *testing.T) {
testNameServiceInvokeAux(t, bc, defaultNameServiceSysfee, from, "totalSupply", 1)
testNameServiceInvokeAux(t, bc, defaultNameServiceSysfee, from, "ownerOf",
to.Contract.ScriptHash().BytesBE(), []byte("neo.com"))
cs, cs2 := getTestContractState(bc) // cs2 doesn't have OnNEP11Transfer
require.NoError(t, bc.contracts.Management.PutContractState(bc.dao, cs))
require.NoError(t, bc.contracts.Management.PutContractState(bc.dao, cs2))
testNameServiceInvokeAux(t, bc, defaultRegisterSysfee, to, "transfer",
nil, cs2.Hash.BytesBE(), []byte("neo.com"))
testNameServiceInvokeAux(t, bc, defaultRegisterSysfee, to, "transfer",
true, cs.Hash.BytesBE(), []byte("neo.com"))
testNameServiceInvokeAux(t, bc, defaultNameServiceSysfee, from, "totalSupply", 1)
testNameServiceInvokeAux(t, bc, defaultNameServiceSysfee, from, "ownerOf",
cs.Hash.BytesBE(), []byte("neo.com"))
}

func TestTokensOf(t *testing.T) {
Expand Down
3 changes: 3 additions & 0 deletions pkg/smartcontract/manifest/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ const (
// MethodOnNEP17Payment is name of the method which is called when contract receives NEP-17 tokens.
MethodOnNEP17Payment = "onNEP17Payment"

// MethodOnNEP11Payment is the name of the method which is called when contract receives NEP-11 tokens.
MethodOnNEP11Payment = "onNEP11Payment"

// NEP10StandardName represents the name of NEP10 smartcontract standard.
NEP10StandardName = "NEP-10"
// NEP17StandardName represents the name of NEP17 smartcontract standard.
Expand Down

0 comments on commit cd9b344

Please sign in to comment.