简单公开拍卖智能合约solidity代码
简单公开拍卖基本思想:在竞价期间每个节点都可以调用function bid()参与竞价,若最高出价被抬高,之前的最高出价节点可以调用function withdraw()拿回竞价金额,最终调用function auctionEnd()获取竞价结果。
pragma solidity ^0.8.4;
//简单的公开拍卖
contract SimpleAuction{
address payable public beneficiary;//竞价受益者
uint public auctionEndTime;//竞价最后时间期限
address public highestBidder;//最高竞价者地址
uint public highestBid;//最高竞价
mapping(address => uint) pendingReturns;//记录所有最高竞价者地址和其竞价
bool ended;//标记竞价状态,默认值为false
//调用event可以将合约中某些内容的更改记录到日志,用关键字emit修饰调用
//事件(event)和日志不能在合约内部访问,可以被子合约调用
event HighestBidIncreased(address bidder,uint amount);
event AuctionEnded(address winner,uint amount);
error AuctionAlreadyEnded();//标识该竞价周期已结束
error BidNotHighEnough(uint highestBid);//标识已存在更高的竞价
error AuctionNotYetEnded();//标识当前竞价周期还未结束
error AuctionEndAlreadyCalled();//标识该竞价周期状态ended已更改
//构造函数,部署合约时调用,仅调用一次,初始化竞价受益者地址和竞价周期
//当前版本的address分为:address 和 payable address
//payable address支持.transfer和.send方法,用于发送ether
//payable address只能给payable address转账,而不能给address转账
constructor(uint biddingTime,address payable beneficiaryAddress) public{
beneficiary = beneficiaryAddress;
auctionEndTime = block.timestamp +biddingTime;
}
//竞价,只有payable修饰的function才能接收以太币
function bid() external payable{
//若竞拍周期结束则退出function,回退当前调用所有改变
if(block.timestamp > auctionEndTime)
revert AuctionAlreadyEnded();
//若当前竞价金额并非最高则退出function,回退当前调用所有改变
if(msg.value <= highestBid)
revert BidNotHighEnough(highestBid);
//添加最高竞价信息到一维数组pendingReturns中
if(highestBid != 0)
pendingReturns[highestBidder] += highestBid;
highestBidder = msg.sender;//更新最高竞价者地址
highestBid = msg.value;//更新最高竞价
emit HighestBidIncreased(msg.sender, msg.value);//调用HighestBidIncreased事件更新最新竞价信息
}
//退回调用者的竞价金额,注:msg.sender指调用该函数的地址,而不是调用整个合约的地址
function withdraw() external returns(bool){
uint amount = pendingReturns[msg.sender];//取出调用该function竞价地址的竞价金额
if(amount>0){
pendingReturns[msg.sender] = 0;//将pendingReturns中对应竞价者的竞价金额置为0
//向调用该function的竞价地址返还竞价金额,若返还竞价金额失败则恢复pendingReturns状态
//将msg.sender由address类型强制转换为payable address类型
if(!payable(msg.sender).send(amount)){
pendingReturns[msg.sender] = amount;
return false;//return false表明退钱失败
}
}
return true;//return false表明退钱成功
}
//修改竞价状态,发钱给竞价受益者
function auctionEnd() external{
//下述if类似于:require(block.timestamp >= auctionEndTime,"Auction not yet ended.");
//require抛出异常回退状态并返回字符串,revert error()抛出异常回退状态并返回error数据
if(block.timestamp < auctionEndTime)
revert AuctionAlreadyEnded();//竞价周期结束,退出该function,回退状态
//下述if类似于:require(!ended,"auctionEnd has already been called.");
if(ended)
revert AuctionEndAlreadyCalled();//竞价状态已改变,退出该function,回退状态
ended = true;//修改竞价状态
emit AuctionEnded(highestBidder,highestBid);//调用AuctionEnded事件记录最终最高竞价信息
beneficiary.transfer(highestBid);//给竞价受益者发送最终竞价金额
}
}
来源(solidity官方文档):https://docs.soliditylang.org/en/v0.8.13/solidity-by-example.html#simple-open-auction

浙公网安备 33010602011771号