1#!/usr/bin/env python3 2# blocktools.py - utilities for manipulating blocks and transactions 3# Copyright (c) 2015-2016 The Bitcoin Core developers 4# Distributed under the MIT software license, see the accompanying 5# file COPYING or http://www.opensource.org/licenses/mit-license.php. 6 7from .mininode import * 8from .script import CScript, OP_TRUE, OP_CHECKSIG, OP_RETURN 9 10# Create a block (with regtest difficulty) 11def create_block(hashprev, coinbase, nTime=None): 12 block = CBlock() 13 if nTime is None: 14 import time 15 block.nTime = int(time.time()+600) 16 else: 17 block.nTime = nTime 18 block.hashPrevBlock = hashprev 19 block.nBits = 0x207fffff # Will break after a difficulty adjustment... 20 block.vtx.append(coinbase) 21 block.hashMerkleRoot = block.calc_merkle_root() 22 block.calc_sha256() 23 return block 24 25# From BIP141 26WITNESS_COMMITMENT_HEADER = b"\xaa\x21\xa9\xed" 27 28# According to BIP141, blocks with witness rules active must commit to the 29# hash of all in-block transactions including witness. 30def add_witness_commitment(block, nonce=0): 31 # First calculate the merkle root of the block's 32 # transactions, with witnesses. 33 witness_nonce = nonce 34 witness_root = block.calc_witness_merkle_root() 35 witness_commitment = uint256_from_str(hash256(ser_uint256(witness_root)+ser_uint256(witness_nonce))) 36 # witness_nonce should go to coinbase witness. 37 block.vtx[0].wit.vtxinwit = [CTxInWitness()] 38 block.vtx[0].wit.vtxinwit[0].scriptWitness.stack = [ser_uint256(witness_nonce)] 39 40 # witness commitment is the last OP_RETURN output in coinbase 41 output_data = WITNESS_COMMITMENT_HEADER + ser_uint256(witness_commitment) 42 block.vtx[0].vout.append(CTxOut(0, CScript([OP_RETURN, output_data]))) 43 block.vtx[0].rehash() 44 block.hashMerkleRoot = block.calc_merkle_root() 45 block.rehash() 46 47 48def serialize_script_num(value): 49 r = bytearray(0) 50 if value == 0: 51 return r 52 neg = value < 0 53 absvalue = -value if neg else value 54 while (absvalue): 55 r.append(int(absvalue & 0xff)) 56 absvalue >>= 8 57 if r[-1] & 0x80: 58 r.append(0x80 if neg else 0) 59 elif neg: 60 r[-1] |= 0x80 61 return r 62 63# Create a coinbase transaction, assuming no miner fees. 64# If pubkey is passed in, the coinbase output will be a P2PK output; 65# otherwise an anyone-can-spend output. 66def create_coinbase(height, pubkey = None): 67 coinbase = CTransaction() 68 coinbase.vin.append(CTxIn(COutPoint(0, 0xffffffff), 69 ser_string(serialize_script_num(height)), 0xffffffff)) 70 coinbaseoutput = CTxOut() 71 coinbaseoutput.nValue = 50 * COIN 72 halvings = int(height/150) # regtest 73 coinbaseoutput.nValue >>= halvings 74 if (pubkey != None): 75 coinbaseoutput.scriptPubKey = CScript([pubkey, OP_CHECKSIG]) 76 else: 77 coinbaseoutput.scriptPubKey = CScript([OP_TRUE]) 78 coinbase.vout = [ coinbaseoutput ] 79 coinbase.calc_sha256() 80 return coinbase 81 82# Create a transaction. 83# If the scriptPubKey is not specified, make it anyone-can-spend. 84def create_transaction(prevtx, n, sig, value, scriptPubKey=CScript()): 85 tx = CTransaction() 86 assert(n < len(prevtx.vout)) 87 tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), sig, 0xffffffff)) 88 tx.vout.append(CTxOut(value, scriptPubKey)) 89 tx.calc_sha256() 90 return tx 91 92def get_legacy_sigopcount_block(block, fAccurate=True): 93 count = 0 94 for tx in block.vtx: 95 count += get_legacy_sigopcount_tx(tx, fAccurate) 96 return count 97 98def get_legacy_sigopcount_tx(tx, fAccurate=True): 99 count = 0 100 for i in tx.vout: 101 count += i.scriptPubKey.GetSigOpCount(fAccurate) 102 for j in tx.vin: 103 # scriptSig might be of type bytes, so convert to CScript for the moment 104 count += CScript(j.scriptSig).GetSigOpCount(fAccurate) 105 return count 106