I’m trying to follow the implementation given here to implement signature verification.
The frontend code returns the following error-
Error: invalid arrayify value (argument="value", value="", code=INVALID_ARGUMENT, version=bytes/5.6.0)
I think this is because of the signature being passed as a string instead of bytes. What’s the best way to pass the signature to the contract’s function?
Solidity Code
struct NFTVoucher {
uint256 _id;
uint256 _amount;
string nuri;
bytes signature;
}
function mint(NFTVoucher calldata voucher) payable public {
address signer = _verify(voucher);
_mint(msg.sender,voucher._id, voucher._amount, "");
}
function _verify(NFTVoucher calldata voucher) internal view returns (address) {
bytes32 digest = _hash(voucher);
return ECDSA.recover(digest, voucher.signature);
}
function _hash(NFTVoucher calldata voucher) internal view returns (bytes32) {
return _hashTypedDataV4(keccak256(abi.encode(
keccak256("NFTVoucher(uint256 _id,uint256 _amount,string nuri)"),
voucher._id,
voucher._amount,
keccak256(bytes(voucher.nuri))
)));
}
Javascript Code - Frontend
var voucher = {
_id: 18,
_amount: 1,
nuri: "ipfs://xyz/metadata/14.json",
signature : signaturefrombackend
}
let options = {
contractAddress: TOKEN_CONTRACT_ADDRESS,
functionName: "mint",
abi: ABI,
params: {
voucher: voucher,
},
//msgValue: Moralis.Units.ETH(0.001),
};
const transaction = await Moralis.executeFunction(options);
Backend code to generate signature
var {keccak256} = require("@ethersproject/keccak256");
var {toUtf8Bytes} = require("@ethersproject/strings");
const signature = keccak256(toUtf8Bytes("sampledata"));
//returns string