// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract ReceiverPays {
//定義當前支票的歸屬人默認權限為internal
? ? address owner = msg.sender;
? ? //定義了一個權限為internal 的mapping晦雨,key為用過的nonce,value為bool類型
? ? mapping(uint256 =>bool)usedNonces;
? ? /*
*/
? ? constructor() payable {
}
/*
? ? 定義了一個只供外部使用的函數(shù)暂幼,但是這個函數(shù)必須是從來沒有調(diào)用過的,通過nonce進行區(qū)分*/
? ? function claimPayment(uint256 amount,uint256 nonce,bytes memory signature)external {
require(!usedNonces[nonce]); //當前的nonce不能是已經(jīng)使用過的咙俩。
? ? ? ? usedNonces[nonce] =true;//將當前的nonce設置為true型奥,意思是已經(jīng)使用了
? ? ? ? bytes32 message = prefixed(keccak256(abi.encodePacked(msg.sender,amount,nonce,this)));
? ? ? ? require(recoverSigner(message,signature) == owner);
? ? }
/*
? ? 定義了一個只供外部調(diào)用的方法琐旁,銷毀當前合約*/
? ? function shutdown()external {
require(msg.sender == owner);//只有owner才能執(zhí)行該方法
? ? ? ? selfdestruct(payable(msg.sender));// 調(diào)用了自我銷毀的方法
? ? }
/*
? ? 定義了一個internal函數(shù),只能是當前合約以及當前合約的子合約中pure叮盘,不跟合約狀態(tài)變量做任何讀寫之類的交互秩贰, 返回值有三個, 在函數(shù)內(nèi)還有內(nèi)聯(lián)函數(shù)*/
? ? function splitSignature(bytes memory sig)internal pure returns (uint8 v,bytes32 r,bytes32 s){
require(sig.length ==65);
? ? ? ? assembly {
r := mload(add(sig,32))
s := mload(add(sig,64))
v :=byte(0,mload(add(sig,96)))
}
return (v, r, s);
? ? }
/*
? ? internal 表示當前函數(shù)智能當前合約或者當前合約的子合約可以使用柔吼, pure代表不跟合約的狀態(tài)變量做任何交互毒费,并且返回一個address
? ? 類型的數(shù)據(jù)*/
? ? 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);
? ? }
/*
? ? ? 定義一個內(nèi)部(子類合約也可以)使用的函數(shù),用于加密愈魏,并且當前函數(shù)為pure不跟任何狀態(tài)變量做交互觅玻。 返回一個bytes32 類型的數(shù)據(jù)*/
? ? function prefixed(bytes32 hash)internal pure returns(bytes32){
return keccak256(abi.encodePacked("\x19 Ethereum Signed Message:\n32",hash));
? ? }
}