Solidity

該合約收集 ETH 以換取投票代幣。什麼功能可以讓我將收集到的 ETH 轉入錢包?

  • March 26, 2019
pragma solidity ^0.4.23;

contract Voting {
   bytes32[] public candidateList;

   uint public totalTokens;
   uint public balanceTokens;
   uint public tokenPrice;

   // what is the voter address?
   // total tokens purchased
   // tokens voted per candidate 

   struct voter {
       address voterAddress;
       uint tokensBought;
       uint[] tokensUsedPerCandidate;
   }

   mapping(address => voter) public voterInfo;
   mapping(bytes32 => uint) public votesReceived;

   constructor (uint _totalTokens, uint _tokenPrice, bytes32[] _candidateNames) public {
       totalTokens = _totalTokens;
       balanceTokens = _totalTokens;
       tokenPrice = _tokenPrice;
       candidateList = _candidateNames;
   }

   //1. Users should be able to purchase tokens 
   //2. Users should be able to vote for candidates with tokens
   //3. Anyone should have the ability to lookup voter info

   function buy() payable public {
       uint tokensToBuy = msg.value / tokenPrice;
       require(tokensToBuy <= balanceTokens);
       voterInfo[msg.sender].voterAddress = msg.sender;
       voterInfo[msg.sender].tokensBought += tokensToBuy;
       balanceTokens -= tokensToBuy;
   }

   function voteForCandidate(bytes32 candidate, uint tokens) public {
       // Check to make sure user has enough tokens to vote
       // Increment vote count for candidate
       // Update the voter struct tokensUsedPerCandidate for this voter

       uint availableTokens = voterInfo[msg.sender].tokensBought - totalTokensUsed(voterInfo[msg.sender].tokensUsedPerCandidate);

       require(tokens <= availableTokens, "You don't have enough tokens");
       votesReceived[candidate] += tokens;

       if (voterInfo[msg.sender].tokensUsedPerCandidate.length == 0) {
           for(uint i=0; i<candidateList.length; i++) {
               voterInfo[msg.sender].tokensUsedPerCandidate.push(0);
           }
       }

       uint index = indexOfCandidate(candidate);
       voterInfo[msg.sender].tokensUsedPerCandidate[index] += tokens;
   }

   function indexOfCandidate(bytes32 candidate) view public returns(uint) {
       for(uint i=0; i<candidateList.length; i++) {
           if (candidateList[i] == candidate) {
               return i;
           }
       }
       return uint(-1);
   }

   function totalTokensUsed(uint[] _tokensUsedPerCandidate) private pure returns (uint) {
       uint totalUsedTokens = 0;
       for(uint i=0; i<_tokensUsedPerCandidate.length; i++) {
           totalUsedTokens += _tokensUsedPerCandidate[i];
       }
       return totalUsedTokens;
   }

   function voterDetails(address user) view public returns (uint, uint[]) {
       return (voterInfo[user].tokensBought, voterInfo[user].tokensUsedPerCandidate);
   }

   function tokensSold() public view returns (uint) {
       return totalTokens - balanceTokens;
   }

   function allCandidates() public view returns (bytes32[]) {
       return candidateList;
   }

   function totalVotesFor(bytes32 candidate) public view returns (uint) {
       return votesReceived[candidate];
  }
}

將 Ether 轉移到帳戶的功能可能是這樣的:

function transferBalance() public {
   owner.transfer(address(this).balance);
}

在您的建構子中,您可以像這樣設置所有者(部署合約的人就是所有者,只有他們才能獲得乙太幣)

owner = msg.sender

$$ I edited the original question to make the code more easily understandable. Once I did that, it became obvious that $$此程式碼(如所寫)包含無法提取任何可能通過支付 buy功能累積的乙太幣的方法。 為什麼程式碼看起來像這樣的唯一“某種”解釋是合約的編寫者應該被另一個提供程式碼以提取乙太幣的合約繼承。

我認為,將接受乙太幣的邏輯與允許從合約中移除乙太幣的邏輯分開是一個非常糟糕的設計,就像將投票功能合併到接受乙太幣的聯繫人中一樣。

要麼,應該有兩個合約(一個處理乙太幣,一個處理投票)或一個完全處理兩者的合約。

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