2

我有一个问题,我正在尝试解决一天。

我想用 dapp 更改 nft 价格,但只有当我将其更改为 0.5 EGLD 或 1 EGLD 时它才有效。如果高于它,则返回错误“向非应付合同发送价值”

因此,如果我将价格设置为 2EGLD = 20000000000000000000 并将其转换为十进制十六进制,它将返回 setNewPrice@029a2241af62c0000 当它应该是 setNewPrice@29a2241af62c0000

我知道问题是十六进制的第一个“0”,但是如果它高于 1 EGLD,为什么它不起作用?因为如果我设置为 1EGLD 它返回 setNewPrice@0de0b6b3a7640000 这是正确的。

这就是我将数字转换为十六进制的方式

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

我正在调用这个 SC 函数

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

        Ok(())
    }

那么什么时候应该在十六进制前面有 0 呢?而“if (hex.length < 2)”我必须将其更改为“if (hex.length < 2000000000000000000)”,因为我必须使用 2/10^18

谢谢!

4

2 回答 2

1

我很难弄清楚,而且我不是 100% 确定这是正确的。但我的理解是十六进制应该是一个字节序列,意思是由成对的十六进制分组。

您应该检查十六进制是奇数还是偶数。如果奇数,则添加一个 0,否则保持原样。所以像这样

if (hex.length%2==1) {
   hex = "0" + hex;
}
于 2022-01-27T00:22:16.993 回答
0

首先很奇怪你的 set_new_price 函数上没有 #[payable("EGLD")] 。这就是允许函数接收 ELGD 付款的原因。

其次,使用 erdjs 类来处理合约参数序列化更容易。我认为 Balance 是您在这种情况下所需要的:

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

这会将浮点数转换为 BigNumber 移位 18(ELG 十进制移位)并将其序列化为 BigUint。

使用 erdjs 为您的案例生成交易的示例:

// 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);
于 2022-02-01T09:20:16.310 回答