示例#1
0
 def send(self, to: dict, fee: float, private: PrivateKey) -> Transaction:
     balance = btc_to_satoshi(self.balance())
     fee = btc_to_satoshi(fee)
     to = {key: btc_to_satoshi(val) for key, val in to.items()}
     sum_send = sum(to.values())
     if balance < sum_send + fee:
         raise ValidationError("Insufficient balance")
     elif balance > sum_send + fee:
         raise ValidationError(f"You are trying to send {sum_send/10**8} BTC which is "
                               f"less than this address' current balance of {balance/10**8}."
                               f" You must provide a change address or explicitly add the difference as a fee")
     inputs = [out.spend() for out in self.utxos]
     outputs = [Address(addr)._receive(val) for addr, val in to.items()]
     tx = Transaction(inputs=inputs, outputs=outputs)
     for idx in range(len(tx.inputs)):
         tx.inputs[idx].tx_index = idx
         tx.inputs[idx]._parent = tx
     for inp in tx.inputs:
         inp.sign(private)
     return tx
示例#2
0
    def verify(self, i=None, debug=False):
        """Run the script for the i-th input or all the inputs"""
        sum_inputs = sum(inp.ref().value for inp in self.inputs)
        sum_outputs = sum(out.value for out in self.outputs)
        if sum_outputs > sum_inputs:
            raise ValidationError("Value of outputs is greater than value of inputs")
        if i is not None:
            vm = VM(self, i)
            return vm.verify(debug=debug)
        else:
            results = []
            for idx in range(len(self.inputs)):
                vm = VM(self, idx)
                results.append(vm.verify())

            return all(results)
示例#3
0
 def _receive(self, value: int):
     """Creates an output that sends to this address"""
     addr_type = self.type()
     output = Output(value=value, script=b'')
     if addr_type == ADDRESS.P2PKH:
         address = base58.decode(self.address).rjust(25, b'\x00')
         keyhash = address[1:-4]
         output.script = OP.DUP.byte + OP.HASH160.byte + push(keyhash) + OP.EQUALVERIFY.byte + OP.CHECKSIG.byte
     elif addr_type == ADDRESS.P2SH:
         address = base58.decode(self.address).rjust(25, b'\x00')
         scripthash = address[1:-4]
         output.script = OP.HASH160.byte + push(scripthash) + OP.EQUAL.byte
     elif addr_type in (ADDRESS.P2WPKH, ADDRESS.P2WSH):
         witness_version, witness_program = bech32.decode(network('hrp'), self.address)
         output.script = OP(bytes_to_int(witness_byte(witness_version))).byte + push(bytes(witness_program))
     else:
         raise ValidationError(f"Cannot create output of type {addr_type}")
     return output
示例#4
0
def get_address(script):
    """Extracts the address from a scriptPubkey"""
    script = hex_to_bytes(script) if isinstance(script, str) else script
    stype = get_type(script)
    if stype == TX.P2SH:
        data = script[2:22]
        version = network('scripthash')
        return hashed_payload_to_address(version + data)
    elif stype == TX.P2PKH:
        data = script[3:23]
        version = network('keyhash')
        return hashed_payload_to_address(version + data)
    elif stype in (TX.P2WSH, TX.P2WPKH):
        witver = version_byte(script)
        witprog = witness_program(script)
        return bech32.encode(network('hrp'), witver, witprog)
    elif stype == TX.P2PK:
        return "N/A"
    raise ValidationError(f"Unknown script type: {bytes_to_hex(script)}")