<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      chainLink vrf實驗

      目標

      用vrf寫一個隨機紅包

      數據結構

      紅包:

      struct Envelope {
          Type t;    // 類型,只是erc20 和eth紅包
          ERC20 token;  // erc20 ,如果是erc20紅包,這里是erc2o的地址
          address sender;  // 發紅包的sender
          uint balance;  // 金額
          bool allowAll;  // 允許所有人領取
          uint32 maxReceiver;  // 最大領取數,eg:最多3個人領取紅包
          bool avg; // 平均主義,每個紅包的價值等于balance/maxReceiver //填false則使用隨機紅包
          uint avgMonty; // 平均金額
          uint timeOutBlocks; //超時可以回收紅包 ,也可以打開未領取完的紅包
          address[] received;  // 已經領取過的列表
      }
      

      每個紅包中儲存紅包的信息,可以在允許過程中發送紅包

      存儲數據:

      mapping(bytes32 => Envelope) public envelopes;   // 紅包hash  -> 紅包內容,領取紅包時需要提供紅包hash
      mapping(bytes32 => mapping(address => bool)) public addressAllowList;   // 紅包對應的 allowlist 這個放在紅包外面存是因為struct里面不能放map
      mapping(bytes32 => mapping(address => bool)) addressGotList;  // 已經領取的列表,與received有點重復,建議將received修改為一個int,記錄有多少人領過
      mapping(uint => bytes32) openWithVRF;   // 紅包對應的vrf, 當紅包是隨即紅包時會用到這個
      mapping(ERC20 => uint) ERC20Balance;    // 每個erc20對應的金額,合約自己可以通過看自己的eth余額來判斷,erc20需要單獨記錄,應為可以同時存在多個合約,如果多個合約都是同一個erc20,需要判斷erc20的approve是否足夠
      mapping(bytes32 => uint[]) VRFKey;  // vrf 對應的隨機數列表
      
      // VRFV2PlusClient public COORDINATOR;
      bytes32 keyHash = 0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae;  // VRF 用到的key,可以去官方文檔查
      
      uint256 s_subscriptionId;  // vrf 用到的另一個key
      
      uint32 immutable callbackGasLimit = 100000;  // 官方推薦配置
      
      // The default is 3, but you can set this higher.
      uint16 immutable requestConfirmations = 3;  //官方推薦配置
      

      上面的mapping 主要是紅包合約的配置
      下方的數據則是chainlink vrf的配置,這些key可以去官網查看具體的含義

      合約的初始化

          constructor(
              uint256 _subscriptionId,
              address _coordinator
          ) VRFConsumerBaseV2Plus(_coordinator){
              s_subscriptionId = _subscriptionId;
          }
      

      初始化主要是賦值vrf的訂閱id(后續具體操作有詳細過程)

      構建紅包

          function createETHredEnvelope(
              bool allowAll,
              address[] memory allowList,
              uint32 maxReceiver,
              bool avg,
              uint timeOutBlocks
          ) public payable returns (bytes32) {}
      
      • allowAll:運行所有人領取,如果是true那么任何人都可以根據紅包hash調用get方法領取紅包
      • allowList:如果allowAll,那么allowList無用
      • maxReceiver:最大領取數,最大領取數可以比allowList小,這樣代表有人領不到紅包
      • avg: 是否平均,如果平均那么每個人領取到的金額 = msg.value/maxReceiver
      • timeOutBlocks:經過多少各block后超時,超時之后紅包的發起人可以回收紅包余額,或者打開紅包
          function createERC20redEnvelope(
              address token,
              uint size,  // erc20的數量
              bool allowAll,
              address[] memory allowList,
              uint32 maxReceiver,
              bool avg,
              uint timeOutBlocks
          ) public returns (bytes32) {}
      

      createERC20redEnvelopecreateETHredEnvelope 的區別只是使用的是erc20

      函數內的區別在與erc20要校驗有沒有足夠的apporve

              uint approved = ERC20(token).allowance(msg.sender,address(this));
              require(approved>=ERC20Balance[ERC20(token)]+size);
              ERC20Balance[ERC20(token)] += size;
      

      添加AllowList

          function allowSome(bytes32 hash, address[] memory allowList) public {
              require(envelopes[hash].balance != 0, "envelop balance is 0");
              require(envelopes[hash].sender == msg.sender,"only envelops sender can do this");
              for (uint i = 0; i < allowList.length; i++) {
                  addressAllowList[hash][allowList[i]] = true;
              }
          }
      

      這就不多解釋了

      領取紅包

          function get(bytes32 hash) public {}
      

      領紅包的方法簽名很簡單,只需要傳一個紅包hash就可以,但內部邏輯很復雜,重點看一下它里面的判斷

              require(envelopes[hash].balance != 0, "envelop balance is 0"); // 判讀紅包余額不為0
              require(!addressGotList[hash][msg.sender], "has got"); // 判斷發起人是否已經領取過
              require(   // 判斷紅包是否已經超時
                  envelopes[hash].timeOutBlocks > block.number,
                  "envelop timeOutBlocks is not enough"
              );
              require(
                  addressAllowList[hash][msg.sender] || envelopes[hash].allowAll,// 判斷發起人是否被允許
                  "not allow"
              );
              require(envelopes[hash].received.length < envelopes[hash].maxReceiver, "no more"); // 還是判斷是否已經領取完
      

      在領取上有兩種邏輯,一種是平均紅包,平均紅包get后會馬上到賬。一種是隨機數紅包,隨機數紅包不會立馬到賬需要等領紅包的人數達到maxReceiver 或者紅包超時,后面會詳細講怎么領隨機數紅包。

      打開隨機數紅包

          function openEnvelopes(bytes32 hash)public{
              require(
                  envelopes[hash].timeOutBlocks < block.number || envelopes[hash].received.length == envelopes[hash].maxReceiver,
                  "envelop timeOutBlocks is not enough"
              );
              require(envelopes[hash].maxReceiver > 0,"max receriver max more than 0");
      

      打開隨機數紅包一般是在領取時自動調用,如果領取人沒有達到maxReciver,可以在紅包超時后手動調用。

      這個方法中會向vrf請求一個隨機數,正常情況chainlink會調用fulfillRandomWords方法來返回隨機數。

          function fulfillRandomWords(
              uint256 requestId,
              uint256[] calldata randomWords
          ) internal override {
              require(randomWords.length == envelopes[openWithVRF[requestId]].received.length);
              VRFKey[openWithVRF[requestId]] = randomWords;
          }
      

      實際上可以在這個方法里面寫紅包分發的內容,但是由于這一步是chainlink觸發的是由他來執行手續費,所以這里面邏輯不能太復雜(實際上限制的參數就是keyHash 這個變量)

      手動打開紅包

      由于chainlink返回的時候不能有復雜的邏輯,所以隨機數紅包只能由手動觸發

          function openVRFEnvelop(bytes32 hash)public {
              uint[] memory randomWords = VRFKey[hash];
              require(envelopes[hash].maxReceiver > 0,"max receriver max more than 0");
              require(randomWords.length!=0,"can not get vrf words");
              uint16[] memory words = new uint16[](randomWords.length);
              // 計算每一個小分段的權重
           }
      

      vrf訂閱id獲取

      首先我們需要去chainlink上領取一點測試幣(link幣和eth幣,兩個都要,如有已經有了可以跳過)

      網址: https://faucets.chain.link/

      image-20240913182431182

      然后需要去crf管理頁面構建一個錢包合約,后面請求vrf隨機數時會扣除Link幣

      網址:https://vrf.chain.link/

      image-20240913182732964

      填完信息后,還是這樣網址,下面會出現你的sub

      image-20240913182948316

      點擊你的sub,里面有sub的id,這個id就是合約部署時要用到的id,可以用這個id先把合約部署上去,后面要合約的地址

      image-20240913183148412

      在這個頁面的右下角找到fund 給這個sub沖點link幣

      image-20240913183021680

      沖完之后點左邊的add cousumer ,把你的合約地址填進來

      至此,這個紅包合約就可以用了

      測試

      這個紅包我已經部署在測試網絡上了,可以直接去上面試試

      https://sepolia.etherscan.io/address/0xc81c0913e6365eb31e761d1062b41dd5a96d2e90#writeContract

      合約源碼后續會貼在這里(今天網太卡了,我環境一直下載不下來)

      源碼地址:(這兩天環境弄好了我會把代碼放上去,目前還是一個空項目)

      https://github.com/bighu630/redEnvelop

      posted @ 2024-09-13 18:39  bighu  閱讀(109)  評論(0)    收藏  舉報
      主站蜘蛛池模板: caoporn成人免费公开| 午夜视频免费试看| 五月天天天综合精品无码| 亚洲中文字幕精品无人区| 国产精品自在拍首页视频| 国产成人精品1024免费下载| 波多野结衣网站| 日韩熟妇中文色在线视频| 亚洲国产成人久久77| 西西人体大胆444WWW| 天堂中文在线资源| 亚洲精品成人综合色在线| 久久99久久99精品免观看| 五月丁香啪啪| 中文字幕人妻色偷偷久久| 日韩人妻无码精品久久久不卡| 国产乱人伦真实精品视频| 国产精品一码二码三码四码| 亚洲日韩久热中文字幕| 日韩一区二区三区日韩精品| 亚洲欧美日韩成人综合一区 | 久久综合国产色美利坚| 五月综合网亚洲乱妇久久| 中国国产一级毛片| 国产精品自在线拍国产手机版 | 激情综合网五月激情五月| 亚洲AV国产福利精品在现观看| 国产视频一区二区三区四区视频| 免费国产高清在线精品一区| 亚洲の无码国产の无码步美| 国产一区二区四区不卡| 精品人妻系列无码天堂| 狠狠色噜噜狠狠狠狠色综合久av | 无码丰满人妻熟妇区| 国产精品青青在线观看爽香蕉| 国产精品午夜福利视频234区| 中文字幕理伦午夜福利片| 亚洲大尺度一区二区三区| 色欲国产精品一区成人精品| 成年性午夜免费视频网站| 极品无码国模国产在线观看|