Cómo detectar y aceptar mediante programación depósitos ETH y ERC20

Estoy buscando replicar la funcionalidad proporcionada por los intercambios de criptomonedas como Kraken y Poloniex cuando se trata de depositar ETH y tokens. A saber:

  • Los usuarios pueden generar y enviar fondos a una o más direcciones de depósito para ETH, EOS, OMG y otros tokens
  • El saldo del usuario relevante se actualiza cuando se detecta un depósito para un token o activo determinado
  • Los fondos enviados se almacenan en cuentas controladas por el intercambio.

¿Cuál es la mejor manera de lograr esto?


Tengo algunas ideas usando web3, pero no estoy seguro de que sean las soluciones más eficientes o escalables:

ETH

  • Para cada usuario que desee realizar un depósito, genere una dirección ETH y una clave privada mediante web3.eth.accounts.create(). Asigne la dirección generada al usuario y almacene la clave privada.
  • Úselo web3.eth.filterpara monitorear el último bloque en la cadena de bloques ETH. Haga coincidir las transacciones en el bloque con las direcciones de usuario almacenadas y actualice los saldos de los usuarios según corresponda.

Problemas con este enfoque : monitorear cada bloque y compararlo con las direcciones almacenadas es computacionalmente intensivo, especialmente si la cantidad de direcciones rastreadas se vuelve grande (cientos de miles). ¿Cómo puede esta escala?

Fichas ERC20

  • Para cada usuario que desee realizar un depósito, genere una dirección ETH y una clave privada mediante web3.eth.accounts.create(). Asigne la dirección generada al usuario y al token relevante, y almacene la clave privada.
  • Los contratos ERC20 emiten Transfereventos cuando ocurre una transacción en el contrato. Supervise este evento mediante web3.eth.filter. Cuando Transferocurre un evento para una dirección que existe en nuestra base de datos, actualice el saldo del usuario relevante en el intercambio con el monto transferido.

Problemas con este enfoque : ¿Cómo configura el filtro web3 para detectar Transfereventos solo del token en cuestión, no de toda la red? ¿Debo configurar 1 filtro por dirección o 1 filtro para todas las direcciones de usuario? ¿Cuántas direcciones puede rastrear el filtro web3 a la vez? ¿Qué pasa si las direcciones rastreadas se vuelven muy altas (cientos de miles)?


¿Es esta la forma correcta de pensar en todo esto o me estoy perdiendo algo? Me sorprende que no haya documentación más obvia sobre este flujo, ya que es bastante popular (en intercambios y cualquier otro servicio que acepte pagos en moneda digital).

Me pregunto cómo otros grandes sitios escalan Ethereum. Estoy a punto de crear un procesador de pago escalable para el módulo de pago interno de un servicio, pero tengo problemas como usted.
Vale la pena ver cómo lo hace EtherDelta: github.com/etherdelta (¿o tal vez simplemente crear una interfaz diferente además de sus contratos?) También consumen cerca del 15-20% de todo el gas en la red, por lo que el uso de gas es alto. sigue siendo un problema real.

Respuestas (3)

Probablemente sería algo como esto:

  1. El usuario quiere depositar un token en su intercambio

    1. Si es la primera vez que el usuario deposita ese token, esto ocurre:

      1. Genere una nueva clave/par de billetera en el lado del servidor
      2. Cifre la clave privada con un secreto/sal que solo conozca el servidor y almacene la clave privada cifrada y la dirección pública en su base de datos, junto con la información sobre el token para el que lo generaron y la identificación del usuario que lo inició.
    2. La próxima vez que presionen el botón de depósito para obtener la dirección de depósito, ya tendrá una dirección de depósito única para el usuario almacenada en la base de datos que puede presentar al usuario.

  2. El usuario deposita el token en la dirección de depósito

    1. En su servidor, tenga un trabajador que escuche todos los eventos de blockchain de ethereum. Verifique la dirección "a" de la transacción y compárela con las direcciones de depósito que ha almacenado. Cuando haya una coincidencia, envíe una notificación al usuario sobre el evento de depósito
  3. Llame al método balanceOf de los contratos de token pasándole la dirección de depósito que ha generado vinculada al usuario para mostrar el saldo del token de los usuarios en el intercambio. Solo muestra ese saldo de token en particular y nada más para esa dirección.

  4. El usuario quiere retirar su token

    1. Su intercambio tendrá un fondo de liquidez en espera. Tendrá que transferir algo de ETH de su grupo de liquidez a la dirección de depósito del usuario para pagar el costo del gas. Usted incluye este costo como parte de la tarifa de retiro. Ya tiene el privado cifrado almacenado, por lo que lo descifra con el secreto/sal, firma la transacción de transferencia y la transmite a la red ethereum.

Tengo los mismos pensamientos sobre la implementación. Y creo que la solución que propones es buena. Pero tanto para tokens ether como ERC20, no recomiendo monitorear la cadena de bloques.

Para el saldo de ether, llamará web3.eth.getBalancepasando la dirección para verificar el valor cuando el usuario ingrese a la página y coloque un temporizador de javascript para realizar la llamada cada 15 segundos, por ejemplo.

Y, lo mismo, con respecto a su pregunta para Ether equilibrar los saldos de los tokens ERC20: " ¿Cómo configura el filtro web3 para detectar eventos de transferencia solo del token en cuestión, no de toda la red? ". Creo que la mejor manera es llamar al contrato inteligente del token ERC20 para consultar el saldo de cada token. Esto es llamando al método: function balanceOf(address _owner)para cada token una vez que el usuario ingresa a la página. Y puede configurar un temporizador de javascript para actualizar los valores cada 15 segundos, por ejemplo.

Creo que esto es lo que hace Kraken, por ejemplo, ya que el contenido de la página se recarga cada dos segundos.

Tenga en cuenta que hará una llamada ajax para actualizar los valores de los saldos sin necesidad de actualizar toda la página. Además, la llamada balanceOfes gratuita ya que es un método de solo lectura que se ejecutará en su nodo conectado directamente sin ningún costo de gas.

Como recomiendas llamarlo function balanceOf(address _owner) no es una web3funcion
function balanceOf(address _owner)es un método dentro de cualquier token ERC20. Por lo tanto, puede llamar a este método desde web3cualquier token ERC20.
Creo que es una buena idea. Porque es extremadamente eficiente. De hecho, me ha dejado boquiabierto. Porque creo que la única forma de resolver este problema es como en cuestión. Muchísimas gracias.

Necesita una billetera HD (determinista jerárquica). Echa un vistazo al paquete npm de billetera HD de Truffle. Este enlace podría ayudar: https://www.npmjs.com/package/@truffle/hdwallet-provider

el enlace esta roto
HD significa billetera determinista jerárquica.