Skip to content
This repository was archived by the owner on Mar 26, 2025. It is now read-only.

Adds Python 3 compatibility #67

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions pybitcoin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,8 @@
:license: MIT, see LICENSE for more details.
"""

import services
from .services import *

import transactions
from .transactions import *

import passphrases
from .passphrases import create_passphrase
from .passphrases.legacy import (
random_160bit_passphrase, random_256bit_passphrase
Expand Down
7 changes: 6 additions & 1 deletion pybitcoin/formatcheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,19 @@
import os
import re
import random
import sys
import binascii
from utilitybelt import is_int, is_hex

from .b58check import is_b58check


def is_secret_exponent(val, curve_order):
return (isinstance(val, (int, long)) and val >= 1 and val < curve_order)
number_types = [int]
if sys.version_info.major < 3:
number_types.append(long)

return (isinstance(val, tuple(number_types)) and val >= 1 and val < curve_order)


def is_256bit_hex_string(val):
Expand Down
38 changes: 21 additions & 17 deletions pybitcoin/rpc/namecoind_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,38 +16,42 @@
from .config import NAMECOIND_USE_HTTPS, VALUE_MAX_LIMIT

import ssl
import httplib

create_ssl_authproxy = False
try:
from httplib import HTTPSConnection
except ImportError:
from http.client import HTTPSConnection

create_ssl_authproxy = False
do_wrap_socket = False

if hasattr( ssl, "_create_unverified_context" ):
#opt-out for verifying self-signed certificates (typically used in namecoin/bitcoind)
ssl._create_default_https_context = ssl._create_unverified_context
create_ssl_authproxy = True
create_ssl_authproxy = True

if not hasattr( ssl, "create_default_context" ):
create_ssl_authproxy = False
do_wrap_socket = True


class NamecoindConnection( httplib.HTTPSConnection ):
class NamecoindConnection(HTTPSConnection):
"""
Wrapped SSL connection, if we can't use SSLContext.
"""

def __init__(self, host, port, timeout=None ):
httplib.HTTPSConnection.__init__(self, host, port )

HTTPSConnection.__init__(self, host, port )
self.timeout = timeout

def connect( self ):

sock = socket.create_connection((self.host, self.port), self.timeout)
if self._tunnel_host:
self.sock = sock
self._tunnel()

self.sock = ssl.wrap_socket( sock, cert_reqs=ssl.CERT_NONE )


Expand All @@ -59,7 +63,7 @@ def __init__(self, server=NAMECOIND_SERVER, port=NAMECOIND_PORT,
passphrase=NAMECOIND_WALLET_PASSPHRASE):

global create_ssl_authproxy, do_wrap_socket

if use_https:
http_string = 'https://'
else:
Expand All @@ -69,23 +73,23 @@ def __init__(self, server=NAMECOIND_SERVER, port=NAMECOIND_PORT,

self.passphrase = passphrase
self.server = server

if do_wrap_socket:
# ssl._create_unverified_context and ssl.create_default_context are not supported.
# wrap the socket directly
# wrap the socket directly
connection = NamecoindConnection( server, int(port) )
self.obj = AuthServiceProxy(authproxy_config_uri, connection=connection)

elif create_ssl_authproxy:
# ssl has _create_unverified_context, so we're good to go
# ssl has _create_unverified_context, so we're good to go
self.obj = AuthServiceProxy(authproxy_config_uri)

else:
# have to set up an unverified context ourselves
# have to set up an unverified context ourselves
ssl_ctx = ssl.create_default_context()
ssl_ctx.check_hostname = False
ssl_ctx.verify_mode = ssl.CERT_NONE
connection = httplib.HTTPSConnection( server, int(port), context=ssl_ctx )
connection = HTTPSConnection( server, int(port), context=ssl_ctx )
self.obj = AuthServiceProxy(authproxy_config_uri, connection=connection)


Expand Down
13 changes: 4 additions & 9 deletions pybitcoin/services/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,7 @@
"""

from .blockchain_client import BlockchainClient
from blockcypher import BlockcypherClient
from blockchain_info import BlockchainInfoClient
from chain_com import ChainComClient
from bitcoind import BitcoindClient, create_bitcoind_service_proxy

import blockcypher
import blockchain_info
import chain_com
import bitcoind
from .blockcypher import BlockcypherClient
from .blockchain_info import BlockchainInfoClient
from .chain_com import ChainComClient
from .bitcoind import BitcoindClient, create_bitcoind_service_proxy
7 changes: 5 additions & 2 deletions pybitcoin/services/bitcoind.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
:license: MIT, see LICENSE for more details.
"""

import httplib
try:
from httplib import BadStatusLine
except ImportError:
from http.client import BadStatusLine

from bitcoinrpc.authproxy import AuthServiceProxy

Expand Down Expand Up @@ -89,7 +92,7 @@ def broadcast_transaction(hex_tx, blockchain_client):

try:
resp = bitcoind.sendrawtransaction(hex_tx)
except httplib.BadStatusLine:
except BadStatusLine:
raise Exception('Invalid HTTP status code from bitcoind.')

if len(resp) > 0:
Expand Down
8 changes: 3 additions & 5 deletions pybitcoin/services/blockchain_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ def get_unspents(address, blockchain_client=BlockchainInfoClient()):
r = requests.get(url, auth=auth)
try:
unspents = r.json()["unspent_outputs"]
except ValueError, e:
except ValueError as e:
raise Exception('Invalid response from blockchain.info.')

return format_unspents(unspents)

def broadcast_transaction(hex_tx, blockchain_client=BlockchainInfoClient()):
Expand All @@ -60,10 +60,8 @@ def broadcast_transaction(hex_tx, blockchain_client=BlockchainInfoClient()):
url = BLOCKCHAIN_API_BASE_URL + '/pushtx'
payload = {'tx': hex_tx}
r = requests.post(url, data=payload, auth=blockchain_client.auth)

if 'submitted' in r.text.lower():
return {'success': True}
else:
raise Exception('Invalid response from blockchain.info.')


7 changes: 3 additions & 4 deletions pybitcoin/services/chain_com.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ def get_unspents(address, blockchain_client=ChainComClient()):

try:
unspents = r.json()
except ValueError, e:
except ValueError as e:
raise Exception('Received non-JSON response from chain.com.')

return format_unspents(unspents)

def broadcast_transaction(hex_tx, blockchain_client):
Expand All @@ -72,7 +72,7 @@ def broadcast_transaction(hex_tx, blockchain_client):

try:
data = r.json()
except ValueError, e:
except ValueError as e:
raise Exception('Received non-JSON from chain.com.')

if 'transaction_hash' in data:
Expand All @@ -82,4 +82,3 @@ def broadcast_transaction(hex_tx, blockchain_client):
return reply
else:
raise Exception('Tx hash missing from chain.com response: ' + str(data) + '\noriginal: ' + str(payload))

2 changes: 0 additions & 2 deletions pybitcoin/transactions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
:license: MIT, see LICENSE for more details.
"""

import opcodes

from .network import broadcast_transaction, send_to_address, get_unspents, \
embed_data_in_blockchain, make_send_to_address_tx, make_op_return_tx, \
analyze_private_key, serialize_sign_and_broadcast, \
Expand Down
9 changes: 7 additions & 2 deletions pybitcoin/transactions/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"""

import struct
import sys
from binascii import hexlify, unhexlify
from utilitybelt import is_hex

Expand All @@ -26,7 +27,11 @@ def variable_length_int(i):
""" Encodes integers into variable length integers, which are used in
Bitcoin in order to save space.
"""
if not isinstance(i, (int,long)):
number_types = [int]
if sys.version_info.major < 3:
number_types.append(long)

if not isinstance(i, tuple(number_types)):
raise Exception('i must be an integer')

if i < (2**8-3):
Expand All @@ -38,4 +43,4 @@ def variable_length_int(i):
elif i < (2**64):
return chr(255) + struct.pack('<Q', i) # pack into 8 bites
else:
raise Exception('Integer cannot exceed 8 bytes in length.')
raise Exception('Integer cannot exceed 8 bytes in length.')