Let's say you've created and issued an ERC20 token. You then create a crowdsale and only want to accept the token you issued, not Ethereum.
Is this possible?
If you control both token and crowdsale it can be done easily
contract Token {
address officialCrowdsale;
function investCrowdsale(uint256 _value, bytes _extraData) returns (bool success) {
allowance[msg.sender][officialCrowdsale] = _value;
Crowdsale crowdsale = Crowdsale(officialCrowdsale);
crowdsale.investFromToken(msg.sender, _value, _extraData);
return true;
}
}
And in your crowdsale
contract Crowdsale {
address officialToken;
address depositToken;
function investFromToken(address _from, uint256 _value ,bytes _extraData) returns (bool success) {
if (msg.sender != officialToken) throw; // only accept transfer from the official token
Token token = Token(_token);
token.transferFrom(_from, depositToken, _value); // store tokens in deposit
DoInvest(_value, _extraData); // Do the investment
return true;
}
}
If your token is already deployed and has support for approveAndCall you can do something similar.
An alternative solution could be this:
first of all, the user should call the approve() function of your ERC-20 token, passing as parameters the crowdsale contract and the amount he wants to spend in the crowdsale:
approve(crowdsaleAddress, amount)
then in your crowdsale contract, you should first check the user's balance and then tranfer the amount to your crowdsale address.
You crowdsale contract:
//interface to your Token
contract YourToken{
function transferFrom(address _from, address _to, uint _value) returns (bool success);
function approve(address _spender, uint _value) returns (bool success);
function balanceOf(address _owner) constant returns (uint balance);
}
contract Crowdsale {
address owner;
mapping(address => uint256) balances;
function Crowdsale(){
owner = msg.sender;
}
function acceptOnlyMyToken(address _yourTokenAddress, uint256 amount){
address user = msg.sender;
YourToken token = YourToken(_yourTokenAddress);
//get the user's balance
uint256 userBalance = token.balanceOf(user);
//check user's balance
if(userBalance >= amount){
token.transferFrom(user, owner, amount);
}
}
}
I asked a similar question: Best practices for interacting with other contracts