Elrond Smart Contract call via JavaScript SDK returns a user error

137 views Asked by At

I am trying to call a function from a Elrond Smart Contract to create a NFT, I am using their JavaScript SDK.

This is the error I get:

TransactionCompletionStrategy.isCompleted(), found event: signalError

Transaction return code: user error

This is my JavaScript code:

const {
  Transaction,
  BytesValue,
  ContractCallPayloadBuilder,
  ContractFunction,
  BigUIntValue,
  Account,
  Address,
  TransactionWatcher,
  ResultsParser,
} = require('@elrondnetwork/erdjs')
const { BigNumber } = require('bignumber.js')
const fs = require('fs')
const {
  UserSecretKey,
  UserSigner,
  parseUserKey,
} = require('@elrondnetwork/erdjs-walletcore')
const {
  ProxyNetworkProvider,
} = require('@elrondnetwork/erdjs-network-providers')

const contractAddress = new Address(
  'erd1qqqqqqqqqqqqqpgqlsd27rdekm3px5aydfahf9lcau0wrss3rfyqtvvxke',
)
const specialOpertationsGasLimit = 3_000_000
let attributes, hash

const setup = async () => {
  const pemKeyFileName = './mypemfile.pem'
  const walletPemKey = fs.readFileSync(pemKeyFileName, 'utf8')
  const pemKey = UserSecretKey.fromPem(walletPemKey)
  const signer = new UserSigner(pemKey)

  const provider = new ProxyNetworkProvider('https://devnet-gateway.elrond.com')

  const userKey = parseUserKey(walletPemKey)
  const account = new Account(userKey.generatePublicKey().toAddress())
  let accountOnNetwork = await provider.getAccount(
    userKey.generatePublicKey().toAddress(),
  )
  account.update(accountOnNetwork)

  return {
    signer,
    account,
    provider,
  }
}

const commonTxOperations = async (tx, account, signer, provider) => {
  tx.setNonce(account.getNonceThenIncrement())
  signer.sign(tx)
  await provider.sendTransaction(tx)
  const watcher = new TransactionWatcher(provider)
  const transactionOnNetwork = await watcher.awaitCompleted(tx)

  const txHash = transactionOnNetwork.hash
  const txStatus = transactionOnNetwork.status

  let { returnCode } = new ResultsParser().parseUntypedOutcome(
    transactionOnNetwork,
  )

  console.log(`\nTransaction return code: ${returnCode}`)
  console.log(`\nTransaction status: ${txStatus}`)
  console.log(
    `Transaction link: https://devnet-explorer.elrond.com/transactions/${txHash}\n`,
  )
}

const createNft = async () => {
  try {
    const { name, royalties, uri, sellingPrice } = {
      name: 'testifulify',
      royalties: 5,
      uri:
        'https://dweb.link/ipfs/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi',
      sellingPrice: 50000000000000000n, //(0.05 EGLD)
    }

    const { signer, account, provider } = await setup()

    const args = [
      BytesValue.fromUTF8(name),
      new BigUIntValue(new BigNumber(Number(royalties) * 100 || 0)),
      BytesValue.fromUTF8(uri || ''),
      new BigUIntValue(new BigNumber(Number(sellingPrice) || 0)),
    ]

    const data = new ContractCallPayloadBuilder()
      .setFunction(new ContractFunction('createNft'))
      .setArgs(args)
      .build()

    const tx = new Transaction({
      data,
      gasLimit:
        specialOpertationsGasLimit +
        data.length() * 1500 +
        (attributes?.length || 0 + hash?.length || 0) * 50000,
      receiver: contractAddress,
      sender: signer.getAddress(),
      value: 0,
      chainID: 'D',
    })

    await commonTxOperations(tx, account, signer, provider)
  } catch (e) {
    console.log(e?.message)
  }
}

createNft()

I am using their NFT Minter example from this repository https://github.com/ElrondNetwork/elrond-wasm-rs/blob/master/contracts/examples/nft-minter/src/lib.rs

The Smart Contract is deployed to the Devnet https://devnet-explorer.elrond.com/accounts/erd1qqqqqqqqqqqqqpgqlsd27rdekm3px5aydfahf9lcau0wrss3rfyqtvvxke

Really appreciate help, because I am stuck at the moment, tried different variations to call the contract but getting always the same error.

1

There are 1 answers

0
Patric Robert Gutersohn On BEST ANSWER

Called the Smart Contract methods in the wrong order.

Initially I needed to call issueToken, then setLocalRoles and afterwards createNft.