4

I would like to create a token contract and an implementation of that token contract, to be able to replace the implementation if I ever need to.

The constant functions work fine but the functions which modify the state do not.

Here is the code. I stripped some functions to make the code shorter

contract CoinImplementation is Owned, Token {

    mapping (address => uint256) balances;         // each address in this contract may have tokens. 
    bytes8 _name = "Soarcoin";                     // name of this contract and investment fund
    bytes4 _symbol = "SOAR";                       // token symbol
    uint8 _decimals = 6;                           // decimals (for humans)
    uint256 _totalSupply;
    uint8 flag = 0;

    function CoinImplementation(uint256 initialMint) {
        _totalSupply = initialMint;
        balances[msg.sender] = initialMint;
    }

// transfer tokens from one address to another
    function transfer(address _to, uint256 _value) returns (bool success)
    {
        if (_value <= 0) throw;
    // Check send token value > 0;
        if (balances[msg.sender] < _value) return true;
    // Check if the sender has enough
        if (balances[msg.sender] < _value) return false;
    // Check for overflows
        balances[msg.sender] -= _value;
    // Subtract from the sender
        balances[_to] += _value;
    // Add the same to the recipient, if it's the contact itself then it signals a sell order of those tokens
        Transfer(msg.sender, _to, _value);
    // Notify anyone listening that this transfer took place
        return true;
    }
}

and then I have the calling contract

contract Coin is Owned, Token {

    Token implementation;

    function Coin(Token _implementation) {
        implementation = _implementation;
    }

    function transfer(address _to, uint256 _value) returns (bool success) {
        return implementation.transfer(_to, _value);
    }
}    

if the transfer is called directly on the implementation it works but if the transfer on the Coin contract is called nothing happens.

Jesbus
  • 10,478
  • 6
  • 35
  • 62
Micha Roon
  • 2,203
  • 21
  • 36
  • See http://ethereum.stackexchange.com/questions/9178/how-to-call-library-function-from-a-contract-error-the-contract-code-could . You need to configure the homestead block using the genesis.json . – BokkyPooBah Mar 17 '17 at 13:43

2 Answers2

2

I think it's a logic issue in the design.

function transfer()

is using

balances[msg.sender]

In this context, msg.sender is the CoinImplementation contract in every case. It's checking Coin's balance, not the user who sent the transaction.

I would recommend that you do not switch to tx.origin, even though it might seem tempting to do so. tx.origin is supposed to provide the transaction originator, not the most recent contract in the chain. Unfortunately, it's a security problem, therefore not a suitable solution in this case.

Here are two general approaches to think about.

  1. You can pass a from address into CoinImplementation and use msg.sender to confirm the caller is trusted (i.e. a trusted Coin contract), and then carry on. This is reasonable since the Coin contract is (I think) supposed to be the controller in charge.
  2. You can refactor CoinImplementation as a library. When you delegate calls to a library, they execute in the context of the calling contract and then your msg.sender should be the originator that your code expects it to be. I noticed the title/question here implies that this the current implementation. It's not. You're sending messages between contracts right now.

Hope it helps.

Rob Hitchens
  • 55,151
  • 11
  • 89
  • 145
0

Functions that modify the state of the blockchain can not return anything. These functions create transactions, which cost gas and are included in the Ethereum Blockchain. Therefore these functions are only completed when the resulting transaction has been included in a new block.

Depending on your parameters (gas price, gas limit) that can take anywhere between a few seconds and multiple hours. Thats why you cant a return value from these methods.

If you need to get some type of return from these methods, consider using events (http://solidity.readthedocs.io/en/develop/contracts.html#events). It's basically a log, the function can write in that log and once the transaction has been mined, you can request the transaction receipt for it which contains the fired events.

Max Binnewies
  • 677
  • 4
  • 11
  • you are right that the return value will be mostly useless. But it should not hurt to have one. The official interface specifies a return value for the transfer function https://github.com/ethereum/EIPs/issues/20 – Micha Roon Mar 17 '17 at 14:17
  • the question was: why is my Token.transfer not transferring anything? when the TokenImplementation.transfer does its job – Micha Roon Mar 17 '17 at 14:17