Solidity

這個honeypot是如何工作的?‘OpenAddressLottery’

  • May 20, 2019
/**
* Source Code first verified at https://etherscan.io on Saturday, February 10, 2018
(UTC) */

pragma solidity ^0.4.19;
/*
* This is a distributed lottery that chooses random addresses as lucky addresses. If these
* participate, they get the jackpot: 7 times the price of their bet.
* Of course one address can only win once. The owner regularly reseeds the secret
* seed of the contract (based on which the lucky addresses are chosen), so if you did not win,
* just wait for a reseed and try again!
*
* Jackpot chance:   1 in 8
* Ticket price: Anything larger than (or equal to) 0.1 ETH
* Jackpot size: 7 times the ticket price
*
* HOW TO PARTICIPATE: Just send any amount greater than (or equal to) 0.1 ETH to the contract's address
* Keep in mind that your address can only win once
*
* If the contract doesn't have enough ETH to pay the jackpot, it sends the whole balance.
*/

contract OpenAddressLottery{
   struct SeedComponents{
       uint component1;
       uint component2;
       uint component3;
       uint component4;
   }
   
   address owner; //address of the owner
   uint private secretSeed; //seed used to calculate number of an address
   uint private lastReseed; //last reseed - used to automatically reseed the contract every 1000 blocks
   uint LuckyNumber = 7; //if the number of an address equals 7, it wins
       
   mapping (address => bool) winner; //keeping track of addresses that have already won
   
   function OpenAddressLottery() {
       owner = msg.sender;
       reseed(SeedComponents((uint)(block.coinbase), block.difficulty, block.gaslimit, block.timestamp)); //generate a quality random seed
   }
   
   function participate() payable {
       if(msg.value<0.1 ether)
           return; //verify ticket price
       
       // make sure he hasn't won already
       require(winner[msg.sender] == false);
       
       if(luckyNumberOfAddress(msg.sender) == LuckyNumber){ //check if it equals 7
           winner[msg.sender] = true; // every address can only win once
           
           uint win=msg.value*7; //win = 7 times the ticket price
           
           if(win>this.balance) //if the balance isnt sufficient...
               win=this.balance; //...send everything we've got
           msg.sender.transfer(win);
       }
       
       if(block.number-lastReseed>1000) //reseed if needed
           reseed(SeedComponents((uint)(block.coinbase), block.difficulty, block.gaslimit, block.timestamp)); //generate a quality random seed
   }
   
   function luckyNumberOfAddress(address addr) constant returns(uint n){
       // calculate the number of current address - 1 in 8 chance
       n = uint(keccak256(uint(addr), secretSeed)[0]) % 8;
   }
   
   function reseed(SeedComponents components) internal {
       secretSeed = uint256(keccak256(
           components.component1,
           components.component2,
           components.component3,
           components.component4
       )); //hash the incoming parameters and use the hash to (re)initialize the seed
       lastReseed = block.number;
   }
   
   function kill() {
       require(msg.sender==owner);
       
       selfdestruct(msg.sender);
   }
   
   function forceReseed() { //reseed initiated by the owner - for testing purposes
       require(msg.sender==owner);
       
       SeedComponents s;
       s.component1 = uint(msg.sender);
       s.component2 = uint256(block.blockhash(block.number - 1));
       s.component3 = block.difficulty*(uint)(block.coinbase);
       s.component4 = tx.gasprice * 7;
       
       reseed(s); //reseed
   }
   
   function () payable { //if someone sends money without any function call, just assume he wanted to participate
       if(msg.value>=0.1 ether && msg.sender!=owner) //owner can't participate, he can only fund the jackpot
           participate();
   }

}

在這個honeypot中,當luckynumber =7時,玩家獲得乙太幣,

玩家的幸運數字以 8 為模計算。

uint LuckyNumber = 7;

LuckyNumber 是硬編碼的,所以所有者不能修改這個值。這個honeypot是如何工作的?

在重新播種時,該函式通過用目前區塊時間戳(組件 4)覆蓋它來修改幸運數字,該時間戳永遠不會匹配模 8。在 forceReseed 中類似,它是 gasPrice * 7,它也永遠無法匹配

編輯:只有 forceReseed 覆蓋幸運數字抱歉

它對玩家的地址進行雜湊處理,從而確保隨機性。

然後它取結果模 8 的最後一個字節,這確保了 1/8 的獲勝機率。

引用自:https://ethereum.stackexchange.com/questions/70888