core: add witness check to nep5 transfer method

We have to check, whether transaction's sender is authorised to transfer
nep5 assets.
This commit is contained in:
Anna Shaleva 2020-05-19 10:19:05 +03:00
parent 1afd630169
commit 9f2cb1726b
5 changed files with 44 additions and 2 deletions

View file

@ -178,6 +178,12 @@ func TestCreateBasicChain(t *testing.T) {
txMoveNeo.ValidUntilBlock = validUntilBlock
txMoveNeo.Nonce = getNextNonce()
txMoveNeo.Sender = neoOwner
txMoveNeo.Cosigners = []transaction.Cosigner{{
Account: neoOwner,
Scopes: transaction.CalledByEntry,
AllowedContracts: nil,
AllowedGroups: nil,
}}
// use output of issue tx from genesis block as an input
genesisBlock, err := bc.GetBlock(bc.GetHeaderHash(0))
@ -362,6 +368,14 @@ func TestCreateBasicChain(t *testing.T) {
transferTx.Nonce = getNextNonce()
transferTx.ValidUntilBlock = validUntilBlock
transferTx.Sender = priv0ScriptHash
transferTx.Cosigners = []transaction.Cosigner{
{
Account: priv0ScriptHash,
Scopes: transaction.CalledByEntry,
AllowedContracts: nil,
AllowedGroups: nil,
},
}
require.NoError(t, addNetworkFee(bc, transferTx, acc0))
require.NoError(t, acc0.SignTx(transferTx))
@ -373,6 +387,14 @@ func TestCreateBasicChain(t *testing.T) {
transferTx.Nonce = getNextNonce()
transferTx.ValidUntilBlock = validUntilBlock
transferTx.Sender = priv0ScriptHash
transferTx.Cosigners = []transaction.Cosigner{
{
Account: priv0ScriptHash,
Scopes: transaction.CalledByEntry,
AllowedContracts: nil,
AllowedGroups: nil,
},
}
require.NoError(t, addNetworkFee(bc, transferTx, acc0))
require.NoError(t, acc0.SignTx(transferTx))

View file

@ -5,6 +5,7 @@ import (
"math/big"
"github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/core/interop/runtime"
"github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
@ -147,6 +148,17 @@ func (c *nep5TokenNative) transfer(ic *interop.Context, from, to util.Uint160, a
return errors.New("negative amount")
}
ok, err := runtime.CheckHashedWitness(ic, nep5ScriptHash{
callingScriptHash: c.Hash,
entryScriptHash: c.Hash,
currentScriptHash: c.Hash,
}, from)
if err != nil {
return err
} else if !ok {
return errors.New("invalid signature")
}
keyFrom := makeAccountKey(from)
siFrom := ic.DAO.GetStorageItem(c.Hash, keyFrom)
if siFrom == nil {

View file

@ -111,6 +111,14 @@ func (c *Client) TransferNEP5(acc *wallet.Account, to util.Uint160, token *walle
script := w.Bytes()
tx := transaction.NewInvocationTX(script, gas)
tx.Sender = from
tx.Cosigners = []transaction.Cosigner{
{
Account: from,
Scopes: transaction.CalledByEntry,
AllowedContracts: nil,
AllowedGroups: nil,
},
}
result, err := c.InvokeScript(hex.EncodeToString(script))
if err != nil {

View file

@ -580,7 +580,7 @@ var rpcTestCases = map[string][]rpcTestCase{
"gettransactionheight": {
{
name: "positive",
params: `["792dfa667e204c41fe68437df9324b04b14bcc94bbf7c6108ef0067a196c7600"]`,
params: `["0e873d5d565a03c6cd39efa3b446e1901b4636c448a22bc7e8c259c5a28a2eda"]`,
result: func(e *executor) interface{} {
h := 1
return &h
@ -792,7 +792,7 @@ var rpcTestCases = map[string][]rpcTestCase{
"sendrawtransaction": {
{
name: "positive",
params: `["80000b000000316e851039019d39dfc2c37d6c3fee19fd5809870000000000000000a267050000000000b0040000000001232837446dce2cd43b7b340f72da323eac420cf4c0a0908dc38c08c5c3cbfd31010001787cc0a786adfe829bc2dffc5637e6855c0a82e02deee97dedbc2aac3e0e5e1a0030d3dec3862300316e851039019d39dfc2c37d6c3fee19fd58098701420c4074335c72529aabf9e4b22727a9ca8b851217cd2d6cb5d5634dbc6c60ab8dce225f90e208362805499cbc607bcd991a021f5e6a5e0b2f663ffb64fb3767966d88290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4"]`,
params: `["80000b000000316e851039019d39dfc2c37d6c3fee19fd5809870000000000000000a267050000000000b00400000000017a03a89832a347c4fb53af1f526d0d930b14ab6eb01629ce20ffbaeaeef58af3010001787cc0a786adfe829bc2dffc5637e6855c0a82e02deee97dedbc2aac3e0e5e1a0030d3dec3862300316e851039019d39dfc2c37d6c3fee19fd58098701420c40b6aeec1d2699194b842f399448b395d98bbb287dc89ea9e5ce3bb99a1c8c9bf933f55b69db6709b44e6a5c8b28b97018466479e5d500e414a0874c37abab262d290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4"]`,
result: func(e *executor) interface{} {
v := true
return &v

Binary file not shown.