examples: use base64 to encode HASHY token ID

Base58 does not preserve one-to-one byte correspondence with the
original data, so different combinations of the same number of bytes
might have different encoded string length. We use GAS transfer to mint
HASHY token, where the token hash is Base58Encode(Ripemd160(data + txHash)).

The problem is that `invokescript` RPC call is used to define transfer tx
sysfee, thus, txHash during testinvoke differs from the actual one, that's
why resulting token ID may have different length during testinvoke and
real invoke. As far as we use token ID as a key to store contract
values, the storage price may also differ. The result is failing
TestNEP11_OwnerOf_BalanceOf_Transfer test due to `gas limit exceeded`
error:

```
    logger.go:130: 2021-06-10T21:09:08.984+0300	WARN	contract invocation failed	{"tx": "45a0220b19725eaa0a4d01fa7a6cdaac8498592e8f3b43bdde27aae7d9ecf635", "block": 5, "error": "error encountered at instruction 36 (SYSCALL): error during call from native: error encountered at instruction 22 (SYSCALL): failed to invoke syscall 1736177434: gas limit exceeded"}
    executor_test.go:219:
        	Error Trace:	executor_test.go:219
        	            				nep11_test.go:132
        	            				nep11_test.go:235
        	Error:      	Not equal:
        	            	expected: 0x2
        	            	actual  : 0x4
        	Test:       	TestNEP11_OwnerOf_BalanceOf_Transfer
```

Fixed by using base64 instead of base58 (base64 preserves the resulting
encoded string length for the same input length).
This commit is contained in:
Anna Shaleva 2021-06-11 13:39:48 +03:00
parent 08bd21bdf9
commit 39e096da64
2 changed files with 7 additions and 7 deletions

View file

@ -214,7 +214,7 @@ func TestNEP11_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// tokensOf: good // tokensOf: good
e.Run(t, cmdTokensOf...) e.Run(t, cmdTokensOf...)
e.checkNextLine(t, string(tokenID)) require.Equal(t, string(tokenID), e.getNextLine(t))
// properties: no contract // properties: no contract
cmdProperties := []string{ cmdProperties := []string{
@ -240,8 +240,8 @@ func TestNEP11_OwnerOf_BalanceOf_Transfer(t *testing.T) {
fst, snd = snd, fst fst, snd = snd, fst
} }
e.checkNextLine(t, string(fst)) require.Equal(t, string(fst), e.getNextLine(t))
e.checkNextLine(t, string(snd)) require.Equal(t, string(snd), e.getNextLine(t))
// tokens: missing contract hash // tokens: missing contract hash
cmdTokens := []string{"neo-go", "wallet", "nep11", "tokens", cmdTokens := []string{"neo-go", "wallet", "nep11", "tokens",
@ -252,8 +252,8 @@ func TestNEP11_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// tokens: good, several tokens // tokens: good, several tokens
e.Run(t, cmdTokens...) e.Run(t, cmdTokens...)
e.checkNextLine(t, string(fst)) require.Equal(t, string(fst), e.getNextLine(t))
e.checkNextLine(t, string(snd)) require.Equal(t, string(snd), e.getNextLine(t))
// balance check: several tokens, ok // balance check: several tokens, ok
e.Run(t, append(cmdCheckBalance, "--token", h.StringLE())...) e.Run(t, append(cmdCheckBalance, "--token", h.StringLE())...)

View file

@ -2,7 +2,7 @@
Package nft contains non-divisible non-fungible NEP11-compatible token Package nft contains non-divisible non-fungible NEP11-compatible token
implementation. This token can be minted with GAS transfer to contract address, implementation. This token can be minted with GAS transfer to contract address,
it will hash some data (including data provided in transfer) and produce it will hash some data (including data provided in transfer) and produce
base58-encoded string that is your NFT. Since it's based on hashing and basically base64-encoded string that is your NFT. Since it's based on hashing and basically
you own a hash it's HASHY. you own a hash it's HASHY.
*/ */
package nft package nft
@ -230,7 +230,7 @@ func OnNEP17Payment(from interop.Hash160, amount int, data interface{}) {
} }
tokenHash := crypto.Ripemd160(tokIn) tokenHash := crypto.Ripemd160(tokIn)
token := std.Base58Encode(tokenHash) token := std.Base64Encode(tokenHash)
addToken(ctx, from, []byte(token)) addToken(ctx, from, []byte(token))
setOwnerOf(ctx, []byte(token), from) setOwnerOf(ctx, []byte(token), from)