mirror of
https://github.com/alexgo-io/stacks-puppet-node.git
synced 2026-06-16 01:24:25 +08:00
Merge branch 'jude' of https://github.com/namesystem/blockstore into jude
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 )
|
||||
|
||||
|
||||
@@ -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 )
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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 ):
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 )
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
129
coinkit-fixes.patch
Normal 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,
|
||||
Reference in New Issue
Block a user