from decimal import Decimal
import time
from test_framework.bch.script import anycanspend_locking_script
from .nodemessages import CBlock, CTransaction, CTxIn, COutPoint, CTxOut
from ..script import CScript
from ..constants import COIN
from ..serialize import ser_string, serialize_script_num
COINBASE_REWARD = Decimal("50.00000000")
def create_block(hashprev, coinbase, n_time: int | None = None, txns=None) -> CBlock:
block = CBlock()
if n_time is None:
block.n_time = int(time.time() + 600)
else:
block.n_time = n_time
if isinstance(hashprev, str):
hashprev = int(hashprev, 16)
block.hash_prev_block = hashprev
block.n_bits = 0x207FFFFF if coinbase:
block.vtx.append(coinbase)
if txns:
txns.sort(key=lambda x: x.hash)
block.vtx += txns
block.hash_merkle_root = block.calc_merkle_root()
block.rehash()
return block
def create_coinbase(height) -> CTransaction:
coinbase = CTransaction()
coinbase.vin.append(
CTxIn(
COutPoint(0, 0xFFFFFFFF),
ser_string(serialize_script_num(height)),
0xFFFFFFFF,
)
)
coinbaseoutput = CTxOut()
coinbaseoutput.n_value = int(COINBASE_REWARD) * COIN
halvings = int(height / 150) coinbaseoutput.n_value >>= halvings
script_pubkey = anycanspend_locking_script()
coinbaseoutput.script_pubkey = CScript(script_pubkey)
coinbase.vout = [coinbaseoutput]
coinbase_size = len(coinbase.serialize())
if coinbase_size < 100:
coinbase.vin[0].script_sig += b"x" * (100 - coinbase_size)
coinbase.calc_sha256()
return coinbase
PADDED_ANY_SPEND = (
b"\x61" * 50
)
def create_transaction(
prevtx: CTransaction, n, sig, value, out=PADDED_ANY_SPEND, out_type=0
) -> CTransaction:
prevtx.calc_sha256()
if not isinstance(value, list):
value = [value]
tx = CTransaction()
assert n < len(prevtx.vout)
tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), sig, 0xFFFFFFFF))
for v in value:
tx.vout.append(CTxOut(v, out))
tx.rehash()
return tx