# ---------------------------
# Simple UTXO Blockchain
# ---------------------------

class TxOut:
    def __init__(self, addr, amt, txid, idx):
        self.addr, self.amt, self.txid, self.idx = addr, amt, txid, idx

class TxIn:
    def __init__(self, ref_id): self.ref_id = ref_id

class Tx:
    def __init__(self, txid, ins, outs):
        self.id, self.ins, self.outs = txid, ins, outs

class Block:
    def __init__(self, txs): self.txs = txs

# ---------------------------
# Build UTXO Set
# ---------------------------
def build_utxo(chain):
    utxos = {}
    for blk in chain:
        for tx in blk.txs:
            # Remove spent outputs
            for tin in tx.ins: utxos.pop(tin.ref_id, None)
            # Add new outputs
            for i, tout in enumerate(tx.outs):
                utxos[f"{tx.id}:{i}"] = tout
    return utxos

# ---------------------------
# Example Blockchain
# ---------------------------

# Block 1: Coinbase to Alice
tx1 = Tx("tx1", [], [TxOut("Alice", 50, "tx1", 0)])
# Block 2: Alice sends 30 to Bob, 20 back to herself
tx2 = Tx("tx2", [TxIn("tx1:0")], [TxOut("Bob", 30, "tx2", 0), TxOut("Alice", 20, "tx2", 1)])

chain = [Block([tx1]), Block([tx2])]
utxos = build_utxo(chain)

# Print UTXO set
print("\nUTXO Set:")
for uid, u in utxos.items():
    print(f"{uid} -> {u.addr} has {u.amt}")
