I agree with @Betcheg answer, but both A and B must have ether to invoke transferFrom and approve transactions, respectively.
But is there a way, such that only A need to have ether. And so B and C would have only tokens, not ether?
One way that I imagine is to change the "normal" way to implement a ERC20 token.
For example, change tranferFrom method to give permition to an address, like the owner (or another person/address), to be able to call transferFrom method even if not at approved list:
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
require(_value <= allowed[_from][msg.sender] || msg.sender == owner); // Check allowed
allowed[_from][msg.sender] -= _value;
//Other require validations
balances[_from] -= _value;
// Add the same to the recipient
balances[_to] += _value;
emit Transfer(_from, _to, _value);
return true;
}
Or create a complete new method transferByOwner that is independent of allowence:
function transferByOwner(address _from, address _to, uint256 _value) public returns (bool success) {
require(msg.sender == owner);
//Other require validations
balances[_from] -= _value;
// Add the same to the recipient
balances[_to] += _value;
emit Transfer(_from, _to, _value);
return true;
}
Though, one can reply that this give the owner full control to all token balances. Sure that's exactly right :)