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
:
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 didn
t work because I didn
t pass correct arguments. Inreceiver.tokenFallback(msg.sender, _value, _data)
I must to pass zero instead emty ormsg.value
.