2

I have a problem which I'm trying to fix for a day now.

I want to change the nft price with the dapp but it's working only if I change it to 0.5 EGLD or 1 EGLD. If it's above it returns an error "sending value to non payable contract"

So if I set the price to be 2EGLD = 2000000000000000000 and I convert it to deciamal hex, it returns setNewPrice@029a2241af62c0000 when it should be setNewPrice@29a2241af62c0000

I know that the problem is the first "0" from the hex but why it's not working if it's above 1 EGLD? Because if I set to 1EGLD it returns setNewPrice@0de0b6b3a7640000 which is correct.

This is how I convert numbers to hex

export const decimalToHex = (strVal: Number) =>
{
  let hex = Number(strVal).toString(16);
  if (hex.length < 2) {
       hex = "0" + hex;
  }
  return hex;
}

and I'm calling this SC function

#[only_owner]
    #[endpoint(setNewPrice)]
    fn set_new_price(&self, price: BigUint) -> SCResult<()> {
        self.selling_price().set(&price);

        Ok(())
    }

So when it should have 0 in front of the hex? And "if (hex.length < 2)" I must change it to "if (hex.length < 2000000000000000000)" since I must use 2/10^18

Thank you!

paulv
  • 83
  • 2
  • 12

2 Answers2

1

I had a hard time figuring it out, and I am not a 100% sure this is correct. But what I understood is that the hexadecimal should be a sequence of bytes, meaning grouped by pairs of hexadecimals.

You should check if the hex is odd or even. If odd, then add a 0, else leave it as it is. So something like this

if (hex.length%2==1) {
   hex = "0" + hex;
}
Sia
  • 11
  • 1
0

First it's weird you don't have a #[payable("EGLD")] on your set_new_price function. This is what allow a function to receive an ELGD payment.

Second, it's easier to use erdjs class to handle contract arguments serialization. I think that Balance is what you need in this case :

new BigUIntValue(Balance.egld(newPrice).valueOf())

This will convert a floating number into a BigNumber shift by 18 (ELG décimal shift) and serialize it as BigUint.

Example of generating a transaction with erdjs for your case :

// Generate Transaction payload
const payload = TransactionPayload.contractCall()
            .setFunction(new ContractFunction("setNewPrice"))
            .setArgs([
                new BigUIntValue(Balance.egld(sellingPrice).valueOf())
            ])
            .build();
        
// Create Transaction
const transaction = new Transaction({
            sender: walletAddress,
            receiver: new Address(smartContractAddress),
            gasLimit: new GasLimit(10000000),
            data: payload,
        });
transaction.setNonce(account.nonce);