почему нельзя передать токен в функции GetReward в eqzip crowdsale? - PullRequest
0 голосов
/ 12 мая 2018

Ниже приведен мой контракт после развертывания контракта eqcoin и контракта eqzip. Я попытался использовать account2, отправив эфир в контракт eqzip, тогда бенефициар может получить эфир, но когда краудсейл закончится. Я попытался с помощью account2 выполнить функцию GetReward, чтобы получить вознаграждение, но после выполнения функции GetReward account2 не получил токен, почему? Не могли бы вы просмотреть мой исходный код и сказать, что не так с моим контрактом? Спасибо!

Eqcoin контракт:

pragma solidity ^0.4.21;

interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) external; }

contract Eqcoin {

    // Public variables of the token
    // string public constant whitePaperForEqcoin = "The total supply of eqcoin is 100000 which corresponds to 1% of Eqzip stock,\
    // 0.01% of Eqcoin stock and 10% of Lostk stock...\
    // The decimals of Eqcoin is 18...\
    // ";

    string public name = "eqcoin";
    string public symbol = "eqc";
    uint8 public decimals = 18;
    // 18 decimals is the strongly suggested default, avoid changing it
    uint256 public totalSupply;

    // This creates an array with all balances
    mapping (address => uint256) public balanceOf;
    mapping (address => mapping (address => uint256)) public allowance;


    // The owner's address
    // address private owner;

    // This generates a public event on the blockchain that will notify clients
    event Transfer(address indexed from, address indexed to, uint256 value);

    // This notifies clients about the amount burnt
    event Burn(address indexed from, uint256 value);

    // The following is test stub comment when release
    // string public ownerAddress;

    event Log(string log, address _address, uint256 value);

    /**
     * Constructor function
     *
     * Initializes contract with initial supply tokens to the creator of the contract
     */
    function Eqcoin(uint256 initialSupply,
        string tokenName,
        string tokenSymbol) public {
        totalSupply = initialSupply * 10 ** uint256(decimals);  // Update total supply with the decimal amount
        balanceOf[msg.sender] = totalSupply;                // Give the creator all initial tokens
        // owner = msg.sender;                                 // Set the owner
        // ownerAddress = toAsciiString(msg.sender);
        name = tokenName;
        symbol = tokenSymbol;
    }

      /**
     * Internal transfer, only can be called by this contract
     */
    function _transfer(address _from, address _to, uint _value) internal {
        emit Log("_transfer", _to, _value);
        // Prevent transfer to 0x0 address. Use burn() instead
        require(_to != 0x0);
        // Check if the sender has enough
        require(balanceOf[_from] >= _value);
        // Check for overflows
        require(balanceOf[_to] + _value >= balanceOf[_to]);
        // Save this for an assertion in the future
        uint previousBalances = balanceOf[_from] + balanceOf[_to];
        // Subtract from the sender
        balanceOf[_from] -= _value;
        // Add the same to the recipient
        balanceOf[_to] += _value;
        emit Transfer(_from, _to, _value);
        // Asserts are used to use static analysis to find bugs in your code. They should never fail
        assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
    }

    /**
     * Transfer tokens
     *
     * Send `_value` tokens to `_to` from your account
     *
     * @param _to The address of the recipient
     * @param _value the amount to send
     */
    function transfer(address _to, uint256 _value) public {
        emit Log("transfer", msg.sender, _value);
        _transfer(msg.sender, _to, _value);
    }

    /**
     * Transfer tokens from other address
     *
     * Send `_value` tokens to `_to` on behalf of `_from`
     *
     * @param _from The address of the sender
     * @param _to The address of the recipient
     * @param _value the amount to send
     */
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
        require(_value <= allowance[_from][msg.sender]);     // Check allowance
        allowance[_from][msg.sender] -= _value;
        _transfer(_from, _to, _value);
        return true;
    }

    /**
     * Set allowance for other address
     *
     * Allows `_spender` to spend no more than `_value` tokens on your behalf
     *
     * @param _spender The address authorized to spend
     * @param _value the max amount they can spend
     */
    function approve(address _spender, uint256 _value) public
        returns (bool success) {
        allowance[msg.sender][_spender] = _value;
        return true;
    }

    /**
     * Set allowance for other address and notify
     *
     * Allows `_spender` to spend no more than `_value` tokens on your behalf, and then ping the contract about it
     *
     * @param _spender The address authorized to spend
     * @param _value the max amount they can spend
     * @param _extraData some extra information to send to the approved contract
     */
    function approveAndCall(address _spender, uint256 _value, bytes _extraData)
        public
        returns (bool success) {
        tokenRecipient spender = tokenRecipient(_spender);
        if (approve(_spender, _value)) {
            spender.receiveApproval(msg.sender, _value, this, _extraData);
            return true;
        }
    }



    // /**
    //  * Destroy tokens
    //  *
    //  * Remove `_value` tokens from the system irreversibly
    //  *
    //  * @param _value the amount of money to burn
    //  */
    // function burn(uint256 _value) public returns (bool success) {

    //     if(balanceOf[msg.sender] < _value){
    //         return;
    //     }
    //     balanceOf[msg.sender] -= _value;            // Subtract from the sender
    //     if(msg.sender == owner){
    //         totalSupply -= _value;                      // Updates totalSupply
    //     }
    //     emit Burn(msg.sender, _value);
    //     return true;

    // }

    /**
     * Destroy tokens
     *
     * Remove `_value` tokens from the system irreversibly
     *
     * @param _value the amount of money to burn
     */
    function burn(uint256 _value) public returns (bool success) {
        require(balanceOf[msg.sender] >= _value);   // Check if the sender has enough
        balanceOf[msg.sender] -= _value;            // Subtract from the sender
        totalSupply -= _value;                      // Updates totalSupply
        emit Burn(msg.sender, _value);
        return true;
    }

    /**
     * Destroy tokens from other account
     *
     * Remove `_value` tokens from the system irreversibly on behalf of `_from`.
     *
     * @param _from the address of the sender
     * @param _value the amount of money to burn
     */
    function burnFrom(address _from, uint256 _value) public returns (bool success) {
        require(balanceOf[_from] >= _value);                // Check if the targeted balance is enough
        require(_value <= allowance[_from][msg.sender]);    // Check allowance
        balanceOf[_from] -= _value;                         // Subtract from the targeted balance
        allowance[_from][msg.sender] -= _value;             // Subtract from the sender's allowance
        totalSupply -= _value;                              // Update totalSupply
        emit Burn(_from, _value);
        return true;
    }

    function getTotalSupply() public constant returns (uint256 _totalSupply){
        return totalSupply;
    }

    // function getOwner() public constant returns(address _address){
    //     return owner;
    // }

    // the following is test stub comment when release
//     function toAsciiString(address x) internal pure returns (string) {
//     bytes memory s = new bytes(40);
//     for (uint i = 0; i < 20; i++) {
//         byte b = byte(uint8(uint(x) / (2**(8*(19 - i)))));
//         byte hi = byte(uint8(b) / 16);
//         byte lo = byte(uint8(b) - 16 * uint8(hi));
//         s[2*i] = char(hi);
//         s[2*i+1] = char(lo);           
//     }
//     return string(s);
// }

// function char(byte b) internal pure returns (byte c) {
//     if (b < 10) return byte(uint8(b) + 0x30);
//     else return byte(uint8(b) + 0x57);
// }


}

Eqzip краудсейл контракт:

pragma solidity ^0.4.21;

interface token {
    function transfer(address receiver, uint amount) external;
    function getTotalSupply() external returns (uint256 _totalSupply);
    // function getOwner() external returns(address _address);
}

contract EqzipCrowdsale {

    string public constant whitePaperForEqzip = "The total supply of eqcoin is 100000 which corresponds to: \n\
    1. 1% of Eqzip stock. \n\
    2. 0.01% of Eqcoin stock. \n\
    3. 10% of Lostk stock. \n\
    4. Get the EQC corresponding to the price of eqcoin ico. \n\
    5. If the Ether from one person's investment is greater than or equal to 333, \
    hope life offers one cloned resurrection place (only 3 places, take the top 3). \n\
    6. Hired Hope Media to provide Growth Hacker, product design, and business architecture design for Ethereum. \n\
    7. Prior to joining eqzip work, under the same conditions to participate in the next round of financing eqzip. \n\
    The decimals of Eqcoin is 18... \n\
    owner: Xun Wang \n\
    wechat: nju20006 \n\
    email: 10509759@qq.com \n\
    URL: www.eqzip.com www.eqzip.cn www.lostk.com www.lostk.cn github.com/eqzip/eqcoin github.com/eqzip/lostk \n\
    ";

    // The owner's address
    address public owner;

    // This generates a public event on the blockchain that will notify clients
    event Transfer(address indexed from, address indexed to, uint256 value);

    // This notifies clients about the amount burnt
    event Burn(string reason, uint256 value);

    uint public fundingGoal;
    uint public amountRaised;
    uint public funderNumbers;
    uint public deadline;
    struct BalanceOfFounder{
        uint256 _ether;
        bool isSentToken;
    }
    // This creates an array with all balances of eqcoin, ether and if have sent token
    mapping(address => BalanceOfFounder) public balanceOfEther;

    token public tokenReward;

    address public beneficiary;
    bool burnedUnsaleToken = false;

    event GoalReached(address recipient, uint totalAmountRaised);

    // Milestone
    string public milestone;
    // Total supply
    uint256 public totalSupply;

    event Log(string log, address _address, uint256 value);

    /**
     * Constructor function
     *
     * Setup the owner
     */
    function EqzipCrowdsale(
        address ifSuccessfulSendTo,
        uint fundingGoalInEthers,
        uint durationInMinutes,
        address addressOfTokenUsedAsReward
    ) public {

        // For Eqzip crowdsale
        beneficiary = ifSuccessfulSendTo;
        fundingGoal = fundingGoalInEthers * 1 ether;
        deadline = now + durationInMinutes * 1 minutes;
        tokenReward = token(addressOfTokenUsedAsReward);
        totalSupply = tokenReward.getTotalSupply();
        owner = msg.sender;
        emit Log("cons", owner, 0);
        // emit Log("cons", tokenReward.getOwner(), 1);

    }

    /**
     * Fallback function
     *
     * The function without name is the default function that is called whenever anyone sends funds to a contract
     */
    function () beforeDeadline public payable {
        balanceOfEther[msg.sender]._ether += msg.value;
        balanceOfEther[msg.sender].isSentToken = false;
        amountRaised += msg.value;
        beneficiary.transfer(msg.value);
        emit GoalReached(msg.sender, msg.value);
    }

    modifier afterDeadline() { if (now > deadline) _; }

    modifier beforeDeadline() { if (now <= deadline) _; }

    function getReward() afterDeadline public {
        emit Log("getReward", owner, 0);
        // require(!balanceOfEther[msg.sender].isSentToken);

        // save investment value
        // uint256 amount = balanceOfEther[msg.sender]._ether;

        emit Log("getReward after require", msg.sender, 1);

        // because have sent the token to founder so set isSentToken to true to void get multiply reward
        balanceOfEther[msg.sender].isSentToken = true;

        // if amount raised less than founding goal then burn un sold token and reduce the total supply
        // if((amountRaised < fundingGoal) && !burnedUnsaleToken){
        //         burnedUnsaleToken = true;
        //         // totalSupply = (totalSupply*amountRaised)/fundingGoal;
        //         // balanceOf[owner] = totalSupply;
        //         // emit Burn("Token not sold out all the sold value is", totalSupply);
        //     }

        if(amountRaised < fundingGoal && !burnedUnsaleToken){
            burnedUnsaleToken = true;
            totalSupply = (totalSupply*amountRaised)/fundingGoal;
            emit Burn("Token not sold out all the sold value is", totalSupply);
        }

        emit Log("getReward tokenReward.transfer", msg.sender, 2);
        tokenReward.transfer(msg.sender, (balanceOfEther[msg.sender]._ether*totalSupply)/amountRaised);
        emit Log("getReward after tokenReward.transfer", msg.sender, 3);
        // _transfer(owner, msg.sender, (amount*totalSupply)/amountRaised);

    }

    function getBalanceOfEther(address _address) public payable returns(uint256) {

        emit Log("getBalanceOfEther", _address, balanceOfEther[_address]._ether);
        return balanceOfEther[_address]._ether;

    }

    function updateMilestone(string str) public {
        emit Log("updateMilestone", msg.sender, 0);
        milestone = strConcat(milestone, "\n", toAsciiString(msg.sender), "\n", str);
    }

    function strConcat(string _a, string _b, string _c, string _d, string _e) internal pure returns (string){
        bytes memory _ba = bytes(_a);
        bytes memory _bb = bytes(_b);
        bytes memory _bc = bytes(_c);
        bytes memory _bd = bytes(_d);
        bytes memory _be = bytes(_e);
        string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length);
        bytes memory babcde = bytes(abcde);
        uint k = 0;
        for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i];
        for (i = 0; i < _bb.length; i++) babcde[k++] = _bb[i];
        for (i = 0; i < _bc.length; i++) babcde[k++] = _bc[i];
        for (i = 0; i < _bd.length; i++) babcde[k++] = _bd[i];
        for (i = 0; i < _be.length; i++) babcde[k++] = _be[i];
        return string(babcde);
    }

function toAsciiString(address x) internal pure returns (string) {
    bytes memory s = new bytes(40);
    for (uint i = 0; i < 20; i++) {
        byte b = byte(uint8(uint(x) / (2**(8*(19 - i)))));
        byte hi = byte(uint8(b) / 16);
        byte lo = byte(uint8(b) - 16 * uint8(hi));
        s[2*i] = char(hi);
        s[2*i+1] = char(lo);           
    }
    return string(s);
}

function char(byte b) internal pure returns (byte c) {
    if (b < 10) return byte(uint8(b) + 0x30);
    else return byte(uint8(b) + 0x57);
}

}
...