예제 #1
0
    def unsigned_datas(self, detail: bool = False) -> List[dict]:
        """
        Get Vapor transaction unsigned datas(messages) with instruction.

        :param detail: Vapor unsigned datas to see detail, defaults to False.
        :type detail: bool

        :returns: list -- Vapor transaction unsigned datas.

        >>> from swap.providers.vapor.htlc import HTLC
        >>> from swap.providers.vapor.transaction import FundTransaction
        >>> htlc: HTLC = HTLC(network="mainnet")
        >>> htlc.build_htlc(secret_hash="3a26da82ead15a80533a02696656b14b5dbfd84eb14790f2e1be5e9e45820eeb", recipient_public_key="3e0a377ae4afa031d4551599d9bb7d5b27f4736d77f78cac4d476f0ffba5ae3e", sender_public_key="fe6b3fd4458291b19605d92837ae1060cc0237e68022b2eb9faf01a118226212", endblock=120723497)
        >>> fund_transaction: FundTransaction = FundTransaction(network="mainnet")
        >>> fund_transaction.build_transaction(address="vp1qk9vj4jaezlcnjdckds4fkm8fwv5kawmqwpnpvs", htlc=htlc, amount=0.1, asset="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", unit="BTM")
        >>> fund_transaction.unsigned_datas()
        [{'datas': ['d7107257ef5fbfb04fc4747d6887f230a30676ecd6703a58015878b54f1f7b4f'], 'public_key': 'fe6b3fd4458291b19605d92837ae1060cc0237e68022b2eb9faf01a118226212', 'network': 'mainnet', 'path': 'm/44/153/1/0/1'}]
        """

        # Check transaction
        if self._transaction is None:
            raise ValueError("Transaction is none, build transaction first.")

        unsigned_datas: List[dict] = []
        for signing_instruction in self._transaction["signing_instructions"]:
            unsigned_data = dict(datas=signing_instruction["sign_data"])
            if "pubkey" in signing_instruction and signing_instruction["pubkey"]:
                unsigned_data.setdefault("public_key", signing_instruction["pubkey"])
                if detail:
                    program = get_program(public_key=signing_instruction["pubkey"])
                    address = get_address(program=program, network=self._network)
                    unsigned_data.setdefault("program", program)
                    unsigned_data.setdefault("address", address)
                else:
                    unsigned_data.setdefault("network", self._network)
            else:
                if detail:
                    unsigned_data.setdefault("public_key", None)
                    unsigned_data.setdefault("program", None)
                    unsigned_data.setdefault("address", None)
                else:
                    unsigned_data.setdefault("network", self._network)
            if "derivation_path" in signing_instruction and signing_instruction["derivation_path"]:
                path = indexes_to_path(indexes=signing_instruction["derivation_path"])
                if detail:
                    unsigned_data.setdefault("indexes", signing_instruction["derivation_path"])
                unsigned_data.setdefault("path", path)
            else:
                if detail:
                    unsigned_data.setdefault("indexes", None)
                unsigned_data.setdefault("path", None)
            # Append unsigned datas
            unsigned_datas.append(unsigned_data)

        return unsigned_datas
예제 #2
0
 def unsigned(self, detail=False):
     unsigned_datas = list()
     if self.transaction is None:
         raise ValueError("transaction is none, build transaction first.")
     for signing_instruction in self.transaction["signing_instructions"]:
         unsigned_data = dict(datas=signing_instruction["sign_data"])
         if "pubkey" in signing_instruction and signing_instruction[
                 "pubkey"]:
             unsigned_data.setdefault("public_key",
                                      signing_instruction["pubkey"])
             if detail:
                 program = get_program(
                     public_key=signing_instruction["pubkey"])
                 address = get_address(program=program,
                                       network=self.network)
                 unsigned_data.setdefault("program", program)
                 unsigned_data.setdefault("address", address)
             else:
                 unsigned_data.setdefault("network", self.network)
         else:
             if detail:
                 unsigned_data.setdefault("public_key", None)
                 unsigned_data.setdefault("program", None)
                 unsigned_data.setdefault("address", None)
             else:
                 unsigned_data.setdefault("network", self.network)
         if "derivation_path" in signing_instruction and signing_instruction[
                 "derivation_path"]:
             path = indexes_to_path(
                 indexes=signing_instruction["derivation_path"])
             if detail:
                 unsigned_data.setdefault(
                     "indexes", signing_instruction["derivation_path"])
             unsigned_data.setdefault("path", path)
         else:
             if detail:
                 unsigned_data.setdefault("indexes", None)
             unsigned_data.setdefault("path", None)
         # Append unsigned datas
         unsigned_datas.append(unsigned_data)
     # Returning
     return unsigned_datas
예제 #3
0
    def from_public_key(self, public):
        """
        Initiate Bytom wallet from public key.

        :param public: Bytom wallet public key.
        :type public: str.
        :returns:  Wallet -- Bytom wallet instance.

        >>> from swap.providers.bytom.wallet import Wallet
        >>> wallet = Wallet(network="mainnet")
        >>> wallet.from_public_key("91ff7f525ff40874c4f47f0cab42e46e3bf53adad59adef9558ad1b6448f22e2")
        <swap.providers.bytom.wallet.Wallet object at 0x040DA268>
        """

        # Bytom wallet initialization.
        Bytom = BTMWallet()
        self._public_key = public
        self._program = get_program(public_key=self._public_key)
        self._address = get_address(program=self._program,
                                    network=self.network)
        return self
예제 #4
0
    def from_xpublic_key(self, xpublic_key):
        """
        Initiate Bytom wallet from xpublic key.

        :param xpublic_key: Bytom wallet xpublic key.
        :type xpublic_key: str.
        :returns:  Wallet -- Bytom wallet instance.

        >>> from swap.providers.bytom.wallet import Wallet
        >>> wallet = Wallet(network="mainnet")
        >>> wallet.from_xpublic_key("16476b7fd68ca2acd92cfc38fa353e75d6103f828276f44d587e660a6bd7a5c5ef4490504bd2b6f997113671892458830de09518e6bd5958d5d5dd97624cfa4b")
        <swap.providers.bytom.wallet.Wallet object at 0x040DA268>
        """

        # Bytom wallet initialization.
        Bytom = BTMWallet()
        self._xpublic_key = xpublic_key
        self._public_key = get_public_key(xpublic_key=self._xpublic_key,
                                          path=self.path())
        self._program = get_program(public_key=self._public_key)
        self._address = get_address(program=self._program,
                                    network=self.network)
        return self
예제 #5
0
def test_wallet_tools():

    assert get_xpublic_key(
        xprivate_key=_["wallet"]["xprivate_key"]) == _["wallet"]["xpublic_key"]
    assert get_expand_xprivate_key(xprivate_key=_["wallet"]["xprivate_key"]
                                   ) == _["wallet"]["expand_xprivate_key"]

    assert indexes_to_path(
        indexes=_["wallet"]["indexes"]) == _["wallet"]["path"]
    assert path_to_indexes(path=_["wallet"]["path"]) == _["wallet"]["indexes"]

    assert get_child_xprivate_key(xprivate_key=_["wallet"]["xprivate_key"]
                                  ) == _["wallet"]["xprivate_key"]
    assert get_child_xprivate_key(
        xprivate_key=_["wallet"]["xprivate_key"],
        indexes=_["wallet"]["indexes"]) == _["wallet"]["child_xprivate_key"]
    assert get_child_xprivate_key(
        xprivate_key=_["wallet"]["xprivate_key"],
        path=_["wallet"]["path"]) == _["wallet"]["child_xprivate_key"]

    assert get_child_xpublic_key(
        xpublic_key=_["wallet"]["xpublic_key"]) == _["wallet"]["xpublic_key"]
    assert get_child_xpublic_key(
        xpublic_key=_["wallet"]["xpublic_key"],
        indexes=_["wallet"]["indexes"]) == _["wallet"]["child_xpublic_key"]
    assert get_child_xpublic_key(
        xpublic_key=_["wallet"]["xpublic_key"],
        path=_["wallet"]["path"]) == _["wallet"]["child_xpublic_key"]

    assert get_private_key(xprivate_key=_["wallet"]
                           ["xprivate_key"]) == _["wallet"]["xprivate_key"]
    assert get_private_key(
        xprivate_key=_["wallet"]["xprivate_key"],
        indexes=_["wallet"]["indexes"]) == _["wallet"]["child_xprivate_key"]
    assert get_private_key(
        xprivate_key=_["wallet"]["xprivate_key"],
        path=_["wallet"]["path"]) == _["wallet"]["child_xprivate_key"]

    assert get_public_key(xpublic_key=_["wallet"]
                          ["xpublic_key"]) == _["wallet"]["xpublic_key"][:64]
    assert get_public_key(
        xpublic_key=_["wallet"]["xpublic_key"],
        indexes=_["wallet"]["indexes"]) == _["wallet"]["public_key"]
    assert get_public_key(
        xpublic_key=_["wallet"]["xpublic_key"],
        path=_["wallet"]["path"]) == _["wallet"]["public_key"]

    assert get_program(
        public_key=_["wallet"]["public_key"]) == _["wallet"]["program"]

    assert get_address(program=_["wallet"]["program"],
                       network="mainnet",
                       vapor=False) == _["wallet"]["address"]["mainnet"]
    assert get_address(program=_["wallet"]["program"],
                       network="solonet",
                       vapor=False) == _["wallet"]["address"]["solonet"]
    assert get_address(program=_["wallet"]["program"],
                       network="testnet",
                       vapor=False) == _["wallet"]["address"]["testnet"]

    assert get_address(program=_["wallet"]["program"],
                       network="mainnet",
                       vapor=True) == _["wallet"]["vapor_address"]["mainnet"]
    assert get_address(program=_["wallet"]["program"],
                       network="solonet",
                       vapor=True) == _["wallet"]["vapor_address"]["solonet"]
    assert get_address(program=_["wallet"]["program"],
                       network="testnet",
                       vapor=True) == _["wallet"]["vapor_address"]["testnet"]
예제 #6
0
    def unsigned_datas(self, detail=False):
        """
        Get Bytom transaction unsigned datas with instruction.

        :param detail: Bytom unsigned datas to see detail, defaults to False.
        :type detail: bool
        :returns: list -- Bytom transaction unsigned datas.

        >>> from swap.providers.bytom.htlc import HTLC
        >>> from swap.providers.bytom.transaction import FundTransaction
        >>> from swap.providers.bytom.wallet import Wallet
        >>> htlc = HTLC(network="testnet").init("821124b554d13f247b1e5d10b84e44fb1296f18f38bbaa1bea34a12c843e0158", "3e0a377ae4afa031d4551599d9bb7d5b27f4736d77f78cac4d476f0ffba5ae3e", "91ff7f525ff40874c4f47f0cab42e46e3bf53adad59adef9558ad1b6448f22e2", 1000)
        >>> sender_wallet = Wallet(network="testnet").from_mnemonic("indicate warm sock mistake code spot acid ribbon sing over taxi toast")
        >>> fund_transaction = FundTransaction(network="testnet")
        >>> fund_transaction.build_transaction(sender_wallet, htlc, 10000)
        >>> fund_transaction.unsigned_datas()
        [{'datas': ['38601bf7ce08dab921916f2c723acca0451d8904649bbec16c2076f1455dd1a2'], 'public_key': '91ff7f525ff40874c4f47f0cab42e46e3bf53adad59adef9558ad1b6448f22e2', 'network': 'mainnet', 'path': 'm/44/153/1/0/1'}]
        """

        # Checking transaction
        if self.transaction is None:
            raise ValueError("transaction is none, build transaction first.")

        unsigned_datas = []
        for signing_instruction in self.transaction["signing_instructions"]:
            unsigned_data = dict(datas=signing_instruction["sign_data"])
            if "pubkey" in signing_instruction and signing_instruction[
                    "pubkey"]:
                unsigned_data.setdefault("public_key",
                                         signing_instruction["pubkey"])
                if detail:
                    program = get_program(
                        public_key=signing_instruction["pubkey"])
                    address = get_address(program=program,
                                          network=self.network)
                    unsigned_data.setdefault("program", program)
                    unsigned_data.setdefault("address", address)
                else:
                    unsigned_data.setdefault("network", self.network)
            else:
                if detail:
                    unsigned_data.setdefault("public_key", None)
                    unsigned_data.setdefault("program", None)
                    unsigned_data.setdefault("address", None)
                else:
                    unsigned_data.setdefault("network", self.network)
            if "derivation_path" in signing_instruction and signing_instruction[
                    "derivation_path"]:
                path = indexes_to_path(
                    indexes=signing_instruction["derivation_path"])
                if detail:
                    unsigned_data.setdefault(
                        "indexes", signing_instruction["derivation_path"])
                unsigned_data.setdefault("path", path)
            else:
                if detail:
                    unsigned_data.setdefault("indexes", None)
                unsigned_data.setdefault("path", None)
            # Append unsigned datas
            unsigned_datas.append(unsigned_data)
        # Returning
        return unsigned_datas
예제 #7
0
파일: htlc.py 프로젝트: saloppe73/swap
    def build_htlc(self,
                   secret_hash: str,
                   recipient_public_key: str,
                   sender_public_key: str,
                   endblock: int,
                   use_script: bool = False) -> "HTLC":
        """
        Build Bytom Hash Time Lock Contract (HTLC).

        :param secret_hash: secret sha-256 hash.
        :type secret_hash: str
        :param recipient_public_key: Bytom recipient public key.
        :type recipient_public_key: str
        :param sender_public_key: Bytom sender public key.
        :type sender_public_key: str
        :param endblock: Bytom expiration block height.
        :type endblock: int
        :param use_script: Initialize HTLC by using script, default to ``False``.
        :type use_script: bool

        :returns: HTLC -- Bytom Hash Time Lock Contract (HTLC) instance.

        >>> from swap.providers.bytom.htlc import HTLC
        >>> from swap.providers.bytom.rpc import get_current_block_height
        >>> from swap.utils import sha256
        >>> htlc: HTLC = HTLC(network="mainnet")
        >>> htlc.build_htlc(secret_hash=sha256("Hello Meheret!"), recipient_public_key="3e0a377ae4afa031d4551599d9bb7d5b27f4736d77f78cac4d476f0ffba5ae3e", sender_public_key="fe6b3fd4458291b19605d92837ae1060cc0237e68022b2eb9faf01a118226212", endblock=get_current_block_height(plus=100), use_script=False)
        <swap.providers.bytom.htlc.HTLC object at 0x0409DAF0>
        """

        # Checking parameters instances
        if len(secret_hash) != 64:
            raise ValueError("Invalid secret hash, length must be 64")
        if len(recipient_public_key) != 64:
            raise ValueError(
                "Invalid Bytom recipient public key, length must be 64")
        if len(sender_public_key) != 64:
            raise ValueError(
                "Invalid Bytom sender public key, length must be 64")

        if use_script:

            # Get current working directory path (like linux or unix path).
            cwd: str = PurePosixPath(
                os.path.dirname(os.path.realpath(__file__))).__str__().replace(
                    "\\", "/")

            with open(f"{cwd}/contracts/htlc.equity", "r",
                      encoding="utf-8") as htlc_equity_file:
                htlc_script: str = "".join(htlc_equity_file.readlines()[-14:])
                htlc_equity_file.close()

            htlc_agreement: List[str, int] = [
                secret_hash, recipient_public_key, sender_public_key, endblock
            ]
            # Compile HTLC by script
            self._script = Equity(config[self._network]["bytom-core"])\
                .compile_source(htlc_script, htlc_agreement)
        else:
            # Compile HTLC by script binary
            builder: Builder = Builder()
            builder.add_int(endblock)
            builder.add_bytes(bytes.fromhex(sender_public_key))
            builder.add_bytes(bytes.fromhex(recipient_public_key))
            builder.add_bytes(bytes.fromhex(secret_hash))
            builder.add_op(OP_DEPTH)
            builder.add_bytes(bytes.fromhex(config["htlc_script_binary"]))
            builder.add_op(OP_FALSE)
            builder.add_op(OP_CHECKPREDICATE)

            sequence: str = bytes(c_int64(endblock)).rstrip(b'\x00').hex()
            self._script = dict(
                program=builder.hex_digest(),
                opcodes=
                f"0x{sequence} 0x{sender_public_key} 0x{recipient_public_key} "
                f"0x{secret_hash} DEPTH 0x{config['htlc_script_binary']} FALSE CHECKPREDICATE"
            )

        self.agreements = {
            "secret_hash": secret_hash,
            "recipient": {
                "public_key":
                recipient_public_key,
                "address":
                get_address(
                    program=get_program(public_key=recipient_public_key),
                    network=self._network,
                    vapor=False)
            },
            "sender": {
                "public_key":
                sender_public_key,
                "address":
                get_address(program=get_program(public_key=sender_public_key),
                            network=self._network,
                            vapor=False)
            },
            "endblock": endblock
        }
        return self
예제 #8
0
PATH: str = "m/44/153/1/0/1"

print("Get XPublic Key:", get_xpublic_key(xprivate_key=XPRIVATE_KEY))
print("Get Expand XPrivate Key:",
      get_expand_xprivate_key(xprivate_key=XPRIVATE_KEY))

print("Indexes To Path:", indexes_to_path(indexes=INDEXES))
print("Path To Indexes:", path_to_indexes(path=PATH))

print("Get Child XPrivate Key:",
      get_child_xprivate_key(xprivate_key=XPRIVATE_KEY))
print("Get Child XPublic Key:", get_child_xpublic_key(xpublic_key=XPUBLIC_KEY))

print("Get Private Key:", get_private_key(xprivate_key=XPRIVATE_KEY))
print("Get Public Key:", get_public_key(xpublic_key=XPUBLIC_KEY))

print("Get Program:",
      get_program(public_key=get_public_key(xpublic_key=XPUBLIC_KEY)))
print(
    "Get Address:",
    get_address(program=get_program(public_key=get_public_key(
        xpublic_key=XPUBLIC_KEY)),
                network="mainnet",
                vapor=False))
print(
    "Get Vapor Address:",
    get_address(program=get_program(public_key=get_public_key(
        xpublic_key=XPUBLIC_KEY)),
                network="mainnet",
                vapor=True))
예제 #9
0
    def unsigned_datas(self, detail: bool = False) -> List[dict]:
        """
        Get Bytom transaction unsigned datas(messages) with instruction.

        :param detail: Bytom unsigned datas to see detail, defaults to False.
        :type detail: bool

        :returns: list -- Bytom transaction unsigned datas.

        >>> from swap.providers.bytom.htlc import HTLC
        >>> from swap.providers.bytom.transaction import FundTransaction
        >>> htlc: HTLC = HTLC(network="mainnet")
        >>> htlc.build_htlc(secret_hash="3a26da82ead15a80533a02696656b14b5dbfd84eb14790f2e1be5e9e45820eeb", recipient_public_key="3e0a377ae4afa031d4551599d9bb7d5b27f4736d77f78cac4d476f0ffba5ae3e", sender_public_key="fe6b3fd4458291b19605d92837ae1060cc0237e68022b2eb9faf01a118226212", endblock=679208)
        >>> fund_transaction: FundTransaction = FundTransaction(network="mainnet")
        >>> fund_transaction.build_transaction(address="bm1qk9vj4jaezlcnjdckds4fkm8fwv5kawmq9qrufx", htlc=htlc, amount=0.1, asset="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", unit="BTM")
        >>> fund_transaction.unsigned_datas()
        [{"datas": ["f42a2b6e15585b88da8b34237c7a6fd83af12ee6971813d66cf794a63ebcc16f"], "public_key": "fe6b3fd4458291b19605d92837ae1060cc0237e68022b2eb9faf01a118226212", "network": "mainnet", "path": "m/44/153/1/0/1"}]
        """

        # Check transaction
        if self._transaction is None:
            raise ValueError("Transaction is none, build transaction first.")

        unsigned_datas: List[dict] = []
        for signing_instruction in self._transaction["signing_instructions"]:
            unsigned_data = dict(datas=signing_instruction["sign_data"])
            if "pubkey" in signing_instruction and signing_instruction[
                    "pubkey"]:
                unsigned_data.setdefault("public_key",
                                         signing_instruction["pubkey"])
                if detail:
                    program = get_program(
                        public_key=signing_instruction["pubkey"])
                    address = get_address(program=program,
                                          network=self._network)
                    unsigned_data.setdefault("program", program)
                    unsigned_data.setdefault("address", address)
                else:
                    unsigned_data.setdefault("network", self._network)
            else:
                if detail:
                    unsigned_data.setdefault("public_key", None)
                    unsigned_data.setdefault("program", None)
                    unsigned_data.setdefault("address", None)
                else:
                    unsigned_data.setdefault("network", self._network)
            if "derivation_path" in signing_instruction and signing_instruction[
                    "derivation_path"]:
                path = indexes_to_path(
                    indexes=signing_instruction["derivation_path"])
                if detail:
                    unsigned_data.setdefault(
                        "indexes", signing_instruction["derivation_path"])
                unsigned_data.setdefault("path", path)
            else:
                if detail:
                    unsigned_data.setdefault("indexes", None)
                unsigned_data.setdefault("path", None)
            # Append unsigned datas
            unsigned_datas.append(unsigned_data)

        return unsigned_datas
예제 #10
0
NETWORK: str = "mainnet"
# Bytom public key
PUBLIC_KEY: str = "5b5a06f6fbcb74b58ebb42293808fec6222234df6c97d7c1cff6d857a6024dc2"

# Get public key hash
public_key_hash = get_public_key_hash(public_key=PUBLIC_KEY)
print("Public Key Hash:", public_key_hash)
# Get Pay to Public Key Hash(P2PKH) program
p2pkh_program = get_p2pkh_program(public_key_hash=public_key_hash)
print("P2PKH Program:", p2pkh_program)
# Get Pay to Witness Public Key Hash(P2WPKH) program
p2wpkh_program = get_p2wpkh_program(public_key_hash=public_key_hash)
assert get_program(public_key=PUBLIC_KEY) == p2wpkh_program
print("P2WPKH Program:", p2wpkh_program)
# Get Pay to Witness Public Key Hash(P2WPKH) address
p2wpkh_address = get_p2wpkh_address(public_key_hash=public_key_hash,
                                    network=NETWORK,
                                    vapor=False)
assert get_address(program=get_program(public_key=PUBLIC_KEY),
                   network=NETWORK,
                   vapor=False) == p2wpkh_address
print("P2WPKH Address:", p2wpkh_address)
# Get Pay to Witness Public Key Hash(P2WPKH) vapor address
p2wpkh_vapor_address = get_p2wpkh_address(public_key_hash=public_key_hash,
                                          network=NETWORK,
                                          vapor=True)
assert get_address(program=get_program(public_key=PUBLIC_KEY),
                   network=NETWORK,
                   vapor=True) == p2wpkh_vapor_address
print("P2WPKH Vapor Address:", p2wpkh_vapor_address)