You need a take care of a few concerns.
On the receiving side, what to accept and the necessary accounting so the withdrawal side will know what is acceptable.
On the withdrawal side, it needs to send a transaction to the token contract to do a transfer. This requires knowledge of the contract interface. I've paired it down what is strictly necessary for this example.
I had to make some assumptions about what you want to do. This is fashioned after an ATM. Users can get their own money (tokens) back. Also, it only accepts one type of token to keep the accounting data structure simple.
pragma solidity 0.5.1; // reduce confusion with this declaration
contract ERC223Interface {
function transfer(address to, uint value) public;
}
contract ContractReceiver {
address public owner;
// address public sender; there will be more than one
ERC223Interface token; // requires the interface contract above
uint public value;
bytes public data;
mapping(address => uint) public balances; // each user has an amount of tokens stored in this contract
event LogTokensReceived(address tokenContract, address sender, uint amount, bytes data);
event LogWithdrawal(address receiver, uint amount);
constructor(address ERC223TokenContract) public { // should not be payable
owner = msg.sender;
token = ERC223Interface(ERC223TokenContract); // configure to accept only this token
}
modifier onlyOwner(){
require(msg.sender == owner);
_;
}
It's not robust for production but should be you the idea.
Hope it helps.
function tokenFallback(address _from, uint _value, bytes memory _data) public { // _from is sender
require(msg.sender == address(token)); // reject all except expected token
balances[msg.sender] += _value; // track tokens received by sender. Anyone can send tokens here.
emit LogTokensReceived(msg.sender, _from, _value, _data);
}
function withDrawTokens(uint amount) public {
uint balance = balances[msg.sender];
require(amount <= balance, "Insufficient funds.");
balances[msg.sender] = balance - amount;
emit LogWithdrawal(msg.sender, amount);
token.transfer(msg.sender, amount); // send them
}
}