Método de contrato de llamada desde un contrato ya implementado

Implementé un contrato de token y ahora quiero usar varias transferencias. Pensé que podía hacer esto implementando otro contrato que ejecutará la iteración sobre la función de transferencia de mi contrato de token implementado.

Pero recibo una transacción fallida. He realizado otra prueba para aclarar también, a continuación se muestran los detalles:

Ejemplo de contrato implementado:

contract MyToken {
    /* This creates an array with all balances */
    mapping (address => uint256) public balanceOf;

    /* Initializes contract with initial supply tokens to the creator of the contract */
    function MyToken(
        uint256 initialSupply
        ) {
        balanceOf[msg.sender] = initialSupply;              // Give the creator all initial tokens
    }

    /* Send coins */
    function transfer(address _to, uint256 _value) {
        require(balanceOf[msg.sender] >= _value);           // Check if the sender has enough
        require(balanceOf[_to] + _value >= balanceOf[_to]); // Check for overflows
        balanceOf[msg.sender] -= _value;                    // Subtract from the sender
        balanceOf[_to] += _value;                           // Add the same to the recipient
    }
}

Ejemplo de contrato de llamada:

pragma solidity ^0.4.21;

contract MyToken {function transfer(address _to, uint256 _value) public; }

contract ADTest {

    function CallTransfer(address tokenAddress, address _to, uint256 _value) public {
        MyToken(tokenAddress).transfer(_to, _value);
    }

}

¿Puede alguien por favor ayudar con la solución? No estoy seguro de lo que estoy haciendo mal.

ACTUALIZAR Pensé que si envío algunos tokens al contrato de la persona que llama, entonces el contrato de la persona que llama se envía a diferentes direcciones, sin ningún problema. No estoy seguro de que el clima sea una solución adecuada por ahora, pero podría ayudar a alguien.

Respuestas (2)

Prueba así. Comentarios en línea.

pragma solidity ^0.4.21;

// added I as naming convention (Interface)
contract MyTokenI {function transfer(address _to, uint256 _value) public; }

contract ADTest {

    // will hold an instance cast as type MyToken
    MyTokenI myToken;

    // pass the deployed MyToken address into this constructor
    function ADTest(address _myToken) public {
        // instantiate the deployed contract at _myToken
        myToken = MyTokenI(_myToken);
    }

    function CallTransfer(address _to, uint256 _value) public {
        // use the instance
        myToken.transfer(_to, _value);
    }

}

Espero eso ayude.

Hola @Rob Hitchens Gracias por la rápida respuesta, pero sigo recibiendo el mismo error, Error de transacción. Excepción lanzada en el código del contrato. Límite de gas fijado peligrosamente alto. Es probable que falle la aprobación de esta transacción.

Bueno, primero creas MyTokencon tu usuario 0x1234Luego, 0x1234...llama a la dirección ADTest.CallTransfer(). MyTokencontrato desplegado comprobará el saldo de msg.sender. Pero msg.senderes contrato ADTest, no usuario "0x1234". Por lo tanto, require(balanceOf[msg.sender] >= _value);fallará y la transacción se revertirá.

Aquí está mi sugerencia, usando la sugerencia de Rob también:

contract MyToken {
    /* This creates an array with all balances */
    mapping (address => uint256) public balanceOf;

    /* Initializes contract with initial supply tokens to the creator of the contract */
    function MyToken(
        uint256 initialSupply
        ) {
        balanceOf[msg.sender] = initialSupply;              // Give the creator all initial tokens
    }

    /* Send coins */
    function transfer(address sender, address _to, uint256 _value) {
        require(balanceOf[sender] >= _value);           // Check if the sender has enough
        require(balanceOf[_to] + _value >= balanceOf[_to]); // Check for overflows
        balanceOf[sender] -= _value;                    // Subtract from the sender
        balanceOf[_to] += _value;                           // Add the same to the recipient
    }
}

contract MyTokenI {function transfer(address sender, address _to, uint256 _value) public; }

contract ADTest {

    // will hold an instance cast as type MyToken
    MyTokenI myToken;

    // pass the deployed MyToken address into this constructor
    function ADTest(address _myToken) public {
        // instantiate the deployed contract at _myToken
        myToken = MyTokenI(_myToken);
    }

    function CallTransfer(address _to, uint256 _value) public {
        // use the instance
        myToken.transfer(msg.sender, _to, _value);
    }

}
Hola @luiz, estoy buscando una solución para un contrato implementado, pero esta solución requerirá que cambie la firma del contrato ya implementado. Cosa que no puedo hacer.
Bueno, en ese caso, solo quien implementó MyTokenpodrá transferir debido a este requisito:balanceOf[msg.sender] = initialSupply;