Encadenamiento de entrada/salida de transacciones sin procesar correlacionadas

Así que estoy en el proceso de implementar un módulo de pago basado en BTC donde por cada transacción a una cuenta que no sea de billetera, una fracción del monto terminará en una cuenta de caridad en una billetera externa no controlada por este módulo.

Una ronda típica para eso sería:

  • El módulo recibe el pago del usuario.
  • Reenvía el 90% (este porcentaje es arbitrario) del importe a su destino final (p.ej. un comercio)
  • Ahora tiene que reenviar el 10 % restante a la organización benéfica que elija el usuario.

En un nivel inferior, el sistema:

  • Recibe una transacción TxFromUserdel usuario con una cantidad de XBTC
  • Espera hasta que tenga 6 confirmaciones
  • Crea una nueva transacción sin procesar TxToMerchantpara reenviar el pago al comerciante
  • Crea otra transacción sin procesar TxToCharitypara reenviar la donación a la organización benéfica

Profundizando un poco más:

TxToMerchant:

  • Crear nueva transacción sin procesar
  • Agregar nueva entrada:TxFromUser
  • Agregar nueva salida: Dirección: Merchant's address, Cantidad: 0.9 * TxFromUser.Amount
  • Agregar nueva salida: Dirección: Module's own wallet address, Cantidad: 0.1 * TxFromUser.Amount
  • Calcular la tarifa de esta transacción
  • Reste la tarifa de la cantidad de la segunda salida
  • Crea el hexadecimal de la transacción y fírmalo con la tecla correcta
  • Envía la transacción y obtén su id:TxToMerchant.Id

TxToCharity:

  • Espere a que se confirme la transacción anterior (TxToMerchant)
  • Crear una nueva transacción sin procesar
  • Agregar nueva entrada: TxToMerchant(este será el cambio que solicitamos anteriormente)
  • Agregar nueva salida: Dirección: Charity's address, Cantidad: TxToMerchant.Amount = 0.1 * TxFromUser.Amount
  • Calcular la tarifa de esta transacción
  • Reste la tarifa del monto de salida de la transacción
  • Crea el hexadecimal de la transacción y fírmalo con la tecla correcta
  • Envía la transacción y obtén su id:TxToCharity.Id

Soy consciente del hecho de que podría fusionar estas dos transacciones (TxToMerchant y TxToCharity) en una sola transacción, sin embargo, por varias razones (requisito comercial), digamos que esto no es posible en este momento.

El problema que tengo con la implementación anterior es el siguiente: esperar a TxToMerchantque se confirme crea un retraso, ya que no puedo reenviar el pago a la organización benéfica TxToCharityhasta TxToMerchantque se confirme (¿o puedo, sin tener que preocuparme por la maleabilidad de la transacción, etc.?).

Además de eso, cuando llega el momento de agregar la TxToCharityentrada, tengo que hacer un seguimiento de cómo se devolvió el cambio TxToMerchanty luego obtener la transacción no gastada correcta (donde listunspent.txid = TxToMerchant.Id), ¿existe una forma más eficiente? y menos propensa a errores para hacer esto?

Supongamos que el usuario desea dividir el pago entre 2 comerciantes (o un comerciante y un servicio de carga, lo que tiene más sentido), por lo que en el ejemplo anterior habría 1 transacción más como TxToMerchant, llamémosla TxToFreightService. Digamos ahora que TxToMerchantfunciona bien y se confirma, pero TxToFreightServicefalla y nunca se confirma porque la entrada utilizada para ello fue un gasto doble, independientemente de las 6 confirmaciones que obtuvimos (para su entrada) antes de procesarlo. TxToCharitydepende de TxToFreightServiceporque el cambio solicitado en TxToFreightServiceservirá como entrada para TxToCharity. ¿Cómo trato este escenario programáticamente sin tener que realizar correcciones a mano cada vez que esto sucede?

Respuestas (1)

Creo que su proceso comercial está confundiendo el problema. Voy a suponer que el lado "comercial" de esto también quiere tomar una parte de la transacción o quiere retrasar el pago de la caridad y es por eso que esto se ha vuelto más complicado.

Hay una serie de consideraciones, entre ellas el hecho de que está utilizando una entrada para pagar al comerciante, y el cambio para pagar el flete, y el cambio de eso para pagar la caridad.

Lo que le preocupa es la incapacidad que ha incorporado para pagar a una de las partes debido a una transacción anterior, pero ese es su proceso comercial con la culpa, no el protocolo de Bitcoin.

También debe considerar el monto de pago mínimo y la eventual tarifa de red, ninguno de los cuales está basado en porcentajes.

Estos no se mencionan y, de hecho, al realizar dos (o posiblemente cuatro) transacciones, está incurriendo en hasta 4 veces las tarifas de transacción de la red bitcoin.

Esta es una de las principales razones por las que (desde una perspectiva comercial) no debe dividir las transacciones, es decir, es más costoso y ¿quién se hará cargo de los costos? ¿La caridad? el comerciante? ¿el flete? ¿Tú?

¿Puedo sugerir también que ha malinterpretado las "confirmaciones" como algo más que su transacción incluida en un bloque? Cuando un par solicita una transacción antes de incluirla en un bloque, el par valida la transacción de forma independiente y, si por alguna razón no es buena, se rechaza. Este NO es el proceso de "confirmación".

Todos los pares en efecto harán la misma validación de su transacción a medida que se propaga a través de la red (que, por cierto, es extremadamente rápido).

La confirmación, por otro lado, es cuando la transacción se ha incluido en un bloque, y la única vez que esto se convierte en un problema es si hay una bifurcación en la cadena de bloques. Pero incluso entonces, aún puede retransmitir una transacción si la "otra bifurcación" se convierte en la final, siempre que la base sobre la que se hizo sea buena.

El punto que quiero señalar es que está poniendo demasiado énfasis en las confirmaciones de las transacciones que usted mismo ha creado y luego espera hasta que alguien más confirme lo que ya sabe que es cierto, y esto parece completamente inútil.

¿Quizás pueda ampliar su pregunta para explicar las "razones comerciales"?

+1 Por el extenso análisis. Los pagos retrasados ​​​​a las organizaciones benéficas y los servicios de carga es donde se genera el flujo de ingresos. Soy plenamente consciente de que este no es un problema del protocolo de bitcoin, sin embargo, estoy seguro de que más empresarios que querrán hacer uso de las capacidades de crédito incorporadas enfrentarán los mismos problemas. Las tarifas están incluidas en nuestro modelo (aunque no se mencionan anteriormente) y los pagos en polvo no calificarán y se reenviarán intactos al comerciante.
Con respecto a las confirmaciones, también tuve la misma opinión que usted hasta que me topé con las publicaciones de algunos veteranos que dejaban en claro que no debemos asumir que solo porque creamos transacciones basadas en el cambio de una transacción anterior en la billetera, este cambio es seguro. gastar. Echa un vistazo aquí: reddit.com/r/Bitcoin/comments/1xm49o/…
@DougPeters no es que tenga que esperar para gastar transacciones anteriores en la billetera, es que está obligado a hacerlo. De lo contrario, no se validará ninguna transacción posterior. En una nota al margen, probablemente esté en terreno resbaladizo si cree que Bitcoin puede respaldar cualquier forma de crédito. Inmediatamente se encontrará frente a un competidor que ofrece distribución inmediata, simplemente porque puede hacerlo. Es un punto discutible, pero no me gustaría tratar de hacer que funcione;)
Con las transacciones sin procesar, puede enviar un pago que tiene como entrada un cambio no confirmado, por lo que no estoy realmente obligado a esperar, lo que pasa es que esto no es realmente una buena práctica. Bitcoin ya admite una forma de crédito con el uso de depósito en garantía. Decidí incluir esto en mi solicitud, pero de nuevo, centrémonos en las preguntas de la respuesta principal por ahora.