1

I am trying to call a contract read which is deployed on the Azero smartnet using @polkadot/api-contract following https://polkadot.js.org/docs/api-contract. Here is my current code.

import { ApiPromise, HttpProvider } from "@polkadot/api";
import { ContractPromise } from "@polkadot/api-contract";

import { abi } from "./psp34-metadata";

const main = async () => {
  const wsProvider = new HttpProvider("https://rpc-smartnet.test.azero.dev/");
  const api = await ApiPromise.create({ provider: wsProvider });

  const nftCollectionAddress = `5FoLoL5mYXpBwxJUMDo3tcwh5VTrzaz3LvbA4B7LiivjXV7C`;

  // Construct our Code helper. The abi is an Abi object, an unparsed JSON string
  // or the raw JSON data (after doing a JSON.parse). The wasm is either a hex
  // string (0x prefixed), an Uint8Array or a Node.js Buffer object
  const contract = new ContractPromise(api, abi, nftCollectionAddress);
  
  const value = 0; // only useful on isPayable messages

  const gasLimit = 3000n * 1000000n;

  const senderAddress = `5CXCzYooepihLkWNbFQ9VJieLSWgguTEPe6eWrDM8wAytCea`; // * My SubWallet address

  const tokenId = 1; // Token ID of NFT Im trying to read

  const { gasConsumed, result, output } = await contract.query[
    "psp34Traits::tokenUri"
  ](senderAddress, { value, gasLimit }, value);

  console.log({ gasConsumed, result, output });
};

main();

I create the ContractPromise and can console.log the various methods on contract.query, but when i try to call psp34Traits::tokenUri I receive the error

Enum(Err):: Enum(Module):: Struct: failed on error: u8:: u8: Input too large. Found input with 26 bits, expected 8

Here is the exact message method from the deployed contract in ink! I am calling from Node

#[ink(message)]
fn token_uri(
    &self,
    token_id: u64
) -> String {
    let value = self.get_attribute(Id::U8(0), String::from("baseURI").into_bytes());
    let mut token_uri = String::from_utf8(value.unwrap()).unwrap();
    token_uri = token_uri + &token_id.to_string() + &String::from(".json");
    return token_uri;
}

Here is also the full error log. Any tips to point me in the right direction would be greatly appreciated

2022-06-01 01:12:05        RPC-CORE: call(callRequest: ContractCallRequest, at?: BlockHash): ContractExecResult:: createType(ContractExecResult):: Struct: failed on result: {"_enum":{"Ok":"ContractExecResultOk","Err":"ContractExecResultErr"}}:: Enum(Err):: Enum(Module):: Struct: failed on error: u8:: u8: Input too large. Found input with 26 bits, expected 8
/Users/user/Work/azero/polkadotjs/node_modules/@polkadot/types-create/cjs/create/type.js:70
    firstError = new Error(`createType(${type}):: ${error.message}`);
                 ^
Error: createType(ContractExecResult):: Struct: failed on result: {"_enum":{"Ok":"ContractExecResultOk","Err":"ContractExecResultErr"}}:: Enum(Err):: Enum(Module):: Struct: failed on error: u8:: u8: Input too large. Found input with 26 bits, expected 8
2

1 Answer 1

1

You can use contract.query either to read a contract value or to get cost estimations for a contract transaction. Any contract dispatchable can be called via query to get the gas and storage deposit estimations before submitting the transaction.

Because there are no on-chain consequences for query, you can pass -1 as gas limit. This is not recommended for contract.tx where real costs can occur. In this case, you should use the gasRequired value returned by the query.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.