def create_transaction(prevtx, n, sig, value): tx = CTransaction() assert (n < len(prevtx.vout)) tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), sig, 0xffffffff)) tx.vout.append(CTxOut(value, "")) tx.calc_sha256() return tx
def create_transaction(prevtx, n, sig, value): tx = CTransaction() assert(n < len(prevtx.vout)) tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), sig, 0xffffffff)) tx.vout.append(CTxOut(value, "")) tx.calc_sha256() return tx
def create_transaction(self, node, coinbase, to_address, amount): from_txid = node.getblock(coinbase)['tx'][0] inputs = [{ "txid" : from_txid, "vout" : 0}] outputs = { to_address : amount } rawtx = node.createrawtransaction(inputs, outputs) signresult = node.signrawtransaction(rawtx) tx = CTransaction() f = cStringIO.StringIO(unhexlify(signresult['hex'])) tx.deserialize(f) return tx
def create_transaction(self, node, coinbase, to_address, amount): from_txid = node.getblock(coinbase)['tx'][0] inputs = [{"txid": from_txid, "vout": 0}] outputs = {to_address: amount} rawtx = node.createrawtransaction(inputs, outputs) signresult = node.signrawtransaction(rawtx) tx = CTransaction() f = cStringIO.StringIO(unhexlify(signresult['hex'])) tx.deserialize(f) return tx
def get(self, txhash): serialized_tx = None try: serialized_tx = self.txDB[repr(txhash)] except KeyError: return None f = cStringIO.StringIO(serialized_tx) ret = CTransaction() ret.deserialize(f) ret.calc_sha256() return ret
def create_coinbase(heightAdjust = 0): global counter coinbase = CTransaction() coinbase.vin.append(CTxIn(COutPoint(0, 0xffffffff), ser_string(serialize_script_num(counter+heightAdjust)), 0xffffffff)) counter += 1 coinbaseoutput = CTxOut() coinbaseoutput.nValue = 50*100000000 halvings = int((counter+heightAdjust)/150) # regtest coinbaseoutput.nValue >>= halvings coinbaseoutput.scriptPubKey = "" coinbase.vout = [ coinbaseoutput ] coinbase.calc_sha256() return coinbase
def SignatureHash(script, txTo, inIdx, hashtype): """Consensus-correct SignatureHash Returns (hash, err) to precisely match the consensus-critical behavior of the SIGHASH_SINGLE bug. (inIdx is *not* checked for validity) """ HASH_ONE = b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' if inIdx >= len(txTo.vin): return (HASH_ONE, "inIdx %d out of range (%d)" % (inIdx, len(txTo.vin))) txtmp = CTransaction(txTo) for txin in txtmp.vin: txin.scriptSig = b'' txtmp.vin[inIdx].scriptSig = FindAndDelete(script, CScript([OP_CODESEPARATOR])) if (hashtype & 0x1f) == SIGHASH_NONE: txtmp.vout = [] for i in range(len(txtmp.vin)): if i != inIdx: txtmp.vin[i].nSequence = 0 elif (hashtype & 0x1f) == SIGHASH_SINGLE: outIdx = inIdx if outIdx >= len(txtmp.vout): return (HASH_ONE, "outIdx %d out of range (%d)" % (outIdx, len(txtmp.vout))) tmp = txtmp.vout[outIdx] txtmp.vout = [] for i in range(outIdx): txtmp.vout.append(CTxOut()) txtmp.vout.append(tmp) for i in range(len(txtmp.vin)): if i != inIdx: txtmp.vin[i].nSequence = 0 if hashtype & SIGHASH_ANYONECANPAY: tmp = txtmp.vin[inIdx] txtmp.vin = [] txtmp.vin.append(tmp) s = txtmp.serialize() s += struct.pack(b"<I", hashtype) hash = hash256(s) return (hash, None)
def create_coinbase(heightAdjust=0): global counter coinbase = CTransaction() coinbase.vin.append( CTxIn(COutPoint(0, 0xffffffff), ser_string(serialize_script_num(counter + heightAdjust)), 0xffffffff)) counter += 1 coinbaseoutput = CTxOut() coinbaseoutput.nValue = 50 * 100000000 halvings = int((counter + heightAdjust) / 150) # regtest coinbaseoutput.nValue >>= halvings coinbaseoutput.scriptPubKey = "" coinbase.vout = [coinbaseoutput] coinbase.calc_sha256() return coinbase
def create_coinbase_h(block_height, halving_interval=2000, heightAdjust=0): subsidy = int(12.5 * 100000000) halvings = int((block_height + heightAdjust) // halving_interval) # 2000 is default for regtest subsidy >>= halvings coinbase = CTransaction() coinbase.vin.append( CTxIn(COutPoint(0, 0xffffffff), CScript([block_height + heightAdjust, OP_0]), 0xffffffff)) coinbaseoutput = CTxOut() coinbaseoutput.nValue = subsidy coinbaseoutput.scriptPubKey = b"" coinbase.vout.append(coinbaseoutput) found, supn, secn = get_coinbase_quotas(block_height) found_out = CTxOut() found_out.nValue = subsidy * found // 1000 found_out.scriptPubKey = CScript([OP_HASH160, found_addr, OP_EQUAL]) coinbaseoutput.nValue -= found_out.nValue coinbase.vout.append(found_out) if supn > 0: supn_out = CTxOut() supn_out.nValue = subsidy * supn // 1000 supn_out.scriptPubKey = CScript([OP_HASH160, supn_addr, OP_EQUAL]) coinbaseoutput.nValue -= supn_out.nValue coinbase.vout.append(supn_out) if secn > 0: secn_out = CTxOut() secn_out.nValue = subsidy * secn // 1000 secn_out.scriptPubKey = CScript([OP_HASH160, secn_addr, OP_EQUAL]) coinbaseoutput.nValue -= secn_out.nValue coinbase.vout.append(secn_out) coinbase.calc_sha256() return coinbase
def create_coinbase(heightAdjust=0): global counter coinbase = CTransaction() coinbase.vin.append( CTxIn(COutPoint(0, 0xffffffff), CScript([counter + heightAdjust, OP_0]), 0xffffffff)) counter += 1 coinbaseoutput = CTxOut() coinbaseoutput.nValue = int(5 * 100000000) halvings = int((counter + heightAdjust) / 150) # regtest coinbaseoutput.nValue >>= halvings coinbaseoutput.scriptPubKey = "" coinbase.vout = [coinbaseoutput] if halvings == 0: # regtest froutput = CTxOut() froutput.nValue = coinbaseoutput.nValue / 5 # regtest fraddr = bytearray([ 0x67, 0x08, 0xe6, 0x67, 0x0d, 0xb0, 0xb9, 0x50, 0xda, 0xc6, 0x80, 0x31, 0x02, 0x5c, 0xc5, 0xb6, 0x32, 0x13, 0xa4, 0x91 ]) froutput.scriptPubKey = CScript([OP_HASH160, fraddr, OP_EQUAL]) coinbaseoutput.nValue -= froutput.nValue coinbase.vout = [coinbaseoutput, froutput] coinbase.calc_sha256() return coinbase
def create_coinbase(heightAdjust = 0): global counter coinbase = CTransaction() coinbase.vin.append(CTxIn(COutPoint(0, 0xffffffff), CScript([counter+heightAdjust, OP_0]), 0xffffffff)) counter += 1 coinbaseoutput = CTxOut() coinbaseoutput.nValue = int(12.5*100000000) halvings = int((counter+heightAdjust)/150) # regtest coinbaseoutput.nValue >>= halvings coinbaseoutput.scriptPubKey = "" coinbase.vout = [ coinbaseoutput ] if halvings == 0: # regtest froutput = CTxOut() froutput.nValue = coinbaseoutput.nValue / 5 # regtest fraddr = bytearray([0x67, 0x08, 0xe6, 0x67, 0x0d, 0xb0, 0xb9, 0x50, 0xda, 0xc6, 0x80, 0x31, 0x02, 0x5c, 0xc5, 0xb6, 0x32, 0x13, 0xa4, 0x91]) froutput.scriptPubKey = CScript([OP_HASH160, fraddr, OP_EQUAL]) coinbaseoutput.nValue -= froutput.nValue coinbase.vout = [ coinbaseoutput, froutput ] coinbase.calc_sha256() return coinbase
def SignatureHash(script, txTo, inIdx, hashtype): """Consensus-correct SignatureHash Returns (hash, err) to precisely match the consensus-critical behavior of the SIGHASH_SINGLE bug. (inIdx is *not* checked for validity) """ HASH_ONE = b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' if inIdx >= len(txTo.vin): return (HASH_ONE, "inIdx %d out of range (%d)" % (inIdx, len(txTo.vin))) txtmp = CTransaction(txTo) for txin in txtmp.vin: txin.scriptSig = b'' txtmp.vin[inIdx].scriptSig = FindAndDelete(script, CScript([OP_CODESEPARATOR])) if (hashtype & 0x1f) == SIGHASH_NONE: txtmp.vout = [] for i in range(len(txtmp.vin)): if i != inIdx: txtmp.vin[i].nSequence = 0 elif (hashtype & 0x1f) == SIGHASH_SINGLE: outIdx = inIdx if outIdx >= len(txtmp.vout): return (HASH_ONE, "outIdx %d out of range (%d)" % (outIdx, len(txtmp.vout))) tmp = txtmp.vout[outIdx] txtmp.vout = [] for i in range(outIdx): txtmp.vout.append(CTxOut(-1)) txtmp.vout.append(tmp) for i in range(len(txtmp.vin)): if i != inIdx: txtmp.vin[i].nSequence = 0 if hashtype & SIGHASH_ANYONECANPAY: tmp = txtmp.vin[inIdx] txtmp.vin = [] txtmp.vin.append(tmp) s = txtmp.serialize() s += struct.pack(b"<I", hashtype) hash = hash256(s) return (hash, None)
def create_tampered_rawtx_cbh(node_from, node_to, tx_amount, fee, mode): genesis_block_hash = node_from.getblock(str(0))['hash'] # select necessary UTXOs usp = node_from.listunspent() assert (len(usp) != 0) amount = Decimal('0') inputs = [] for x in usp: amount += Decimal(x['amount']) inputs.append({"txid": x['txid'], "vout": x['vout']}) if amount >= tx_amount + fee: break outputs = { node_from.getnewaddress(): (Decimal(amount) - tx_amount - fee), node_to.getnewaddress(): tx_amount } rawTx = node_from.createrawtransaction(inputs, outputs) # build an object from the raw Tx in order to be able to modify it tx_01 = CTransaction() f = StringIO(unhexlify(rawTx)) tx_01.deserialize(f) # corrupt vouts in this Tx for vout_idx in range(len(tx_01.vout)): decodedScriptOrig = node_from.decodescript( hexlify(tx_01.vout[vout_idx].scriptPubKey)) scriptOrigAsm = decodedScriptOrig['asm'] params = scriptOrigAsm.split() hash160 = hex_str_to_bytes(params[2]) original_height = int(params[6]) original_hash = hex_str_to_bytes(params[5]) if mode == MODE_HEIGHT: # new referenced block height evil_height = -1 # new referenced block hash modTargetHash = hex_str_to_bytes(swap_bytes(genesis_block_hash)) # build modified script: CScript is putting a 4f (OP_NEGATE) for our -1 # edit script.py to send different stuff for the -1 value (like ff itself!) modScriptPubKey = CScript([ OP_DUP, OP_HASH160, hash160, OP_EQUALVERIFY, OP_CHECKSIG, modTargetHash, evil_height, OP_CHECKBLOCKATHEIGHT ]) elif mode == MODE_SWAP_ARGS: modScriptPubKey = CScript([ OP_DUP, OP_HASH160, hash160, OP_EQUALVERIFY, OP_CHECKSIG, original_height, original_hash, OP_CHECKBLOCKATHEIGHT ]) elif mode == MODE_NON_MIN_ENC: non_min_h = hex_str_to_bytes("07000000") modScriptPubKey = CScript([ OP_DUP, OP_HASH160, hash160, OP_EQUALVERIFY, OP_CHECKSIG, original_hash, non_min_h, OP_CHECKBLOCKATHEIGHT ]) else: assert (False) tx_01.vout[vout_idx].scriptPubKey = modScriptPubKey tx_01.rehash() signedRawTx = node_from.signrawtransaction(ToHex(tx_01)) return signedRawTx