When i tried deploying this contract using 10 ethers, and then providing :
claimPayment() -> amount - 9000000000000000000 i.e 9 ethers
-> nonce - 123
-> signature - 0x6162630000000000000000000000000000000000000000000000000000000000 which is "abc"
I am getting this error -> revert The transaction has been reverted to the initial state. Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information.
edit : added payable in function, still issue persists.
https://docs.soliditylang.org/en/v0.8.21/solidity-by-example.html#micropayment-channel
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
// This will report a warning due to deprecated selfdestruct
contract ReceiverPays {
address owner = msg.sender;
mapping(uint256 => bool) usedNonces;
constructor() payable {}
function claimPayment(uint256 amount, uint256 nonce, bytes memory signature) external {
require(!usedNonces[nonce]);
usedNonces[nonce] = true;
// this recreates the message that was signed on the client
bytes32 message = prefixed(keccak256(abi.encodePacked(msg.sender, amount, nonce, this)));
require(recoverSigner(message, signature) == owner);
payable(msg.sender).transfer(amount);
}
/// destroy the contract and reclaim the leftover funds.
function shutdown() external {
require(msg.sender == owner);
selfdestruct(payable(msg.sender));
}
/// signature methods.
function splitSignature(bytes memory sig)
internal
pure
returns (uint8 v, bytes32 r, bytes32 s)
{
require(sig.length == 65);
assembly {
// first 32 bytes, after the length prefix.
r := mload(add(sig, 32))
// second 32 bytes.
s := mload(add(sig, 64))
// final byte (first byte of the next 32 bytes).
v := byte(0, mload(add(sig, 96)))
}
return (v, r, s);
}
function recoverSigner(bytes32 message, bytes memory sig)
internal
pure
returns (address)
{
(uint8 v, bytes32 r, bytes32 s) = splitSignature(sig);
return ecrecover(message, v, r, s);
}
/// builds a prefixed hash to mimic the behavior of eth_sign.
function prefixed(bytes32 hash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
}