No, but yes.
No, because the contract can't send anything from anything other than itself. There's no {from: account} possibility. Transactions are "from" the contract. No exceptions.
Yes, because if the token contract is in charge of maintaining a ledger for tokens or something else it tracks, then it merely needs to perform some internal bookkeeping operations.
Just a simplified example with illustration about the functionality needed in token.transfer. Be really careful about making sure you haven't opened it up to users spending tokens from any old account. That would be chaos:
function sendTokensFromAnywhere(address sender, address receiver, uint amount)
onlyAuthorized // needs definition, or look at 2nd example
returns(bool success)
{
token.transfer(sender, receiver, amount);
return true;
}
contract Token {
modifier onlyOwner() {
// owner is trusted, but no one else
if(msg.sender != owner) throw;
_;
}
function Token() {
// assume deployment originates from the "owner"
owner = msg.sender;
// owner will be the only contract authorized to use transfer()
}
...
function transfer(address sender, address receiver, uint amount)
onlyOwner // sender is obviously dangerous, so control who can call this
returns (bool success)
{
if(balances[sender] < amount) throw;
balances[sender] -= amount;
balances[receiver] += amount;
return true;
}
In practice, the functions exposed to the public should probably ensure users can only transfer from their own accounts:
function sendTokensFromAnywhere(address receiver, uint amount)
public
returns(bool success)
{
token.transfer(msg.sender, receiver, amount); // only own tokens
return true;
}
The entity calling the function can only transfer() from its own assets, so we can remove onlyAuthorized instead of defining it.
With a little added caution, (although nothing in token.transfer currently returns false):
function sendTokensFromAnywhere(address receiver, uint amount)
public
returns(bool success)
{
if(token.transfer(msg.sender, receiver, amount)) return true;
// looks like something went wrong with the transfer
throw;
}
Hope it helps.