Dieser Vertrag sammelt ETH im Austausch gegen Abstimmungstoken. Welche Funktion ermöglicht es mir, die gesammelten ETH in eine Brieftasche zu übertragen?

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];
   }
}

Antworten (2)

Die Funktion zum Überweisen von Ether auf ein Konto könnte etwa so aussehen:

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

Und in Ihrem Konstruktor können Sie den Eigentümer wie folgt festlegen (wer auch immer den Vertrag bereitgestellt hat, ist der Eigentümer und nur er erhält den Ether)

 owner = msg.sender
Diese Implementierung ermöglicht es jedem, die Übertragung zu initiieren. Dies bedeutet nicht, dass Ether gestohlen werden könnte, da sie sowieso an den Besitzer gesendet werden, aber dies könnte es schwierig machen, nachzuverfolgen, wie viel Ether abgezogen wurde.

[Ich habe die ursprüngliche Frage bearbeitet, um den Code leichter verständlich zu machen. Sobald ich das getan habe, wurde es offensichtlich, dass] dieser Code (wie geschrieben) keine Möglichkeit enthält, Ether zu extrahieren, die über die Bezahlfunktion buy angesammelt werden könnten .

Die einzige "Art" Erklärung dafür, warum der Code so aussehen könnte, ist, dass der Vertragsschreiber von einem anderen Vertrag geerbt werden soll, der den Code zum Extrahieren des Äthers bereitstellt.

Die Trennung der Logik, die den Äther akzeptiert, von der Logik, die es erlaubt, den Äther aus dem Vertrag zu entfernen, ist meiner Meinung nach ein sehr schlechtes Design, ebenso wie die Einbeziehung der Abstimmungsfunktion in den Kontakt, der den Äther akzeptiert.

Entweder sollte es zwei Verträge geben (einer, der sich mit dem Äther befasst, und einer, der sich mit der Abstimmung befasst) oder ein einziger Vertrag, der sich vollständig mit beiden befasst.