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.

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.

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.

  • 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 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.