chia-blockchain/chia/types/spend_bundle.py

67 lines
2.1 KiB
Python

from dataclasses import dataclass
from typing import List
from blspy import AugSchemeMPL, G2Element
from chia.types.blockchain_format.coin import Coin
from chia.types.blockchain_format.sized_bytes import bytes32
from chia.util.streamable import Streamable, streamable
from .coin_solution import CoinSolution
@dataclass(frozen=True)
@streamable
class SpendBundle(Streamable):
"""
This is a list of coins being spent along with their solution programs, and a single
aggregated signature. This is the object that most closely corresponds to a bitcoin
transaction (although because of non-interactive signature aggregation, the boundaries
between transactions are more flexible than in bitcoin).
"""
coin_solutions: List[CoinSolution]
aggregated_signature: G2Element
@classmethod
def aggregate(cls, spend_bundles) -> "SpendBundle":
coin_solutions: List[CoinSolution] = []
sigs: List[G2Element] = []
for bundle in spend_bundles:
coin_solutions += bundle.coin_solutions
sigs.append(bundle.aggregated_signature)
aggregated_signature = AugSchemeMPL.aggregate(sigs)
return cls(coin_solutions, aggregated_signature)
def additions(self) -> List[Coin]:
items: List[Coin] = []
for coin_solution in self.coin_solutions:
items.extend(coin_solution.additions())
return items
def removals(self) -> List[Coin]:
"""This should be used only by wallet"""
return [_.coin for _ in self.coin_solutions]
def fees(self) -> int:
"""Unsafe to use for fees validation!!!"""
amount_in = sum(_.amount for _ in self.removals())
amount_out = sum(_.amount for _ in self.additions())
return amount_in - amount_out
def name(self) -> bytes32:
return self.get_hash()
def not_ephemeral_additions(self):
all_removals = self.removals()
all_additions = self.additions()
result: List[Coin] = []
for add in all_additions:
if add in all_removals:
continue
result.append(add)
return result