Supongamos que estamos construyendo un casino/mercado en línea y queremos recibir pagos.
Para ser escalable , seguro y tener una buena experiencia de usuario, nosotros:
listreceivedbyaddress
porque verificar regularmente cientos de miles de direcciones no es escalable. También una gran salida de RPC cuando un solo usuario realiza miles de depósitos.Absolutamente no podemos usar ninguna llamada RPC que enumere una lista completa y creciente de transacciones, como todas las transacciones para la billetera o todas las transacciones para la dirección.
Por lo tanto, la forma más sensata debería ser verificar listsinceblock
para analizar todas las transacciones "por bloque analizado" y unirse a los saldos de los usuarios por dirección de destino: aumente la cantidad del usuario en nuestro servicio en línea y marque este pago como "completado" para no contarlo por segunda vez . La forma más sencilla de marcar esta transacción como "ya resuelta" es almacenar su ID como "ya usado" en la misma transacción SQL que aumenta el saldo del usuario.
Pero escuché que es posible cambiar la identificación de la transacción en la cadena de bloques, entonces, ¿es segura esa solución?
¿Cómo puedo usar llamadas RPC para recibir pagos bloque tras bloque y qué datos puedo usar para marcar el pago como resuelto para estar a salvo de depósitos duplicados en un solo pago?
TL;DR, ¿cómo reciben pagos los "grandes jugadores" como Cryptsy?
Use Bitcoin Core en modo servidor y use sus funciones de notificación:
server=1
blocknotify = curl\yoururl
walletnotify = curl\yoururl
Configúrelos para hacer una llamada a su aplicación.
De esta manera, no realizará costosas llamadas RPC a Bitcoin Core. Solo estarás recibiendo notificaciones de operaciones que el propio Bitcoin Core ya esté realizando. Por lo tanto, no traerá ninguna carga adicional a Bitcoin Core. Estará limitado por su propia escalabilidad.
¿Cómo reciben los pagos los "grandes jugadores" como Cryptsy?
La mayoría de los grandes jugadores confían en la escalabilidad de Bitcoin Core que se ejecuta en modo servidor sin traerle una carga adicional, hasta donde yo sé.
Pero escuché que es posible cambiar la identificación de la transacción en la cadena de bloques, entonces, ¿es segura esa solución?
No después de haber recibido una confirmación. Entonces, el método que describió funciona si espera la llamada blocknotify para un TX antes de actualizar el saldo de sus usuarios.
Cryptsy está generando una nueva dirección por usuario. Una vez generado, sigue siendo el mismo, por lo que no hay riesgo de depositarlo en la "dirección anterior". Esto es escalable y también más fácil de asociar depósitos al usuario correcto independientemente de la dirección de envío.
Sé que es tarde para responder, pero proporciono mi solución que maneja la mayoría de los riesgos.
En primer lugar, prefiero generar una nueva dirección para cualquier momento en que el usuario quiera depositar; Pero si la condición no lo permite, ¡hay otra solución!
Solución: Hay una getreceivedbyaddress
API que da la cantidad total de Bitcoins recibidos para una dirección específica. Uso esto y una base de datos para rastrear los depósitos de los usuarios.
Aquí está la forma en que lo rastreé:
var totalReceived = (RPC request including the address in params field)
var lastDeposit = (DB query for fetching the user's last deposit's data)
if(lastDeposit.amount < totalReceived) {
// insert a new deposit record for user
// record includes the following fields:
// 1. userId (Obvious)
// 2. amount
// 3. diff
// 4. ts (for sorting, etc)
insertNewDeposit(userId: userId, amount: totalReceived, diff: totalReceived - lastDeposit.amount)
}
// fetch the user's balance from db
var currentBalance = (db query)
// calculate the user's new balance (based on the new deposit)
var newBalance = currentBalance + (currenctBalance - lastDeposit.amount)
// update the user's balance in db
updateBalance(userId: userId, balance: newBalance)
Debe usar este método antes que cualquier otro que pueda requerir el último saldo de una dirección (usuario).
Esto siempre rastreará el saldo de una dirección específica (usuario) incluso si el servicio web se cae; justo después de que su servicio web esté en línea, cuando el usuario solicite algo relacionado con el saldo, ¡este método se actualizará y realizará un seguimiento del saldo!
¡El código podría haber sido más optimizado!
Saludos :)
Emre Kenci