//SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.17;
contract SimplePaymentChannel {
//定义了一个公共状态变量发送人,并且类型是可以收款的地址
address payable public sender;
//定义了一个公共状态变量收款人,并且类型是可以收款的地址
address payable public recipient;
//定义了一个公共状态变量过期时间,无符号整形256类型的数据用于记录过期时间
uint256 public expiration;
/*
定义了一个构造函数,接受两个参数,第一个是收款地址,第二个是持续时间。
并且给创建合约的地址初始化为sender,并且类型转换为可接受付款的地址。*/
constructor(address payable recipientAddress,uint256 duration){
sender = payable(msg.sender);
recipient = recipientAddress;
expiration = block.timestamp + duration;//过期时间等于当前区块的时间戳取秒数+持续时间
}
/*
定义了一个close的方法,供外部调用,里面传递了两个参数,金额和签名*/
function close(uint256 amount,bytes memory signature)external {
require(msg.sender == recipient);
require(isValidSignature(amount,signature));
recipient.transfer(amount);
selfdestruct(sender);
}
function extend(uint256 newExpiration)external{
require(msg.sender == sender);
require(newExpiration> expiration);
expiration = newExpiration;
}
/*
定义了一个供外部函数调用的方法*/
function claimTimeout()external{
require(block.timestamp >= expiration);
selfdestruct(sender);// 调用析构函数销毁合约
}
/*
定义了一个合约内部以及子合约能访问的函数,对状态变量只读,并且返回bool型的值,验证签名是否合法*/
function isValidSignature(uint256 amount,bytes memory signature)internal view returns (bool){
bytes32 message = prefixed(keccak256(abi.encodePacked(this,amount)));
return recoverSigner(message,signature) == sender;
}
/*
定义了一个恢复签名的方法,接收两个参数,该方法不涉及到对状态变量的访问,是一个内部方法,返回值为addres类型*/
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);
}
/*
定义了一个分割签名的内部方法,不涉及对状态变量的访问, 返回值有三个,并且利用了内联函数.
*/
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,32))
v :=byte(0,mload(add(sig,96)))
}
return (v,r,s);
}
/*
定义了一个增加前缀的方法在传入的hash值之前加入特定的内容, 该方法时一个内部调用的方法,并且不涉及到对状态变量的访问.
返回值为bytes32
*/
function prefixed(bytes32 hash)internal pure returns(bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32",hash));
}
}