He creado una criptomoneda siguiendo este enlace . He implementado el contrato en Mist. Estoy usando la función transferFrom () en la billetera Ethereum para transferir moneda de una cuenta a otra, pero obtengo un error de gas intrínseco demasiado bajo (falló la ejecución. Consumió todo el gas provisto). Aunque mi cuenta principal (desde la que estoy tratando de transferir) contiene suficientes éteres (más de 20,000 éteres).
function transferFrom(dirección _from, dirección _to, uint256 _value) devuelve (bool éxito) { if (balanceOf[_from] asignación[_from][msg.sender]) throw; // Comprobar asignación balanceDe[_desde] -= _valor; // Restar del remitente saldoDe[_a] += _valor; // Agregar lo mismo al destinatario asignación[_de][mensaje.remitente] -= _valor; recompensa=calcularRecompensa(ahora); balanceOf[bloque.coinbase] += recompensa; Transferir(_desde, _a, _valor); devolver verdadero; }
mientras que otras funciones similares, como la transferencia (), funcionan bien. No puedo entender por qué dos funciones se comportan de manera diferente. Estoy agregando la imagen de error como referencia.
Sospecho que tu problema se debe a que no has aprobado la transferencia requerida para llamar transferFrom(...)
.
Aquí están las funciones relevantes:
/* Send coins */
function transfer(address _to, uint256 _value) {
if (balanceOf[msg.sender] < _value) throw; // Check if the sender has enough
if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
balanceOf[msg.sender] -= _value; // Subtract from the sender
balanceOf[_to] += _value; // Add the same to the recipient
Transfer(msg.sender, _to, _value); // Notify anyone listening that this transfer took place
}
/* Allow another contract to spend some tokens in your behalf */
function approveAndCall(address _spender, uint256 _value, bytes _extraData)
returns (bool success) {
allowance[msg.sender][_spender] = _value;
tokenRecipient spender = tokenRecipient(_spender);
spender.receiveApproval(msg.sender, _value, this, _extraData);
return true;
}
/* A contract attempts to get the coins */
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
if (balanceOf[_from] < _value) throw; // Check if the sender has enough
if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
if (_value > allowance[_from][msg.sender]) throw; // Check allowance
balanceOf[_from] -= _value; // Subtract from the sender
balanceOf[_to] += _value; // Add the same to the recipient
allowance[_from][msg.sender] -= _value;
Transfer(_from, _to, _value);
return true;
}
Si usted es el propietario actual de los tokens, puede llamar transfer(...)
para transferir su saldo a otra dirección.
Sin embargo, si desea transferir desde otra dirección, deberá llamar transferFrom(...)
y verificará la allowance[...][...]
estructura de datos para confirmar si esta transferencia ha sido aprobada.
Entonces, llame approveAndCall(...)
primero para aprobar su transferencia y debería poder llamar transferFrom(...)
para transferir sus tokens.
Cuando llamas transferFrom(...)
sin llamar primero approveAndCall(...)
, y aparece un error en la línea
if (_value > allowance[_from][msg.sender]) throw; // Check allowance
Este error aparecerá como un error de falta de gas en la billetera Ethereum.
Si se siente cómodo usando geth
, consulte ¿Cómo se puede detectar el estado de la transacción de un error lanzado cuando el gas puede ser exactamente el mismo que el gas utilizado para una transacción exitosa? para el siguiente código que se puede usar para verificar el motivo exacto de su error:
> var status = debug.traceTransaction("0xd23219e2ea10528b245deb9e47993cae2ffd3ffe9fc27aeb808e94fc4e75d37b")
undefined
> if (status.structLogs.length > 0) {
console.log(status.structLogs[status.structLogs.length-1].error)
}
"invalid jump destination (PUSH1) 2"
transferFrom()
sin llamar approveAndCall()
para poder entender el funcionamiento de debug.traceTransaction()
. Pero cuando ejecuté debug.traceTransaction
obtuve el siguiente error.var status=debug.traceTransaction("0x19aadd7de37594c8277dceb7e0ca5ca69fe88189fab84e17a32079da8afc50db") transaction 19aadd7de37594c8277dceb7e0ca5ca69fe88189fab84e17a32079da8afc50db not found at web3.js:3119:20 at web3.js:6023:15 at web3.js:4995:36 at <anonymous>:1:13
debug.traceTransaction(...)
con el hash de transacción resultante.transferFrom(..)
sin llamar approveAndCall(...)
a la consola geth, que me devolvió un hash tx. Lo pasé debug.traceTransaction(..)
pero obtuve el error de que no se encontró la transacción. Sé que mi transferencia no debería haberse hecho pero estaba esperandoinvalid jump destination (PUSH1) 2
eth.getTransaction(txHash)
y eth.getTransactionReceipt(txHash)
trabajar? Si lo hace, debug.traceTransaction(txHash)
debería funcionar. Si no es así, algo más está sucediendo. Comprueba si estás minando.Supongo que tengo la respuesta. No hay problema de poca gasolina en Mist. La función no se ejecutó porque mientras approveAndCall
llamamos estamos usando allowance[msg.sender][_spender] = _value;
pero en transferFrom()
la función estamos comparando el valor con allowance[_from][msg.sender])
. Lo modifiqué a if (_value > allowance[msg.sender][_from]) throw;
in transferFrom
y todo empezó a funcionar bien.
transfer(B, 10)
. O de la cuenta A, usted approveAndCall(B, 10, xxx)
y luego de la cuenta B, usted transferFrom(A, B, 10)
. Si está utilizando la cuenta A para ejecutar todas las funciones, tendría que hacer el cambio de lógica que hizo, pero eso anularía el propósito de permitir que la cuenta B llame a transferFrom(...)
.transferFrom(B,C,10)
transferir el monto aprobado por approveAndCall(B,10,xxx)
. Entonces, básicamente, B puede transferir a cualquier otra cuenta como C, la cantidad que fue aprobada por A.
ética
transferFrom
requiere más gas quetransfer
. Probaste aumentando el gas?Prashant Prabhakar Singh