¿Qué hace la parte de ensamblaje de esta función? (en recibir aprobación)

Estoy tratando de entender la approveAndCall()función, porque quiero permitir que los usuarios paguen por las funciones de mi contrato principal con los tokens asociados.

Estoy tratando de entender el ejemplo de este artículo . En la sección " aprobarAndCall() ", se muestran las siguientes funciones:

function approveAndCall(address _recipient,
                    uint256 _value,
                    bytes _extraData) {
  approve(_recipient, _value);
  TokenRecipient(_recipient).receiveApproval(msg.sender,
                                         _value,
                                         address(this),
                                         _extraData);
}

y

function receiveApproval(address _sender,
                         uint256 _value,
                         TokenContract _tokenContract,
                         bytes _extraData) {
  require(_tokenContract == tokenContract);
  require(tokenContract.transferFrom(_sender, address(this), 1));
  uint256 payloadSize;
  uint256 payload;
  assembly {
    payloadSize := mload(_extraData)
    payload := mload(add(_extraData, 0x20))
  }
  payload = payload >> 8*(32 - payloadSize);
  info[sender] = payload;
}

¿Qué hace la pieza de montaje en la segunda función?

La función de ejemplo almacena datos, por lo que toda la función real llamada a través del contrato de token es info[sender] = payload;. ¿Necesito una carga útil si la reemplazo con mi función que solo tiene argumentos "simples"? (No bytes, solo uints, direcciones, etc.) ¿Es necesario convertirlos a bytes?

(Podría hacer una pregunta diferente para obtener más detalles sobre approveAndCall()y recieveApproval, por ahora solo quiero entender esa parte de la carga útil).

Respuestas (1)

No, no necesita el código relacionado con la carga útil. Puede modificar la función y eliminar los bytes _exrtaData o simplemente pasar un valor aleatorio allí.

El reciveApprovalsolo necesita ejecutar transferFrom(address from, address to, uint value)para mover los tokens aprobados.

Para el montaje, bueno, parece ser muy específico. Puede ver aquí acerca de la instrucción mload.

mload(0xAB) carga los datos almacenados en la ubicación 0XAB. Las instrucciones parecen reflejar una aplicación particular en la que el contrato recibe una posición de memoria (_extraData) en la que se almacena información sobre el tamaño de los datos. Luego, en una posición _extraData + 0x20, están los datos que se modifican al realizar una operación de desplazamiento a la derecha y luego se almacena el resultado info(no tengo idea del propósito de esto)

espero que esto ayude

EDITAR después del comentario OP.

Si tendrá que recibir el comportamiento de Aprobación dependiendo de lo que el sujeto quiera hacer, puede pedirle que pase un parámetro adicional como este:

function receiveApproval(address _sender, uint256 _value, TokenContract _tokenContract, string param) public {
    require(tokenContract.transferFrom(_sender, address(this), _value));
    if (param == 'your_first_code'){
        //do something
    }
    if (param == 'your_second_code'){
        //do something
    } 
    // more conditional as functions you have
}
Gracias. Entonces, ¿en qué escribo receiveApproval? No puedo escribir instrucciones directamente, porque quiero poder llamar a diferentes funciones. ¿Tengo que escribir tantas approveAndCally receiveApprovalcomo funciones tengo?
Actualicé la respuesta. Podría tener solo una aprobación y llamada y solicitar un parámetro adicional que defina qué función debe ejecutarse en su contrato. Escribí un ejemplo de esto en la respuesta. Déjame saber como va.
Entonces, debido a que está en mi contrato de servicio y no en mi contrato de token, en el ifs puedo llamar a mi función directamente, ¿verdad? Comoif (function_code == 1) { function1(arg1, arg2); } else if (function_code == 2) { function2(arg3); }
Sí, esto ahora está en su contrato para que pueda llamar a las funciones directamente
Muchas cosas todavía están borrosas. ¿ Es recipientla dirección del contrato de servicio? Si no, ¿dónde pongo la dirección del contrato?
Si tenía una función que usaba msg.sender, ¿puedo seguir usándola o tengo que reemplazarla? (Supongo que en la receiveApproval()función, msg.senderse convierte en el token de contacto, ¿estoy en lo correcto?)
Sí, recipientes la dirección del contrato de servicio. Tenga en cuenta que esto creará una entrada de saldo en el contrato de token para el contrato de servicio. Entonces, su servicio de contrato debe tener una función para transferir los tokens si es necesario. Sí de nuevo, msg.sender ahora es el contrato de token, sin embargo, el remitente original está recibiendo aprobación como _sender
Si he respondido a su pregunta, por favor acéptela.
Sí, por supuesto, iba a. Solo quería hacer algunas preguntas complementarias porque no había entendido todo. Creo que tengo todo lo que necesito por ahora :)