예제 #1
0
 def add_fee(self):
     """Adding fee to the transaction by decreasing 'change' transaction."""
     if not self.fee:
         self.calculate_fee()
     fee_in_satoshi = to_base_units(self.fee)
     if len(self.tx.vout) == 1 or self.tx.vout[1].nValue < fee_in_satoshi:
         raise RuntimeError(
             'Cannot subtract fee from change transaction. You need to add more input transactions.'
         )
     self.tx.vout[1].nValue -= fee_in_satoshi
예제 #2
0
    def build_outputs(self):
        if not self.secret_hash:
            self.generate_hash()
            self.set_locktime(number_of_hours=self.init_hours)
        else:
            self.set_locktime(number_of_hours=self.participate_hours)

        self.build_atomic_swap_contract()

        contract_p2sh = self.contract.to_p2sh_scriptPubKey()

        self.tx_out_list = [
            CMutableTxOut(to_base_units(self.value), contract_p2sh),
        ]
        if self.utxo_value > self.value:
            change = self.utxo_value - self.value
            self.tx_out_list.append(
                CMutableTxOut(
                    to_base_units(change),
                    CBitcoinAddress(self.sender_address).to_scriptPubKey()))
예제 #3
0
    def get_first_vout_from_tx_json(cls, tx_json: dict) -> CTxOut:
        '''
        Adapter method for returning first vout.

        Args:
            tx_json (dict): dictionary with transaction details

        Returns:
            CTxOut: transaction output
        '''
        cscript = script.CScript.fromhex(
            tx_json['vout'][0]['scriptPubKey']['hex'])
        nValue = to_base_units(float(tx_json['vout'][0]['value']))
        return CTxOut(nValue, cscript)
예제 #4
0
def test_transaction_fee(unsigned_transaction):

    assert type(unsigned_transaction.size) == int

    unsigned_transaction.fee_per_kb = 0.002
    unsigned_transaction.add_fee()
    assert type(unsigned_transaction.fee) == float
    assert unsigned_transaction.fee < 1, 'Transaction fee should be in main units'

    change_without_fee = unsigned_transaction.tx.vout[1].nValue
    unsigned_transaction.add_fee()
    change_with_fee = unsigned_transaction.tx.vout[1].nValue

    assert change_without_fee - to_base_units(unsigned_transaction.fee) == change_with_fee
    assert unsigned_transaction.tx.serialize()
예제 #5
0
 def build_outputs(self):
     self.tx_out_list = [
         CMutableTxOut(
             to_base_units(self.value),
             CBitcoinAddress(self.recipient_address).to_scriptPubKey())
     ]
예제 #6
0
    def __init__(
        self,
        network,
        contract: str,
        raw_transaction: Optional[str]=None,
        transaction_address: Optional[str]=None
    ):

        if not raw_transaction and not transaction_address:
            raise ValueError('Provide raw_transaction or transaction_address argument.')

        self.network = network
        self.symbol = self.network.default_symbol
        self.contract = contract
        self.tx = None
        self.vout = None
        self.confirmations = None
        self.tx_address = transaction_address
        if raw_transaction:
            self.tx = self.network.deserialize_raw_transaction(raw_transaction)
            try:
                self.vout = self.tx.vout[0]
            except IndexError:
                raise ValueError('Given transaction has no outputs.')
        else:
            tx_json = get_transaction(network.default_symbol, transaction_address, network.is_test_network())
            if not tx_json:
                raise ValueError('No transaction found under given address.')
            if 'hex' in tx_json:
                # transaction from blockcypher or raven explorer
                self.tx = self.network.deserialize_raw_transaction(tx_json['hex'])
                self.vout = self.tx.vout[0]
            else:
                # transaction from cryptoid
                incorrect_cscript = script.CScript.fromhex(tx_json['outputs'][0]['script'])
                correct_cscript = script.CScript([script.OP_HASH160, list(incorrect_cscript)[2], script.OP_EQUAL])
                nValue = to_base_units(tx_json['outputs'][0]['amount'])
                self.vout = CTxOut(nValue, correct_cscript)

            if 'confirmations' in tx_json:
                self.confirmations = tx_json['confirmations']
            elif 'block_height' in tx_json:
                self.confirmations = self.network.latest_block - tx_json['block_height']
            elif 'block' in tx_json:
                self.confirmations = self.network.latest_block - tx_json['block']

        if not self.vout:
            raise ValueError('Given transaction has no outputs.')

        contract_tx_out = self.vout
        contract_script = script.CScript.fromhex(self.contract)
        script_pub_key = contract_script.to_p2sh_scriptPubKey()
        valid_p2sh = script_pub_key == contract_tx_out.scriptPubKey
        self.address = str(CBitcoinAddress.from_scriptPubKey(script_pub_key))
        self.balance = get_balance(self.network, self.address)

        script_ops = list(contract_script)
        if valid_p2sh and self.is_valid_contract_script(script_ops):
            self.recipient_address = str(P2PKHBitcoinAddress.from_bytes(script_ops[6]))
            self.refund_address = str(P2PKHBitcoinAddress.from_bytes(script_ops[13]))
            self.locktime_timestamp = int.from_bytes(script_ops[8], byteorder='little')
            self.locktime = datetime.utcfromtimestamp(self.locktime_timestamp)
            self.secret_hash = b2x(script_ops[2])
            self.value = from_base_units(contract_tx_out.nValue)
        else:
            raise ValueError('Given transaction is not a valid contract.')
예제 #7
0
def test_to_base_units(btc_value):
    satoshi_value = to_base_units(btc_value)

    assert isinstance(satoshi_value, int)
    assert satoshi_value == round(btc_value * COIN)
예제 #8
0
파일: cryptoid.py 프로젝트: MerlinB/clove
 def get_first_vout_from_tx_json(cls, tx_json: dict) -> CTxOut:
     incorrect_cscript = script.CScript.fromhex(tx_json['outputs'][0]['script'])
     correct_cscript = script.CScript([script.OP_HASH160, list(incorrect_cscript)[2], script.OP_EQUAL])
     nValue = to_base_units(tx_json['outputs'][0]['amount'])
     return CTxOut(nValue, correct_cscript)
예제 #9
0
 def get_first_vout_from_tx_json(cls, tx_json: dict) -> CTxOut:
     cscript = script.CScript.fromhex(tx_json['vout'][0]['scriptPubKey']['hex'])
     nValue = to_base_units(float(tx_json['vout'][0]['value']))
     return CTxOut(nValue, cscript)