rpc: accept NEP11 token IDs as []byte for client methods

Accepting IDs as string is encoding-ambiguous, so make it []byte instead.
This commit is contained in:
Anna Shaleva 2022-02-09 11:55:07 +03:00
parent 91350c3a48
commit 47652643df
4 changed files with 28 additions and 22 deletions

View file

@ -110,6 +110,12 @@ func topIterableFromStack(st []stackitem.Item, resultItemType interface{}) ([]in
result := make([]interface{}, len(iter.Values))
for i := range iter.Values {
switch resultItemType.(type) {
case []byte:
bytes, err := iter.Values[i].TryBytes()
if err != nil {
return nil, fmt.Errorf("failed to deserialize []byte from stackitem #%d: %w", i, err)
}
result[i] = bytes
case string:
bytes, err := iter.Values[i].TryBytes()
if err != nil {

View file

@ -51,15 +51,15 @@ func (c *Client) nepTotalSupply(tokenHash util.Uint160) (int64, error) {
}
// nepBalanceOf invokes `balanceOf` NEP* method on a specified contract.
func (c *Client) nepBalanceOf(tokenHash, acc util.Uint160, tokenID *string) (int64, error) {
func (c *Client) nepBalanceOf(tokenHash, acc util.Uint160, tokenID []byte) (int64, error) {
params := []smartcontract.Parameter{{
Type: smartcontract.Hash160Type,
Value: acc,
}}
if tokenID != nil {
params = append(params, smartcontract.Parameter{
Type: smartcontract.StringType,
Value: *tokenID,
Type: smartcontract.ByteArrayType,
Value: tokenID,
})
}
result, err := c.InvokeFunction(tokenHash, "balanceOf", params, nil)

View file

@ -86,7 +86,7 @@ func (c *Client) CreateNEP11TransferTx(acc *wallet.Account, tokenHash util.Uint1
}
// NEP11TokensOf returns an array of token IDs for the specified owner of the specified NFT token.
func (c *Client) NEP11TokensOf(tokenHash util.Uint160, owner util.Uint160) ([]string, error) {
func (c *Client) NEP11TokensOf(tokenHash util.Uint160, owner util.Uint160) ([][]byte, error) {
result, err := c.InvokeFunction(tokenHash, "tokensOf", []smartcontract.Parameter{
{
Type: smartcontract.Hash160Type,
@ -101,13 +101,13 @@ func (c *Client) NEP11TokensOf(tokenHash util.Uint160, owner util.Uint160) ([]st
return nil, err
}
arr, err := topIterableFromStack(result.Stack, string(""))
arr, err := topIterableFromStack(result.Stack, []byte{})
if err != nil {
return nil, fmt.Errorf("failed to get token IDs from stack: %w", err)
}
ids := make([]string, len(arr))
ids := make([][]byte, len(arr))
for i := range ids {
ids[i] = arr[i].(string)
ids[i] = arr[i].([]byte)
}
return ids, nil
}
@ -116,10 +116,10 @@ func (c *Client) NEP11TokensOf(tokenHash util.Uint160, owner util.Uint160) ([]st
// NEP11NDOwnerOf invokes `ownerOf` non-devisible NEP-11 method with the
// specified token ID on a specified contract.
func (c *Client) NEP11NDOwnerOf(tokenHash util.Uint160, tokenID string) (util.Uint160, error) {
func (c *Client) NEP11NDOwnerOf(tokenHash util.Uint160, tokenID []byte) (util.Uint160, error) {
result, err := c.InvokeFunction(tokenHash, "ownerOf", []smartcontract.Parameter{
{
Type: smartcontract.StringType,
Type: smartcontract.ByteArrayType,
Value: tokenID,
},
}, nil)
@ -143,7 +143,7 @@ func (c *Client) NEP11NDOwnerOf(tokenHash util.Uint160, tokenID string) (util.Ui
// (in FixedN format using contract's number of decimals) to given account and
// sends it to the network returning just a hash of it.
func (c *Client) TransferNEP11D(acc *wallet.Account, to util.Uint160,
tokenHash util.Uint160, amount int64, tokenID string, data interface{}, gas int64, cosigners []SignerAccount) (util.Uint256, error) {
tokenHash util.Uint160, amount int64, tokenID []byte, data interface{}, gas int64, cosigners []SignerAccount) (util.Uint256, error) {
if !c.initDone {
return util.Uint256{}, errNetworkNotInitialized
}
@ -161,15 +161,15 @@ func (c *Client) TransferNEP11D(acc *wallet.Account, to util.Uint160,
// NEP11DBalanceOf invokes `balanceOf` divisible NEP-11 method on a
// specified contract.
func (c *Client) NEP11DBalanceOf(tokenHash, owner util.Uint160, tokenID string) (int64, error) {
return c.nepBalanceOf(tokenHash, owner, &tokenID)
func (c *Client) NEP11DBalanceOf(tokenHash, owner util.Uint160, tokenID []byte) (int64, error) {
return c.nepBalanceOf(tokenHash, owner, tokenID)
}
// NEP11DOwnerOf returns list of the specified NEP-11 divisible token owners.
func (c *Client) NEP11DOwnerOf(tokenHash util.Uint160, tokenID string) ([]util.Uint160, error) {
func (c *Client) NEP11DOwnerOf(tokenHash util.Uint160, tokenID []byte) ([]util.Uint160, error) {
result, err := c.InvokeFunction(tokenHash, "ownerOf", []smartcontract.Parameter{
{
Type: smartcontract.StringType,
Type: smartcontract.ByteArrayType,
Value: tokenID,
},
}, nil)
@ -198,9 +198,9 @@ func (c *Client) NEP11DOwnerOf(tokenHash util.Uint160, tokenID string) ([]util.U
// NEP11Properties invokes `properties` optional NEP-11 method on a
// specified contract.
func (c *Client) NEP11Properties(tokenHash util.Uint160, tokenID string) (*stackitem.Map, error) {
func (c *Client) NEP11Properties(tokenHash util.Uint160, tokenID []byte) (*stackitem.Map, error) {
result, err := c.InvokeFunction(tokenHash, "properties", []smartcontract.Parameter{{
Type: smartcontract.StringType,
Type: smartcontract.ByteArrayType,
Value: tokenID,
}}, nil)
if err != nil {
@ -215,7 +215,7 @@ func (c *Client) NEP11Properties(tokenHash util.Uint160, tokenID string) (*stack
}
// NEP11Tokens returns list of the tokens minted by the contract.
func (c *Client) NEP11Tokens(tokenHash util.Uint160) ([]string, error) {
func (c *Client) NEP11Tokens(tokenHash util.Uint160) ([][]byte, error) {
result, err := c.InvokeFunction(tokenHash, "tokens", []smartcontract.Parameter{}, nil)
if err != nil {
return nil, err
@ -225,13 +225,13 @@ func (c *Client) NEP11Tokens(tokenHash util.Uint160) ([]string, error) {
return nil, err
}
arr, err := topIterableFromStack(result.Stack, string(""))
arr, err := topIterableFromStack(result.Stack, []byte{})
if err != nil {
return nil, fmt.Errorf("failed to get token IDs from stack: %w", err)
}
tokens := make([]string, len(arr))
tokens := make([][]byte, len(arr))
for i := range tokens {
tokens[i] = arr[i].(string)
tokens[i] = arr[i].([]byte)
}
return tokens, nil
}

View file

@ -846,12 +846,12 @@ func TestClient_NEP11(t *testing.T) {
require.EqualValues(t, 1, b)
})
t.Run("OwnerOf", func(t *testing.T) {
b, err := c.NEP11NDOwnerOf(h, "neo.com")
b, err := c.NEP11NDOwnerOf(h, []byte("neo.com"))
require.NoError(t, err)
require.EqualValues(t, acc, b)
})
t.Run("Properties", func(t *testing.T) {
p, err := c.NEP11Properties(h, "neo.com")
p, err := c.NEP11Properties(h, []byte("neo.com"))
require.NoError(t, err)
blockRegisterDomain, err := chain.GetBlock(chain.GetHeaderHash(14)) // `neo.com` domain was registered in 14th block
require.NoError(t, err)