def input_script(cls, txin, i, for_sig): # for_sig: # -1 : do not sign, estimate length # i>=0 : serialized tx for signing input i # None : add all known signatures p2sh = txin.get('redeemScript') is not None num_sig = txin['num_sig'] if p2sh else 1 address = txin['address'] x_signatures = txin['signatures'] signatures = filter(None, x_signatures) is_complete = len(signatures) == num_sig if for_sig in [-1, None]: # if we have enough signatures, we use the actual pubkeys # use extended pubkeys (with bip32 derivation) if for_sig == -1: # we assume that signature will be 0x48 bytes long pubkeys = txin['pubkeys'] sig_list = ["00" * 0x48] * num_sig elif is_complete: pubkeys = txin['pubkeys'] sig_list = ((sig + '01') for sig in signatures) else: pubkeys = txin['x_pubkeys'] sig_list = ((sig + '01') if sig else NO_SIGNATURE for sig in x_signatures) script = ''.join(push_script(x) for x in sig_list) if not p2sh: x_pubkey = pubkeys[0] if x_pubkey is None: addrtype, h160 = bc_address_to_hash_160(txin['address']) x_pubkey = 'fd' + (chr(addrtype) + h160).encode('hex') script += push_script(x_pubkey) else: script = '00' + script # put op_0 in front of script redeem_script = cls.multisig_script(pubkeys, num_sig) script += push_script(redeem_script) elif for_sig == i: script_type = TYPE_ADDRESS if 'is_claim' in txin and txin['is_claim']: script_type |= TYPE_CLAIM address = ((txin['claim_name'], txin['claim_value']), address) elif 'is_support' in txin and txin['is_support']: script_type |= TYPE_SUPPORT address = ((txin['claim_name'], txin['claim_id']), address) elif 'is_update' in txin and txin['is_update']: script_type |= TYPE_UPDATE address = ((txin['claim_name'], txin['claim_id'], txin['claim_value']), address) script = txin['redeemScript'] if p2sh else cls.pay_script( script_type, address) else: script = '' return script
def pay_script(cls, output_type, addr): script = '' if output_type & TYPE_CLAIM: claim, addr = addr claim_name, claim_value = claim script += 'b5' # op_claim_name script += push_script(claim_name.encode('hex')) # In order to solve ulord can not resolve ... if not gl.flag_claim: claim_value = base64.b64encode(claim_value) else: gl.flag_abandon = False script += push_script(claim_value.encode('hex')) script += '6d75' # op_2drop, op_drop elif output_type & TYPE_SUPPORT: claim, addr = addr claim_name, claim_id = claim script += 'b6' script += push_script(claim_name.encode('hex')) script += push_script(claim_id.encode('hex')) script += '6d75' elif output_type & TYPE_UPDATE: claim, addr = addr claim_name, claim_id, claim_value = claim script += 'b7' script += push_script(claim_name.encode('hex')) script += push_script(claim_id.encode('hex')) claim_value = base64.b64encode(claim_value) #+ script += push_script(claim_value.encode('hex')) script += '6d6d' if output_type & TYPE_SCRIPT: script += addr.encode('hex') elif output_type & TYPE_ADDRESS: # op_2drop, op_drop addrtype, hash_160 = bc_address_to_hash_160(addr) if addrtype == 0: script += '76a9' # op_dup, op_hash_160 script += push_script(hash_160.encode('hex')) script += '88ac' # op_equalverify, op_checksig elif addrtype == 5: script += 'a9' # op_hash_160 script += push_script(hash_160.encode('hex')) script += '87' # op_equal else: raise Exception("Unknown address type: %s" % addrtype) else: raise Exception("Unknown output type: %s" % output_type) return script