def sweep(klass, privkeys, network, to_address, fee): inputs = [] for privkey in privkeys: pubkey = public_key_from_private_key(privkey, chainparams.get_active_chain().wif_version) address = address_from_private_key(privkey, chainparams.get_active_chain().p2pkh_version, chainparams.get_active_chain().wif_version) u = network.synchronous_get([ ('blockchain.address.listunspent',[address])])[0] pay_script = klass.pay_script('address', address) for item in u: item['scriptPubKey'] = pay_script item['redeemPubkey'] = pubkey item['address'] = address item['prevout_hash'] = item['tx_hash'] item['prevout_n'] = item['tx_pos'] item['pubkeys'] = [pubkey] item['x_pubkeys'] = [None] item['signatures'] = [None] item['num_sig'] = 1 inputs += u if not inputs: return total = sum( map(lambda x:int(x.get('value')), inputs) ) - fee outputs = [('address', to_address, total)] self = klass(inputs, outputs) self.sign({ pubkey:privkey }) return self
def __init__(self, v): self.active_chain = chainparams.get_active_chain() self.receiving_pubkeys = v.get('receiving', []) self.change_pubkeys = v.get('change', []) # addresses will not be stored on disk self.receiving_addresses = map(self.pubkeys_to_address, self.receiving_pubkeys) self.change_addresses = map(self.pubkeys_to_address, self.change_pubkeys)
def _get_address_from_output_script(decoded, matches, active_chain=None): """Find address in output script. matches is a list of tuples of the form: ( opcodes_to_match (list), address type (str), index in script where address is (int), actions to take on extracted data (list) ) actions to take on extracted data may contain one or more of the following to have the corresponding effect on the extracted data, "data": - 'encode': data.encode('hex') - 'address': hash_160_to_bc_address(data, p2pkh_version) - 'p2sh': hash_160_to_bc_address(data, p2sh_version) """ if active_chain is None: active_chain = chainparams.get_active_chain() for match, addr_type, data_index, actions in matches: if match_decoded(decoded, match): data = decoded[data_index][1] # Convert to address if addr_type == 'address': addr_version = active_chain.p2pkh_version if 'p2sh' in actions: addr_version = active_chain.p2sh_version data = hash_160_to_bc_address(data, addr_version) # Encode in hex if necessary if 'encode' in actions: data = data.encode('hex') return addr_type, data return "(None)", "(None)"
def __init__(self, inputs, outputs, locktime=0, active_chain=None): """Create a new transaction. Args: inputs (list): List of dicts. An input is a dict with the following items: - coinbase (bool): Whether this is a coinbase input. - prevout_hash (str): TxID containing the output that this input spends. - prevout_n (int): Index of the output that this input spends. - value (int): Value of the output that this input spends, in satoshis. - address (str): Address of key(s) in this input's scriptSig. - num_sig (int): Number of signatures this input requires. - pubkeys (list): Strings of public keys in hex. - x_pubkeys (list): Strings of extended public keys in hex. - signatures (list): Strings of signatures in hex. P2PKH inputs have a 'redeemPubkey' key; P2SH inputs have a 'redeemScript' key. outputs (list): List of tuples. Output format: (type, address, value) - type is 'address' for P2PKH outputs, 'pubkey' for P2PK outputs, or 'op_return' for null data outputs. - address is an address for P2PKH outputs, a pubkey for P2PK outputs, or raw bytes for null data outputs. """ self.inputs = inputs self.outputs = outputs self.locktime = locktime self.raw = None if active_chain is None: active_chain = chainparams.get_active_chain() self.active_chain = active_chain
def parse_servers(result, active_chain=None): """ parse servers list into dict format""" from version import PROTOCOL_VERSION if active_chain is None: active_chain = chainparams.get_active_chain() defaultports = active_chain.DEFAULT_PORTS servers = {} for item in result: host = item[1] out = {} version = None pruning_level = '-' if len(item) > 2: for v in item[2]: if re.match("[stgh]\d*", v): protocol, port = v[0], v[1:] if port == '': port = defaultports[protocol] out[protocol] = port elif re.match("v(.?)+", v): version = v[1:] elif re.match("p\d*", v): pruning_level = v[1:] if pruning_level == '': pruning_level = '0' try: is_recent = float(version)>=float(PROTOCOL_VERSION) except Exception: is_recent = False if out and is_recent: out['pruning'] = pruning_level servers[host] = out return servers
def get_address_from_output_script(bytes): decoded = [ x for x in script_GetOp(bytes) ] active_chain = chainparams.get_active_chain() # The Genesis Block, self-payments, and pay-by-IP-address payments look like: # 65 BYTES:... CHECKSIG match = [ opcodes.OP_PUSHDATA4, opcodes.OP_CHECKSIG ] if match_decoded(decoded, match): return 'pubkey', decoded[0][1].encode('hex') # Pay-by-Bitcoin-address TxOuts look like: # DUP HASH160 20 BYTES:... EQUALVERIFY CHECKSIG match = [ opcodes.OP_DUP, opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUALVERIFY, opcodes.OP_CHECKSIG ] if match_decoded(decoded, match): return 'address', hash_160_to_bc_address(decoded[2][1], active_chain.p2pkh_version) # p2sh match = [ opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUAL ] if match_decoded(decoded, match): return 'address', hash_160_to_bc_address(decoded[1][1], active_chain.p2sh_version) # OP_RETURN match = [ opcodes.OP_RETURN, opcodes.OP_PUSHDATA4 ] if match_decoded(decoded, match): return 'op_return', decoded[1][1] return "(None)", "(None)"
def __init__(self, processor, config): threading.Thread.__init__(self) self.processor = processor self.daemon = True self.active_chain = chainparams.get_active_chain() self.stratum_tcp_port = config.get('server', 'stratum_tcp_port') self.stratum_http_port = config.get('server', 'stratum_http_port') self.stratum_tcp_ssl_port = config.get('server', 'stratum_tcp_ssl_port') self.stratum_http_ssl_port = config.get('server', 'stratum_http_ssl_port') self.report_stratum_tcp_port = config.get('server', 'report_stratum_tcp_port') self.report_stratum_http_port = config.get('server', 'report_stratum_http_port') self.report_stratum_tcp_ssl_port = config.get('server', 'report_stratum_tcp_ssl_port') self.report_stratum_http_ssl_port = config.get('server', 'report_stratum_http_ssl_port') self.host = config.get('server', 'host') self.report_host = config.get('server', 'report_host') self.nick = config.get('server', 'irc_nick') if self.report_stratum_tcp_port: self.stratum_tcp_port = self.report_stratum_tcp_port if self.report_stratum_http_port: self.stratum_http_port = self.report_stratum_http_port if self.report_stratum_tcp_ssl_port: self.stratum_tcp_ssl_port = self.report_stratum_tcp_ssl_port if self.report_stratum_http_ssl_port: self.stratum_http_ssl_port = self.report_stratum_http_ssl_port if self.report_host: self.host = self.report_host if not self.nick: self.nick = Hash(self.host)[:5].encode("hex") self.pruning = True self.pruning_limit = config.get('leveldb', 'pruning_limit') self.nick = self.active_chain.irc_nick_prefix + self.nick self.password = None
def pick_random_server(hostmap = None, protocol = 's', exclude_set = set(), active_chain = None): if hostmap is None: if active_chain is None: active_chain = chainparams.get_active_chain() hostmap = active_chain.DEFAULT_SERVERS eligible = list(set(filter_protocol(hostmap, protocol)) - exclude_set) return random.choice(eligible) if eligible else None
def __init__(self, config, shared, test_reorgs): self.dbpath = config.get('leveldb', 'path') if not os.path.exists(self.dbpath): os.mkdir(self.dbpath) self.pruning_limit = config.getint('leveldb', 'pruning_limit') self.shared = shared self.hash_list = {} self.parents = {} self.test_reorgs = test_reorgs try: self.db_utxo = plyvel.DB( os.path.join(self.dbpath, 'utxo'), create_if_missing=True, compression=None) self.db_addr = plyvel.DB( os.path.join(self.dbpath, 'addr'), create_if_missing=True, compression=None) self.db_hist = plyvel.DB( os.path.join(self.dbpath, 'hist'), create_if_missing=True, compression=None) self.db_undo = plyvel.DB( os.path.join(self.dbpath, 'undo'), create_if_missing=True, compression=None) except: logger.error('db init', exc_info=True) self.shared.stop() self.db_version = 3 # increase this when database needs to be updated try: self.last_hash, self.height, db_version = ast.literal_eval( self.db_undo.get('height')) print_log("Database version", self.db_version) print_log("Blockchain height", self.height) except: print_log('initializing database') self.height = 0 self.last_hash = chainparams.get_active_chain().genesis_hash db_version = self.db_version # write root self.put_node('', {}) # check version if self.db_version != db_version: print_log( "Your database '%s' is deprecated. Please create a new database" % self.dbpath) self.shared.stop() return # compute root hash d = self.get_node('') self.root_hash, v = self.get_node_hash('', d, None) print_log("UTXO tree root hash:", self.root_hash.encode('hex')) print_log("Coins in database:", v)
def __init__(self, config, shared): Processor.__init__(self) self.active_chain = chainparams.get_active_chain() self.mtimes = {} # monitoring self.shared = shared self.config = config self.up_to_date = False self.watch_lock = threading.Lock() self.watch_blocks = [] self.watch_headers = [] self.watched_addresses = {} self.block_cache = OrderedDict() try: self.block_cache_size = config.getint('server', 'block_cache_size') except ConfigParser.NoOptionError: self.block_cache_size = default_block_cache_size self.history_cache = {} self.max_cache_size = 100000 self.chunk_cache = {} self.cache_lock = threading.Lock() self.headers_data = '' self.headers_path = config.get('leveldb', 'path') self.mempool_values = {} self.mempool_addresses = {} self.mempool_hist = {} self.mempool_hashes = set([]) self.mempool_lock = threading.Lock() self.address_queue = Queue() try: self.test_reorgs = config.getboolean('leveldb', 'test_reorgs') # simulate random blockchain reorgs except: self.test_reorgs = False self.storage = Storage(config, shared, self.test_reorgs) self.dblock = threading.Lock() self.bitcoind_url = 'http://%s:%s@%s:%s/' % ( config.get('bitcoind', 'bitcoind_user'), config.get('bitcoind', 'bitcoind_password'), config.get('bitcoind', 'bitcoind_host'), config.get('bitcoind', 'bitcoind_port')) self.sent_height = 0 self.sent_header = None # catch_up headers self.init_headers(self.storage.height) self.blockchain_thread = threading.Thread(target = self.do_catch_up) self.blockchain_thread.start()
def getheader(self, height, deserialized=False): """Retrieve the block header at a given height.""" header = self.network.get_header(int(height)) if not header or isinstance(header, unicode): return 'Error: Unknown block' # genesis block if header.get('prev_block_hash') is None and header.get('block_height') == 0: header['prev_block_hash'] = '0'*64 return header if deserialized else chainparams.get_active_chain().header_to_string(header)
def dumpconfig(self, above_chain=False): """Dump the contents of your configuration file.""" if above_chain: return self.config.user_config chain = chainparams.get_active_chain().code chain_config = self.config.get_chain_config(chain) if chain_config is not None: return chain_config else: return 'Error: No configuration section for chain "{}"'.format(chain)
def DecodeBase58Check(psz): vchRet = b58decode(psz, None) key = vchRet[0:-4] csum = vchRet[-4:] hash = chainparams.get_active_chain().base58_hash(key) cs32 = hash[0:4] if cs32 != csum: return None else: return key
def hash_160_to_address(h160, addrtype = None): """ Checks if the provided hash is actually 160bits or 20 bytes long and returns the address, else None """ active_chain = chainparams.get_active_chain() if addrtype is None: addrtype = active_chain.p2pkh_version if h160 is None or len(h160) is not 20: return None vh160 = chr(addrtype) + h160 h = active_chain.base58_hash(vh160) addr = vh160 + h[0:4] return b58encode(addr)
def hash_160_to_address(h160, addrtype=None): """ Checks if the provided hash is actually 160bits or 20 bytes long and returns the address, else None """ active_chain = chainparams.get_active_chain() if addrtype is None: addrtype = active_chain.p2pkh_version if h160 is None or len(h160) is not 20: return None vh160 = chr(addrtype) + h160 h = active_chain.base58_hash(vh160) addr = vh160 + h[0:4] return b58encode(addr)
def filter_protocol(hostmap = None, protocol = 's', active_chain = None): '''Filters the hostmap for those implementing protocol. The result is a list in serialized form.''' if hostmap is None: if active_chain is None: active_chain = chainparams.get_active_chain() hostmap = active_chain.DEFAULT_SERVERS eligible = [] for host, portmap in hostmap.items(): port = portmap.get(protocol) if port: eligible.append(serialize_server(host, port, protocol)) return eligible
def __init__(self, pipe, config=None, active_chain=None): if config is None: config = {} # Do not use mutables as default values! util.DaemonThread.__init__(self) self.config = SimpleConfig(config) if type(config) == type({}) else config if active_chain is None: active_chain = chainparams.get_active_chain() self.active_chain = active_chain self.num_server = 8 if not self.config.get('oneserver') else 0 self.blockchain = Blockchain(self.config, self, self.active_chain) self.queue = Queue.Queue() self.requests_queue = pipe.send_queue self.response_queue = pipe.get_queue # run() will block while this event is cleared self.chain_switched = threading.Event() self.chain_switched.set() # A deque of interface header requests, processed left-to-right self.bc_requests = deque() # Server for addresses and transactions self.sanitize_default_server() self.irc_servers = {} # returned by interface (list from irc) self.recent_servers = self.read_recent_servers() self.banner = '' self.heights = {} self.merkle_roots = {} self.utxo_roots = {} dir_path = os.path.join( self.config.path, 'certs') if not os.path.exists(dir_path): os.mkdir(dir_path) # subscriptions and requests self.subscribed_addresses = set() # cached address status self.addr_responses = {} # unanswered requests self.unanswered_requests = {} # retry times self.server_retry_time = time.time() self.nodes_retry_time = time.time() # kick off the network. interface is the main server we are currently # communicating with. interfaces is the set of servers we are connecting # to or have an ongoing connection with self.interface = None self.interfaces = {} self.start_network(deserialize_server(self.default_server)[2], deserialize_proxy(self.config.get('proxy')))
def parse_URI(uri, active_chain=None): import urlparse import bitcoin from decimal import Decimal import chainparams if active_chain is None: active_chain = chainparams.get_active_chain() if ':' not in uri: assert bitcoin.is_address(uri, active_chain) return uri, None, None, None, None uri_scheme = active_chain.coin_name.lower() u = urlparse.urlparse(uri) assert u.scheme == uri_scheme address = u.path valid_address = bitcoin.is_address(address, active_chain) pq = urlparse.parse_qs(u.query) for k, v in pq.items(): if len(v)!=1: raise Exception('Duplicate Key', k) amount = label = message = request_url = '' if 'amount' in pq: am = pq['amount'][0] m = re.match('([0-9\.]+)X([0-9])', am) if m: k = int(m.group(2)) - 8 amount = Decimal(m.group(1)) * pow( Decimal(10) , k) else: amount = Decimal(am) * 100000000 if 'message' in pq: message = pq['message'][0] if 'label' in pq: label = pq['label'][0] if 'r' in pq: request_url = pq['r'][0] if request_url != '': return address, amount, label, message, request_url assert valid_address return address, amount, label, message, request_url
def __init__(self, config, network): threading.Thread.__init__(self) self.daemon = True self.config = config self.active_chain = chainparams.get_active_chain() self.chunk_size = self.active_chain.chunk_size self.network = network self.lock = threading.Lock() self.local_height = 0 self.running = False # Currently disabled until chain-specific URLs implemented self.headers_url = "" #'http://headers.electrum.org/blockchain_headers' self.set_local_height() self.queue = Queue.Queue()
def pay_script(self, type, addr, active_chain=None): if active_chain is None: active_chain = chainparams.get_active_chain() self.active_chain = active_chain if type == 'op_return': return null_output_script(addr) else: assert type == 'address' script = [] addrtype, hash_160 = bc_address_to_hash_160(addr) if addrtype == self.active_chain.p2pkh_version: script.append(p2pkh_script(hash_160)) elif addrtype == self.active_chain.p2sh_version: script.append(p2sh_script(hash_160)) else: raise return ''.join(script)
def __init__(self, config=None): if config is None: config = {} # Do not use mutables as default values! threading.Thread.__init__(self) self.daemon = True self.config = SimpleConfig(config) if type(config) == type({}) else config self.active_chain = chainparams.get_active_chain() self.default_servers = self.active_chain.DEFAULT_SERVERS self.lock = threading.Lock() self.num_server = 8 if not self.config.get('oneserver') else 0 self.blockchain = Blockchain(self.config, self) self.interfaces = {} self.queue = Queue.Queue() self.protocol = self.config.get('protocol','s') self.running = False # Server for addresses and transactions self.default_server = self.config.get('server') if not self.default_server: self.default_server = pick_random_server(self.protocol) self.irc_servers = {} # returned by interface (list from irc) self.disconnected_servers = set([]) self.disconnected_time = time.time() self.recent_servers = self.config.get('recent_servers',[]) # successful connections self.pending_servers = set() self.banner = '' self.interface = None self.proxy = self.config.get('proxy') self.heights = {} self.merkle_roots = {} self.utxo_roots = {} dir_path = os.path.join( self.config.path, 'certs') if not os.path.exists(dir_path): os.mkdir(dir_path) # address subscriptions and cached results self.addresses = {} self.connection_status = 'connecting' self.requests_queue = Queue.Queue()
def pay_script(self, type, addr): self.chain = chainparams.get_active_chain() if type == 'op_return': h = addr.encode('hex') return '6a' + push_script(h) else: assert type == 'address' addrtype, hash_160 = bc_address_to_hash_160(addr) if addrtype == self.chain.p2pkh_version: script = '76a9' # op_dup, op_hash_160 script += push_script(hash_160.encode('hex')) script += '88ac' # op_equalverify, op_checksig elif addrtype == self.chain.p2sh_version: script = 'a9' # op_hash_160 script += push_script(hash_160.encode('hex')) script += '87' # op_equal else: raise return script
def switch_chains(self, chaincode=None): if chaincode is None: chain = chainparams.get_active_chain() else: chain = chainparams.get_chain_instance(chaincode) self.chain_switched.clear() self.active_chain = chain if self.config.get_active_chain_code() != self.active_chain.code: self.config.set_active_chain_code(self.active_chain.code) self.print_error('switching chains to {}'.format(chain.code)) self.stop_network() time.sleep(0.2) self.bc_requests.clear() self.blockchain = Blockchain(self.config, self, self.active_chain) self.queue = Queue.Queue() self.sanitize_default_server() self.irc_servers = {} # returned by interface (list from irc) self.recent_servers = self.read_recent_servers() self.banner = '' self.heights = {} self.merkle_roots = {} self.utxo_roots = {} self.interface = None self.interfaces = {} # subscriptions and requests self.subscribed_addresses = set() # cached address status self.addr_responses = {} # unanswered requests self.unanswered_requests = {} self.blockchain.init() # Start the new network self.start_network(deserialize_server(self.default_server)[2], deserialize_proxy(self.config.get('proxy'))) time.sleep(0.2) self.chain_switched.set()
def get_address_from_output_script(bytes, active_chain=None): if active_chain is None: active_chain = chainparams.get_active_chain() decoded = [ x for x in script_GetOp(bytes) ] # list of (opcodes_list, addr_type, addr_data_index, [actions_to_take]) # actions_to_take contains things such as 'encode' if the data should be hex-encoded. matches = [ # The Genesis Block, self-payments, and pay-by-IP-address payments ([ opcodes.OP_PUSHDATA4, opcodes.OP_CHECKSIG ], 'pubkey', 0, ['encode']), # Pay-to-Public-Key-Hash ([ opcodes.OP_DUP, opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUALVERIFY, opcodes.OP_CHECKSIG ], 'address', 2, [None]), # Pay-to-Script-Hash ([ opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUAL ], 'address', 1, ['p2sh']), # OP_RETURN (null output) ([ opcodes.OP_RETURN, opcodes.OP_PUSHDATA4 ], 'op_return', 1, [None]) ] run_chainhook('transaction_get_address_from_output_script', opcodes, matches) return _get_address_from_output_script(decoded, matches, active_chain)
def parse_xpub(x_pubkey): active_chain = chainparams.get_active_chain() if x_pubkey[0:2] in ['02','03','04']: pubkey = x_pubkey elif x_pubkey[0:2] == 'ff': from account import BIP32_Account xpub, s = BIP32_Account.parse_xpubkey(x_pubkey) pubkey = BIP32_Account.derive_pubkey_from_xpub(xpub, s[0], s[1]) elif x_pubkey[0:2] == 'fe': from account import OldAccount mpk, s = OldAccount.parse_xpubkey(x_pubkey) pubkey = OldAccount.get_pubkey_from_mpk(mpk.decode('hex'), s[0], s[1]) elif x_pubkey[0:2] == 'fd': addrtype = ord(x_pubkey[2:4].decode('hex')) hash160 = x_pubkey[4:].decode('hex') pubkey = None address = hash_160_to_bc_address(hash160, active_chain.p2pkh_version) else: raise BaseException("Cannnot parse pubkey") if pubkey: address = public_key_to_bc_address(pubkey.decode('hex'), active_chain.p2pkh_version) return pubkey, address
def validateaddress(self, address, above_chain=False): """Check that the address is valid. """ if above_chain: return is_valid(address) return is_valid(address, chainparams.get_active_chain())
def deserialize(klass, raw): self = klass([],[]) self.chain = chainparams.get_active_chain() self.update(raw) return self
def parse_scriptSig(d, bytes, active_chain=None): if active_chain is None: active_chain = chainparams.get_active_chain() try: decoded = [ x for x in script_GetOp(bytes) ] except Exception: # coinbase transactions raise an exception print_error("cannot find address in input script", bytes.encode('hex')) return # payto_pubkey match = [ opcodes.OP_PUSHDATA4 ] if match_decoded(decoded, match): sig = decoded[0][1].encode('hex') d['address'] = "(pubkey)" d['signatures'] = [sig] d['num_sig'] = 1 d['x_pubkeys'] = ["(pubkey)"] d['pubkeys'] = ["(pubkey)"] return # non-generated TxIn transactions push a signature # (seventy-something bytes) and then their public key # (65 bytes) onto the stack: match = [ opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4 ] if match_decoded(decoded, match): sig = decoded[0][1].encode('hex') x_pubkey = decoded[1][1].encode('hex') try: signatures = parse_sig([sig]) pubkey, address = parse_xpub(x_pubkey, active_chain) except: import traceback traceback.print_exc(file=sys.stdout) print_error("cannot find address in input script", bytes.encode('hex')) return d['signatures'] = signatures d['x_pubkeys'] = [x_pubkey] d['num_sig'] = 1 d['pubkeys'] = [pubkey] d['address'] = address return # p2sh transaction, m of n match = [ opcodes.OP_0 ] while len(match) < len(decoded): match.append(opcodes.OP_PUSHDATA4) if not match_decoded(decoded, match): print_error("cannot find address in input script", bytes.encode('hex')) return x_sig = map(lambda x:x[1].encode('hex'), decoded[1:-1]) d['signatures'] = parse_sig(x_sig) dec2 = [ x for x in script_GetOp(decoded[-1][1]) ] multis_m = multis_n = None multis_mn = match_decoded_multisig(dec2) if multis_mn: multis_m = multis_mn[0] multis_n = multis_mn[1] x_pubkeys = map(lambda x:x[1].encode('hex'), dec2[1:-2]) d['num_sig'] = multis_m else: print_error("cannot find address in input script", bytes.encode('hex')) return d['x_pubkeys'] = x_pubkeys pubkeys = map(lambda x: parse_xpub(x)[0], x_pubkeys) d['pubkeys'] = pubkeys redeemScript = multisig_script(pubkeys,multis_m) d['redeemScript'] = redeemScript d['address'] = hash_160_to_bc_address(hash_160(redeemScript.decode('hex')), active_chain.p2sh_version)
def pick_random_server(p='s'): try: servers = chainparams.get_active_chain().DEFAULT_SERVERS except: servers = DEFAULT_SERVERS return random.choice( filter_protocol(servers,p) )
def switch_to_active_chain(self): """Create a new Network instance or send message to daemon.""" with self.lock: # for the network.switch_chains request message_id = self.message_id self.message_id = 0 self.unanswered_requests = {} self.subscriptions = {} self.pending_transactions_for_notifications = [] self.callbacks = {} self.status = 'connecting' self.servers = {} self.banner = '' self.blockchain_height = 0 self.server_height = 0 self.interfaces = [] # Not daemon, probably running GUI if self.network: self.network.switch_chains() for key in ['status','banner','updated','servers','interfaces']: value = self.network.get_status_value(key) self.pipe.get_queue.put({'method':'network.status', 'params':[key, value]}) # Daemon is running else: req = {'id': message_id, 'method': 'network.switch_chains', 'params':[chainparams.get_active_chain().code]} self.pipe.send(req)
def createmultisig(self, num, pubkeys): """Create multisig address""" assert isinstance(pubkeys, list), (type(num), type(pubkeys)) redeem_script = script.multisig_script(pubkeys, num) address = hash_160_to_bc_address(hash_160(redeem_script.decode('hex')), chainparams.get_active_chain().p2sh_version) return {'address':address, 'redeemScript':redeem_script}