견고함을 기반으로 한 빨간 봉투 그랩 코드
1. 기능 구현
- 빨간봉투 발신인은 비밀번호, 빨간봉투의 종류, 빨간봉투를 잡을 수 있는 최대 인원, 빨간봉투의 유효시간을 설정할 수 있습니다.
- 사람의 특정 빨간봉투의 현재 잔고를 볼 수 있습니다.
- 현재의 모든 빨간 봉투에 남아 있는 돈을 볼 수 있습니다.
- 현재 빨간 봉투에 아직 돈이 있는 모든 지갑 발신인의 주소를 볼 수 있습니다.
- 빨간색 패킷에 대한 빨간색 패킷을 잡은 결과를 볼 수 있습니다.
- 빨간봉투 발신인이 보낸 빨간봉투에서 사람(주소)이 얼마나 잡았는지 확인할 수 있습니다.
- 한 사람이 여러 개의 빨간 봉투를 보낼 수 있으며 각 사람은 동일한 빨간 봉투를 한 번만 잡을 수 있습니다.
- 친구 기능, 빨간 봉투 소유자의 친구만 빨간 봉투를 잡을 수 있습니다.
- 빨간봉투는 유효기간을 설정해야 하며, 유효기간 내 친구는 빨간봉투를 잡을 수 있으며, 유효기간이 지나면 빨간봉투 소유자는 빨간봉투를 인출할 수 있습니다. 빨간 봉투 소유자는 빨간 봉투를 철회할 수 있습니다).
- 빨간 봉투 계약은 동시에 여러 개의 빨간 봉투의 존재를 지원하며, 누구든지 빨간 봉투 계약을 호출하여 계속해서 새로운 빨간 봉투를 추가할 수 있습니다. 각 빨간 봉투는 자신의 비밀번호에 해당하며 빨간 봉투를 잡는 사람은 다음이 필요합니다. 빨간 봉투를 잡기 위해 암호를 입력합니다.
- 레드 패킷의 균등하고 무작위 배포를 지원합니다.
2. 원본 링크
주제 참조: Solidity Grab Red Envelope 계약 구현 - tzy577의 블로그 - CSDN 블로그
3. 솔리디티 코드
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract red_envelope {
struct redbag {
uint256 amount;
uint256 leixing;
uint256 maxnum;
uint256 time;
uint256 left_money;
bytes32 kouling;
address sender;
address[] qiang;
}
mapping (address => uint256) countNum;
mapping (address => mapping(uint256 => redbag)) public whosredbag;
event Fahongbao(address indexed _sender,uint256 _amount,uint256 _maxnum);
event BeFriend(address _mine,address _friend);
event GetRed(address indexed _mine,address _sender,uint256 _whichRB,uint256 _amount);
event GetRealse(address _sender,uint256 _leftRed,uint256 _nowTime);
mapping (address => address[]) friend;
function beFriend(address _friend) public{
require(!isFriend(_friend,msg.sender),"already friend");
friend[msg.sender].push(_friend);
emit BeFriend(msg.sender,_friend);
}
function _countNum(address _Addr) internal returns(uint256 _whichRB){
countNum[_Addr] += 1;
_whichRB = countNum[_Addr];
return _whichRB;
}
function getRealse(address _leftRed,uint256 _whichRB) public returns(bool) {
redbag storage _newSender = whosredbag[_leftRed][_whichRB];
require(msg.sender == _newSender.sender,"you are not the owner");
require(_newSender.time < block.timestamp,"time isn't out");
uint256 _amount = _newSender.left_money;
_newSender.left_money -= _amount;
(bool success,) = payable(msg.sender).call{value:_amount}("");
emit GetRealse(_newSender.sender,_amount,block.timestamp);
return success;
}
function fahongbao(
uint256 _maxnum,
uint256 _time,
bytes32 _kouling,
uint256 _leixing
) public payable
{
redbag storage _newSender = whosredbag[msg.sender][_countNum(msg.sender)];
uint256 _nowTime = block.timestamp;
_newSender.time = _time + _nowTime;
_newSender.kouling = _kouling;
_newSender.amount = msg.value;
_newSender.sender = msg.sender;
_newSender.maxnum = _maxnum;
_newSender.leixing = _leixing;
_newSender.left_money = msg.value;
emit Fahongbao(_newSender.sender,_newSender.amount,_newSender.maxnum);
}
// 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4
// 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2
// 0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db
// 0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB
function kouling(string memory _kouling) public pure returns(bytes32 result){
assembly{
result := mload(add(_kouling,32))
}
}
function getRed(address _who,bytes32 _kouling,uint256 _whichRB) public returns(bool) {
require(isFriend(msg.sender,_who),"not friend");
redbag storage _newSender = whosredbag[_who][_whichRB];
require(_kouling == _newSender.kouling);
require(_newSender.time > block.timestamp,"time is out");
require(_isqiang(_who,_whichRB));
if(_newSender.qiang.length == _newSender.maxnum - 1){
uint256 _amount = _newSender.left_money;
_newSender.qiang.push(msg.sender);
_newSender.left_money -= _amount;
(bool success,) = payable(msg.sender).call{value:_amount}("");
emit GetRed(msg.sender,_newSender.sender,_whichRB,_amount);
return success;
}
else{uint256 _amount = _perValue(_who,_newSender.leixing,_whichRB);
_newSender.qiang.push(msg.sender);
_newSender.left_money -= _amount;
(bool success,) = payable(msg.sender).call{value:_amount}("");
emit GetRed(msg.sender,_newSender.sender,_whichRB,_amount);
return success;
}
}
function _isqiang(address _who,uint256 _whichRB) internal view returns(bool restult) {
redbag memory _newSender = whosredbag[_who][_whichRB];
for(uint256 i = 0; i < _newSender.qiang.length;i ++){
require(msg.sender != _newSender.qiang[i],"you have already done this");
}
return true;
}
function isFriend(address _mine,address _owner) internal view returns(bool result) {
for(uint256 i = 0; i < friend[_owner].length;i ++){
if(_mine == friend[_owner][i]){
result = true;
}
}
return result;
}
function _perValue(address _owner,uint256 _type,uint256 _whichRB) internal view returns(uint256 restult) {
require(_type < 2,"_type should be 1 or 0");
redbag memory _newSender = whosredbag[_owner][_whichRB];
uint256 _amount = _newSender.amount / _newSender.maxnum;
if(_type == 1){
return restult = _amount;
}
else if(_type == 0){
return restult = (_random() * _amount) / 50 ;
}
}
function _random() internal view returns(uint256 restult){
bytes32 randomBytes = keccak256(abi.encodePacked(block.number, msg.sender, blockhash(block.timestamp-1)));
return restult = (uint(randomBytes) % 100);
}
}
4. 요약
나는 코드 초보자입니다 (단단함을 배우기 시작하여 의사 소통 및 학습 방법을 찾고 있음) + 깨진 영어 현재 난수는 매우 간단하고 무례하며 uint256 오버플로 문제에 대한 보호 장치가 없으며 코드가 완전히 주제를 참조하십시오. 오신 것을 환영합니다 코드가 테스트되었습니다. 응답에 문제가 있습니다. 함께 배우고 의사 소통합시다, 감사합니다!