Ethereum Crowdsale Discussion

#41

Hi Filip,
In the ERC-20 contract we define the contract as:
contract FilipCoin is ERC20Interface, Owned, SafeMath {

My question is in regard to the modifier Owned. I assume this is similar to the Ownable modifier except that it specifies that the contract creator owns the contract?
I could not find it in github. Is it possible for us to see the code for this modifier?

Thanks in advance.
Leif

#42

Hi Leif,

Good question. Owned in that case is not a modifier but a contract that FilipCoin is inheriting from. If you scroll up in that file you will see the Owned Contract. That contract contains the modifier onlyOwner, that we use in the token contract in order to limit the access to the owner only for certain functions. Was that clear? Let me know if you have any more questions.

#43

Thanks for your help.

1 Like
#44

Well you can refer this resource on explanation on 2d array.

1 Like
#45

Hello Filip and everyone of the community!!!

Guys i have this error in the token.sol contract and i would like some help with that and know why it’s happened, Thank you

#46

You should read more about memory and storage. https://medium.com/coinmonks/ethereum-solidity-memory-vs-storage-which-to-use-in-local-functions-72b593c3703a

You should be able to figure it out from that. Otherwise let me know.

1 Like
#47

Hi Filip,

I have my ether transaction stuck in transit. I sent ether from Hitbtc exchange but have not reached the destination still propagating the network for 4 weeks now. Today I sent ether from Coin base Hotbit exchange but it got stuck too. Also within my Hitbtc account I tried to move ether to my trading account it also got stuck. Please can you advise what to do?

Attached are the copies of screen shots4-weeks%20stuck From%20Coinbase%20to%20Hotbit Stuck%20with%20Hitbtc%20accounts

#48

Is this related to the ethereum crowdsale contract? Otherwise, please create a new thread and tag me in that post.

#49

Hi Filip, late to this lesson, but pushing through, LOL. I have a question. How it isn’t allowed to use constant anymore, as in the attached, if I have specified the compiler version to be ^0.4.24? Thanks in advance.


(I’m stuck because of this. Tried changing to view, then I would have to change the compiler version because of error, to 0.5.1; then a couple more errors would show up in the code.)

#50

You need to change the compiler version in 2 places. Both in the code and in remix (in the compile tab). Have you done that?

#51

Oh… haha, ok great. Thanks!

#52

I’m stuck on Crowdsale part 3 trying to deploy the token contract. When I click “Deploy” nothing happens; no errors, no popups. I have remix set to injected web3 and my metamask account is set to Rinkeby. I used the 0.4.24 compiler to match the version on GitHub

Here is the code for the contract:

pragma solidity ^0.4.24;
// ----------------------------------------------------------------------------
// 'AV Coin' token contract
//
// Deployed to : 0xf630316552988a44c7D40Ed122C79D1874f78281
// Symbol      : AVCoin
// Name        :Average Coin
// Total supply: 100000000
// Decimals    : 18
//
// Enjoy.
//
// (c) by Moritz Neto with BokkyPooBah / Bok Consulting Pty Ltd Au 2017. The MIT Licence.
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Safe maths
// ----------------------------------------------------------------------------
contract SafeMath {
    function safeAdd(uint a, uint b) public pure returns (uint c) {
        c = a + b;
        require(c >= a);
    }
    function safeSub(uint a, uint b) public pure returns (uint c) {
        require(b <= a);
        c = a - b;
    }
    function safeMul(uint a, uint b) public pure returns (uint c) {
        c = a * b;
        require(a == 0 || c / a == b);
    }
    function safeDiv(uint a, uint b) public pure returns (uint c) {
        require(b > 0);
        c = a / b;
    }
}

// ----------------------------------------------------------------------------
// ERC Token Standard #20 Interface
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
// ----------------------------------------------------------------------------
contract ERC20Interface {
    function totalSupply() public constant returns (uint);
    function balanceOf(address tokenOwner) public constant returns (uint balance);
    function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
    function transfer(address to, uint tokens) public returns (bool success);
    function approve(address spender, uint tokens) public returns (bool success);
    function transferFrom(address from, address to, uint tokens) public returns (bool success);

    event Transfer(address indexed from, address indexed to, uint tokens);
    event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}

// ----------------------------------------------------------------------------
// Contract function to receive approval and execute function in one call
//
// Borrowed from MiniMeToken
// ----------------------------------------------------------------------------
contract ApproveAndCallFallBack {
    function receiveApproval(address from, uint256 tokens, address token, bytes data) public;
}

// ----------------------------------------------------------------------------
// Owned contract
// ----------------------------------------------------------------------------
contract Owned {
    address public owner;
    address public newOwner;

    event OwnershipTransferred(address indexed _from, address indexed _to);

    constructor() public {
        owner = msg.sender;
    }

    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }

    function transferOwnership(address _newOwner) public onlyOwner {
        newOwner = _newOwner;
    }

    function acceptOwnership() public {
        require(msg.sender == newOwner);
        emit OwnershipTransferred(owner, newOwner);
        owner = newOwner;
        newOwner = address(0);
    }
}

// ----------------------------------------------------------------------------
// ERC20 Token, with the addition of symbol, name and decimals and assisted
// token transfers
// ----------------------------------------------------------------------------

contract AVCoin is ERC20Interface, Owned, SafeMath {
    string public symbol;
    string public  name;
    uint8 public decimals;
    uint public _totalSupply;

    mapping(address => uint) balances;
    mapping(address => mapping(address => uint)) allowed;

// ------------------------------------------------------------------------
// Constructor
// ------------------------------------------------------------------------

    constructor() public {
        symbol = "AVCoin";
        name = "Average Coin";
        decimals = 18;
        _totalSupply = 100000000000000000000000000;
        balances[0xf630316552988a44c7D40Ed122C79D1874f78281] = _totalSupply;
        emit Transfer(address(0), 0xf630316552988a44c7D40Ed122C79D1874f78281, _totalSupply);
    }

// ------------------------------------------------------------------------
// Total supply
// ------------------------------------------------------------------------
    function totalSupply() public constant returns (uint) {
        return _totalSupply  - balances[address(0)];
    }

// ------------------------------------------------------------------------
// Get the token balance for account tokenOwner
// ------------------------------------------------------------------------
    function balanceOf(address tokenOwner) public constant returns (uint balance) {
        return balances[tokenOwner];
    }

    // ------------------------------------------------------------------------
    // Transfer the balance from token owner's account to to account
    // - Owner's account must have sufficient balance to transfer
    // - 0 value transfers are allowed
    // ------------------------------------------------------------------------
    function transfer(address to, uint tokens) public returns (bool success) {
        balances[msg.sender] = safeSub(balances[msg.sender], tokens);
        balances[to] = safeAdd(balances[to], tokens);
        emit Transfer(msg.sender, to, tokens);
        return true;
    }

    // ------------------------------------------------------------------------
    // Token owner can approve for spender to transferFrom(...) tokens
    // from the token owner's account
    //
    // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
    // recommends that there are no checks for the approval double-spend attack
    // as this should be implemented in user interfaces 
    // ------------------------------------------------------------------------
    function approve(address spender, uint tokens) public returns (bool success) {
        allowed[msg.sender][spender] = tokens;
        emit Approval(msg.sender, spender, tokens);
        return true;
    }

    // ------------------------------------------------------------------------
    // Transfer tokens from the from account to the to account
    // 
    // The calling account must already have sufficient tokens approve(...)-d
    // for spending from the from account and
    // - From account must have sufficient balance to transfer
    // - Spender must have sufficient allowance to transfer
    // - 0 value transfers are allowed
    // ------------------------------------------------------------------------
    function transferFrom(address from, address to, uint tokens) public returns (bool success) {
        balances[from] = safeSub(balances[from], tokens);
        allowed[from][msg.sender] = safeSub(allowed[from][msg.sender], tokens);
        balances[to] = safeAdd(balances[to], tokens);
        emit Transfer(from, to, tokens);
        return true;
    }

    // ------------------------------------------------------------------------
    // Returns the amount of tokens approved by the owner that can be
    // transferred to the spender's account
    // ------------------------------------------------------------------------
    function allowance(address tokenOwner, address spender) public constant returns (uint remaining) {
        return allowed[tokenOwner][spender];
    }

    // ------------------------------------------------------------------------
    // Token owner can approve for spender to transferFrom(...) tokens
    // from the token owner's account. The spender contract function
    // receiveApproval(...) is then executed
    // ------------------------------------------------------------------------
    function approveAndCall(address spender, uint tokens, bytes data) public returns (bool success) {
        allowed[msg.sender][spender] = tokens;
        emit Approval(msg.sender, spender, tokens);
        ApproveAndCallFallBack(spender).receiveApproval(msg.sender, tokens, this, data);
        return true;
    }
    // ------------------------------------------------------------------------
    // Don't accept ETH
    // ------------------------------------------------------------------------
    function () public payable {
        revert();
    }

    // ------------------------------------------------------------------------
    // Owner can transfer out any accidentally sent ERC20 tokens
    // ------------------------------------------------------------------------
    function transferAnyERC20Token(address tokenAddress, uint tokens) public onlyOwner returns (bool success) {
        return ERC20Interface(tokenAddress).transfer(owner, tokens);
    }
}
#53

Works for me if I use your code. Do you have metamask installed att are you logged in to metamask?

#54

Thanks for double checking on this for me. I went through the rest of the course and then came back to this section. It worked for me this time.

1 Like
#55

Hi Filip, First of all, thank you for the course, it has been very informative. I was wondering, do you have finished code for transferring the CrowdSale and Token contracts to Super Blocks? I have tried to do it myself, but am getting stuck on how to configure the constructor arguments in SuperBlocks for the Token Contract.

Btw, even though the ‘network’ entry on the configuration page for EriCoin says Network: browser, the compile still fails when I set it to Rinkeby.

#56

Seems to be a compilation error, not a deploy issue. Can you send your code? Please format it nicely so it’s easy for me to read :wink:

#57

**Hi Filip, **

thank you for responding, sure thing, here is the contract code for the token that I created using your code and the lessons:

pragma solidity ^0.4.24;

// ----------------------------------------------------------------------------
// EricToken token contract
//
// Deployed to : 0xEb7208A7453dFC3C7380170A99fc5156A160Cd75
// Symbol : ERICOIN
// Name : ERICOIN
// Total supply: 100000000
// Decimals : 18
//
// Enjoy.
//
// © by Moritz Neto with BokkyPooBah / Bok Consulting Pty Ltd Au 2017. The MIT Licence.
// ----------------------------------------------------------------------------

// ----------------------------------------------------------------------------
// Safe maths
// ----------------------------------------------------------------------------
contract SafeMath {
function safeAdd(uint a, uint b) public pure returns (uint c) {
c = a + b;
require(c >= a);
}
function safeSub(uint a, uint b) public pure returns (uint c) {
require(b <= a);
c = a - b;
}
function safeMul(uint a, uint b) public pure returns (uint c) {
c = a * b;
require(a == 0 || c / a == b);
}
function safeDiv(uint a, uint b) public pure returns (uint c) {
require(b > 0);
c = a / b;
}
}

// ----------------------------------------------------------------------------
// ERC Token Standard #20 Interface
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
// ----------------------------------------------------------------------------
contract ERC20Interface {
function totalSupply() public constant returns (uint);
function balanceOf(address tokenOwner) public constant returns (uint balance);
function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
function transfer(address to, uint tokens) public returns (bool success);
function approve(address spender, uint tokens) public returns (bool success);
function transferFrom(address from, address to, uint tokens) public returns (bool success);

event Transfer(address indexed from, address indexed to, uint tokens);
event Approval(address indexed tokenOwner, address indexed spender, uint tokens);

}

// ----------------------------------------------------------------------------
// Contract function to receive approval and execute function in one call
//
// Borrowed from MiniMeToken
// ----------------------------------------------------------------------------
contract ApproveAndCallFallBack {
function receiveApproval(address from, uint256 tokens, address token, bytes data) public;
}

// ----------------------------------------------------------------------------
// Owned contract
// ----------------------------------------------------------------------------
contract Owned {
address public owner;
address public newOwner;

event OwnershipTransferred(address indexed _from, address indexed _to);

constructor() public {
    owner = msg.sender;
}

modifier onlyOwner {
    require(msg.sender == owner);
    _;
}

function transferOwnership(address _newOwner) public onlyOwner {
    newOwner = _newOwner;
}
function acceptOwnership() public {
    require(msg.sender == newOwner);
    emit OwnershipTransferred(owner, newOwner);
    owner = newOwner;
    newOwner = address(0);
}

}

// ----------------------------------------------------------------------------
// ERC20 Token, with the addition of symbol, name and decimals and assisted
// token transfers
// ----------------------------------------------------------------------------
contract EriCoin is ERC20Interface, Owned, SafeMath {
string public symbol;
string public name;
uint8 public decimals;
uint public _totalSupply;

mapping(address => uint) balances;
mapping(address => mapping(address => uint)) allowed;


// ------------------------------------------------------------------------
// Constructor
// ------------------------------------------------------------------------
constructor() public {
    symbol = "ERICOIN";
    name = "EriCoin";
    decimals = 18;
    _totalSupply = 100000000000000000000000000;
    balances[0xEb7208A7453dFC3C7380170A99fc5156A160Cd75] = _totalSupply;
    emit Transfer(address(0), 0xEb7208A7453dFC3C7380170A99fc5156A160Cd75, _totalSupply);
}


// ------------------------------------------------------------------------
// Total supply
// ------------------------------------------------------------------------
function totalSupply() public constant returns (uint) {
    return _totalSupply  - balances[address(0)];
}


// ------------------------------------------------------------------------
// Get the token balance for account tokenOwner
// ------------------------------------------------------------------------
function balanceOf(address tokenOwner) public constant returns (uint balance) {
    return balances[tokenOwner];
}


// ------------------------------------------------------------------------
// Transfer the balance from token owner's account to to account
// - Owner's account must have sufficient balance to transfer
// - 0 value transfers are allowed
// ------------------------------------------------------------------------
function transfer(address to, uint tokens) public returns (bool success) {
    balances[msg.sender] = safeSub(balances[msg.sender], tokens);
    balances[to] = safeAdd(balances[to], tokens);
    emit Transfer(msg.sender, to, tokens);
    return true;
}


// ------------------------------------------------------------------------
// Token owner can approve for spender to transferFrom(...) tokens
// from the token owner's account
//
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
// recommends that there are no checks for the approval double-spend attack
// as this should be implemented in user interfaces 
// ------------------------------------------------------------------------
function approve(address spender, uint tokens) public returns (bool success) {
    allowed[msg.sender][spender] = tokens;
    emit Approval(msg.sender, spender, tokens);
    return true;
}


// ------------------------------------------------------------------------
// Transfer tokens from the from account to the to account
// 
// The calling account must already have sufficient tokens approve(...)-d
// for spending from the from account and
// - From account must have sufficient balance to transfer
// - Spender must have sufficient allowance to transfer
// - 0 value transfers are allowed
// ------------------------------------------------------------------------
function transferFrom(address from, address to, uint tokens) public returns (bool success) {
    balances[from] = safeSub(balances[from], tokens);
    allowed[from][msg.sender] = safeSub(allowed[from][msg.sender], tokens);
    balances[to] = safeAdd(balances[to], tokens);
    emit Transfer(from, to, tokens);
    return true;
}


// ------------------------------------------------------------------------
// Returns the amount of tokens approved by the owner that can be
// transferred to the spender's account
// ------------------------------------------------------------------------
function allowance(address tokenOwner, address spender) public constant returns (uint remaining) {
    return allowed[tokenOwner][spender];
}


// ------------------------------------------------------------------------
// Token owner can approve for spender to transferFrom(...) tokens
// from the token owner's account. The spender contract function
// receiveApproval(...) is then executed
// ------------------------------------------------------------------------
function approveAndCall(address spender, uint tokens, bytes data) public returns (bool success) {
    allowed[msg.sender][spender] = tokens;
    emit Approval(msg.sender, spender, tokens);
    ApproveAndCallFallBack(spender).receiveApproval(msg.sender, tokens, this, data);
    return true;
}


// ------------------------------------------------------------------------
// Don't accept ETH
// ------------------------------------------------------------------------
function () public payable {
    revert();
}


// ------------------------------------------------------------------------
// Owner can transfer out any accidentally sent ERC20 tokens
// ------------------------------------------------------------------------
function transferAnyERC20Token(address tokenAddress, uint tokens) public onlyOwner returns (bool success) {
    return ERC20Interface(tokenAddress).transfer(owner, tokens);
}

}

and here is the code for the crowdsale:

pragma solidity ^0.4.16;

interface EriCoin {
function transfer(address receiver, uint amount);
}

contract Crowdsale {

address public beneficiary; //person who gets the payout from the contract
uint public fundingGoal;
uint public totalAmountRaised;
uint public crowdSaleDeadline;
uint public tokenPrice;
EriCoin public token;
mapping(address => uint) public balanceOf; //database of everyone's contributions to the crowdSaleDeadline
bool fundingGoalReached = false;
bool crowdSaleClosed = false;

/**
 * Constructor
 * ifSuccessfulSendTo: Address where funds should be sent if sale reaches target
 * goalInEther: What is the target goal for the crowdsale in ethers.
 * durationInMinutes: How long will the crowdsale be running.
 * tokenPriceInEther: How much does each token cost
 * addressOfToken: Where is the token contract deployed.
 */
function Crowdsale(
    address ifSuccessfulSendTo,
    uint goalInEther,
    uint durationInMinutes,
    uint tokenPriceInEther,
    address addressOfToken
) {
    beneficiary = ifSuccessfulSendTo;
    fundingGoal = goalInEther;
    crowdSaleDeadline = now + durationInMinutes * 1 minutes; //done this way to get the type 'minutes'
    tokenPrice = tokenPriceInEther * 1 ether; //like above, done this way to get the type 'ether'
    token = EriCoin(addressOfToken); //this will be filled in later when the EriCoin contract is deployed
}

/**
 * Fallback function
 *
 * Default function which gets called when someone sends money to the contract. Will be used for joining sale.
 */
function () payable {
    require(!crowdSaleClosed);
    uint amount = msg.value;
    balanceOf[msg.sender] += amount;
    totalAmountRaised += amount;
    token.transfer(msg.sender, amount);
}

/**
 * Modifier used to check if deadline for crowdsale has passed
 */
modifier afterDeadline() {
    if(now >= crowdSaleDeadline){
        _;
    }

}

/**
 * Check if the funding goal was reached. Will only be checked if afterDeadline modifier above is true.
 *
 */
function checkGoalReached() public afterDeadline {
    if(totalAmountRaised >= fundingGoal){
        fundingGoalReached = true;
    }
    crowdSaleClosed = true;
}


/**
 * Withdraw the funds
 *
 * Will withdraw the money after the deadline has been reached. If the goal was reached, only the owner can withdraw money to the beneficiary account.
 * If you goal was not reached, everyone who participated can withdraw their share.
 */
function safeWithdrawal() public afterDeadline {
    if(!fundingGoalReached){
        uint amount = balanceOf[msg.sender];
        balanceOf[msg.sender] = 0;
        if(amount > 0){
            if(!msg.sender.send(amount)){
                balanceOf[msg.sender] = amount;
            }
        }
    }
    if(fundingGoalReached && msg.sender == beneficiary){
        fundingGoalReached = false;
    }
}

}

#58

Please format it correctly using the code tool here on the forum. Now only parts are and it’s very hard to read.

#59

Hi Filip, my apologies, here is a link to the EriCoin contract on my github:


and here is one for the Crowdsale:https://github.com/mudguts70/ivanOnTechCodingAcademyCode/blob/master/Crowdsale

#60

Thank you. Seems like the github repository I used in my video has been updated slightly. Should work if you change the pragma version so it’s 0.4.24 in both files.

I will fix this issue in the course next week. So that no more students will stumble upon this.