1import io
2
3from .hash import sha256
4from pycoin.coins.bitcoin.SegwitChecker import ZERO32
5from pycoin.coins.bitcoin.SolutionChecker import BitcoinSolutionChecker
6from pycoin.encoding.bytes32 import from_bytes_32
7
8from pycoin.satoshi.satoshi_struct import stream_struct
9
10from pycoin.satoshi.flags import (
11    SIGHASH_NONE, SIGHASH_SINGLE, SIGHASH_ANYONECANPAY,
12)
13
14
15class GroestlcoinSolutionChecker(BitcoinSolutionChecker):
16    def _hash_prevouts(self, hash_type):
17        if hash_type & SIGHASH_ANYONECANPAY:
18            return ZERO32
19        f = io.BytesIO()
20        for tx_in in self.tx.txs_in:
21            f.write(tx_in.previous_hash)
22            stream_struct("L", f, tx_in.previous_index)
23        return sha256(f.getvalue())
24
25    def _hash_sequence(self, hash_type):
26        if (
27                (hash_type & SIGHASH_ANYONECANPAY) or
28                ((hash_type & 0x1f) == SIGHASH_SINGLE) or
29                ((hash_type & 0x1f) == SIGHASH_NONE)
30        ):
31            return ZERO32
32
33        f = io.BytesIO()
34        for tx_in in self.tx.txs_in:
35            stream_struct("L", f, tx_in.sequence)
36        return sha256(f.getvalue())
37
38    def _hash_outputs(self, hash_type, tx_in_idx):
39        txs_out = self.tx.txs_out
40        if hash_type & 0x1f == SIGHASH_SINGLE:
41            if tx_in_idx >= len(txs_out):
42                return ZERO32
43            txs_out = txs_out[tx_in_idx:tx_in_idx+1]
44        elif hash_type & 0x1f == SIGHASH_NONE:
45            return ZERO32
46        f = io.BytesIO()
47        for tx_out in txs_out:
48            stream_struct("QS", f, tx_out.coin_value, tx_out.script)
49        return sha256(f.getvalue())
50
51    def _signature_for_hash_type_segwit(self, script, tx_in_idx, hash_type):
52        return from_bytes_32(sha256(self._segwit_signature_preimage(script, tx_in_idx, hash_type)))
53