예제 #1
0
    def utxos(self):
        if self._outputs is None:
            import urllib.request
            import json
            url = network('utxo_url').format(address=self.address)

            req = urllib.request.Request(url)
            outputs = []
            try:
                with urllib.request.urlopen(req) as resp:
                    data = json.loads(resp.read().decode())
            except HTTPError as e:
                resp = e.read().decode()
                if resp == 'No free outputs to spend':
                    self._outputs = []
                else:
                    raise UpstreamError(resp)
            else:
                for item in data['unspent_outputs']:
                    out = Output(value=item['value'],
                                 script=hex_to_bytes(item['script']))
                    out.parent_id = hex_to_bytes(item['tx_hash_big_endian'])
                    out.tx_index = item['tx_output_n']
                    outputs.append(out)
                self._outputs = outputs
        return self._outputs
예제 #2
0
    def test_encoding(self):
        raw_sig = hex_to_bytes('304402206878b5690514437a2342405029426cc2b25b4a03fc396fef845d656cf62bad2c022018610a8d37e3384245176ab49ddbdbe8da4133f661bf5ea7ad4e3d2b912d856f')

        sig = Signature.decode(raw_sig)

        self.assertEqual(sig.r, 47253809947851177065887724633329625063088643784040492056218945870752194997548)
        self.assertEqual(sig.s, 11026965355983493404719379810734327200902731292741433431270495068542334764399)

        self.assertEqual(sig.encode(), raw_sig)

        r = hex_to_int('316eb3cad8b66fcf1494a6e6f9542c3555addbf337f04b62bf4758483fdc881d')
        s = hex_to_int('bf46d26cef45d998a2cb5d2d0b8342d70973fa7c3c37ae72234696524b2bc812')
        sig_high_s = hex_to_bytes('30450220316eb3cad8b66fcf1494a6e6f9542c3555addbf337f04b62bf4758483fdc881d022100bf46d26cef45d998a2cb5d2d0b8342d70973fa7c3c37ae72234696524b2bc812')
        sig_low_s = hex_to_bytes('30440220316eb3cad8b66fcf1494a6e6f9542c3555addbf337f04b62bf4758483fdc881d022040b92d9310ba26675d34a2d2f47cbd27b13ae26a7310f1c99c8bc83a850a792f')

        sig_high = Signature(r, s, force_low_s=False)
        sig_low = Signature(r, s, force_low_s=True)
        self.assertEqual(sig_low.encode(), sig_low_s)
        self.assertEqual(sig_high.encode(), sig_high_s)
        self.assertEqual(sig_low, Signature.decode(sig_high_s))
        self.assertEqual(sig_low, Signature.decode(sig_low_s))

        sig = Signature(secrets.randbelow(CURVE.N), secrets.randbelow(CURVE.N))
        self.assertEqual(sig, Signature.decode(sig.encode()))

        # Test padding
        sig = Signature(secrets.randbelow(10**8), secrets.randbelow(10**8))
        self.assertEqual(sig, Signature.decode(sig.encode()))
예제 #3
0
 def from_seed(cls, seed: Union[bytes, str], addresstype='P2PKH') -> 'Xprv':
     if isinstance(seed, str):
         seed = hex_to_bytes(seed)
     assert 16 <= len(seed) <= 64, 'Seed should be between 128 and 512 bits'
     I = hmac.new(key=b"Bitcoin seed", msg=seed,
                  digestmod=hashlib.sha512).digest()
     I_L, I_R = I[:32], I[32:]
     if bytes_to_int(I_L) == 0 or bytes_to_int(I_L) > CURVE.N:
         raise KeyDerivationError
     key, code = PrivateKey(I_L), I_R
     return cls(key, code, addresstype=addresstype)
예제 #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)}")
예제 #5
0
def get_type(script):
    """https://github.com/bitcoin/bitcoin/blob/5961b23898ee7c0af2626c46d5d70e80136578d3/src/script/script.cpp#L202"""
    script = hex_to_bytes(script) if isinstance(script, str) else script
    if script.startswith(OP.HASH160.byte + OP.PUSH20.byte) and script.endswith(
            OP.EQUAL.byte) and len(script) == 23:
        return TX.P2SH
    elif script.startswith(OP.DUP.byte + OP.HASH160.byte) and script.endswith(
            OP.EQUALVERIFY.byte + OP.CHECKSIG.byte) and len(script) == 25:
        return TX.P2PKH
    elif script.startswith(b'\x00' + OP.PUSH32.byte) and len(script) == 34:
        return TX.P2WSH
    elif script.startswith(b'\x00' + OP.PUSH20.byte) and len(script) == 22:
        return TX.P2WPKH
    elif script.startswith(OP.PUSH65.byte + b'\x04') and script.endswith(
            OP.CHECKSIG.byte) and len(script) == 67:  # uncompressed PK
        return TX.P2PK
    elif script.startswith((b'\x21\x03', b'\x21\x02')) and script.endswith(
            OP.CHECKSIG.byte) and len(script) == 35:  # compressed PK
        return TX.P2PK
    else:
        raise ScriptValidationError(
            f"Unknown script type: {bytes_to_hex(script)}")
예제 #6
0
def asm(script):
    """Turns a script into a symbolic representation"""
    if isinstance(script, str):
        script = hex_to_bytes(script)
    else:
        script = copy(script)

    def read(n):
        nonlocal script
        data = script[:n]
        assert data or n == 0, 'EOF'
        script = script[n:]
        return data

    results = []
    while script:
        byte = bytes_to_int(read(1))
        op = OP(byte)
        if byte in range(1, 76):
            results.append(bytes_to_hex(read(byte)))
        else:
            results.append(str(op))

    return ' '.join(results)
예제 #7
0
 def from_hex(cls, hexstring: str) -> 'PublicKey':
     return cls.decode(hex_to_bytes(hexstring))
예제 #8
0
 def from_hex(cls, hexstring):
     return cls.deserialize(hex_to_bytes(hexstring))