Author

Topic: Realizar envio a 2 cuentas bitcoin en python (Read 1048 times)

legendary
Activity: 1623
Merit: 1608
pdta: no me arroja ningún error en particular solo el mensaje (### ERROR - SWEEP NO REALIZADO ###) pero las direcciones y el wif son correctos ademas tienen saldo.

De primeras, estaría bien que obtuvieras el error específico que devuelve el programa.

Para Python 2.5 y anteriores modifica el código así:

Code:
except Exception,e: 
    print str(e)
    print ('### ERROR - SWEEP NO REALIZADO ###')

Para Python 2.6 y 3.x, modifica el código así:
Code:
except Exception as e: 
    print(e)
    print ('### ERROR - SWEEP NO REALIZADO ###')

Y si con eso no es suficiente, pues ya ir poniendo logs en los sitios críticos hasta dar con el problema. Vamos, la típica vida del programmer.  Smiley
newbie
Activity: 3
Merit: 0

Agradezco tu solución, pero lo que propones me es imposible ya que no solo se necesita tener la wallet de Bitcoin core y ya, si no que también implica descargar todo el nodo para que esta funcione y son mas de 200 GB y esto no puedo hacerlo.

Si me equivoco te agradezco me lo hagas saber y aclares mis equivocaciones.

Gracias de antemano.

Siempre puedes instalar un cliente de core en la version "prune", que no ocupa tantisimo espacio, pero te imposibilita utilizar los comandos -rescan y -txindex

Basicamente tienes que escribir lo siguiente en el fichero de configuración de Core

Code:
prune=N

Donde prune es el tamaño en MiB que quieres que la cadena descargada ocupe

Tambien puedes usar este comando como parametro de inicio en lugar de editar el fichero de configuración

Code:
"C:\Users\\AppData\Roaming\Bitcoin\bitcoin-qt.exe" -prune=550

Dejo aqui la guia de referencia por si he acortado demasiado o traducido algo mal....

Gracias por tu ayuda amigo, pero no me sirve tu solución ya que necesito estar escaneando constantemente la wallet.
copper member
Activity: 1652
Merit: 1325
I'm sometimes known as "miniadmin"

Agradezco tu solución, pero lo que propones me es imposible ya que no solo se necesita tener la wallet de Bitcoin core y ya, si no que también implica descargar todo el nodo para que esta funcione y son mas de 200 GB y esto no puedo hacerlo.

Si me equivoco te agradezco me lo hagas saber y aclares mis equivocaciones.

Gracias de antemano.

Siempre puedes instalar un cliente de core en la version "prune", que no ocupa tantisimo espacio, pero te imposibilita utilizar los comandos -rescan y -txindex

Basicamente tienes que escribir lo siguiente en el fichero de configuración de Core

Code:
prune=N

Donde prune es el tamaño en MiB que quieres que la cadena descargada ocupe

Tambien puedes usar este comando como parametro de inicio en lugar de editar el fichero de configuración

Code:
"C:\Users\\AppData\Roaming\Bitcoin\bitcoin-qt.exe" -prune=550

Dejo aqui la guia de referencia por si he acortado demasiado o traducido algo mal....
newbie
Activity: 3
Merit: 0
...
Saludos compañero, estoy pasando por lo mismo que pasaste hace ya un tiempo, necesito barrer todo el saldo de una dirección Bitcoin y ademas necesito poder enviar transacciones solo de una parte ejemplo: saldo en la dirección 1 BTC enviar solo x valor o x % no todo el saldo me hice entender ? xD.

Estuve probando el código que dejaste en este post pero por mas que lo he intentado modificando el código, instalando diferentes versiones de las librerías usadas (ya que algunas han sido actualizadas) y de mas no he podido hacer correr tu script, tanto el que barre todo el saldo como el de las transacciones, me seria de gran ayuda si pudieras detallar un poco sobre las versiones de las librerías que usaste o ayudándome de alguna otra manera con el fin de poder correr el script me seria de gran utilidad y estaría agradecido eternamente contigo  Grin Grin

pdta: no me arroja ningún error en particular solo el mensaje (### ERROR - SWEEP NO REALIZADO ###) pero las direcciones y el wif son correctos ademas tienen saldo.


Saludos y gracias de antemano.

Buen día colega y bienvenido al foro, me imagino que llegaste a este post a través de google ya que es una publicación del 2016...

Sobre el código parece ser algo viejo, pero encontrarás la información en la siguiente liga:

https://pypi.org/project/python-bitcointx/

Lo que yo te recomendaría es hacer un script en bash y manipular el core directo de linea de comandos, con bitcoin-cli puedes construir las transacciones y enviarlas. Para que te des una idea de como se hace esto dejo referencia a un post que realicé el año pasado:

https://bitcointalksearch.org/topic/manipulacion-de-las-transacciones-de-bitcoin-5169506


Agradezco tu solución, pero lo que propones me es imposible ya que no solo se necesita tener la wallet de Bitcoin core y ya, si no que también implica descargar todo el nodo para que esta funcione y son mas de 200 GB y esto no puedo hacerlo.

Si me equivoco te agradezco me lo hagas saber y aclares mis equivocaciones.

Gracias de antemano.
legendary
Activity: 3346
Merit: 3130
...
Saludos compañero, estoy pasando por lo mismo que pasaste hace ya un tiempo, necesito barrer todo el saldo de una dirección Bitcoin y ademas necesito poder enviar transacciones solo de una parte ejemplo: saldo en la dirección 1 BTC enviar solo x valor o x % no todo el saldo me hice entender ? xD.

Estuve probando el código que dejaste en este post pero por mas que lo he intentado modificando el código, instalando diferentes versiones de las librerías usadas (ya que algunas han sido actualizadas) y de mas no he podido hacer correr tu script, tanto el que barre todo el saldo como el de las transacciones, me seria de gran ayuda si pudieras detallar un poco sobre las versiones de las librerías que usaste o ayudándome de alguna otra manera con el fin de poder correr el script me seria de gran utilidad y estaría agradecido eternamente contigo  Grin Grin

pdta: no me arroja ningún error en particular solo el mensaje (### ERROR - SWEEP NO REALIZADO ###) pero las direcciones y el wif son correctos ademas tienen saldo.


Saludos y gracias de antemano.

Buen día colega y bienvenido al foro, me imagino que llegaste a este post a través de google ya que es una publicación del 2016...

Sobre el código parece ser algo viejo, pero encontrarás la información en la siguiente liga:

https://pypi.org/project/python-bitcointx/

Lo que yo te recomendaría es hacer un script en bash y manipular el core directo de linea de comandos, con bitcoin-cli puedes construir las transacciones y enviarlas. Para que te des una idea de como se hace esto dejo referencia a un post que realicé el año pasado:

https://bitcointalksearch.org/topic/manipulacion-de-las-transacciones-de-bitcoin-5169506
newbie
Activity: 3
Merit: 0
Buenas a todos.
Estoy experimentando con las diferentes librerías bitcoin existentes para python, y actualmente uso pycoin.
Ahora estoy mirando de realizar una transacción a 2 direcciones bitcoin.

Me explico:

- Dirección Original tiene 1 btc. Quiero enviar 0.3 btc a la dirección A y 0.7 btc a la dirección B (Evidentemente menos las comisiones)

Mirando las diferentes instrucciones que tiene pycon, ya he hecho varias pruebas exitosas para pasar todo lo que hay en una dirección, a la otra, pero lo que no consigo es enviar a 2 billeteras, o lo que es lo mismo, en lugar de enviar el 100% del saldo, enviar, por poner un ejemplo, simplemente el 40%.

Pongo un ejemplo de como hago el envío total, por si alguien me puede ayudar:

Code:
from pycoin.key import Key
from pycoin.key.validate import is_address_valid, is_wif_valid
from pycoin.services import spendables_for_address
from pycoin.tx.tx_utils import create_signed_tx


def hacer_sweep(src_address,wif, dst_address):

spendables = spendables_for_address(src_address,"BTC")

key = Key.from_text(wif)
if src_address not in (key.address(use_uncompressed=False), key.address(use_uncompressed=True)):
print("** WIF NO CORRESPONDE A %s" % src_address)
print("EL EXPONENTE SECRETO ES %d" % key.secret_exponent())

try:
tx = create_signed_tx(spendables, payables=[dst_address], wifs=[wif], fee= 'standard')

pushtx(tx.as_hex())
print ('### SWEEP REALIZADO CORRECTAMENTE ###')
return 1
except:
print ('### ERROR - SWEEP NO REALIZADO ###')
return -1

s = hacer_sweep(DIRECCION BTC ORIGEN, PRIVADA ORIGEN, DIRECCION BTC DESTINO)

He probado de poner la cantidad a enviar de la siguiente manera:

tx = create_signed_tx(50000, payables=[dst_address], wifs=[wif], fee= 'standard')

pero me ha generado una operación que creo que se ha ido directamente al minero... :-(

¿Alguna idea?

Saludos compañero, estoy pasando por lo mismo que pasaste hace ya un tiempo, necesito barrer todo el saldo de una dirección Bitcoin y ademas necesito poder enviar transacciones solo de una parte ejemplo: saldo en la dirección 1 BTC enviar solo x valor o x % no todo el saldo me hice entender ? xD.

Estuve probando el código que dejaste en este post pero por mas que lo he intentado modificando el código, instalando diferentes versiones de las librerías usadas (ya que algunas han sido actualizadas) y de mas no he podido hacer correr tu script, tanto el que barre todo el saldo como el de las transacciones, me seria de gran ayuda si pudieras detallar un poco sobre las versiones de las librerías que usaste o ayudándome de alguna otra manera con el fin de poder correr el script me seria de gran utilidad y estaría agradecido eternamente contigo  Grin Grin

pdta: no me arroja ningún error en particular solo el mensaje (### ERROR - SWEEP NO REALIZADO ###) pero las direcciones y el wif son correctos ademas tienen saldo.


Saludos y gracias de antemano.
legendary
Activity: 1623
Merit: 1608
He encontrado esta fórmula, pero si la aplico el fee me sale muy alto:

Tamaño = (148 *inputs) + (34 * outputs) + 10

En el caso de hacer una transacción de una dirección bitcoin a 2 sería: 148 + 68 + 10 = 226 bytes

Según la API de: https://bitcoinfees.21.co/api/v1/fees/recommended la fee ideal para una transacción rápida sería de 60 satoshis/byte

En nuestro caso: 13560 satoshis

¿Un poco alta no?

Yo la operación la he hecho con 1000 y ha funcionado correctamente.

¿Lo estoy calculando mal?

Lo estás calculando bien. Lo que ocurre es que https://bitcoinfees.21.co/api/v1/fees/recommended está devolviendo valores especialmente conservadores (altos). Ahora mismo devuelve:
{"fastestFee":60,"halfHourFee":60,"hourFee":40}

mientras que Bitcoin Core está dando un estimatefee en 3 bloques de 35116 satoshis/KB, de 6 bloques de 22000 satoshis/KB, y en 24 bloques de 15104 satoshis/KB.
También hay que tener en cuenta que bitcoinfees.21.co evalúa horas mientras que Bitcoin Core evalúa bloques. Una hora no es lo mismo que 6 bloques.
hero member
Activity: 865
Merit: 1006
He encontrado esta fórmula, pero si la aplico el fee me sale muy alto:

Tamaño = (148 *inputs) + (34 * outputs) + 10

En el caso de hacer una transacción de una dirección bitcoin a 2 sería: 148 + 68 + 10 = 226 bytes

Según la API de: https://bitcoinfees.21.co/api/v1/fees/recommended la fee ideal para una transacción rápida sería de 60 satoshis/byte

En nuestro caso: 13560 satoshis

¿Un poco alta no?

Yo la operación la he hecho con 1000 y ha funcionado correctamente.

¿Lo estoy calculando mal?
hero member
Activity: 865
Merit: 1006
Inicialmente no se trata de una aplicación web, por lo que el tema de los callbacks, como muy bien dices, no tendría mucho sentido aquí.

Me gustaría afinar aún más el programa, y en lugar de lanzar cada vez una llamada a la función que hace la operación con un fee diferente (incrementándolo en 100 satoshis cada vez) calculara el fee "ideal" antes de hacer la operación.

Encontré esta API: https://bitcoinfees.21.co

Tiene buena pinta, pero necesito saber el tamaño de la operación que lanzo ... y ahí me pierdo

¿Alguna idea?

Saludos
legendary
Activity: 1623
Merit: 1608
El código funciona y nada que objetar sobre la parte desarrollada en pycoin. Sin embargo, si el código va en una aplicación web, sería mejor gestionar las confirmaciones con el "receive payments API" de blockchain.info en vez de consultar activamente cada minuto.

La principal ventaja del "receive payments API" es que trabajas con "callbacks", que es lo normal con eventos asíncronos. Más aún en este caso, en el que la llegada del evento (6 confirmaciones) puede tardar más de una hora.

Es cierto que si la web no tiene un tráfico intenso, la ventaja del "receive payments API" no es tan evidente y quizás no merezca la pena el cambio, pero ahí dejo la sugerencia. (Si no es una web, seguramente tampoco sería práctico porque requeriría abrir un puerto para recibir los "callbacks" ).
hero member
Activity: 865
Merit: 1006
Bueno, ya he conseguido lo que me proponía, hacer una transferencia bitcoin a 2 direcciones diferentes, con importes diferentes y mediante código (python), sin utilizar ninguna billetera.

Pongo el código usado por si a alguien le puede servir también.

MUCHO CUIDADO, antes de utilizarlo, probar con cantidades pequeñas, y en caso de duda... NO UTILIZARLO.
En mis muchas pruebas he "perdido satoshis" en 2 ocasiones.

Code:
from bitcoin import *
import os
import time
import requests
import json
from pycoin.key import Key
from pycoin.key.validate import is_address_valid, is_wif_valid
from pycoin.services import spendables_for_address
from pycoin.tx.tx_utils import create_signed_tx

def hacer_transf(src_address, wif, dst_address1, importe1, dst_address2, importe2):

try:
spendables = spendables_for_address(src_address,"BTC")
tx = create_signed_tx(spendables, payables=[(dst_address1, importe1), (dst_address2, importe2)], wifs=[wif], fee= 'standard')
pushtx(tx.as_hex())
print ('### TRANSFERENCIA REALIZADA CORRECTAMENTE ###')
return 1
except:
print ('### ERROR - TRANSFERENCIA NO REALIZADA - ESPERANDO 60 SEGUNDOS ###')
return -1

# PROGRAMA PRINCIPAL #########################

addr = "1SSSSSSSSSSSSSSSSSSSSSSSS" # Direccion Origen de donde salen los fondos
wif = "5FFFFGGFDSDFGHHJJKKKLLLLKK" # Clave Privada en formato WIF de la direccion Origen
dst_address1 = "1ZZZZZZZZZZZZZZZZZZZZZZZZZ" # Direccion destino 1
dst_address2 = "1AAAAAAAAAAAAAAAAAAAAAAAAA" # Direccion destino 2
fee = 1000
confirmaciones = 6 #Numero de confirmaciones antes de empezar la operacion de tranferencia

recibido = False
pausaOk = 60
while not recibido:
try:
request = 'https://blockchain.info/q/addressbalance/' + addr + '?confirmations=' + str(confirmaciones)
response = requests.get(request)
content = response.json()
content = int(content)
if content > 0:
recibido = True
else:
print('ESPERANDO ' + str(pausaOk) + ' Seg. PARA TENER 6 CONFIRMACIONES')
time.sleep(pausaOk)
except KeyboardInterrupt:
exit()
except:
print ('### ERROR DE CONEXION - ESPERANDO 10 Seg.###')
recibido = False
time.sleep(10)

print ('SALDO DE LA CUENTA : ' + str(content))

print ('INICIANDO TRANSFERENCIA')


st = -1
while st == -1:
importe1 = int((content * 0.3)-(fee/2)) #Transferencia 1, 30% del Saldo menos comisiones
importe2 = int((content * 0.7)-(fee/2)) #Transferencia 2, 70% del Saldo menos comisiones
st = hacer_transf(addr, wif, dst_address1, importe1, dst_address2, importe2)

if st == -1:
fee += 100
if fee >= importe1 or fee >= importe2:
print ('### ERROR SALDO INSUFICIENTE PARA REALIZAR TRANSFERENCIA ###')
exit()
time.sleep(10)

print ('### PROCESO FINALIZADO CON EXITO ###')
hero member
Activity: 865
Merit: 1006
Por ejemplo:

tx = create_signed_tx([50000,20000], payables=['DIRECCION1','DIRECCION2'], wifs=[wif], fee= 'standard')  Huh?

Seria algo así?

No lo he probado. Creo que sería así, aunque puedo estar equivocado:
Code:
tx = create_signed_tx(['DIR_ORIGEN1','DIR_ORIGEN2'], payables=[('DIR_DESTINO1', satoshisEnviar1), ('DIR_DESTINO2', satoshisEnviar2), ('DIR_DESTINO3', satoshisEnviar3)], wifs=['wifOrigen1', 'wifOrigen2'], fee= 'standard') 

o bien

Code:
tx = create_signed_tx(['DIR_ORIGEN1','DIR_ORIGEN2'], payables=[('DIR_DESTINO1', satoshisEnviar1), ('DIR_DESTINO2', satoshisEnviar2), ('DIR_DESTINO3', satoshisEnviar3)], wifs=['wifOrigen1', 'wifOrigen2'], fee=7000) 

Después de revisar un poco esta función de utilidad create_signed_tx, la ventaja que le veo es que no tienes el riesgo de que termines pagando una comisión demasiado alta al dar un valor demasiado alto la fórmula: suma(outputs)-suma(inputs) porque la API ya hace sus cálculos para pagar la comisión que indicas como parámetro.

Lo que me gusta menos es que al pasar como primer parámetros las direcciones de origen con fondos, la aplicación necesita conectarse con una API externa (Insight) para obtener los pares txid-vout a gastar. Aunque puede que muchos desarrolladores lo prefieran así.

siguiendo este ejemplo que pones, en mi caso seria:
Code:
tx = create_signed_tx(['DIR_ORIGEN1'], payables=[('DIR_DESTINO1', satoshisEnviar1), ('DIR_DESTINO2', satoshisEnviar2)], wifs=['wifOrigen1'], fee= 'standard')

Lo probaré y ya pondré por aquí los resultados.

Un saludo
legendary
Activity: 1623
Merit: 1608
Por ejemplo:

tx = create_signed_tx([50000,20000], payables=['DIRECCION1','DIRECCION2'], wifs=[wif], fee= 'standard')  Huh?

Seria algo así?

No lo he probado. Creo que sería así, aunque puedo estar equivocado:
Code:
tx = create_signed_tx(['DIR_ORIGEN1','DIR_ORIGEN2'], payables=[('DIR_DESTINO1', satoshisEnviar1), ('DIR_DESTINO2', satoshisEnviar2), ('DIR_DESTINO3', satoshisEnviar3)], wifs=['wifOrigen1', 'wifOrigen2'], fee= 'standard') 

o bien

Code:
tx = create_signed_tx(['DIR_ORIGEN1','DIR_ORIGEN2'], payables=[('DIR_DESTINO1', satoshisEnviar1), ('DIR_DESTINO2', satoshisEnviar2), ('DIR_DESTINO3', satoshisEnviar3)], wifs=['wifOrigen1', 'wifOrigen2'], fee=7000) 

Después de revisar un poco esta función de utilidad create_signed_tx, la ventaja que le veo es que no tienes el riesgo de que termines pagando una comisión demasiado alta al dar un valor demasiado alto la fórmula: suma(outputs)-suma(inputs) porque la API ya hace sus cálculos para pagar la comisión que indicas como parámetro.

Lo que me gusta menos es que al pasar como primer parámetros las direcciones de origen con fondos, la aplicación necesita conectarse con una API externa (Insight) para obtener los pares txid-vout a gastar. Aunque puede que muchos desarrolladores lo prefieran así.
hero member
Activity: 865
Merit: 1006
pero me ha generado una operación que creo que se ha ido directamente al minero... :-(

Claro. Concepto importante: Las comisiones al minero es la suma de outputs finales menos la suma de inputs. Es decir, si tomas un UTXO de 1 BTC y solo generas un output de 0.2 BTC, ¡ estás dando al minero 0.8 BTC !

Tienes que crear dos outputs finales en código. El de 0.2 BTC y otro a la propia dirección enviante de 0.7999 BTC, por ejemplo. Esos 0.7999 BTC sería el cambio ("change"). Entonces, la comisión a los mineros sería la adecuada, de solo 0.0001 BTC.

Lo que no veo es como poner los importes diferentes:

Por ejemplo:

tx = create_signed_tx([50000,20000], payables=['DIRECCION1','DIRECCION2'], wifs=[wif], fee= 'standard')  Huh?

Seria algo así?
legendary
Activity: 1623
Merit: 1608
pero me ha generado una operación que creo que se ha ido directamente al minero... :-(

Claro. Concepto importante: Las comisiones al minero es la suma de outputs finales menos la suma de inputs. Es decir, si tomas un UTXO de 1 BTC y solo generas un output de 0.2 BTC, ¡ estás dando al minero 0.8 BTC !

Tienes que crear dos outputs finales en código. El de 0.2 BTC y otro a la propia dirección enviante de 0.7999 BTC, por ejemplo. Esos 0.7999 BTC sería el cambio ("change"). Entonces, la comisión a los mineros sería la adecuada, de solo 0.0001 BTC.
hero member
Activity: 865
Merit: 1006
Buenas a todos.
Estoy experimentando con las diferentes librerías bitcoin existentes para python, y actualmente uso pycoin.
Ahora estoy mirando de realizar una transacción a 2 direcciones bitcoin.

Me explico:

- Dirección Original tiene 1 btc. Quiero enviar 0.3 btc a la dirección A y 0.7 btc a la dirección B (Evidentemente menos las comisiones)

Mirando las diferentes instrucciones que tiene pycon, ya he hecho varias pruebas exitosas para pasar todo lo que hay en una dirección, a la otra, pero lo que no consigo es enviar a 2 billeteras, o lo que es lo mismo, en lugar de enviar el 100% del saldo, enviar, por poner un ejemplo, simplemente el 40%.

Pongo un ejemplo de como hago el envío total, por si alguien me puede ayudar:

Code:
from pycoin.key import Key
from pycoin.key.validate import is_address_valid, is_wif_valid
from pycoin.services import spendables_for_address
from pycoin.tx.tx_utils import create_signed_tx


def hacer_sweep(src_address,wif, dst_address):

spendables = spendables_for_address(src_address,"BTC")

key = Key.from_text(wif)
if src_address not in (key.address(use_uncompressed=False), key.address(use_uncompressed=True)):
print("** WIF NO CORRESPONDE A %s" % src_address)
print("EL EXPONENTE SECRETO ES %d" % key.secret_exponent())

try:
tx = create_signed_tx(spendables, payables=[dst_address], wifs=[wif], fee= 'standard')

pushtx(tx.as_hex())
print ('### SWEEP REALIZADO CORRECTAMENTE ###')
return 1
except:
print ('### ERROR - SWEEP NO REALIZADO ###')
return -1

s = hacer_sweep(DIRECCION BTC ORIGEN, PRIVADA ORIGEN, DIRECCION BTC DESTINO)

He probado de poner la cantidad a enviar de la siguiente manera:

tx = create_signed_tx(50000, payables=[dst_address], wifs=[wif], fee= 'standard')

pero me ha generado una operación que creo que se ha ido directamente al minero... :-(

¿Alguna idea?
Jump to: