def submit_opreturn(rpc_connection, address, data): from bitcoin.core import CTxIn, CMutableTxOut, CScript, CMutableTransaction, COIN, CENT, b2x, b2lx from bitcoin.core.script import OP_CHECKSIG, OP_RETURN txouts = [] unspent = sorted([y for y in rpc_connection.listunspent(0) if str(y['address']) == address], key=lambda x: hash(x['amount'])) txins = [CTxIn(unspent[-1]['outpoint'])] value_in = unspent[-1]['amount'] change_pubkey = rpc_connection.validateaddress(address)['pubkey'] change_out = CMutableTxOut(int(value_in - 2*CENT), CScript([change_pubkey, OP_CHECKSIG])) digest_outs = [CMutableTxOut(CENT, CScript([OP_RETURN, data]))] txouts = [change_out] + digest_outs tx = CMutableTransaction(txins, txouts) print tx.serialize().encode('hex') r = rpc_connection.signrawtransaction(tx) assert r['complete'] tx = r['tx'] #print b2x(tx.serialize()) #print len(tx.serialize()), 'bytes' print(b2lx(rpc_connection.sendrawtransaction(tx)))
def adjust_transaction(tx_hex): # if you don't want change you wallet signature code # you can use this to adjust high S signature to a canonical signature tx = CTransaction.deserialize(x(tx_hex)) for vin in tx.vin: script_lst = list(vin.scriptSig) sig = script_lst[0] # normal signature format <sig> <pubkey> if len(script_lst) == 2 and not IsLowDERSignature(sig): low_s_sig = signature_to_low_s(sig)#.encode('hex') #print sig.encode('hex'), low_s_sig.encode('hex') script_lst[0] = low_s_sig vin.scriptSig = CScript(script_lst) # 2/2 or 2/3 multisig format <0> <signature> <signature> <redeemscript> elif len(script_lst) == 4: script_lst_new = [] for idx, sig in enumerate(script_lst[1:3]): if not IsLowDERSignature(sig): low_s_sig = signature_to_low_s(sig)#.encode('hex') #print sig.encode('hex'), low_s_sig.encode('hex') script_lst_new.append(low_s_sig) else: script_lst_new.append(sig) script_lst_new.append(script_lst[3]) vin.scriptSig = "\x00" + CScript(script_lst_new) return b2x(tx.serialize())
def from_utxo(txid_in: str, tx_index_in: int, sats: int, privkey: str, fee: int, local_node_privkey: str, local_funding_privkey: str, remote_node_privkey: str, remote_funding_privkey: str, chain_hash: str = regtest_hash) -> Tuple['Funding', str]: """Make a funding transaction by spending this utxo using privkey: return Funding, tx.""" # Create dummy one to start: we will fill in txid at the end. funding = Funding('', 0, sats - fee, local_node_privkey, local_funding_privkey, remote_node_privkey, remote_funding_privkey, chain_hash) # input private key. inkey = privkey_expand(privkey) inkey_pub = coincurve.PublicKey.from_secret(inkey.secret) # use RBF'able input (requirement for dual-funded things) txin = CTxIn(COutPoint(bytes.fromhex(txid_in), tx_index_in), nSequence=0xFFFFFFFD) txout = CTxOut( sats - fee, CScript([script.OP_0, sha256(funding.redeemscript()).digest()])) tx = CMutableTransaction([txin], [txout], nVersion=2, nLockTime=funding.locktime) # now fill in funding txid. funding.txid = tx.GetTxid().hex() funding.tx = tx # while we're here, sign the transaction. address = P2WPKHBitcoinAddress.from_scriptPubKey( CScript([script.OP_0, Hash160(inkey_pub.format())])) sighash = script.SignatureHash(address.to_redeemScript(), tx, 0, script.SIGHASH_ALL, amount=sats, sigversion=script.SIGVERSION_WITNESS_V0) sig = inkey.sign(sighash, hasher=None) + bytes([script.SIGHASH_ALL]) tx.wit = CTxWitness( [CTxInWitness(CScriptWitness([sig, inkey_pub.format()]))]) return funding, tx.serialize().hex()
def mock_listunspent_mainnet(self, addrs): output1 = { 'outpoint': COutPoint( lx('34eb81bc0d1a822369f75174fd4916b1ec490d8fbcba33168e820cc78a52f608' ), 0), 'confirmations': 123, 'address': P2PKHBitcoinAddress('13yNf3azc8sUrjf6UFjUCRZx4B6JnQ4XeJ'), 'spendable': False, 'amount': 6342, 'solvable': False, 'scriptPubKey': CScript([ OP_DUP, OP_HASH160, x('cc0a909c4c83068be8b45d69b60a6f09c2be0fda'), OP_EQUALVERIFY, OP_CHECKSIG ]), 'account': '' } output2 = { 'address': P2PKHBitcoinAddress('13yNf3azc8sUrjf6UFjUCRZx4B6JnQ4XeJ'), 'amount': 2750, 'account': '', 'spendable': False, 'solvable': False, 'confirmations': 456, 'outpoint': COutPoint( lx('6773785b4dc5d2cced67d26fc0820329307a8e10dfaef50d506924984387bf0b' ), 1), 'scriptPubKey': CScript([ OP_DUP, OP_HASH160, x('cc0a909c4c83068be8b45d69b60a6f09c2be0fda'), OP_EQUALVERIFY, OP_CHECKSIG ]) } unspent_outputs = [output1, output2] return unspent_outputs
def add_output(self, serial_id: int, script: str, sats: int) -> None: txout = CTxOut(sats, CScript(bytes.fromhex(script))) self.outputs.append({'output': txout, 'serial_id': serial_id})
def close_tx(self, fee: int, privkey_dest: str) -> str: """Create a (mutual) close tx""" txin = CTxIn(COutPoint(bytes.fromhex(self.txid), self.output_index)) out_privkey = privkey_expand(privkey_dest) txout = CTxOut(self.amount - fee, CScript([script.OP_0, Hash160(coincurve.PublicKey.from_secret(out_privkey.secret).format())])) tx = CMutableTransaction(vin=[txin], vout=[txout]) sighash = script.SignatureHash(self.redeemscript(), tx, inIdx=0, hashtype=script.SIGHASH_ALL, amount=self.amount, sigversion=script.SIGVERSION_WITNESS_V0) sigs = [key.sign(sighash, hasher=None) for key in self.funding_privkeys_for_tx()] # BOLT #3: # ## Closing Transaction # ... # * `txin[0]` witness: `0 <signature_for_pubkey1> <signature_for_pubkey2>` witness = CScriptWitness([bytes(), sigs[0] + bytes([script.SIGHASH_ALL]), sigs[1] + bytes([script.SIGHASH_ALL]), self.redeemscript()]) tx.wit = CTxWitness([CTxInWitness(witness)]) return tx.serialize().hex()
def creates_add_input(bitcoind, tx): """Creates and add an input to a CMutableTransaction, SIGHASH_ALL. :returns: The txid of the first stage fee bumping tx (for convenience) """ # First we get some coins privkey = CKey(os.urandom(32)) scriptPubKey = CScript([OP_0, Hash160(privkey.pub)]) address = CBitcoinAddress.from_scriptPubKey(scriptPubKey) # Let's say we want to increase the fees by 5000 sats amount = 5000 # Bitcoind is nice and will create the first stage transaction first_txid = bitcoind.rpc.sendtoaddress(str(address), amount / COIN) vout_index = get_output_index( bitcoind.rpc.getrawtransaction(first_txid, 1), amount) # === We don't generate a block yet ! === tx.vin.append( CTxIn(COutPoint(lx(first_txid), vout_index), nSequence=0xfffffffe)) # Sign the new input with ALL tx_hash = SignatureHash(address.to_redeemScript(), tx, 1, SIGHASH_ALL, amount, SIGVERSION_WITNESS_V0) sig = privkey.sign(tx_hash) + bytes([SIGHASH_ALL]) tx.wit.vtxinwit.append(CTxInWitness(CScriptWitness([sig, privkey.pub]))) return first_txid
def add_witnesses(self, witness_stack) -> str: wits = [] for idx, _in in enumerate(self.inputs): privkey = _in['privkey'] serial_id = _in['serial_id'] if privkey: inkey = privkey_expand(privkey) inkey_pub = coincurve.PublicKey.from_secret(inkey.secret) address = P2WPKHBitcoinAddress.from_scriptPubKey(CScript([script.OP_0, Hash160(inkey_pub.format())])) sighash = script.SignatureHash(address.to_redeemScript(), self.tx, idx, script.SIGHASH_ALL, amount=_in['sats'], sigversion=script.SIGVERSION_WITNESS_V0) sig = inkey.sign(sighash, hasher=None) + bytes([script.SIGHASH_ALL]) wits.append(CTxInWitness(CScriptWitness([sig, inkey_pub.format()]))) continue # Every input from the witness stack will be the accepter's # which is always an odd serial assert(serial_id % 2 == 1) elems = witness_stack.pop(0)['witness_element'] stack = [] for elem in elems: stack.append(bytes.fromhex(elem['witness'])) wits.append(CTxInWitness(CScriptWitness(stack))) self.tx.wit = CTxWitness(wits) return self.tx.serialize().hex()
def create_trx(op_return_val, issuing_transaction_fee, issuing_address, tx_outs, tx_inputs): """ :param op_return_val: :param issuing_transaction_fee: :param issuing_address: :param tx_outs: :param tx_input: :return: """ cert_out = CMutableTxOut(0, CScript([OP_RETURN, op_return_val])) tx_ins = [] value_in = 0 for tx_input in tx_inputs: tx_ins.append(CTxIn(COutPoint(tx_input.tx_hash, tx_input.tx_out_index))) value_in += tx_input.coin_value # send change back to our address amount = value_in - issuing_transaction_fee if amount > 0: change_out = create_transaction_output(issuing_address, amount) tx_outs = tx_outs + [change_out] tx_outs = tx_outs + [cert_out] transaction = CMutableTransaction(tx_ins, tx_outs) return transaction
def sign_our_inputs(self) -> None: assert self.tx is not None for idx, _in in enumerate(self.inputs): privkey = _in['privkey'] if privkey and 'sig' not in _in: print('signing our input for tx', self.tx.serialize().hex()) inkey = privkey_expand(privkey) inkey_pub = coincurve.PublicKey.from_secret(inkey.secret) # Really horrid hack to produce a signature for the # multisig utxo in tests/helpers.py if privkey == '38204720bc4f9647fd58c6d0a4bd3a6dd2be16d8e4273c4d1bdd5774e8c51eaf': redeemscript = bytes.fromhex('51210253cdf835e328346a4f19de099cf3d42d4a7041e073cd4057a1c4fd7cdbb1228f2103ae903722f21f85e651b8f9b18fc854084fb90eeb76452bdcfd0cb43a16a382a221036c264d68a9727afdc75949f7d7fa71910ae9ae8001a1fbffa6f7ce000976597c21036429fa8a4ef0b2b1d5cb553e34eeb90a32ab19fae1f0024f332ab4f74283a7282103d4232f19ea85051e7b76bf5f01d03e17eea8751463dee36d71413a739de1a92755ae') else: address = P2WPKHBitcoinAddress.from_scriptPubKey(CScript([script.OP_0, Hash160(inkey_pub.format())])) redeemscript = address.to_redeemScript() sighash = script.SignatureHash(redeemscript, self.tx, idx, script.SIGHASH_ALL, amount=_in['sats'], sigversion=script.SIGVERSION_WITNESS_V0) sig = inkey.sign(sighash, hasher=None) + bytes([script.SIGHASH_ALL]) if privkey == '38204720bc4f9647fd58c6d0a4bd3a6dd2be16d8e4273c4d1bdd5774e8c51eaf': _in['sig'] = CTxInWitness(CScriptWitness([bytes([]), sig, redeemscript])) else: _in['sig'] = CTxInWitness(CScriptWitness([sig, inkey_pub.format()]))
def mock_listunspent(self, addrs): output1 = {'outpoint': COutPoint(lx('34eb81bc0d1a822369f75174fd4916b1ec490d8fbcba33168e820cc78a52f608'), 0), 'confirmations': 62952, 'address': P2PKHBitcoinAddress('mz7poFND7hVGRtPWjiZizcCnjf6wEDWjjT'), 'spendable': False, 'amount': 49000000, 'solvable': False, 'scriptPubKey': CScript( [OP_DUP, OP_HASH160, x('cc0a909c4c83068be8b45d69b60a6f09c2be0fda'), OP_EQUALVERIFY, OP_CHECKSIG]), 'account': ''} output2 = {'address': P2PKHBitcoinAddress('mz7poFND7hVGRtPWjiZizcCnjf6wEDWjjT'), 'amount': 2750, 'account': '', 'spendable': False, 'solvable': False, 'confirmations': 62932, 'outpoint': COutPoint(lx('6773785b4dc5d2cced67d26fc0820329307a8e10dfaef50d506924984387bf0b'), 1), 'scriptPubKey': CScript( [OP_DUP, OP_HASH160, x('cc0a909c4c83068be8b45d69b60a6f09c2be0fda'), OP_EQUALVERIFY, OP_CHECKSIG])} output3 = {'address': P2PKHBitcoinAddress('mz7poFND7hVGRtPWjiZizcCnjf6wEDWjjT'), 'amount': 2750, 'account': '', 'spendable': False, 'solvable': False, 'confirmations': 62932, 'outpoint': COutPoint(lx('6773785b4dc5d2cced67d26fc0820329307a8e10dfaef50d506924984387bf0b'), 5), 'scriptPubKey': CScript( [OP_DUP, OP_HASH160, x('cc0a909c4c83068be8b45d69b60a6f09c2be0fda'), OP_EQUALVERIFY, OP_CHECKSIG])} unspent_outputs = [output1, output2, output3] return unspent_outputs
def forge_prevtx( vouts: Sequence[Tuple[str, int]], network: str = "mainnet") -> Tuple[bytes, messages.TransactionType]: """ Forge a transaction with the given vouts. """ bitcoin.SelectParams(network) input = messages.TxInputType( prev_hash=b"\x00" * 32, prev_index=0xFFFFFFFF, script_sig=b"\x00", sequence=0xFFFFFFFF, ) outputs = [ messages.TxOutputBinType( amount=amount, script_pubkey=bytes(CBitcoinAddress(address).to_scriptPubKey()), ) for address, amount in vouts ] tx = messages.TransactionType( version=1, inputs=[input], bin_outputs=outputs, lock_time=0, ) cin = CTxIn( COutPoint(input.prev_hash, input.prev_index), CScript(input.script_sig), input.sequence, ) couts = [ CTxOut(output.amount, CScript(output.script_pubkey)) for output in tx.bin_outputs ] txhash = CTransaction([cin], couts, tx.lock_time, tx.version).GetTxid()[::-1] bitcoin.SelectParams("mainnet") return txhash, tx
def get_unspent_outputs(self, address): unspent_outputs = [] # this calls a different api not accessible through localhost proxy unspent_url = 'https://blockchain.info/unspent?active=%s&format=json' % address unspent_response = try_get(unspent_url) r = unspent_response.json() for u in r['unspent_outputs']: tx_out = TransactionOutput( COutPoint(unhexlify(u['tx_hash']), u['tx_output_n']), CBitcoinAddress(address), CScript(unhexlify(u['script'])), int(u['value'])) unspent_outputs.append(tx_out) return unspent_outputs
def create_trx(op_return_val, issuing_transaction_cost, issuing_address, txouts, tx_input): cert_out = CMutableTxOut(0, CScript([OP_RETURN, op_return_val])) txins = [CTxIn(tx_input.outpoint)] value_in = tx_input.amount # send change back to our address amount = value_in - issuing_transaction_cost.total if amount > 0: change_out = create_transaction_output(issuing_address, amount) txouts = txouts + [change_out] txouts = txouts + [cert_out] tx = CMutableTransaction(txins, txouts) return tx
def _build_certificate_transactions(wallet, issuing_address, revocation_address, certificate_metadata, fees, tail): """Make transactions for the certificates. """ logging.info('Creating tx of certificate for recipient uid: %s ...', certificate_metadata.uid) with open(certificate_metadata.certificate_hash_file_name, 'rb') as in_file: # this is the recipient-specific hash that will be recorded on the # blockchain hashed_certificate = in_file.read() cert_out = CMutableTxOut(0, CScript([OP_RETURN, hashed_certificate])) # send a transaction to the recipient's public key, and to a revocation # address txouts = create_recipient_outputs(certificate_metadata.pubkey, revocation_address, fees.min_per_output) # define transaction inputs unspent_outputs = wallet.get_unspent_outputs(issuing_address) last_input = unspent_outputs[tail] txins = [CTxIn(last_input.outpoint)] value_in = last_input.amount # very important! If we don't send the excess change back to ourselves, # some lucky miner gets it! amount = value_in - fees.cost_per_transaction if amount > 0: change_out = create_transaction_output(issuing_address, amount) txouts = txouts + [change_out] txouts = txouts + [cert_out] tx = CMutableTransaction(txins, txouts) # this is the transaction for a recipient, unsigned hextx = hexlify(tx.serialize()) with open(certificate_metadata.unsigned_tx_file_name, 'wb') as out_file: out_file.write(bytes(hextx, 'utf-8')) logging.info('Created unsigned tx for recipient; last_input=%s', last_input) return last_input
def add_input_output(bitcoind, tx): """Add an input and an output to a CMutableTransaction, SIGHASH_ALL.""" # First we get some coins privkey = CKey(os.urandom(32)) scriptPubKey = CScript([OP_0, Hash160(privkey.pub)]) address = CBitcoinAddress.from_scriptPubKey(scriptPubKey) amount = Decimal("50") * Decimal(COIN) - Decimal("500") # This creates a one-output transaction txid = bitcoind.pay_to(str(address), amount / Decimal(COIN)) # We bump the fees by 5000 tx.vout.append(CTxOut(amount - Decimal("5000"), scriptPubKey)) tx.vin.append(CTxIn(COutPoint(lx(txid), 0))) # Sign the new output with ALL tx_hash = SignatureHash(address.to_redeemScript(), tx, 1, SIGHASH_ALL, int(amount), SIGVERSION_WITNESS_V0) sig = privkey.sign(tx_hash) + bytes([SIGHASH_ALL]) tx.wit.vtxinwit.append(CTxInWitness(CScriptWitness([sig, privkey.pub])))
def add_input_output(bitcoind, tx, coin, fees): """Add another input to the transaction to bump the feerate.""" coin_amount = Decimal(coin["amount"]) * Decimal(COIN) # First get the private key from bitcoind's wallet. privkey = CKey(wif_decode(bitcoind.dumpprivkey(coin["address"]))) # Add the fetched coin as a new input. tx.vin.append(CTxIn(COutPoint(lx(coin["txid"]), coin["vout"]))) # And likely add an output, otherwise all goes to the fees. scriptPubKey = CScript([OP_0, Hash160(privkey.pub)]) if coin_amount > fees + 294: # For simplicity, pay to the same script tx.vout.append(CTxOut(coin_amount - Decimal(fees), scriptPubKey)) address = CBitcoinAddress.from_scriptPubKey(scriptPubKey) # We only do this once, sign it with ALL tx_hash = SignatureHash(address.to_redeemScript(), tx, 1, SIGHASH_ALL, int(coin_amount), SIGVERSION_WITNESS_V0) sig = privkey.sign(tx_hash) + bytes([SIGHASH_ALL]) tx.wit.vtxinwit.append( CTxInWitness(CScriptWitness([sig, privkey.pub])) ) return tx
def transfer(self, src_addrs_key_map: OrderedDict, dst_addrs_amount_map: dict, txfee: Decimal, auto_calc_pay_back: bool, pay_back_index: int = 0xfffffff, ensure_one_txout: bool = False) -> str: """ :param src_addrs_key_map: {'addr1': 'privkey1', 'addr2': 'privkey2' } 私钥为 hex字符串 :param dst_addrs_amount_map: {'addr1':Decimal(0.1234), 'addr2':Deciaml(0.234) } :param txfee: 矿工费 :param auto_calc_pay_back: 是否自动计算并找零 :param pay_back_index: 找零地址索引 即在 src_addrs_key_map 中的索引 :param ensure_one_txout: 确认只有一个交易输出(比如: 提币不需要找零的情况, 归集) :return: txid """ #仅支持 P2PKH 类型的from地址 assert isinstance(src_addrs_key_map, OrderedDict), 'src_addrs_key_map is not OrderedDict' assert isinstance(dst_addrs_amount_map, dict), 'dst_addrs_amount_map is not dict' assert Decimal('0.00001') <= txfee <= Decimal( '0.001'), 'invalid txfee, please check txfee' assert len( src_addrs_key_map) >= 1, 'src_addrs_key_map length must >= 1' assert not (True == auto_calc_pay_back == ensure_one_txout) , \ 'True == auto_calc_pay_back == ensure_one_txout , must be mutex ' if ensure_one_txout: assert (len(dst_addrs_amount_map) == 1 ), 'dst_addrs_amount_map length must equal 1' elif not auto_calc_pay_back: assert (len(dst_addrs_amount_map) >= 1), 'dst_addrs_amount_map length must >= 2' if auto_calc_pay_back and pay_back_index >= len(src_addrs_key_map): raise Exception('pay_back_index is to large') self.logger.info( f'dst_addrs_amount_map is { json.dumps(dst_addrs_amount_map, indent=4, default=decimal_default) }' ) assert self.ping() == True, 'bitcoind rpc is gone' total_amount = sum(dst_addrs_amount_map.values()) + txfee self.logger.info(f'total_amount is {total_amount}') source_addrs = list(src_addrs_key_map.keys()) #WARNING: 禁止打印私钥!!! is_enough, founded_utxos = self.search_utxo(addrs=source_addrs, total_amount=total_amount) if not is_enough: msg = 'balance is not enough' self.logger.error(msg) raise Exception(msg) self.logger.info( f'founded_utxos is { json.dumps(founded_utxos, indent=4, default=decimal_default) }' ) #设置全局变量 SelectParams(self.net_type) #构造inputs txins = [] utxo_owner_map = dict() for addr, utxos in founded_utxos.items(): assert addr in src_addrs_key_map, 'addr is not in src_addrs_key_map' for utxo in utxos: txin = CMutableTxIn( prevout=COutPoint(hash=lx(utxo['txid']), n=utxo['vout'])) txins.append(txin) #因为顺序不会被打乱, 所以可以直接使用 索引进行对应 utxo_owner_map[len(txins) - 1] = addr #构造outputs txouts = [] for to_addr, amount in dst_addrs_amount_map.items(): out = CMutableTxOut( nValue=amount * COIN, scriptPubKey=CBitcoinAddress(to_addr).to_scriptPubKey()) txouts.append(out) #自动结算 if auto_calc_pay_back: sum_in_satoshi = 0 for addr, utxos in founded_utxos.items(): for utxo in utxos: sum_in_satoshi += utxo['value'] pay_back_in_satoshi = int(sum_in_satoshi - int(total_amount * COIN)) #判断找零的金额, 如果太小就不要了, 作为矿工费 if pay_back_in_satoshi >= MIN_AVAILABLE_UTXO_VALUE_IN_SATOSHI: pay_back_addr = list(src_addrs_key_map.keys())[pay_back_index] pay_back_out = CMutableTxOut( nValue=pay_back_in_satoshi, scriptPubKey=CBitcoinAddress( pay_back_addr).to_scriptPubKey()) txouts.append(pay_back_out) muttx = CMutableTransaction(vin=txins, vout=txouts) #对每个 input 进行签名 for n in range(len(txins)): #查找这个utxo属于哪个地址 owner_addr = utxo_owner_map[n] privkey = src_addrs_key_map[owner_addr] if len(privkey) == 64: # hex wif_key = PrivKeyToWIFCompress(privkey, self.net_type != 'mainnet') seckey = CBitcoinSecret(s=wif_key) elif len(privkey) == 52: #base58格式 seckey = CBitcoinSecret(s=privkey) else: raise Exception("invalid privkey") txin_script_pubkey = CScript([ OP_DUP, OP_HASH160, Hash160(seckey.pub), OP_EQUALVERIFY, OP_CHECKSIG ]) sig_hash = SignatureHash(txin_script_pubkey, muttx, n, SIGHASH_ALL) sig = seckey.sign(sig_hash) + bytes([SIGHASH_ALL]) muttx.vin[n].scriptSig = CScript([sig, seckey.pub]) #TODO: 处理验签失败抛异常 VerifyScript(muttx.vin[n].scriptSig, txin_script_pubkey, muttx, n, (SCRIPT_VERIFY_P2SH, )) pass raw_tx_hex = b2x(muttx.serialize()) self.logger.info(f'raw_tx_hex is: {raw_tx_hex}') # local_tx_hash = muttx.GetTxid() # self.logger.info(f'local_tx_hash is: {b2x(local_tx_hash)}') #广播交易 assert self.ping( ) == True, 'bitcoind rpc is gone' #测试 bitcoind的 rpc服务是否还在 txid = self.send_raw_tx(raw_tx_hex=raw_tx_hex) self.logger.info(f'send_raw_tx txid is: {txid}') return txid
for x in hashes_missing_in_genesis_block: if missing_addresses[x] in ignore_because_refunded: continue print " ->",x," height:" + str(missing_heights[x]) + " XEL:" + amtamt(missing_heights[x],float(missing_amounts_per_address[missing_addresses[x]])) + " [" + missing_addresses[x] + "] =",missing_amounts_per_address[missing_addresses[x]],"BTC in total (dont count addrs twice)" print "\n\nNow, Handing the Abnormal ..." # Now handling the abnormals abnormal_add_map = {} btc_abnormal = 0 for x in abnormal: btc_abnormal += float(x["btc_amount"]) scr = CScript(hash_to_script[x["btc_tx"]].decode("hex")) reas="" for kk in iter(scr): reas = kk scr2 = CScript(reas) reas="" want = 0 have = 0 cnt=0 for kk in iter(scr2): if cnt==0: want=kk else: if len(str(kk))>30: reas += str(P2PKHBitcoinAddress.from_pubkey(kk)) + "-" else:
def create_raw_velvet_tx(payload_buf): VELVET_FORK_MARKER = b'interlink' digest_outs = [CMutableTxOut(0, CScript([OP_RETURN, VELVET_FORK_MARKER, payload_buf]))] tx = CMutableTransaction([], digest_outs) return tx.serialize().hex()
def __init__(self, raw_hex): self._hex = raw_hex self._script = CScript(self._hex) self._operations = None
def locking_script_keys(key_one: coincurve.PublicKey, key_two: coincurve.PublicKey) -> CScript: return CScript([script.OP_0, sha256(Funding.redeemscript_keys(key_one, key_two)).digest()])
def redeemscript_keys(key_one: coincurve.PublicKey, key_two: coincurve.PublicKey) -> CScript: return CScript([script.OP_2] + [k.format() for k in Funding.sort_by_keys(key_one, key_two, key_one, key_two)] + [script.OP_2, script.OP_CHECKMULTISIG])
def redeemscript(self) -> CScript: return CScript([script.OP_2] + [k.format() for k in self.funding_pubkeys_for_tx()] + [script.OP_2, script.OP_CHECKMULTISIG])