Пример #1
0
 def address(self) -> str:
     if not self.scope.script_pubkey.data:
         return "Fee"
     if self.scope.script_pubkey.data.startswith(b"\x6a"):
         if len(self.scope.script_pubkey.data) == 1:
             return "DUMMY"  # dummy output to blind
         else:
             return "OP_RETURN " + self.scope.script_pubkey.data[1:].hex()
     try:
         # try making a liquid address
         return liquid_address(
             self.scope.script_pubkey, self.blinding_key, network=self.network
         )
     except:
         # if failed - return hex of the scriptpubkey
         return self.scope.script_pubkey.data.hex()
Пример #2
0
    def decoderawtransaction(self, tx):
        unblinded = self.unblindrawtransaction(tx)["hex"]
        obj = super().__getattr__("decoderawtransaction")(unblinded)
        try:
            # unblind the rest of outputs
            b = LTransaction.from_string(tx)

            mbpk = PrivateKey(bytes.fromhex(self.dumpmasterblindingkey()))
            net = get_network(self.getblockchaininfo().get("chain"))

            outputs = obj["vout"]
            datas = []
            fee = 0
            # search for datas encoded in rangeproofs
            for i, out in enumerate(b.vout):
                o = outputs[i]
                if isinstance(out.value, int):
                    if "value" in o:
                        assert o["value"] == round(out.value * 1e-8, 8)
                    else:
                        o["value"] = round(out.value * 1e-8, 8)
                    if "asset" in o:
                        assert o["asset"] == bytes(reversed(
                            out.asset[-32:])).hex()
                    else:
                        o["asset"] = bytes(reversed(out.asset[-32:])).hex()
                    try:
                        o["scriptPubKey"]["addresses"] = [
                            liquid_address(out.script_pubkey, network=net)
                        ]
                    except:
                        pass
                    if out.script_pubkey.data == b"":
                        # fee negative?
                        fee -= out.value

                pk = slip77.blinding_key(mbpk, out.script_pubkey)
                try:
                    res = out.unblind(pk.secret, message_length=1000)
                    value, asset, vbf, abf, extra, min_value, max_value = res
                    if "value" in o:
                        assert o["value"] == round(value * 1e-8, 8)
                    else:
                        o["value"] = round(value * 1e-8, 8)
                    if "asset" in o:
                        assert o["asset"] == bytes(reversed(asset[-32:])).hex()
                    else:
                        o["asset"] = bytes(reversed(asset[-32:])).hex()
                    try:
                        o["scriptPubKey"]["addresses"] = [
                            liquid_address(out.script_pubkey, pk, network=net)
                        ]
                    except:
                        pass
                    if len(extra.rstrip(b"\x00")) > 0:
                        datas.append(extra)
                except Exception as e:
                    pass

            # should be changed with seed from tx
            tx = PSET(b)
            seed = tagged_hash("liquid/blinding_seed", mbpk.secret)
            txseed = tx.txseed(seed)
            pubkeys = {}

            for extra in datas:
                s = BytesIO(extra)
                while True:
                    k = read_string(s)
                    if len(k) == 0:
                        break
                    v = read_string(s)
                    if k[0] == 1 and len(k) == 5:
                        idx = int.from_bytes(k[1:], "little")
                        pubkeys[idx] = v
                    elif k == b"\x01\x00":
                        txseed = v

            for i, out in enumerate(outputs):
                o = out
                if i in pubkeys and len(pubkeys[i]) in [33, 65]:
                    nonce = tagged_hash("liquid/range_proof",
                                        txseed + i.to_bytes(4, "little"))
                    if b.vout[i].ecdh_pubkey == PrivateKey(nonce).sec():
                        try:
                            res = unblind(
                                pubkeys[i],
                                nonce,
                                b.vout[i].witness.range_proof.data,
                                b.vout[i].value,
                                b.vout[i].asset,
                                b.vout[i].script_pubkey,
                            )
                            value, asset, vbf, abf, extra, min_value, max_value = res
                            if "value" in o:
                                assert o["value"] == round(value * 1e-8, 8)
                            else:
                                o["value"] = round(value * 1e-8, 8)
                            if "asset" in o:
                                assert o["asset"] == bytes(
                                    reversed(asset[-32:])).hex()
                            else:
                                o["asset"] = bytes(reversed(asset[-32:])).hex()
                            try:
                                o["scriptPubKey"]["addresses"] = [
                                    liquid_address(
                                        b.vout[i].script_pubkey,
                                        PublicKey.parse(pubkeys[i]),
                                        network=net,
                                    )
                                ]
                            except:
                                pass
                        except Exception as e:
                            logger.warn(
                                f"Failed at unblinding output {i}: {e}")
                    else:
                        logger.warn(f"Failed at unblinding: {e}")
            if fee != 0:
                obj["fee"] = round(-fee * 1e-8, 8)
        except Exception as e:
            logger.warn(f"Failed at unblinding transaction: {e}")
        return obj
Пример #3
0
 def address(self) -> str:
     # TODO: blinding key?
     try:
         return liquid_address(self.scope.script_pubkey, network=self.network)
     except:
         return None