[Ethereum] ERC223 tokenFallback function doesn`t work

erc-223myetherwalletsoliditytokens

I try use ERC223 token and I want understand how is it work.
I use recommended realization of this standard Dexaran
This is code of ERC223 token.

pragma solidity ^0.4.15;

import './ERC223_interface.sol';
import './Receiver_Interface.sol';
import '././SafeMath.sol';

/**
 * @title ERC223 standard token implementation.
 */
contract ERC223BasicToken is ERC223Interface {
    using SafeMath for uint;

    mapping(address => uint) balances; // List of user balances.
    address  public owner;
    uint public constant totalSupply = 10000000000000;
    uint public constant decimals = 8;
    string public constant name = "ERC223Stepan";
    string public constant symbol = "ESP223";

    function ERC223BasicToken () {
        owner = msg.sender;
        balances[owner] = totalSupply;
    }

    /**
     * @dev Transfer the specified amount of tokens to the specified address.
     *      Invokes the `tokenFallback` function if the recipient is a contract.
     *      The token transfer fails if the recipient is a contract
     *      but does not implement the `tokenFallback` function
     *      or the fallback function to receive funds.
     *
     * @param _to    Receiver address.
     * @param _value Amount of tokens that will be transferred.
     * @param _data  Transaction metadata.
     */
    function transfer(address _to, uint _value, bytes _data) {
        // Standard function transfer similar to ERC20 transfer with no _data .
        // Added due to backwards compatibility reasons .
        uint codeLength;

        assembly {
            // Retrieve the size of the code on target address, this needs assembly .
            codeLength := extcodesize(_to)
        }

        balances[msg.sender] = SafeMath.sub(balances[msg.sender],_value);
        balances[_to] = SafeMath.add(balances[_to], _value);
        if(codeLength>0) {
           ContractReceiver receiver = ContractReceiver(_to);
            receiver.tokenFallback(msg.sender, _value, _data);
        }
        Transfer(msg.sender, _to, _value, _data);
    }

    /**
     * @dev Transfer the specified amount of tokens to the specified address.
     *      This function works the same with the previous one
     *      but doesn't contain `_data` param.
     *      Added due to backwards compatibility reasons.
     *
     * @param _to    Receiver address.
     * @param _value Amount of tokens that will be transferred.
     */
    function transfer(address _to, uint _value) {
        uint codeLength;
        bytes memory empty;

        assembly {
            // Retrieve the size of the code on target address, this needs assembly .
            codeLength := extcodesize(_to)
        }

        balances[msg.sender] = SafeMath.sub(balances[msg.sender],_value);
        balances[_to] = SafeMath.add(balances[_to], _value);
        if(codeLength>0) {
            ContractReceiver receiver = ContractReceiver(_to);
            receiver.tokenFallback(msg.sender, _value, empty);
        }
        Transfer(msg.sender, _to, _value, empty);
    }


    /**
     * @dev Returns balance of the `_owner`.
     *
     * @param _owner   The address whose balance will be returned.
     * @return balance Balance of the `_owner`.
     */
    function balanceOf(address _owner) constant returns (uint balance) {
        return balances[_owner];
    }
}

And it is a receiv contract:

pragma solidity ^0.4.15;

 /*
 * Contract that is working with ERC223 tokens
 */

contract ContractReceiver {

    struct TKN {
        address sender;
        uint value;
        bytes data;
        bytes4 sig;
    }


    function tokenFallback(address _from, uint _value, bytes _data){
      TKN memory tkn;
      tkn.sender = _from;
      tkn.value = _value;
      tkn.data = _data;
      uint32 u = uint32(_data[3]) + (uint32(_data[2]) << 8) + (uint32(_data[1]) << 16) + (uint32(_data[0]) << 24);
      tkn.sig = bytes4(u);

      /* tkn variable is analogue of msg variable of Ether transaction
      *  tkn.sender is person who initiated this token transaction   (analogue of msg.sender)
      *  tkn.value the number of tokens that were sent   (analogue of msg.value)
      *  tkn.data is data of token transaction   (analogue of msg.data)
      *  tkn.sig is 4 bytes signature of function
      *  if data of token transaction is a function execution
      */
    }

    function rewiewToken  () returns (address, uint, bytes, bytes4) {
        TKN memory tkn;

        return (tkn.sender, tkn.value, tkn.data, tkn.sig);

    }
}

Transfer tokens between addresses of owners occurred correct but between contract to contract not occure, because I have next situation when I try send tokens to the ReceiveContract:
enter image description here

If I change amout of Gas Limit and sign transaction in conclution I have faild transaction

How can I fix bug with trasfer tokens on contract from contract?
What should data I pass in _data bytes when I call tokenFallback?

Best Answer

It didnt work because I didnt pass correct arguments. In receiver.tokenFallback(msg.sender, _value, _data) I must to pass zero instead emty or msg.value.

Related Topic