This commit is contained in:
Jude Nelson
2015-07-28 12:03:02 -04:00
15 changed files with 242 additions and 62 deletions

View File

@@ -330,7 +330,7 @@ def run_cli():
name = args.name
value = args.data
key = coinit.hex_hash160(value)
key = coinkit.hex_hash160(value)
logger.debug("Signing hash '%s' by '%s'", key, name)
client = proxy.callRemote('signdata', name, key, value, args.privatekey)

View File

@@ -49,8 +49,7 @@ CHAIN_COM_API_ID = None
CHAIN_COM_API_SECRET = None
from lib import preorder_name, register_name, update_name, \
transfer_name
transfer_name, namespace_define, namespace_begin, putdata_storage, rmdata_storage
def signal_handler(signal, frame):
""" Handle Ctrl+C for dht node
@@ -216,7 +215,14 @@ class BlockstoredRPC(jsonrpc.JSONRPC):
reply['error'] = "hash(value) doesn't match, not storing"
return reply
return self.dht_server.set(key, value)
result = self.dht_server.set(key, value)
if result:
reply['key'] = hash
reply['result'] = True
else:
reply['result'] = False
return reply
def jsonrpc_signdata(self, name, key, value, privatekey):

View File

@@ -11,7 +11,7 @@ from ConfigParser import SafeConfigParser
import schemas
DEBUG = True
TESTNET = True
TESTNET = False
TESTSET = True
""" constants
@@ -187,7 +187,7 @@ def default_bitcoind_opts( config_file=None ):
REINDEX_FREQUENCY = 10 # in seconds
FIRST_BLOCK_MAINNET = 343883
FIRST_BLOCK_MAINNET = 367090 # 343883
FIRST_BLOCK_MAINNET_TESTSET = FIRST_BLOCK_MAINNET
# FIRST_BLOCK_TESTNET = 343883
FIRST_BLOCK_TESTNET = 508800
@@ -264,9 +264,9 @@ MIN_OP_LENGTHS = {
'transfer': LENGTHS['namelen'] + LENGTHS['name_min'],
'data_put': LENGTHS['name_hash'] + LENGTHS['data_hash'],
'data_remove': LENGTHS['name_hash'] + LENGTHS['data_hash'],
'namespace_define': LENGTHS['blockchain_id_namespace_id'] + LENGTHS['blockchain_id_namespace_id_len'],
'namespace_begin': LENGTHS['blockchain_id_namespace_life'] + LENGTHS['blockchain_id_namespace_cost'] + \
LENGTHS['blockchain_id_namespace_price_decay'] + LENGTHS['blockchain_id_namespace_id_len'] + LENGTHS['blockchain_id_namespace_id']
'namespace_begin': LENGTHS['blockchain_id_namespace_id_len'] + 1,
'namespace_define': LENGTHS['blockchain_id_namespace_life'] + LENGTHS['blockchain_id_namespace_cost'] + \
LENGTHS['blockchain_id_namespace_price_decay'] + LENGTHS['blockchain_id_namespace_id_len']
}
OP_RETURN_MAX_SIZE = 40

View File

@@ -8,6 +8,7 @@ from .config import LENGTHS
def hash_name(name, script_pubkey):
print "hash_name %s %s" % (name, script_pubkey)
bin_name = b40_to_bin(name)
name_and_pubkey = bin_name + unhexlify(script_pubkey)
return hex_hash160(name_and_pubkey)

View File

@@ -5,7 +5,7 @@ from binascii import hexlify, unhexlify
from .check import *
from .commit import commit_registration, commit_update, commit_transfer, \
commit_renewal, commit_namespace, commit_putdata, commit_deletedata
from .log import log_preorder, log_registration, log_update, log_transfer, log_namespace_define, log_namespace_begin
from .log import log_preorder, log_registration, log_update, log_transfer, log_namespace_define, log_namespace_begin, log_putdata, log_deletedata
from ..fees import is_mining_fee_sufficient
from ..parsing import parse_blockstore_op
@@ -105,10 +105,10 @@ def log_blockstore_op(db, blockstore_op, block_number):
log_namespace_begin(db, blockstore_op, block_number)
elif opcode == DATA_PUT:
log_data_put( db, blockstore_op, block_number )
log_putdata( db, blockstore_op, block_number )
elif opcode == DATA_DELETE:
log_data_delete( db, blockstore_op, block_number )
log_deletedata( db, blockstore_op, block_number )
def name_record_to_string(name, name_record):

View File

@@ -1,6 +1,6 @@
from ..hashing import hash_name, hash256_trunc128
from ..config import BLOCKS_CONSENSUS_HASH_IS_VALID
from .namedb import get_name_from_hash128
def name_registered(db, name):
if name in db.name_records:
@@ -21,21 +21,29 @@ def namespace_registered( db, namespace ):
else:
return False
def namespace_importing( db, namespace ):
def namespace_importing_hash( db, namespace_id_hash ):
"""
Is a namespace in the process of being defined?
"""
try:
namespace_id_hash = hash_name(namespace_id, sender_script_pubkey)
except ValueError:
return False
if namespace_id_hash in db.imports.keys():
return True
else:
return False
def namespace_importing( db, namespace, sender_script_pubkey ):
"""
Is a namespace in the process of being defined?
"""
try:
namespace_id_hash = hash_name(namespace, sender_script_pubkey)
except ValueError:
return False
return namespace_importing_hash( db, namespace_id_hash )
def has_defined_namespace( db, namespace_id, sender_script_pubkey ):
"""
Has the given user (identified by the sender_script_pubkey) defined this namespace?
@@ -63,11 +71,19 @@ def has_preordered_name(db, name, sender_script_pubkey):
try:
name_hash = hash_name(name, sender_script_pubkey)
except ValueError:
raise
return False
if name_hash in db.preorders:
print "%s: %s" % (name_hash, db.preorders[name_hash])
if sender_script_pubkey == db.preorders[name_hash]['sender']:
return True
else:
print "requester: %s; preorderer: %s" % (sender_script_pubkey, db.preorders[name_hash]['sender'])
return False
else:
print "%s not found" % name_hash
return False
@@ -125,4 +141,6 @@ def is_storageop_from_registered_name( db, storageop ):
if name_owner != storageop['sender']:
return False
else:
return True

View File

@@ -1,5 +1,5 @@
from ..hashing import hash_name, hash256_trunc128
from .namedb import get_name_from_hash128
from .namedb import get_name_from_hash128, put_signed_data
def remove_preorder(db, name, script_pubkey):
try:
@@ -95,7 +95,7 @@ def commit_putdata( db, storageop ):
name_hash = storageop['name_hash']
data_hash = storageop['data_hash']
name = get_name_from_hash128( name_hash )
name = get_name_from_hash128( name_hash, db )
put_signed_data( name, data_hash, db )
@@ -107,6 +107,6 @@ def commit_deletedata( db, storageop):
name_hash = storageop['name_hash']
data_hash = storageop['data_hash']
name = get_name_from_hash128( name_hash )
name = get_name_from_hash128( name_hash, db )
remove_signed_data( name, data_hash, db )

View File

@@ -1,11 +1,11 @@
from .check import name_not_registered, has_preordered_name, \
is_name_owner, is_preorder_hash_unique, name_registered, \
is_consensus_hash_valid, is_storageop_from_registered_name, \
namespace_importing
namespace_importing, namespace_importing_hash, namespace_registered
from ..fees import is_mining_fee_sufficient
from .namedb import get_name_from_hash128, put_signed_data, get_namespace_from_name
from ..hashing import hash256_trunc128, hash_name
from collections import defaultdict
def log_import( db, nameop, block_number ):
"""
@@ -28,21 +28,26 @@ def log_registration(db, nameop, block_number):
namespace_id = get_namespace_from_name( name )
# part of an import?
if namespace_importing( db, namespace_id ):
if namespace_importing( db, namespace_id, nameop['sender'] ):
# yup--remember which block, to avoid conflicts
log_import( db, nameop, block_number )
else:
namespace = get_namespace( db, namespace_id )
# TODO: look up namespace, and make sure the registration fee is sufficient
# namespace = get_namespace( db, namespace_id )
print ""
print "name: %s, available? %s, preordered by %s? %s, fee? %s" % (name, name_not_registered(db, name), nameop['sender'], has_preordered_name(db, name, nameop['sender']), is_mining_fee_sufficient(name, nameop['fee'], 0, 0))
print ""
# check if this registration is a valid one
if (name_not_registered(db, name) and has_preordered_name(db, name, nameop['sender']) and is_mining_fee_sufficient(name, nameop['fee'])):
if (name_not_registered(db, name) and has_preordered_name(db, name, nameop['sender']) and is_mining_fee_sufficient(name, nameop['fee'], 0, 0)):
# we're good - log the registration!
db.pending_registrations[name].append(nameop)
# check if this registration is actually a valid renewal
if (name_registered(db, name) and is_name_owner(db, name, nameop['sender']) and is_mining_fee_sufficient(name, nameop['fee'])):
if (name_registered(db, name) and is_name_owner(db, name, nameop['sender']) and is_mining_fee_sufficient(name, nameop['fee'], 0, 0)):
# we're good - log the renewal!
db.pending_renewals[name].append(nameop)
@@ -62,7 +67,7 @@ def log_update(db, nameop, block_number):
namespace_id = get_namespace_from_name( name )
# part of an import?
if namespace_importing( db, namespace_id ):
if namespace_importing( db, namespace_id, nameop['sender'] ):
# yup--remember which block, to avoid conflicts
log_import( db, nameop, block_number )
@@ -80,7 +85,7 @@ def log_transfer(db, nameop, block_number):
namespace_id = get_namespace_from_name( name )
# part of an import?
if namespace_importing( db, namespace_id ):
if namespace_importing( db, namespace_id, nameop['sender'] ):
# yup--remember which block, to avoid conflicts
log_import( db, nameop, block_number )
@@ -116,9 +121,11 @@ def log_namespace_define(db, nameop, block_number):
namespace_id_hash = nameop['namespace_id_hash']
if not namespace_registered( db, namespace_id_hash ) and not namespace_importing( db, namespace_id_hash ):
if not namespace_registered( db, namespace_id_hash ) and not namespace_importing_hash( db, namespace_id_hash ):
# can begin the import
db.imports[ namespace_id_hash ] = defaultdict(list)
if not db.imports.has_key( namespace_id_hash ):
db.imports[ namespace_id_hash ] = []
db.imports[ namespace_id_hash ].append( nameop )
@@ -130,7 +137,7 @@ def log_namespace_begin(db, nameop, block_number):
namespace_id = nameop['namespace_id']
if not namespace_registered( db, namespace_id ) and namespace_importing( db, namespace_id ) and has_defined_namespace( db, namespace_id, nameop['sender'] ):
if not namespace_registered( db, namespace_id ) and namespace_importing( db, namespace_id, nameop['sender'] ) and has_defined_namespace( db, namespace_id, nameop['sender'] ):
# can merge on next commit. this namespace is no longer importing.
db.pending_imports[ namespace_id ] = db.imports[ namespace_id_hash ]
del db.imports[ namespace_id_hash ]
@@ -144,13 +151,17 @@ def log_putdata( db, storageop, block_number ):
data_hash = storageop['data_hash']
if is_storageop_from_registered_name( storageop ):
if is_storageop_from_registered_name( db, storageop ):
name_hash = storageop['name_hash']
name = get_name_from_hash128( name_hash )
name = get_name_from_hash128( name_hash, db )
if name is not None:
db.pending_data_puts[name].append( data_hash )
db.pending_data_puts[name].append( storageop )
else:
print "Unrecognized name_hash '%s'" % name_hash
else:
print "Not from registered name: %s" % storageop
def log_deletedata( db, storageop, block_number ):
@@ -161,7 +172,7 @@ def log_deletedata( db, storageop, block_number ):
data_hash = storageop['data_hash']
if is_storageop_from_registered_name( storageop ):
if is_storageop_from_registered_name( db, storageop ):
name_hash = storageop['name_hash']
name = get_name_from_hash128( name_hash )
@@ -170,4 +181,4 @@ def log_deletedata( db, storageop, block_number ):
# user owns this data
db.pending_data_deletes[name].append( data_hash )

View File

@@ -197,6 +197,8 @@ def put_signed_data( owner_name, data_hash, db ):
NOTE: this doesn't verify that the name is valid; the caller must do so.
"""
print "user %s owns %s" % (owner_name, data_hash)
if db.signed_data.has_key( owner_name ):
db.signed_data[owner_name].update( set([data_hash]) )
@@ -210,12 +212,15 @@ def verify_signed_data( owner_name, data_hash, db ):
Return True if so; False if not
"""
debug_str = ""
if not db.signed_data.has_key( owner_name ):
# user has written nothing
return False
debug_str = "user %s does not own anything" % owner_name
return {"debug": debug_str, "result": False}
return data_hash in db.signed_data[ owner_name ]
debug_str = "user %s owns %s? %s" % (owner_name, data_hash, data_hash in db.signed_data[owner_name])
return {"debug": debug_str, "result": data_hash in db.signed_data[ owner_name ] }
def delete_signed_data( owner_name, data_hash, db ):

View File

@@ -15,9 +15,9 @@ def build( namespace_id, testset=False ):
Format:
0 2 3 4 23
|-----|--|--|-------------|
magic op len ns_id
0 2 3 4 5 24
|-----|--|--|--|-----------|
magic op len . ns_id
"""
# sanity check
@@ -27,7 +27,7 @@ def build( namespace_id, testset=False ):
if len(namespace_id) == 0 or len(namespace_id) > LENGTHS['blockchain_id_namespace_id']:
raise Exception("Invalid namespace ID '%s (expected length between 1 and %s)" % (namespace_id, LENGTHS['blockchain_id_namespace_id']))
readable_script = "NAMESPACE_BEGIN %i %s" % (len(namespace_id), namespace_id)
readable_script = "NAMESPACE_BEGIN %i %s" % (len(namespace_id), hexlify("." + namespace_id))
hex_script = blockstore_script_to_hex(readable_script)
packaged_script = add_magic_bytes(hex_script, testset=testset)
@@ -49,9 +49,9 @@ def parse( bin_payload ):
"""
namespace_id_len = ord( bin_payload[0:LENGTHS['blockchain_id_namespace_id_len']] )
namespace_id = bin_payload[ LENGTHS['blockchain_id_namespace_id_len']:LENGTHS['blockchain_id_namespace_id_len'] + namespace_id_len ]
namespace_id = bin_payload[ LENGTHS['blockchain_id_namespace_id_len'] + 1:LENGTHS['blockchain_id_namespace_id_len'] + namespace_id_len + 1 ] # skip the '.'
return {
'opcode': 'NAMESPACE_BEGIN',
'namespace_id': namespace_id
}
}

View File

@@ -5,7 +5,7 @@ from binascii import hexlify, unhexlify
from ..b40 import b40_to_hex, bin_to_b40, is_b40
from ..config import *
from ..scripts import blockstore_script_to_hex, add_magic_bytes, get_script_pubkey
from ..hashing import hash_name
def namespace_decay_to_float( namespace_decay_fixedpoint ):
"""
@@ -128,19 +128,19 @@ def parse( bin_payload ):
namespace_id_len = None
namespace_id = None
life = ord( bin_payload[off:off+LENGTHS['blockchain_id_namespace_life']] )
life = int( hexlify(bin_payload[off:off+LENGTHS['blockchain_id_namespace_life']]), 16 )
off += LENGTHS['blockchain_id_namespace_life']
cost = ord( bin_payload[off:off+LENGTHS['blockchain_id_namespace_cost']] )
cost = int( hexlify(bin_payload[off:off+LENGTHS['blockchain_id_namespace_cost']]), 16 )
off += LENGTHS['blockchain_id_namespace_cost']
decay_fixedpoint = ord( bin_payload[off:off+LENGTHS['blockchain_id_namespace_price_decay']] )
decay_fixedpoint = int( hexlify(bin_payload[off:off+LENGTHS['blockchain_id_namespace_price_decay']]), 16 )
off += LENGTHS['blockchain_id_namespace_price_decay']
namespace_id_len = ord( bin_payload[off:off+LENGTHS['blockchain_id_namespace_id_len']] )
namespace_id_len = int( hexlify(bin_payload[off:off+LENGTHS['blockchain_id_namespace_id_len']]), 16 )
off += LENGTHS['blockchain_id_namespace_id_len']
@@ -151,6 +151,6 @@ def parse( bin_payload ):
'lifetime': life,
'cost': cost,
'price_decay': namespace_decay_to_float( decay_fixedpoint ),
'namespace_id_hash': namespace_id_hash
'namespace_id_hash': hexlify( namespace_id_hash )
}

View File

@@ -49,14 +49,14 @@ def parse(bin_payload):
will not be present in bin_payload.
"""
fqn = unhexlify( bin_payload )
scheme = fqn[0:(len(NAME_SCHEME) - 3)] # excludes 'id://'
if scheme != NAME_SCHEME[3:]:
fqn = bin_payload
scheme = fqn[0:len(NAME_SCHEME)] # exclude scheme
if scheme != NAME_SCHEME:
raise Exception("Invalid bin payload: does not start with '%s'" % NAME_SCHEME)
return {
'opcode': 'NAME_REGISTRATION',
'name': fqn[(len(NAME_SCHEME) - 3):] # skip the '//', since that's what bin_payload will always start with
'name': fqn[len(NAME_SCHEME):] # skip the scheme
}

View File

@@ -60,31 +60,40 @@ def parse_blockstore_op_data(data):
else:
# this is a name registration
opcode = NAME_REGISTRATION
payload = bin_data
op = None
if opcode == NAME_PREORDER and len(payload) >= MIN_OP_LENGTHS['preorder']:
print "Parse NAME_PREORDER: %s" % data
op = parse_preorder(payload)
elif (opcode == NAME_REGISTRATION and len(payload) >= MIN_OP_LENGTHS['registration']):
print "Parse NAME_REGISTRATION: %s" % data
op = parse_registration(payload)
elif opcode == NAME_UPDATE and len(payload) >= MIN_OP_LENGTHS['update']:
print "Parse NAME_UPDATE: %s" % data
op = parse_update(payload)
elif (opcode == NAME_TRANSFER and len(payload) >= MIN_OP_LENGTHS['transfer']):
print "Parse NAME_TRANSFER: %s" % data
op = parse_transfer(payload)
elif opcode == NAMESPACE_DEFINE and len(payload) >= MIN_OP_LENGTHS['namespace_define']:
print "Parse NAMESPACE_DEFINE: %s" % data
op = parse_namespacedefine( payload )
elif opcode == NAMESPACE_BEGIN and len(payload) >= MIN_OP_LENGTHS['namespace_begin']:
print "Parse NAMESPACE_BEGIN: %s" % data
op = parse_namespacebegin( payload )
elif opcode == DATA_PUT and len(payload) >= MIN_OP_LENGTHS['data_put']:
print "Parse DATA_PUT: %s" % data
op = parse_putdata( payload )
elif opcode == DATA_REMOVE and len(payload) >= MIN_OP_LENGTHS['data_remove']:
print "Parse DATA_REMOVE: %s" % data
op = parse_rmdata( payload )
return op

View File

@@ -50,6 +50,7 @@ def data_script_to_hex(script):
# generate a pay-to-pubkeyhash script from a private key.
def get_script_pubkey( private_key ):
hash160 = BitcoinPrivateKey(private_key).public_key().hash160()
hash160 = BitcoinPrivateKey(private_key).public_key(compressed=True).hash160()
script_pubkey = script_to_hex( 'OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG' % hash160)
return script_pubkey
print "script_pubkey of %s is %s" % (private_key, script_pubkey)
return script_pubkey

129
coinkit-fixes.patch Normal file
View File

@@ -0,0 +1,129 @@
diff -r -u build/lib.linux-x86_64-2.7/coinkit/formatcheck.py /usr/local/lib/python2.7/dist-packages/coinkit-0.7.8-py2.7.egg/coinkit/formatcheck.py
--- build/lib.linux-x86_64-2.7/coinkit/formatcheck.py 2015-03-06 17:18:55.000000000 +0000
+++ /usr/local/lib/python2.7/dist-packages/coinkit-0.7.8-py2.7.egg/coinkit/formatcheck.py 2015-07-26 20:49:07.671300855 +0000
@@ -19,7 +19,7 @@
return (isinstance(val, str) and len(val) == 64 and is_hex(val))
def is_wif_pk(val):
- return (len(val) >= 51 and len(val) <= 51 and is_b58check(val))
+ return (len(val) >= 51 and len(val) <= 52 and is_b58check(val))
def is_b58check_address(val):
return is_b58check(val)
diff -r -u build/lib.linux-x86_64-2.7/coinkit/privatekey.py /usr/local/lib/python2.7/dist-packages/coinkit-0.7.8-py2.7.egg/coinkit/privatekey.py
--- build/lib.linux-x86_64-2.7/coinkit/privatekey.py 2015-03-06 17:18:55.000000000 +0000
+++ /usr/local/lib/python2.7/dist-packages/coinkit-0.7.8-py2.7.egg/coinkit/privatekey.py 2015-07-27 06:27:05.595300855 +0000
@@ -11,7 +11,7 @@
from binascii import hexlify, unhexlify
from ecdsa.keys import SigningKey
from utilitybelt import is_int, dev_random_entropy, dev_urandom_entropy
-from pybitcointools import compress
+from pybitcointools import compress, encode_privkey
from .errors import _errors
from .formatcheck import *
@@ -88,10 +88,16 @@
def to_bin(self):
return self._ecdsa_private_key.to_string()
- def to_hex(self):
+ def to_hex(self, compressed=False):
+ if compressed:
+ return encode_privkey( self.to_bin(), 'hex_compressed' )
+
return hexlify(self.to_bin())
- def to_wif(self):
+ def to_wif(self, compressed=False):
+ if compressed:
+ return encode_privkey( self.to_bin(), 'wif_compressed' )
+
return b58check_encode(self.to_bin(),
version_byte=self.wif_version_byte())
diff -r -u build/lib.linux-x86_64-2.7/coinkit/publickey.py /usr/local/lib/python2.7/dist-packages/coinkit-0.7.8-py2.7.egg/coinkit/publickey.py
--- build/lib.linux-x86_64-2.7/coinkit/publickey.py 2015-03-06 17:25:45.000000000 +0000
+++ /usr/local/lib/python2.7/dist-packages/coinkit-0.7.8-py2.7.egg/coinkit/publickey.py 2015-07-26 22:02:41.871300855 +0000
@@ -144,7 +144,10 @@
def hash160(self):
return hexlify(self.bin_hash160())
- def address(self):
+ def address(self, compressed=None ):
+ if compressed:
+ return bin_hash160_to_address( get_bin_hash160( compress(self.to_bin()) ), version_byte=self._version_byte )
+
return bin_hash160_to_address(self.bin_hash160(),
version_byte=self._version_byte)
diff -r -u build/lib.linux-x86_64-2.7/coinkit/services/chain_com.py /usr/local/lib/python2.7/dist-packages/coinkit-0.7.8-py2.7.egg/coinkit/services/chain_com.py
--- build/lib.linux-x86_64-2.7/coinkit/services/chain_com.py 2015-03-06 17:18:55.000000000 +0000
+++ /usr/local/lib/python2.7/dist-packages/coinkit-0.7.8-py2.7.egg/coinkit/services/chain_com.py 2015-07-26 22:22:10.431300855 +0000
@@ -67,7 +67,7 @@
raise Exception('ChainComClient object must have auth credentials.')
url = CHAIN_API_BASE_URL + '/bitcoin/transactions'
- payload = json.dumps({ 'hex': hex_tx })
+ payload = json.dumps({ 'signed_hex': hex_tx })
r = requests.put(url, data=payload, auth=auth)
try:
@@ -79,5 +79,5 @@
data['success'] = True
return data
else:
- raise Exception('Tx hash missing from chain.com response: ' + str(data))
+ raise Exception('Tx hash missing from chain.com response: ' + str(data) + "\noriginal: %s" % str(payload))
diff -r -u build/lib.linux-x86_64-2.7/coinkit/transactions/network.py /usr/local/lib/python2.7/dist-packages/coinkit-0.7.8-py2.7.egg/coinkit/transactions/network.py
--- build/lib.linux-x86_64-2.7/coinkit/transactions/network.py 2015-03-06 17:18:55.000000000 +0000
+++ /usr/local/lib/python2.7/dist-packages/coinkit-0.7.8-py2.7.egg/coinkit/transactions/network.py 2015-07-27 06:30:57.991300855 +0000
@@ -64,7 +64,8 @@
def analyze_private_key(private_key, blockchain_client):
private_key_obj = get_private_key_obj(private_key)
# determine the address associated with the supplied private key
- from_address = private_key_obj.public_key().address()
+ # from_address = private_key_obj.public_key().address()
+ from_address = private_key_obj.public_key().address( compressed=True )
# get the unspent outputs corresponding to the given address
inputs = get_unspents(from_address, blockchain_client)
# return the inputs
@@ -87,7 +88,7 @@
# serialize the transaction
unsigned_tx = serialize_transaction(inputs, outputs)
# sign the unsigned transaction with the private key
- signed_tx = sign_transaction(unsigned_tx, 0, private_key_obj.to_hex())
+ signed_tx = sign_transaction(unsigned_tx, 0, private_key_obj.to_hex(compressed=True))
# return the signed tx
return signed_tx
@@ -108,7 +109,7 @@
# serialize the transaction
unsigned_tx = serialize_transaction(inputs, outputs)
# sign the unsigned transaction with the private key
- signed_tx = sign_transaction(unsigned_tx, 0, private_key_obj.to_hex())
+ signed_tx = sign_transaction(unsigned_tx, 0, private_key_obj.to_hex(compressed=True))
# return the signed tx
return signed_tx
@@ -146,7 +147,7 @@
# serialize the transaction
unsigned_tx = serialize_transaction(inputs, outputs)
# sign the unsigned transaction with the private key
- signed_tx = sign_transaction(unsigned_tx, 0, private_key_obj.to_hex())
+ signed_tx = sign_transaction(unsigned_tx, 0, private_key_obj.to_hex(compressed=True))
# dispatch the signed transction to the network
response = broadcast_transaction(signed_tx, blockchain_client)
# return the response
diff -r -u build/lib.linux-x86_64-2.7/coinkit/transactions/outputs.py /usr/local/lib/python2.7/dist-packages/coinkit-0.7.8-py2.7.egg/coinkit/transactions/outputs.py
--- build/lib.linux-x86_64-2.7/coinkit/transactions/outputs.py 2015-03-06 17:18:55.000000000 +0000
+++ /usr/local/lib/python2.7/dist-packages/coinkit-0.7.8-py2.7.egg/coinkit/transactions/outputs.py 2015-07-26 21:21:50.423300855 +0000
@@ -17,7 +17,7 @@
change_amount = total_amount_in - send_amount - fee
# check to ensure the change amount is a non-negative value and return it
if change_amount < 0:
- raise Exception('Not enough inputs for transaction.')
+ raise Exception('Not enough inputs for transaction (inputs: %s, send_amount: %s, fee: %s).' % (inputs, send_amount, fee))
return change_amount
def make_pay_to_address_outputs(to_address, send_amount, inputs, change_address,