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

getnep11balances in TokensTrakcer doesn't return correct result compared with invoking tokensOf #754

Closed
superboyiii opened this issue Aug 31, 2022 · 12 comments

Comments

@superboyiii
Copy link
Member

Describe the bug
getnep11balances in TokensTrakcer doesn't return correct result compared with invoking tokensOf

To Reproduce
Steps to reproduce the behavior:

  1. invoke getnep11balances on a T5 node like:
{
  "jsonrpc": "2.0",
  "method": "getnep11balances",
  "params": ["NfcCRKpDUKGZDjz3wQFg8G2x1kh25TCpaq", 0],
  "id": 1
}

return:

{
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
        "address": "NfcCRKpDUKGZDjz3wQFg8G2x1kh25TCpaq",
        "balance": [
            {
                "assethash": "0xaa3ee1db78a9791a80ccc4fd1befe63c468096ab",
                "name": "ilex",
                "symbol": "ilex",
                "decimals": "0",
                "tokens": [
                    {
                        "tokenid": "0b",
                        "amount": "1",
                        "lastupdatedblock": 617871
                    }
                ]
            }
        ]
    }
}

Only 1 NEP-11 token is returned.
2. invoke tokensOf like:

{{
  "jsonrpc": "2.0",
  "method": "invokefunction",
  "params": [
    "0x6a2893f97401e2b58b757f59d71238d91339856a",
    "tokensOf",
    [
        {
        "type": "Hash160",
        "value": "0x833ac279fa278098b9dbe65d5cfb64a9541306d8"
        }
    ]
  ],
  "id": 3
}

return:

{
    "jsonrpc": "2.0",
    "id": 3,
    "result": {
        "script": "DBTYBhNUqWT7XF3m27mYgCf6ecI6gxHAHwwIdG9rZW5zT2YMFGqFORPZOBLXWX91i7XiAXT5kyhqQWJ9W1I=",
        "state": "HALT",
        "gasconsumed": "278448",
        "exception": null,
        "notifications": [],
        "stack": [
            {
                "type": "InteropInterface",
                "interface": "IIterator",
                "id": "c0a7d84f-53dd-4f4c-b8e2-9b17e697087b"
            }
        ],
        "session": "b5348a69-b756-4cd9-af3f-05b485678df8"
    }
}

Go to traverseiterator and invoke

{
  "jsonrpc": "2.0",
  "method": "traverseiterator",
  "params": ["b5348a69-b756-4cd9-af3f-05b485678df8", "c0a7d84f-53dd-4f4c-b8e2-9b17e697087b", 100],
  "id": 3
}

return:

{
    "jsonrpc": "2.0",
    "id": 3,
    "result": [
        {
            "type": "ByteString",
            "value": "SEFTSCAjMDE="
        },
        {
            "type": "ByteString",
            "value": "SEFTSCAjMDI="
        },
        {
            "type": "ByteString",
            "value": "SEFTSCAjMDM="
        },
        {
            "type": "ByteString",
            "value": "V0VCICMwMQ=="
        },
        {
            "type": "ByteString",
            "value": "V0VCICMwMg=="
        },
        {
            "type": "ByteString",
            "value": "V0VCICMwMw=="
        }
    ]
}
  1. You can see absolutely different result

Expected behavior
Should return the same amount of tokenid

Platform:

  • Version v3.4.0
@roman-khimov
Copy link
Contributor

NeoGo 0.99.2:

invoke getnep11balances on a T5 node like:
{
   "jsonrpc" : "2.0",
   "id" : 1,
   "result" : {
      "balance" : [
         {
            "symbol" : "ILEX GENESIS",
            "decimals" : "0",
            "assethash" : "0x6a2893f97401e2b58b757f59d71238d91339856a",
            "name" : "ILEX GENESIS",
            "tokens" : [
               {
                  "amount" : "1",
                  "lastupdatedblock" : 617588,
                  "tokenid" : "4841534820233031"
               },
               {
                  "tokenid" : "4841534820233032",
                  "lastupdatedblock" : 617588,
                  "amount" : "1"
               },
               {
                  "tokenid" : "4841534820233033",
                  "amount" : "1",
                  "lastupdatedblock" : 617588
               },
               {
                  "amount" : "1",
                  "lastupdatedblock" : 617588,
                  "tokenid" : "57454220233031"
               },
               {
                  "amount" : "1",
                  "lastupdatedblock" : 617588,
                  "tokenid" : "57454220233032"
               },
               {
                  "tokenid" : "57454220233033",
                  "amount" : "1",
                  "lastupdatedblock" : 617588
               }
            ]
         }
      ],
      "address" : "NfcCRKpDUKGZDjz3wQFg8G2x1kh25TCpaq"
   }
}
  1. invoke tokensOf like:
{
   "result" : {
      "state" : "HALT",
      "stack" : [
         {
            "type" : "InteropInterface",
            "iterator" : [
               {
                  "type" : "ByteString",
                  "value" : "SEFTSCAjMDE="
               },
               {
                  "type" : "ByteString",
                  "value" : "SEFTSCAjMDI="
               },
               {
                  "value" : "SEFTSCAjMDM=",
                  "type" : "ByteString"
               },
               {
                  "type" : "ByteString",
                  "value" : "V0VCICMwMQ=="
               },
               {
                  "value" : "V0VCICMwMg==",
                  "type" : "ByteString"
               },
               {
                  "type" : "ByteString",
                  "value" : "V0VCICMwMw=="
               }
            ]
         }
      ],
      "script" : "DBTYBhNUqWT7XF3m27mYgCf6ecI6gxHAHwwIdG9rZW5zT2YMFGqFORPZOBLXWX91i7XiAXT5kyhqQWJ9W1I=",
      "exception" : null,
      "gasconsumed" : "278448",
      "notifications" : []
   },
   "id" : 3,
   "jsonrpc" : "2.0"
}

@roman-khimov
Copy link
Contributor

Notice that the symbol is different too if we're to ask 0x6a2893f97401e2b58b757f59d71238d91339856a for it:

$ curl -sd '{"jsonrpc": "2.0", "method": "invokefunction", "params": ["0x6a2893f97401e2b58b757f59d71238d91339856a", "symbol", []],"id": 3}' https://rpc.t5.n3.nspcc.ru:20331
{"id":3,"jsonrpc":"2.0","result":{"state":"HALT","gasconsumed":"167256","script":"wh8MBnN5bWJvbAwUaoU5E9k4EtdZf3WLteIBdPmTKGpBYn1bUg==","stack":[{"type":"ByteString","value":"SUxFWCBHRU5FU0lT"}],"exception":null,"notifications":[]}}
$ echo "SUxFWCBHRU5FU0lT" | base64 -d
ILEX GENESIS

@superboyiii
Copy link
Member Author

Notice that the symbol is different too if we're to ask 0x6a2893f97401e2b58b757f59d71238d91339856a for it:

TokensTracker will deocde that Base64 ByteString.

@roman-khimov
Copy link
Contributor

Notice that the symbol is different too if we're to ask 0x6a2893f97401e2b58b757f59d71238d91339856a for it:

TokensTracker will deocde that Base64 ByteString.

That's not the point, in your output you have

                "name": "ilex",
                "symbol": "ilex",

While NeoGo returns

            "symbol" : "ILEX GENESIS",
            "name" : "ILEX GENESIS",

And that's the correct answer (even though the symbol is bad, we're expecting something short (3-8 characters is recommended), with no whitespace characters or new-lines). I'm not sure why this happens, though.

@superboyiii
Copy link
Member Author

superboyiii commented Sep 1, 2022

That's not the point, in your output you have.....

These are two absolutely different contracts, I find tokenid in 0x6a2893f97401e2b58b757f59d71238d91339856a was in Intger while tokenid in 0xaa3ee1db78a9791a80ccc4fd1befe63c468096ab was in ByteString, that's why TokenTracker can't catch 0x6a2893f97401e2b58b757f59d71238d91339856a.

@roman-khimov
Copy link
Contributor

Huh, thanks for clarification. I was then somewhat surprised that I don't see any tokens listed for 0xaa3ee1db78a9791a80ccc4fd1befe63c468096ab in my output, but looks like they're gone now:

$ curl -sd '{"jsonrpc": "2.0", "method": "invokefunction", "params": ["0xaa3ee1db78a9791a80ccc4fd1befe63c468096ab", "tokensOf", [{"type": "Hash160", "value": "0x833ac279fa278098b9dbe65d5cfb64a9541306d8"}]],"id": 3}' https://rpc.t5.n3.nspcc.ru:20331 |json_pp
{
   "id" : 3,
   "jsonrpc" : "2.0",
   "result" : {
      "notifications" : [],
      "script" : "DBTYBhNUqWT7XF3m27mYgCf6ecI6gxHAHwwIdG9rZW5zT2YMFKuWgEY85u8b/cTMgBp5qXjb4T6qQWJ9W1I=",
      "gasconsumed" : "382635",
      "state" : "HALT",
      "exception" : null,
      "stack" : [
         {
            "type" : "InteropInterface"
         }
      ]
   }
}

While there was something (the same token as in your getnep11balances) at 617871:

$ curl -sd '{"jsonrpc": "2.0", "method": "invokefunctionhistoric", "params": [617871, "0xaa3ee1db78a9791a80ccc4fd1befe63c468096ab", "tokensOf", [{"type": "Hash160", "value": "0x833ac279fa278098b9dbe65d5cfb64a9541306d8"}]],"id": 3}' https://rpc.t5.n3.nspcc.ru:20331 |json_pp
{
   "id" : 3,
   "result" : {
      "notifications" : [],
      "exception" : null,
      "state" : "HALT",
      "gasconsumed" : "382635",
      "script" : "DBTYBhNUqWT7XF3m27mYgCf6ecI6gxHAHwwIdG9rZW5zT2YMFKuWgEY85u8b/cTMgBp5qXjb4T6qQWJ9W1I=",
      "stack" : [
         {
            "type" : "InteropInterface",
            "iterator" : [
               {
                  "value" : "Cw==",
                  "type" : "ByteString"
               }
            ]
         }
      ]
   },
   "jsonrpc" : "2.0"
}

@superboyiii
Copy link
Member Author

TokenId should be ByteString, I will close this.

@mfbz
Copy link

mfbz commented Dec 9, 2022

Hey guys, why if i do the rpc call "getnep11balances" on NEO-GO nodes i get a result with a set of data and if i do the same request to C# nodes i get it different?

Example:

Request body:
{
"jsonrpc": "2.0",
"method": "getnep11balances",
"params": ["Nhiqz5HqKyicYiwnMTgeujmBjRjWvcBQYr"],
"id": 1
}

The contracts that are returning different data here are BlackStoneShard and BoredDoge NFTs. @superboyiii @roman-khimov

@roman-khimov
Copy link
Contributor

@mfbz, I don't have any obvious answer for this one. Take this token for example:

         {
            "assethash" : "0x7bd7b0af7f9085bb4f6f2e3f956ec9ff5a494645",
            "tokens" : [
               {
                  "tokenid" : "546865446f67655761734e6f74416e496d706f73746f722020233532",
                  "lastupdatedblock" : 1680095,
                  "amount" : "1"
               }
            ],
            "symbol" : "BoredDoge",
            "name" : "DogeRift_NFTS",
            "decimals" : "0"
         },

Block 1680095 really has one transaction, 0xb878b2ad81078522b5d2e98f5be89d635223ecf1aea5e43a0ed3a3e57c9b9122 and it has this event generated during the execution:

               {
                  "contract" : "0x7bd7b0af7f9085bb4f6f2e3f956ec9ff5a494645",
                  "eventname" : "Transfer",
                  "state" : {
                     "value" : [
                        {
                           "value" : "7zguJBMYuAgxO8Vzkm7OIq+tTyI=",
                           "type" : "ByteString"
                        },
                        {
                           "value" : "ZHOD/efBT66ngyCMMHdOesko/0I=",
                           "type" : "ByteString"
                        },
                        {
                           "type" : "Integer",
                           "value" : "1"
                        },
                        {
                           "type" : "ByteString",
                           "value" : "VGhlRG9nZVdhc05vdEFuSW1wb3N0b3IgICM1Mg=="
                        }
                     ],
                     "type" : "Array"
                  }
               }

Which seems to be a valid event, so it should be processed correctly by TokensTracker.

@mfbz
Copy link

mfbz commented Dec 9, 2022

Yes, i agree with you.

Another strange thing is that I just tried also with another contract (https://explorer.onegate.space/contractinfo/0xc09af9967175faca47d610716900f075bd8bf18a) that has basically the same Transfer method and NEP11 handling of the BlackStoneShard contract (https://explorer.onegate.space/contractinfo/0xdd191554eb403669221137aee0c424c27670cb2b) and it's correctly returned from getnep11balances.

I think this issue should be reopened

@mfbz
Copy link

mfbz commented Dec 10, 2022

Thanks to NeoLine devs we found the cause of the problem.

Basically BlackStoneShard Nft contract at the beginning had 2 balanceOf methods because i coded it with an overload to handle the case of requesting the balance of a key of a nft like in Ethereum EIP-1155 (https://eips.ethereum.org/EIPS/eip-1155). The fact of having 2 balanceOf methods caused the problem on the c# node.

Now i removed the overload and saw that everything is working correctly.

@roman-khimov
Copy link
Contributor

Reminds me of neo-project/neo#2355. In fact NeoGo uses balanceOf signature check to distinguish between divisible/non-divisble NEP-11 and it was probably using balanceOf(owner, token) in your case, but if that works (returning 1), it's OK. Still I'd say the plugin should be improved, because your additional balanceOf doesn't break compliance with NEP-11 non-divisible spec, the contract can have as many additional methods as it needs to with any kind of signatures, it shouldn't be a problem.

In absence of neo-project/neo#2355 we probably should check for ownerOf signature to separate divisible/non-divisible NFTs, one can't have both versions of it in the same contract.

roman-khimov added a commit to nspcc-dev/neo-go that referenced this issue Dec 10, 2022
It's more heavyweight at the same time, but should be OK for the
purpose. Inspired by neo-project/neo-modules#754 (comment)
roman-khimov added a commit to nspcc-dev/neo-go that referenced this issue Dec 10, 2022
It's more heavyweight at the same time, but should be OK for the
purpose. Inspired by neo-project/neo-modules#754 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants