Cómo enviar una transacción de token inteligente de una cuenta a otra usando la interfaz JSON RPC

Me gustaría enviar cantidades de un token creado de una dirección a otra. Me gustaría usar eth_sendTransaction:

eth_sendTransaction

Creates new message call transaction or a contract creation, if the data field contains code.
Parameters

    Object - The transaction object

    from: DATA, 20 Bytes - The address the transaction is send from.
    to: DATA, 20 Bytes - (optional when creating new contract) The address the transaction is directed to.
    gas: QUANTITY - (optional, default: 90000) Integer of the gas provided for the transaction execution. It will return unused gas.
    gasPrice: QUANTITY - (optional, default: To-Be-Determined) Integer of the gasPrice used for each paid gas
    value: QUANTITY - (optional) Integer of the value send with this transaction
    data: DATA - The compiled code of a contract OR the hash of the invoked method signature and encoded parameters. For details see Ethereum Contract ABI
    nonce: QUANTITY - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce.

params: [{
  "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
  "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
  "gas": "0x76c0", // 30400,
  "gasPrice": "0x9184e72a000", // 10000000000000
  "value": "0x9184e72a", // 2441406250
  "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
}]

The Token uses a basic ERC20 compliant function:
    /* Send coins */
    function transfer(address _to, uint256 _value) {
        if (_to == 0x0) throw;                               // Prevent transfer to 0x0 address. Use burn() instead
        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
    }

Algunas otras preguntas aquí están cerca y ayudan con eth_call, pero no para enviar transacciones.

Cómo llamar a un método de contrato usando la API eth_call JSON-RPC

¿Cómo puedo recuperar el saldo del token Augur (REP) de mi cuenta a través de JSON-RPC?

Veo que se supone que debe cifrar el nombre del método, pero realmente no tengo idea de cómo construir los parámetros para enviar a la transacción, ya que es como agregar los primeros 4 bytes de la firma hash, luego agregar una dirección rellenada con cero a la izquierda.

Ayude a crear la llamada JSON RPC para una transacción de token inteligente.

Si hay una manera fácil de hacer esto en web3.py, también sería útil.

Respuestas (1)

Si hay una manera fácil de hacer esto en web3.py, también sería útil.

Puede crear un objeto de contrato utilizando un ABI de token EIP20 estándar y luego llamarlo utilizando los métodos generados, como:

from web3.contract import ConciseContract

token = web3.eth.contract(
  token_contract_address,
  abi=EIP20_ABI,
  ContractFactoryClass=ConciseContract,
)

token.transfer(
  "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
  2441406250,
  transact={
    "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
    "gasPrice": Web3.toWei(4, 'gwei'),
  }
)

Notas al margen:

  1. La transacción del ejemplo en cuestión envía ether al contrato de token. Supongo que en realidad no desea enviar 2441406250 wei en éter. La solución anterior envía 2441406250 tokens en su lugar.
  2. La transacción del ejemplo en cuestión interactúa con un contrato en "0xd46e8dd67c5d32be8058bb8eb970870f07244567". La solución anterior envía los tokens a esa dirección en su lugar. tienes que rellenartoken_contract_address
  3. Bajé el precio de la gasolina de 10 Terawei exorbitantes a 4 Gigawei, normalmente suficientes.
  4. No estoy seguro de si 30400 es suficiente gasolina, así que eliminé el parámetro. web3.py te lo estimará.