コード例 #1
0
def main(self):
    """
    to run:

    kosmos 'j.clients.goldchain.test(name="transaction_get")'
    """
    cleanup("testnet_unittest_client")

    # create a goldchain client for devnet
    c = j.clients.goldchain.new("testnet_unittest_client", network_type="TEST")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = GoldChainExplorerGetClientStub()
    explorer_client.hash_add(
        "96df1e34533ffcd42ee1db995e165538edd275ba0c065ef9293ead84ff923eec",
        '{"hashtype":"transactionid","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"96df1e34533ffcd42ee1db995e165538edd275ba0c065ef9293ead84ff923eec","height":2662,"parent":"b69bc0a12308938cbc8207483f39df63a2295142875944d6a2db3930d5c2564f","rawtransaction":{"version":0,"data":{"coininputs":[{"parentid":"c1df239aba64ca0c6a241ddf18f3dd18b75e2c650874dd4c8c7dbbb56bd73683","unlocker":{"type":1,"condition":{"publickey":"ed25519:25b6aae78d545d64746f4a7310230e7b7bce263dcaa9dd5b3b6dd614d0f46413"},"fulfillment":{"signature":"7453f27cca1381f0cc05a6142b8d4ded5c1f84132742ba359df99ea7c17b2f304f8b9c8f3722da9ceb632fb7f526c8022c71e385bb75df9542cf94a7f3f3cc06"}}}],"coinoutputs":[{"value":"1000000000000000","unlockhash":"0199f4f21fc13ceb22da91d4b1701e67556a7c23f118bc5b1b15b132433d07b2496e093c4f4cd6"},{"value":"88839999200000000","unlockhash":"0175c11c8124e325cdba4f6843e917ba90519e9580adde5b10de5a7cabcc3251292194c5a0e6d2"}],"minerfees":["100000000"]}},"coininputoutputs":[{"value":"89839999300000000","condition":{"type":1,"data":{"unlockhash":"01d1c4dd242e3badf45004be9a3b86c613923c6d872bab5ec92e4f076114d4c3a15b7b43e1c00f"}},"unlockhash":"01d1c4dd242e3badf45004be9a3b86c613923c6d872bab5ec92e4f076114d4c3a15b7b43e1c00f"}],"coinoutputids":["90513506d1216f89e73a361b6306d8543c81aff092e376ee8d8bb9b7ea024de6","7daf8035a6697701aeed36b4d6fe8de6ff4bbf9fd1ba9b0933d87e260f924783"],"coinoutputunlockhashes":["0199f4f21fc13ceb22da91d4b1701e67556a7c23f118bc5b1b15b132433d07b2496e093c4f4cd6","0175c11c8124e325cdba4f6843e917ba90519e9580adde5b10de5a7cabcc3251292194c5a0e6d2"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    c._explorer_get = explorer_client.explorer_get

    # get a transaction
    txn = c.transaction_get(
        "96df1e34533ffcd42ee1db995e165538edd275ba0c065ef9293ead84ff923eec")

    # from the transaction you can get all kind of info
    assert str(
        txn.id
    ) == "96df1e34533ffcd42ee1db995e165538edd275ba0c065ef9293ead84ff923eec"
    assert txn.height == 2662
    assert (
        txn.version == 1
    )  # in reality it is 0, but the JSX goldchain client converts v0 transactions automatically to v1 transactions
    assert len(txn.coin_inputs) == 1
    assert str(
        txn.coin_inputs[0].parentid
    ) == "c1df239aba64ca0c6a241ddf18f3dd18b75e2c650874dd4c8c7dbbb56bd73683"
    assert len(txn.coin_outputs) == 2
    assert str(txn.coin_outputs[0].value) == "1000000"
    assert (
        str(txn.coin_outputs[1].condition.unlockhash) ==
        "0175c11c8124e325cdba4f6843e917ba90519e9580adde5b10de5a7cabcc3251292194c5a0e6d2"
    )
    assert str(txn.miner_fees[0]) == "0.1"
    assert len(txn.miner_fees) == 1

    # the explorer provides us also with info that is not part of a goldchain txn,
    # the goldchain client injects this into the txn as well for easy look-up
    assert str(txn.coin_inputs[0].parent_output.value) == "89839999.3"
    assert (
        str(txn.coin_inputs[0].parent_output.condition.unlockhash) ==
        "01d1c4dd242e3badf45004be9a3b86c613923c6d872bab5ec92e4f076114d4c3a15b7b43e1c00f"
    )
    assert str(
        txn.coin_outputs[0].id
    ) == "90513506d1216f89e73a361b6306d8543c81aff092e376ee8d8bb9b7ea024de6"
    assert str(
        txn.coin_outputs[1].id
    ) == "7daf8035a6697701aeed36b4d6fe8de6ff4bbf9fd1ba9b0933d87e260f924783"
    assert txn.unconfirmed == False

    c.delete()
コード例 #2
0
def main(self):
    """
    to run:

    kosmos 'j.clients.goldchain.test(name="minter_condition_get")'
    """

    cleanup("testnet_unittest_client")

    # create a goldchain client for devnet
    c = j.clients.goldchain.new("testnet_unittest_client", network_type="TEST")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = GoldChainExplorerGetClientStub()
    # add initial mint condition
    explorer_client.mint_condition_add(
        condition=j.clients.goldchain.types.conditions.from_recipient(
            "01a006599af1155f43d687635e9680650003a6c506934996b90ae84d07648927414046f9f0e936"
        ),
        height=0,
    )
    # overwrite explorer get logic
    c._explorer_get = explorer_client.explorer_get

    # getting the latest mint condition is as easy as making the following call:
    condition = c.minter.condition_get()
    assert condition.unlockhash == "01a006599af1155f43d687635e9680650003a6c506934996b90ae84d07648927414046f9f0e936"

    # you can also get the condition active for a certain block height as follows:
    for height in [0, 500, 23400, 120000]:
        # as there is only one mint condition registered at the moment, it will return that one no matter what
        condition = c.minter.condition_get(height)
        assert condition.unlockhash == "01a006599af1155f43d687635e9680650003a6c506934996b90ae84d07648927414046f9f0e936"

    # if another one gets registered,
    explorer_client.mint_condition_add(
        condition=j.clients.goldchain.types.conditions.from_recipient((
            1,
            [
                "01a006599af1155f43d687635e9680650003a6c506934996b90ae84d07648927414046f9f0e936",
                "011cf61451b58970eeead00819e33f7fc812bd9b2d4e66914efa6163e238752d34be252ac8667f",
            ],
        )),
        height=50,
    )
    # it will return the latest condition when requesting the latest,
    # and it will return the one active at the current height
    condition = c.minter.condition_get()
    assert condition.unlockhash == "037187176be3a123b545209d933f4250a20f4baac78051c0993653500e9d6bc46d290e499b058c"
    for height in [0, 1, 23, 49]:
        condition = c.minter.condition_get(height)
        assert condition.unlockhash == "01a006599af1155f43d687635e9680650003a6c506934996b90ae84d07648927414046f9f0e936"
    for height in [50, 51, 200, 500, 15000]:
        condition = c.minter.condition_get(height)
        assert condition.unlockhash == "037187176be3a123b545209d933f4250a20f4baac78051c0993653500e9d6bc46d290e499b058c"

    c.delete()
コード例 #3
0
def main(self):
    """
    to run:

    kosmos 'j.clients.goldchain.test(name="wallet_new")'
    """

    cleanup("devnet_unittest_client")

    # create a goldchain client for devnet
    c = j.clients.goldchain.new("devnet_unittest_client", network_type="DEV")

    # for standard net you could also immediate create a new wallet using
    # `c = j.goldchain.clients.mydevclient`, or the more explicit form
    # `c = j.clients.goldchain.new("mydevclient", network_type="STD")`

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = GoldChainExplorerGetClientStub()
    c._explorer_get = explorer_client.explorer_get

    # create a new devnet wallet
    w = c.wallets.new("mywallet")  # is the implicit form of `c.wallets.new("mywallet")`

    # a goldchain (JS) wallet uses the underlying goldchain client for all its
    # interaction with the goldchain network
    assert w.network_type == "DEV"

    # the seed is the mnemonic used to generate the entropy from
    assert len(w.seed) > 0
    # the entropy is used to generate the private keys of this wallet,
    # only one private key by default, and for each private key a public key is generated as well
    assert len(w.seed_entropy) > 0

    # a wallet address is generated from the blake2 hash of a public key, owned by the wallet
    assert len(w.addresses) == 1
    # should you want to know the address count there is a property for that
    assert w.key_count == 1

    # generating a new address is easy as well
    assert len(w.address_new()) == 78  # all addresses have a fixed length of 78
    assert w.key_count == 2
    assert w.addresses[0] != w.addresses[1]
    for address in w.addresses:
        assert address[:2] == "01"  # all wallet addresses start with the `01` prefix

    # the private public key pair, for a given unlock hash, is available as well,
    # but is meant for dev purposes, not for an end-user
    for address in w.addresses:
        assert address == str(w.key_pair_get(address).unlockhash)

    c.wallets.delete()
    c.delete()
コード例 #4
0
def main(self):
    """
    to run:

    kosmos 'j.clients.goldchain.test(name="blockstake_output_get")'
    """

    cleanup("testnet_unittest_client")

    # create a goldchain client for devnet
    c = j.clients.goldchain.new("testnet_unittest_client", network_type="TEST")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = GoldChainExplorerGetClientStub()
    # spent block stake output
    explorer_client.hash_add(
        "fb3644143770aeef28020b8bea7c35320cb1e2341d17a338389bd7e3afb9990b",
        '{"hashtype":"blockstakeoutputid","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"a277de3f98a75e3199b1829b4f71093b23044e0fc995cb98224fe22ebda14c84","height":14733,"parent":"62d947526f5012d771c9618851fbf7069930a9106c53cd89dda858738b84f6f1","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"a877078376f423d4f7a477959adffdaa58e445f39ef00c94330d7bf89a053535","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"b52b1aedb4e228914356490467cfcdae4d09d68c214806b358e8e503232fd9d5865ff14ed9196154343498001a25c17396e2109015f21c67387c9a5ea9490706"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["fb3644143770aeef28020b8bea7c35320cb1e2341d17a338389bd7e3afb9990b"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false},{"id":"ba0be0145a3415440eddf5cf6f5268e3119c4ab67207652efb6783f0723b0aba","height":14734,"parent":"1f9454cef5a71e9b43ef2eae35bfb6171b596e96177d9a6ef59a9bd2ec854b30","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"fb3644143770aeef28020b8bea7c35320cb1e2341d17a338389bd7e3afb9990b","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"7ea47daa3d131f9bb28a7b0aebc9c9399ba6d9f1ae216d85ff6a6735362f9fc4bca4c0ec3de2d5b386187d882f7b5f76e9846e5f6c559d3bb196dd38c6d46e0c"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["cf9dc7e9bf57d2ad9be81fa9d1039f41e55afc743f7bce5e5379cf4d8a8ce018"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    c._explorer_get = explorer_client.explorer_get

    # get a blockstake output that has already been spent
    bso, creation_txn, spend_txn = c.blockstake_output_get(
        "fb3644143770aeef28020b8bea7c35320cb1e2341d17a338389bd7e3afb9990b"
    )
    assert spend_txn is not None
    assert bso is not None
    assert creation_txn is not None
    assert bso.id == "fb3644143770aeef28020b8bea7c35320cb1e2341d17a338389bd7e3afb9990b"
    assert str(bso.value) == "3000"
    assert (
        str(bso.condition.unlockhash)
        == "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"
    )
    assert str(creation_txn.id) == "a277de3f98a75e3199b1829b4f71093b23044e0fc995cb98224fe22ebda14c84"
    assert len(creation_txn.coin_inputs) == 0
    assert len(creation_txn.coin_outputs) == 0
    assert len(creation_txn.blockstake_inputs) == 1
    assert (
        str(creation_txn.blockstake_inputs[0].parentid)
        == "a877078376f423d4f7a477959adffdaa58e445f39ef00c94330d7bf89a053535"
    )
    assert len(creation_txn.blockstake_outputs) == 1
    assert creation_txn.blockstake_outputs[0] == bso
    assert str(spend_txn.id) == "ba0be0145a3415440eddf5cf6f5268e3119c4ab67207652efb6783f0723b0aba"
    assert len(spend_txn.blockstake_inputs) == 1
    assert spend_txn.blockstake_inputs[0].parentid == bso.id

    c.delete()
コード例 #5
0
def test():
    """
    to run:

    kosmos 'j.clients.goldchain.test(name="wallet_recover")'
    """

    cleanup("devnet_unittest_client")

    # create a goldchain client for devnet
    c = j.clients.goldchain.new("devnet_unittest_client", network_type="DEV")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = GoldChainExplorerGetClientStub()
    c._explorer_get = explorer_client.explorer_get

    # the devnet genesis seed is the seed of the wallet,
    # which receives all block stakes and coins in the genesis block of the goldchain devnet
    DEVNET_GENESIS_SEED = "carbon boss inject cover mountain fetch fiber fit tornado cloth wing dinosaur proof joy intact fabric thumb rebel borrow poet chair network expire else"

    # create a new devnet wallet
    w = c.wallets.new("mywallet", seed=DEVNET_GENESIS_SEED)
    # we create a new wallet using an existing seed,
    # such that our seed is used and not a new randomly generated seed

    # a goldchain (JS) wallet uses the underlying goldchain client for all its
    # interaction with the goldchain network
    assert w.network_type == "DEV"

    # by default we still have 1 address only,
    # you can change this however by creating a new wallet with the `key_count` parameter
    # set to a value higher than 1
    assert w.key_count == 1
    # the first address is known for the genesis devnet wallet
    assert w.address == "015df22a2e82a3323bc6ffbd1730450ed844feca711c8fe0c15e218c171962fd17b206263220ee"

    # the next 2 addresses are known as well
    assert w.address_new() == "01095d1811ae152aad0a5dd40588d8414e3bc3132ce8bd2405df13df164635646e3afe5e3af280"
    assert w.address_new() == "0183ccf250c5a13b0b0bbe452eb65afdb551bd8c572bf45714a2f8cf37239afa3aaa114cdc8b57"
    # our wallet now has 3 addresses
    assert w.key_count == 3

    c.wallets.delete()
    c.delete()
コード例 #6
0
def main(self):
    """
    to run:

    kosmos 'j.clients.goldchain.test(name="examples_wallet_statements")'
    """

    cleanup("devnet_unittest_client")

    # create a goldchain client for devnet
    c = j.clients.goldchain.new("devnet_unittest_client", network_type="DEV")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = GoldChainExplorerGetClientStub()
    explorer_client.hash_add(
        "0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"208d9f524e937176e50a7399fd3886f584290948983bbd0ed781f59cefc343a8","height":39994,"parent":"c5fb21d8921b8974950b69bdabd2fdccb5b328e4f1cb42a657a4b71ecbdfd3ed","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"a249d627c5a5f8e23c751e7f4a3fef9dd9ddbfeea9d07f5bbf242bd339b287f0","fulfillment":{"type":1,"data":{"publickey":"ed25519:8b371733c8648a50f959efea292f5e1e38063dac3f9bfc0d260829ea74a17fff","signature":"a1c5c349637976ad18e07a206cb23cfdaf831ebb9d4cda3cf768a0b5e723c1ae6e643338c73cff1feb43f946e75788ebdb1b4200f39653efdb127e8e10e6ec02"}}}],"coinoutputs":[{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"01cb0aedd4098efd926195c2f7bba9323d919f99ecd95cf3626f0508f6be33f49bcae3dd62cca6"}}},{"value":"89000000000","condition":{"type":1,"data":{"unlockhash":"0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"100000000000","condition":{"type":1,"data":{"unlockhash":"0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb"}},"unlockhash":"0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb"}],"coinoutputids":["3f90223a71e6e474a0b6c073efec5ff2ce0656e932e55f10b8c3cdbf24ec8ede","b3e3787dc5c83fb8d174752721976341f02d4b3a58914984882520fea99b4eb7"],"coinoutputunlockhashes":["01cb0aedd4098efd926195c2f7bba9323d919f99ecd95cf3626f0508f6be33f49bcae3dd62cca6","0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"544a204f0211e7642f508a7918c5d29334bd7d6892b2612e8acfb6dc36d39bd9","height":39990,"parent":"d37c592e45407b70ea8000e8f4bb46fe0577d1740ff6c7ccf912b9765cb90c2e","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"1d2f5471fce574fb488615d42f8ed0cda3432fd9fde7b8c8914db5b05814e93d","fulfillment":{"type":1,"data":{"publickey":"ed25519:49106a6f57ef3a7c2f1d75acb1911c26b9c70e050b319ae4d00d07b38a328251","signature":"4a877bf9a46b31ff52e37469228516184611274a7b24fbc2d3b699d2a5f87eb81caf6a44fdb95d3b4568ce335447c9408b9f9a6c4aedda6f12ad9624b293f801"}}}],"coinoutputs":[{"value":"400000000000","condition":{"type":1,"data":{"unlockhash":"0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb"}}},{"value":"99991626000000000","condition":{"type":1,"data":{"unlockhash":"01456d748fc44c753f63671cb384b8cb8a2aebb1d48b4e0be82c302d71c10f2448b2d8e3d164f6"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99992027000000000","condition":{"type":1,"data":{"unlockhash":"01773a1dd123347e1030f0822cb8d22082fe3f9b0ea8563d4ac8e7abc377eba920c47efb2fd736"}},"unlockhash":"01773a1dd123347e1030f0822cb8d22082fe3f9b0ea8563d4ac8e7abc377eba920c47efb2fd736"}],"coinoutputids":["07bd125a69db7d7aad56d1cebbdf3d6d8e830b8b1034a15c0482c778d0ca9f91","73b19c28a3995f8d255a772ffba2d8a19d10d3c74970f8de7373611964c97240"],"coinoutputunlockhashes":["0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb","01456d748fc44c753f63671cb384b8cb8a2aebb1d48b4e0be82c302d71c10f2448b2d8e3d164f6"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"779cf13ecee7f45f032af92429056cd5976cb75ce968bab98e3e2fdf9a9b1034","height":39997,"parent":"9e1127983d851593fdaee90979a0d68446c3f0088278b270f48c41ea14178f7f","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"b3e3787dc5c83fb8d174752721976341f02d4b3a58914984882520fea99b4eb7","fulfillment":{"type":1,"data":{"publickey":"ed25519:8b371733c8648a50f959efea292f5e1e38063dac3f9bfc0d260829ea74a17fff","signature":"0985318dcf8a484218d80430880e9668c1569b400bc0b96cdb4834dc9df7745e97e1764a98ad82c65b9aca269200349b500aec7a85ccbfe9e18b804687c0470e"}}}],"coinoutputs":[{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb"}}},{"value":"78000000000","condition":{"type":1,"data":{"unlockhash":"0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"89000000000","condition":{"type":1,"data":{"unlockhash":"0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb"}},"unlockhash":"0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb"}],"coinoutputids":["759d47d4d21f0bb95182fa12790e7f35a5299ed6cd49d7ca2f845baa31281485","80814afea75b03cee855b9a7359f60001e3cf1c9e413054bfa2d63b5cf4a99b7"],"coinoutputunlockhashes":["0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb","0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"b104308e683d4353a5a6b6cdfd4f6dfce39e241ff1218d6d6189bae89945034f","height":39995,"parent":"6dac39c66532c5704d212ce2d88540baa6c3d3567dc01b156531266b3cd244b1","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"231065ee55dc100ea7b4d19143a6daf3b7c29750366329143d842b87eae30a1e","fulfillment":{"type":1,"data":{"publickey":"ed25519:01adfffb60f4a5b84bc29b2c2a3e48a8be892399fe2544d71e1213e2e746fb79","signature":"2acb5319353ebb6bc260bcc81c8085399f973c133056142e1305db3048ade34916c0415fb419337f53e804a69de2cbaf55988cbd1cb7b89ad1eaca65f1722a0e"}}}],"coinoutputs":[{"value":"200000000000","condition":{"type":1,"data":{"unlockhash":"0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb"}}},{"value":"50000000000","condition":{"type":1,"data":{"unlockhash":"01cb0aedd4098efd926195c2f7bba9323d919f99ecd95cf3626f0508f6be33f49bcae3dd62cca6"}}},{"value":"99991274000000000","condition":{"type":1,"data":{"unlockhash":"01f0f397fd6b7b51b46ddd2ffda1e2240e639b19b47d27a4adc2bed78da0fc3d97c1fe7b972d1e"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99991525000000000","condition":{"type":1,"data":{"unlockhash":"015827a0cabfb4be5531ecd2b42470a25cf9910a868b857029c2bdabdc05cad51e66d5dd899064"}},"unlockhash":"015827a0cabfb4be5531ecd2b42470a25cf9910a868b857029c2bdabdc05cad51e66d5dd899064"}],"coinoutputids":["6d39719a217be42db384d947db08dc4224718ed9e357b990cbfc39586d764da8","ed9cf75bffbeb91e756059422874bad956b0aedfbfae337d41dabe9be2a111c3","78282a245a381c7aa700a16fabfa3924e95d6329913e9d916a49a22ad1e4f177"],"coinoutputunlockhashes":["0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb","01cb0aedd4098efd926195c2f7bba9323d919f99ecd95cf3626f0508f6be33f49bcae3dd62cca6","01f0f397fd6b7b51b46ddd2ffda1e2240e639b19b47d27a4adc2bed78da0fc3d97c1fe7b972d1e"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"e7785bacd0d12f93ab435cf3e29301f15b84be82ae8abbdaed1cfd034f4ed652","height":39991,"parent":"3a3b2fee4728f347e26b74ace8ebfdb2b3e042e1be92cbc6ee2711eb42fd43e7","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"73b19c28a3995f8d255a772ffba2d8a19d10d3c74970f8de7373611964c97240","fulfillment":{"type":1,"data":{"publickey":"ed25519:d92be6ab3ddbed0f31d7ee2fd1a61e4e8ba746c4265567f4a9f00c59aa25f470","signature":"a2c990f636a8a1020d9bb937f5b65d7fa76078467b73429444192b2f95fe5b4b2cdfe393a3b00769fb8a3cc706c7dfa26b27454705fdd2df7287c49f618ec502"}}}],"coinoutputs":[{"value":"100000000000","condition":{"type":1,"data":{"unlockhash":"0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb"}}},{"value":"99991525000000000","condition":{"type":1,"data":{"unlockhash":"015827a0cabfb4be5531ecd2b42470a25cf9910a868b857029c2bdabdc05cad51e66d5dd899064"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99991626000000000","condition":{"type":1,"data":{"unlockhash":"01456d748fc44c753f63671cb384b8cb8a2aebb1d48b4e0be82c302d71c10f2448b2d8e3d164f6"}},"unlockhash":"01456d748fc44c753f63671cb384b8cb8a2aebb1d48b4e0be82c302d71c10f2448b2d8e3d164f6"}],"coinoutputids":["a249d627c5a5f8e23c751e7f4a3fef9dd9ddbfeea9d07f5bbf242bd339b287f0","231065ee55dc100ea7b4d19143a6daf3b7c29750366329143d842b87eae30a1e"],"coinoutputunlockhashes":["0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb","015827a0cabfb4be5531ecd2b42470a25cf9910a868b857029c2bdabdc05cad51e66d5dd899064"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"573290763024ae0a5e981412598a3d41bc02f8da628fa1e1adfe07d98818c689","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"78282a245a381c7aa700a16fabfa3924e95d6329913e9d916a49a22ad1e4f177","fulfillment":{"type":1,"data":{"publickey":"ed25519:83ca81ff674dd835801a0aa3e5e5b05758033bffb425524d1be51da06a5a2341","signature":"638caa49226fb31ed1c3f51e5ad13e45f36246fdf6ea249563b0018595623624b01bf028953a3db31e4082d6dd3a9544d5de65a1a8c4b89a55366d004747390d"}}}],"coinoutputs":[{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb"}}},{"value":"99991263000000000","condition":{"type":1,"data":{"unlockhash":"016d2dea96293304aaff85f61fbfa882dd1f5ee2401c3f0dd6d1f20f53047e720c73fc0ddff6e9"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99991274000000000","condition":{"type":1,"data":{"unlockhash":"01f0f397fd6b7b51b46ddd2ffda1e2240e639b19b47d27a4adc2bed78da0fc3d97c1fe7b972d1e"}},"unlockhash":"01f0f397fd6b7b51b46ddd2ffda1e2240e639b19b47d27a4adc2bed78da0fc3d97c1fe7b972d1e"}],"coinoutputids":["3221846ff477b42583278fa4e4704f7f2267542fa1ac2b3ca8a19e4721b20dcb","18b436899914bc3b2f5aa2f3d6dad5f248a4c1a26078eb7e94855cc166d44bfb"],"coinoutputunlockhashes":["0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb","016d2dea96293304aaff85f61fbfa882dd1f5ee2401c3f0dd6d1f20f53047e720c73fc0ddff6e9"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":true}],"multisigaddresses":null,"unconfirmed":false}',
    )
    c._explorer_get = explorer_client.explorer_get

    # the devnet genesis seed is the seed of the wallet,
    # which receives all block stakes and coins in the genesis block of the goldchain devnet
    DEVNET_GENESIS_SEED = "smooth team admit virus weapon tiny jazz ecology check jump unit thought ankle rice please victory fringe logic patient eager rescue trial hawk veteran"

    # create a new devnet wallet
    w = c.wallets.new("mywallet", seed=DEVNET_GENESIS_SEED)
    # we create a new wallet using an existing seed,
    # such that our seed is used and not a new randomly generated seed

    # an example that shows how one can write logic around the GoldChain client,
    # to do something with the transactions linked to a wallet

    addresses = set(w.addresses)
    text = ""
    for txn in w.transactions:
        # collect to addresses, and incoming/outgoing balance,
        # focussing only on the addresses of this wallet
        to_addresses = set()
        incoming_balance = 0
        for co in txn.coin_outputs:
            addr = str(co.condition.unlockhash)
            to_addresses.add(addr)
            if addr not in addresses:
                continue
            incoming_balance = incoming_balance + co.value

        # collect all from addresses, that are not ours,
        # as well as update the incoming balance
        from_addresses = set()
        outgoing_balance = 0
        for ci in txn.coin_inputs:
            pco = ci.parent_output
            addr = str(pco.condition.unlockhash)
            from_addresses.add(addr)
            if addr not in addresses:
                continue
            if incoming_balance > 0:
                if pco.value > incoming_balance:
                    outgoing_balance = outgoing_balance + (pco.value -
                                                           incoming_balance)
                    incoming_balance = 0
                else:
                    incoming_balance -= pco.value
            else:
                outgoing_balance = outgoing_balance + pco.value

        if incoming_balance == 0 and outgoing_balance == 0:
            # nothing to print here
            continue

        if outgoing_balance > 0:
            # remove our addresses from address sets, as these are most likely refunds
            to_addresses -= addresses
            from_addresses -= addresses
        else:
            # only care about subset of addresses in to set
            to_addresses &= addresses

        # balance out the incoming and outgoing balance
        if incoming_balance > outgoing_balance:
            incoming_balance -= outgoing_balance
            outgoing_balance = 0
        else:
            outgoing_balance -= incoming_balance
            incoming_balance = 0

        text += j.core.text.strip("""
            {:<12} Tx: {} | {:^24} | {:^24} |
            \t> to: {}
            \t> from: {}

            """.format(
            ("unconfirmed" if txn.unconfirmed else txn.height),
            str(txn.id),
            "- " + outgoing_balance.str(with_unit=True)
            if outgoing_balance > 0 else "",
            "+ " + incoming_balance.str(with_unit=True)
            if incoming_balance > 0 else "",
            ", ".join(to_addresses)
            if len(to_addresses) > 0 else "this wallet",
            ", ".join(from_addresses)
            if len(from_addresses) > 0 else "this wallet",
        ))

    # print text
    print(text)

    # assert text is as expected
    expected_text = """unconfirmed  Tx: 573290763024ae0a5e981412598a3d41bc02f8da628fa1e1adfe07d98818c689 |                          |         + 10 GFT         |
\t> to: 0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb
\t> from: 01f0f397fd6b7b51b46ddd2ffda1e2240e639b19b47d27a4adc2bed78da0fc3d97c1fe7b972d1e

39997        Tx: 779cf13ecee7f45f032af92429056cd5976cb75ce968bab98e3e2fdf9a9b1034 |         - 1 GFT          |                          |
\t> to: this wallet
\t> from: this wallet

39995        Tx: b104308e683d4353a5a6b6cdfd4f6dfce39e241ff1218d6d6189bae89945034f |                          |        + 200 GFT         |
\t> to: 0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb
\t> from: 015827a0cabfb4be5531ecd2b42470a25cf9910a868b857029c2bdabdc05cad51e66d5dd899064

39994        Tx: 208d9f524e937176e50a7399fd3886f584290948983bbd0ed781f59cefc343a8 |         - 11 GFT         |                          |
\t> to: 01cb0aedd4098efd926195c2f7bba9323d919f99ecd95cf3626f0508f6be33f49bcae3dd62cca6
\t> from: this wallet

39991        Tx: e7785bacd0d12f93ab435cf3e29301f15b84be82ae8abbdaed1cfd034f4ed652 |                          |        + 100 GFT         |
\t> to: 0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb
\t> from: 01456d748fc44c753f63671cb384b8cb8a2aebb1d48b4e0be82c302d71c10f2448b2d8e3d164f6

39990        Tx: 544a204f0211e7642f508a7918c5d29334bd7d6892b2612e8acfb6dc36d39bd9 |                          |        + 400 GFT         |
\t> to: 0125c0156f6c1c0bc43c7d38e17f8948300564bef63caac05c08b0fd68996e494704bbbe0268cb
\t> from: 01773a1dd123347e1030f0822cb8d22082fe3f9b0ea8563d4ac8e7abc377eba920c47efb2fd736

"""
    assert expected_text == text

    c.wallets.delete()
    c.delete()
コード例 #7
0
def main(self):
    """
    to run:

    kosmos 'j.clients.goldchain.test(name="wallet_coins_send")'
    """

    cleanup("devnet_unittest_client")

    # create a goldchain client for devnet
    c = j.clients.goldchain.new("devnet_unittest_client", network_type="DEV")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = GoldChainExplorerGetClientStub()
    explorer_client.hash_add(
        "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"066c03b5cf6db18edd6013591ae6292e8a04f1cc18fc6f0a0f3946d40bb087b3","height":3628,"parent":"761af2728b6f07bbccf4ddaf330c0bb1465246f6fe25fbfb9989129b69fbd899","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"670045cf43421b21577c27613569b65ba0cec613ae5437ee15dc0eea95241cbc","fulfillment":{"type":1,"data":{"publickey":"ed25519:bdea9aff09bcdc66529f6e2ef1bb763a3bab83ce542e8673d97aeaed0581ad97","signature":"e5a47b166eb6724ca7a72b5ddaeff287ebdde09751ed10e8850d320744afc5f45e59aa66e2cc4dc45ff593a0eea696c4e780b81636a1ce748c7149a9ee0ba807"}}},{"parentid":"1d686b8dfe44dfbfea55f327a52d9701a52938cb2c829f709dfb8059bc0e5f87","fulfillment":{"type":1,"data":{"publickey":"ed25519:64ae81a176302ea9ea47ec673f105da7a25e52bdf0cbb5b63d49fc2c69ed2eaa","signature":"5ce7a10373214d269837e9c176ec806469d2b80f200f9ee961c63553b6ee200f88958293a571889f26b2b52664f3c9ff2441eaf8ed61830b51d640003b06fb00"}}}],"coinoutputs":[{"value":"501000000000","condition":{"type":1,"data":{"unlockhash":"0186cea43fa0d303a6379ae76dd79f014698956fb982751549e3ff3844b23fa9551c1725470f55"}}},{"value":"198000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"200000000000","condition":{"type":1,"data":{"unlockhash":"018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd"}},"unlockhash":"018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd"},{"value":"500000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}},"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}],"coinoutputids":["4b43906584620e8a13d98a917d424fb154dd1222a72b886a887c416b2a9120f5","19d4e81d057b4c93a7763f3dfe878f6a37d6111a3808b93afff4b369de0f5376"],"coinoutputunlockhashes":["0186cea43fa0d303a6379ae76dd79f014698956fb982751549e3ff3844b23fa9551c1725470f55","014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"0b5d7509e467b943af12db2d73ddb78a5ec8cfdf64c3c6ecacb2de4af68bdc4d","height":33,"parent":"40e281daee6f113b788d64b8247381c36fe4885233a7475c9be2cce852e1696e","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"a3c8f44d64c0636018a929d2caeec09fb9698bfdcbfa3a8225585a51e09ee563","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"e5b69be3b385f0a33f7978e0d6af30cf37c975bbb99d0f3d06f199cd579d3e6854f6cb398c88082e438c89d11d04de0e7d3b2876e250d4ba8ae457f88547f605"}}}],"coinoutputs":[{"value":"1000000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}}},{"value":"99998999000000000","condition":{"type":1,"data":{"unlockhash":"01f68299b26a89efdb4351a61c3a062321d23edbc1399c8499947c1313375609adbbcd3977363c"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"100000000000000000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"coinoutputids":["75f297550acfa48490c21490f82c3c308326c16f950e17ef3a286486065a51b8","6d157a1eb23cadde122192869bc51e2a0fe44a2d8aba898cbdda8b7218a0f8cb"],"coinoutputunlockhashes":["014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a","01f68299b26a89efdb4351a61c3a062321d23edbc1399c8499947c1313375609adbbcd3977363c"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"1b144b89c4b65cc67416e27286e802c50f78bc7326b4b0e5f6f967f99cc39419","height":200,"parent":"68e3886c9a4c59dea8c7a0eb138ede0e83716b995fd8ebfa5dfc766bfb349565","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"6d157a1eb23cadde122192869bc51e2a0fe44a2d8aba898cbdda8b7218a0f8cb","fulfillment":{"type":1,"data":{"publickey":"ed25519:00bde9571b30e1742c41fcca8c730183402d967df5b17b5f4ced22c677806614","signature":"05c72055d4cca6d8620fd7453c89ac8deaf92c38e366604dc6405cb097321b74e2e5f7ece15b440f4af5721b8aa6ea1f57f4fce44d2a2c6c0fb7a1e068a0480d"}}}],"coinoutputs":[{"value":"500000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}}},{"value":"99998498000000000","condition":{"type":1,"data":{"unlockhash":"0161fbcf58efaeba8813150e88fc33405b3a77d51277a2cdf3f4d2ab770de287c7af9d456c4e68"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99998999000000000","condition":{"type":1,"data":{"unlockhash":"01f68299b26a89efdb4351a61c3a062321d23edbc1399c8499947c1313375609adbbcd3977363c"}},"unlockhash":"01f68299b26a89efdb4351a61c3a062321d23edbc1399c8499947c1313375609adbbcd3977363c"}],"coinoutputids":["1d686b8dfe44dfbfea55f327a52d9701a52938cb2c829f709dfb8059bc0e5f87","e27ed8bbe45177fafdfd7d21394ff483b8bde24f551dd927a046a0b7c37ec228"],"coinoutputunlockhashes":["014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a","0161fbcf58efaeba8813150e88fc33405b3a77d51277a2cdf3f4d2ab770de287c7af9d456c4e68"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"5ab2604c7d54dd9ea39d829724e46deb8bbf2889d8627a3bb3b57907c6f4dff4","height":1433,"parent":"6b9fdad35096c5a84dcdb6e3e9ec2a8c7562f567e05b1207a7f9330ed51582bb","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"e27ed8bbe45177fafdfd7d21394ff483b8bde24f551dd927a046a0b7c37ec228","fulfillment":{"type":1,"data":{"publickey":"ed25519:41e84f3b0f6a06dd7e45ded4d0e227869725355b73906b82d9e3ffc0b6b01416","signature":"47a4d1a6aeb7403ea5c2cbcc26f84bb1964aadcb8765696db4a623694991f794663b860898db53401dd4324477c43f9fff177b74909201a03e131c2cd885cc0d"}}}],"coinoutputs":[{"value":"500000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}}},{"value":"99997997000000000","condition":{"type":1,"data":{"unlockhash":"0137f6f647a3c8019f6ae215ed09902c308efbf555b3520d2112d2b18cb577e40804d6fc5fafd2"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99998498000000000","condition":{"type":1,"data":{"unlockhash":"0161fbcf58efaeba8813150e88fc33405b3a77d51277a2cdf3f4d2ab770de287c7af9d456c4e68"}},"unlockhash":"0161fbcf58efaeba8813150e88fc33405b3a77d51277a2cdf3f4d2ab770de287c7af9d456c4e68"}],"coinoutputids":["b90422bad2dffde79f0a46bd0a41055cf7974b080e115d76f69891ca31d31f11","f386312779f382f16fa836038b3d25536b928ba88ae1afa1f8c0e8dc25c0ba16"],"coinoutputunlockhashes":["014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a","0137f6f647a3c8019f6ae215ed09902c308efbf555b3520d2112d2b18cb577e40804d6fc5fafd2"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"81d81b413fc8af3e528478e639d5a6e999e5e96611593cd2458b4d2d7abc3880","height":1433,"parent":"6b9fdad35096c5a84dcdb6e3e9ec2a8c7562f567e05b1207a7f9330ed51582bb","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"f386312779f382f16fa836038b3d25536b928ba88ae1afa1f8c0e8dc25c0ba16","fulfillment":{"type":1,"data":{"publickey":"ed25519:4e42a2fcfc0963d6fa7bb718fd088d9b6544331e8562d2743e730cdfbedeb55a","signature":"4abae694cf6a6408eca6f034ea2ec6930b9a73303c3e70d3444cf36a9966b0c4cc1b65168c23640affb5bdeae539ea583d42da52c58d21f59b71c288b3faef0e"}}}],"coinoutputs":[{"value":"2000000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}}},{"value":"99995996000000000","condition":{"type":1,"data":{"unlockhash":"0173f82c3ee74286c33fee8d883a7e9e759c6230b9e4e956ef233d7202bde69da45054270eef99"}}}],"minerfees":["1000000000"],"arbitrarydata":"Zm9vYmFy"}},"coininputoutputs":[{"value":"99997997000000000","condition":{"type":1,"data":{"unlockhash":"0137f6f647a3c8019f6ae215ed09902c308efbf555b3520d2112d2b18cb577e40804d6fc5fafd2"}},"unlockhash":"0137f6f647a3c8019f6ae215ed09902c308efbf555b3520d2112d2b18cb577e40804d6fc5fafd2"}],"coinoutputids":["d1f74e90eba8095e78f08a6284c7b76d4cda86b06ac742062d6e0e02dc4607eb","1edccdb04100ffd05d97431b6798533fa57dc7ed1ea58c75f0f445fb64442d6e"],"coinoutputunlockhashes":["014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a","0173f82c3ee74286c33fee8d883a7e9e759c6230b9e4e956ef233d7202bde69da45054270eef99"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":["039e16ed27b2dfa3a5bbb1fa2b5f240ba7ff694b34a52bfc5bed6d4c3b14b763c011d7503ccb3a"],"unconfirmed":false}',
    )
    explorer_client.hash_add(
        "018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"066c03b5cf6db18edd6013591ae6292e8a04f1cc18fc6f0a0f3946d40bb087b3","height":3628,"parent":"761af2728b6f07bbccf4ddaf330c0bb1465246f6fe25fbfb9989129b69fbd899","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"670045cf43421b21577c27613569b65ba0cec613ae5437ee15dc0eea95241cbc","fulfillment":{"type":1,"data":{"publickey":"ed25519:bdea9aff09bcdc66529f6e2ef1bb763a3bab83ce542e8673d97aeaed0581ad97","signature":"e5a47b166eb6724ca7a72b5ddaeff287ebdde09751ed10e8850d320744afc5f45e59aa66e2cc4dc45ff593a0eea696c4e780b81636a1ce748c7149a9ee0ba807"}}},{"parentid":"1d686b8dfe44dfbfea55f327a52d9701a52938cb2c829f709dfb8059bc0e5f87","fulfillment":{"type":1,"data":{"publickey":"ed25519:64ae81a176302ea9ea47ec673f105da7a25e52bdf0cbb5b63d49fc2c69ed2eaa","signature":"5ce7a10373214d269837e9c176ec806469d2b80f200f9ee961c63553b6ee200f88958293a571889f26b2b52664f3c9ff2441eaf8ed61830b51d640003b06fb00"}}}],"coinoutputs":[{"value":"501000000000","condition":{"type":1,"data":{"unlockhash":"0186cea43fa0d303a6379ae76dd79f014698956fb982751549e3ff3844b23fa9551c1725470f55"}}},{"value":"198000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"200000000000","condition":{"type":1,"data":{"unlockhash":"018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd"}},"unlockhash":"018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd"},{"value":"500000000000","condition":{"type":1,"data":{"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}},"unlockhash":"014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"}],"coinoutputids":["4b43906584620e8a13d98a917d424fb154dd1222a72b886a887c416b2a9120f5","19d4e81d057b4c93a7763f3dfe878f6a37d6111a3808b93afff4b369de0f5376"],"coinoutputunlockhashes":["0186cea43fa0d303a6379ae76dd79f014698956fb982751549e3ff3844b23fa9551c1725470f55","014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"d0d290dccddaf086708e4163eacd420bfbaa7acb77deea97c6a8792a139f6e7e","height":3583,"parent":"ca746d80740ff45f6e7f0d6c8b6278b35b1040b4e21baaf41bd03cd3a7a176be","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"1edccdb04100ffd05d97431b6798533fa57dc7ed1ea58c75f0f445fb64442d6e","fulfillment":{"type":1,"data":{"publickey":"ed25519:7469d51063cdb690cc8025db7d28faadc71ff69f7c372779bf3a1e801a923e02","signature":"6f38467bb4ca23900e424d5ac2066a09b61fe9d9ae84a4231755063f591d04711f0a5ab11b60b42c2c32a8e7f73fc1cc1cb0073b036bc417ed504a8ef5f25402"}}}],"coinoutputs":[{"value":"200000000000","condition":{"type":1,"data":{"unlockhash":"018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd"}}},{"value":"99995795000000000","condition":{"type":1,"data":{"unlockhash":"01f706dcbb9f0cb1e97d891ada3a133f68612ebff948c5bbae7851108a65dab7782907eecd86be"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99995996000000000","condition":{"type":1,"data":{"unlockhash":"0173f82c3ee74286c33fee8d883a7e9e759c6230b9e4e956ef233d7202bde69da45054270eef99"}},"unlockhash":"0173f82c3ee74286c33fee8d883a7e9e759c6230b9e4e956ef233d7202bde69da45054270eef99"}],"coinoutputids":["670045cf43421b21577c27613569b65ba0cec613ae5437ee15dc0eea95241cbc","984555e190d58dc752aad81b0a6cf6194fa5bf89b8614efcd9604d138a8953bc"],"coinoutputunlockhashes":["018f5a43327fb865843808ddf549f1b1c06376e07195423778751056be626841f42dcf25a593fd","01f706dcbb9f0cb1e97d891ada3a133f68612ebff948c5bbae7851108a65dab7782907eecd86be"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    explorer_client.chain_info = '{"blockid":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","difficulty":"27801","estimatedactivebs":"59","height":3644,"maturitytimestamp":1549012510,"target":[0,2,91,116,78,165,130,72,116,162,127,4,125,67,108,16,140,247,132,198,107,159,114,177,44,25,18,162,38,157,169,245],"totalcoins":"0","arbitrarydatatotalsize":6,"minerpayoutcount":3650,"transactioncount":3652,"coininputcount":12,"coinoutputcount":15,"blockstakeinputcount":3644,"blockstakeoutputcount":3645,"minerfeecount":7,"arbitrarydatacount":1}'
    explorer_client.hash_add(
        "552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e",
        '{"hashtype":"blockid","block":{"minerpayoutids":["468db689f752414702ef3a5aa06238f03a4539434a61624b3b8a0fb5dc38a211"],"transactions":[{"id":"2396f8e57bbb9b22bd1d749d5de3fd532ea6886e9660a556a13571d701d83e27","height":3644,"parent":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ff5a002ec356b7cb24fbee9f076f239fb8c72d5a8a448cee92ee6d29a87aef52","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"7bec94dfb87640726c6a14de2110599db0f81cf9fa456249e7bf79b0c74b79517edde25c4ee87f181880af44fe6ee054ff20b74eda2144fe07fa5bfb9d884208"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["f683e7319659c61f54e93546bc41b57c5bffe79de26c06ec7371034465804c81"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"47db4274551b0372564f8d1ab89c596428f00e460c0b416327e53983c8765198","timestamp":1549012665,"pobsindexes":{"BlockHeight":3643,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ff5a002ec356b7cb24fbee9f076f239fb8c72d5a8a448cee92ee6d29a87aef52","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"7bec94dfb87640726c6a14de2110599db0f81cf9fa456249e7bf79b0c74b79517edde25c4ee87f181880af44fe6ee054ff20b74eda2144fe07fa5bfb9d884208"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","difficulty":"27801","estimatedactivebs":"59","height":3644,"maturitytimestamp":1549012510,"target":[0,2,91,116,78,165,130,72,116,162,127,4,125,67,108,16,140,247,132,198,107,159,114,177,44,25,18,162,38,157,169,245],"totalcoins":"0","arbitrarydatatotalsize":6,"minerpayoutcount":3650,"transactioncount":3652,"coininputcount":12,"coinoutputcount":15,"blockstakeinputcount":3644,"blockstakeoutputcount":3645,"minerfeecount":7,"arbitrarydatacount":1},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    explorer_client.hash_add(
        "039e16ed27b2dfa3a5bbb1fa2b5f240ba7ff694b34a52bfc5bed6d4c3b14b763c011d7503ccb3a",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"4c70a0406f36cf354edf87642df3f34568fd0a89c052a81d11cc6e4f8fbf685e","height":45,"parent":"f7b78b17d581ff9e58ffbcce1701d4dcadb0781590ca68e839def0dc98b0360a","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"7d4a100fc3bc08b2bdd1284c17260dd2bd6b55fd6c1429dbbd683bf362d92b50","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"c34b8ca1ab08930bc68d61026af504d62d8a8bbda9b79ae01a387560fba22d39b12021e16566732b742ea686f997b3c19c807523797cdc0d74a4d25123691004"}}},{"parentid":"83503f9cea00d562e0460eace93159a4c4dd00df4703c96947e81885b46da04c","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"f6eea681a259baf14433ac55b4293b22ca2056810ee8fed2129039224d14558f54ca58c6d96e9885cb20ecdf7e64ba81d1a83c6e9a42bf9464287fa6359d360c"}}},{"parentid":"578aa43de72b42b4f4547c5ddc7f61736b1cac206e1789bc89fcd9333cf3d1f3","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"a0521d14dfe4a0c9b8b57ed361d738b48b6a8346097246effe0b4ee67b6fecbc3a90e4671ddc0b164f6c2839df249bb5998f10216a4a674ba8d24b8ad6bdf808"}}},{"parentid":"5a1454762e6895431e1b9e4e435e4d0ad60a3881843ac46b88e220771055ca87","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"900e7868780e67bcb68af3ec6976e84289850d0db59210d4689b1c0e2deb3164b9e93eb9ee5a38850f2319463b0845163e1eee443d7b645c59485c2aa0837707"}}},{"parentid":"c04ebebe17a1759457eecaf4d5d33f5ddbe8d154b0be1606f05bc8fd02ab9cd4","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"e992b1cd3347b5362e820166d5929de7c682130c7143fc4c9ff3156f5d44110753687697a0154a2043290b3f022e2537f3e3a6807caf9150f8c255d74e386d0a"}}}],"coinoutputs":[{"value":"42000000000","condition":{"type":4,"data":{"unlockhashes":["014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a","014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"],"minimumsignaturecount":1}}},{"value":"7000000000","condition":{"type":1,"data":{"unlockhash":"01972837ee396f22f96846a0c700f9cf7c8fa83ab4110da91a1c7d02f94f28ff03e45f1470df82"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"},{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"},{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"},{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"},{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"coinoutputids":["29152fe03a2c8782fcbd670579686088c52be83fa3870f5f0788073d97fb5fb2","0fc9b16bb180cd8f8a7144d65e6c8fca66994a4ccaee42e324289d4039ab2841"],"coinoutputunlockhashes":["039e16ed27b2dfa3a5bbb1fa2b5f240ba7ff694b34a52bfc5bed6d4c3b14b763c011d7503ccb3a","01972837ee396f22f96846a0c700f9cf7c8fa83ab4110da91a1c7d02f94f28ff03e45f1470df82"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    c._explorer_get = explorer_client.explorer_get
    c._explorer_post = explorer_client.explorer_post

    # the devnet genesis seed is the seed of the wallet,
    # which receives all block stakes and coins in the genesis block of the goldchain devnet
    DEVNET_GENESIS_SEED = "image orchard airport business cost work mountain obscure flee alpha alert salmon damage engage trumpet route marble subway immune short tide young cycle attract"

    # create a new devnet wallet
    w = c.wallets.new("mywallet", seed=DEVNET_GENESIS_SEED)
    # we create a new wallet using an existing seed,
    # such that our seed is used and not a new randomly generated seed

    # a goldchain (JS) wallet uses the underlying goldchain client for all its
    # interaction with the goldchain network
    assert w.network_type == "DEV"

    # getting the balance of a wallet is as easy as getting the 'balance' property
    balance = w.balance

    # the available and locked tokens can be easily checked
    assert balance.available == "3698 GFT"
    assert balance.locked == 0

    # (1) sending coins to a personal wallet on the used goldchain network can be done as follows:
    result = w.coins_send(
        recipient=
        "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
        amount="108.24",  # the amount of GFT to send
    )
    assert result.submitted  # it is expected the transaction is submitted

    # validate the transaction is as expected
    expected_transaction = {
        "version": 1,
        "data": {
            "coininputs": [{
                "parentid":
                "19d4e81d057b4c93a7763f3dfe878f6a37d6111a3808b93afff4b369de0f5376",
                "fulfillment": {
                    "type": 1,
                    "data": {
                        "publickey":
                        "ed25519:64ae81a176302ea9ea47ec673f105da7a25e52bdf0cbb5b63d49fc2c69ed2eaa",
                        "signature":
                        "4afec02ed2702198e836d826a68dcec278ed55f4eaa778fabbbcf31b510b49450f155e2404c7405480ae590ba424fb53c6997f995742db915862938a559cd20f",
                    },
                },
            }],
            "coinoutputs": [
                {
                    "value": "108240000000",
                    "condition": {
                        "type": 1,
                        "data": {
                            "unlockhash":
                            "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"
                        },
                    },
                },
                {
                    "value": "88760000000",
                    "condition": {
                        "type": 1,
                        "data": {
                            "unlockhash":
                            "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
                        },
                    },
                },
                {
                    "value": "0",
                    "condition": {
                        "type": 128,
                        "data": {
                            "computationtime": 1549012665
                        }
                    }
                },
            ],
            "minerfees": ["1000000000"],
        },
    }
    assert result.transaction.json() == expected_transaction
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == expected_transaction

    # (2) sending coins to a personal wallet with a lock and data is possible as well
    result = w.coins_send(
        recipient=
        "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
        amount=200,  # the amount of GFT to send
        lock=
        "07/12/2020 14:35",  # a lock can be a timestamp, data-time str, duration str, or block height
        data="maximum 83 bytes can be used as optional data",
    )
    assert result.submitted  # it is expected the transaction is submitted

    # validate the transaction is as expected
    expected_transaction = {
        "version": 1,
        "data": {
            "coininputs": [{
                "parentid":
                "b90422bad2dffde79f0a46bd0a41055cf7974b080e115d76f69891ca31d31f11",
                "fulfillment": {
                    "type": 1,
                    "data": {
                        "publickey":
                        "ed25519:64ae81a176302ea9ea47ec673f105da7a25e52bdf0cbb5b63d49fc2c69ed2eaa",
                        "signature":
                        "9fa5322a5b053285768cbf099acd733dd5836463059705291028f5951ba01f3f9544ecf5bfcca8c866e177680fb294b2093701372cacc569c098b8b6f1692802",
                    },
                },
            }],
            "coinoutputs": [
                {
                    "value": "200000000000",
                    "condition": {
                        "type": 3,
                        "data": {
                            "locktime": 1607351700,
                            "condition": {
                                "type": 1,
                                "data": {
                                    "unlockhash":
                                    "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"
                                },
                            },
                        },
                    },
                },
                {
                    "value": "299000000000",
                    "condition": {
                        "type": 1,
                        "data": {
                            "unlockhash":
                            "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
                        },
                    },
                },
                {
                    "value": "0",
                    "condition": {
                        "type": 128,
                        "data": {
                            "computationtime": 1549012665
                        }
                    }
                },
            ],
            "minerfees": ["1000000000"],
            "arbitrarydata":
            "bWF4aW11bSA4MyBieXRlcyBjYW4gYmUgdXNlZCBhcyBvcHRpb25hbCBkYXRh",
        },
    }
    assert result.transaction.json() == expected_transaction
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == expected_transaction

    # (3) one can also send to full multi-sig wallet
    result = w.coins_send(
        recipient=[
            "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
            "010d22cf70053432d70ea08c6940c9e84c4c89e67ad24c3ff9f0444dd2d03bf77c91b3e02c30a1",
        ],
        amount="50 GFT",  # the amount of GFT to send
        lock=
        1550665225,  # a lock can be a timestamp, data-time str, duration str, or block height
        data=b"binary data can be added as well",
    )
    assert result.submitted  # it is expected the transaction is submitted

    # validate the transaction is as expected
    expected_transaction = {
        "version": 1,
        "data": {
            "coininputs": [{
                "parentid":
                "19d4e81d057b4c93a7763f3dfe878f6a37d6111a3808b93afff4b369de0f5376",
                "fulfillment": {
                    "type": 1,
                    "data": {
                        "publickey":
                        "ed25519:64ae81a176302ea9ea47ec673f105da7a25e52bdf0cbb5b63d49fc2c69ed2eaa",
                        "signature":
                        "e6d72ec579a6419b8c7c807e3b496ff8accaeb9221ebeb62957dfc4ef6ccb578d9a1b0e741bda2593130c892bcc4ba88e61c214f195f74d29203e8c5d8532b03",
                    },
                },
            }],
            "coinoutputs": [
                {
                    "value": "50000000000",
                    "condition": {
                        "type": 3,
                        "data": {
                            "locktime": 1550665225,
                            "condition": {
                                "type": 4,
                                "data": {
                                    "minimumsignaturecount":
                                    2,
                                    "unlockhashes": [
                                        "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
                                        "010d22cf70053432d70ea08c6940c9e84c4c89e67ad24c3ff9f0444dd2d03bf77c91b3e02c30a1",
                                    ],
                                },
                            },
                        },
                    },
                },
                {
                    "value": "147000000000",
                    "condition": {
                        "type": 1,
                        "data": {
                            "unlockhash":
                            "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
                        },
                    },
                },
                {
                    "value": "0",
                    "condition": {
                        "type": 128,
                        "data": {
                            "computationtime": 1549012665
                        }
                    }
                },
            ],
            "minerfees": ["1000000000"],
            "arbitrarydata":
            "YmluYXJ5IGRhdGEgY2FuIGJlIGFkZGVkIGFzIHdlbGw=",
        },
    }
    assert result.transaction.json() == expected_transaction
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == expected_transaction

    # (4) one can also send to a x-out-of-n multisig wallet
    result = w.coins_send(
        recipient=(
            1,
            [
                "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
                "010d22cf70053432d70ea08c6940c9e84c4c89e67ad24c3ff9f0444dd2d03bf77c91b3e02c30a1",
            ],
        ),
        amount="300.0",  # the amount of GFT to send
        lock=
        35000,  # a lock can be a timestamp, data-time str, duration str, or block height
        data=bytearray(b"binary data can be added as well"),
    )
    assert result.submitted  # it is expected the transaction is submitted

    # validate the transaction is as expected
    expected_transaction = {
        "version": 1,
        "data": {
            "coininputs": [{
                "parentid":
                "b90422bad2dffde79f0a46bd0a41055cf7974b080e115d76f69891ca31d31f11",
                "fulfillment": {
                    "type": 1,
                    "data": {
                        "publickey":
                        "ed25519:64ae81a176302ea9ea47ec673f105da7a25e52bdf0cbb5b63d49fc2c69ed2eaa",
                        "signature":
                        "79ade0f773ad16d18da81c5aa5e19c4cce794a7d37d55429a96d7a5158cc857a2804b542d1d20c15e9ca651a081ff42ef757a677c53ddcbb498f97ee6241bc04",
                    },
                },
            }],
            "coinoutputs": [
                {
                    "value": "300000000000",
                    "condition": {
                        "type": 3,
                        "data": {
                            "locktime": 35000,
                            "condition": {
                                "type": 4,
                                "data": {
                                    "minimumsignaturecount":
                                    1,
                                    "unlockhashes": [
                                        "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
                                        "010d22cf70053432d70ea08c6940c9e84c4c89e67ad24c3ff9f0444dd2d03bf77c91b3e02c30a1",
                                    ],
                                },
                            },
                        },
                    },
                },
                {
                    "value": "199000000000",
                    "condition": {
                        "type": 1,
                        "data": {
                            "unlockhash":
                            "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
                        },
                    },
                },
                {
                    "value": "0",
                    "condition": {
                        "type": 128,
                        "data": {
                            "computationtime": 1549012665
                        }
                    }
                },
            ],
            "minerfees": ["1000000000"],
            "arbitrarydata":
            "YmluYXJ5IGRhdGEgY2FuIGJlIGFkZGVkIGFzIHdlbGw=",
        },
    }
    assert result.transaction.json() == expected_transaction
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == expected_transaction

    # TODO: fix, these are broken for now
    #       not important als multisig support is not enabled for goldchain at the moment
    # ensure we have the multi-sig wallet that we think we have
    # print(w.balance.wallets)
    # mw = w.balance.wallets["039e16ed27b2dfa3a5bbb1fa2b5f240ba7ff694b34a52bfc5bed6d4c3b14b763c011d7503ccb3a"]
    # assert mw.owners == [
    #     "01ffd7c884aa869056bfb832d957bb71a0005fee13c19046cebec84b3a5047ee8829eab070374b",
    #     "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
    # ]
    # assert mw.signature_count == 1
    # assert mw.available == "42 GFT"
    # assert mw.unconfirmed == "0 GFT"
    # assert mw.locked == "0 GFT"
    #
    # # (5) spending from a multi-sig wallet can be done as follows
    # result = w.coins_send(
    #     recipient="015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
    #     amount=20,  # the amount of GFT to send
    #     lock=None,  # a lock can be a timestamp, data-time str, duration str, or block height
    #     data="some data",
    #     source="039e16ed27b2dfa3a5bbb1fa2b5f240ba7ff694b34a52bfc5bed6d4c3b14b763c011d7503ccb3a",
    # )
    # assert result.submitted  # it is expected the transaction is submitted, as it is a 1-of-2 signature wallet
    #
    # # validate the transaction is as expected
    # expected_transaction = {
    #     "version": 1,
    #     "data": {
    #         "coininputs": [
    #             {
    #                 "parentid": "29152fe03a2c8782fcbd670579686088c52be83fa3870f5f0788073d97fb5fb2",
    #                 "fulfillment": {
    #                     "type": 3,
    #                     "data": {
    #                         "pairs": [
    #                             {
    #                                 "publickey": "ed25519:64ae81a176302ea9ea47ec673f105da7a25e52bdf0cbb5b63d49fc2c69ed2eaa",
    #                                 "signature": "c8efb66be71f7b991148bb479620d93dc909ea6982d640f304655969a7f22265134bd46f7e33868bbbe8a4a2451a68c18ae8380b45bb524c46cc76b1bac0780b",
    #                             }
    #                         ]
    #                     },
    #                 },
    #             }
    #         ],
    #         "coinoutputs": [
    #             {
    #                 "value": "20000000000",
    #                 "condition": {
    #                     "type": 1,
    #                     "data": {
    #                         "unlockhash": "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"
    #                     },
    #                 },
    #             },
    #             {
    #                 "value": "21000000000",
    #                 "condition": {
    #                     "type": 4,
    #                     "data": {
    #                         "minimumsignaturecount": 1,
    #                         "unlockhashes": [
    #                             "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
    #                             "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
    #                         ],
    #                     },
    #                 },
    #             },
    #         ],
    #         "minerfees": ["1000000000"],
    #         "arbitrarydata": "c29tZSBkYXRh",
    #     },
    # }
    # assert result.transaction.json() == expected_transaction
    # # ensure the transaction is posted and as expected there as well
    # txn = explorer_client.posted_transaction_get(result.transaction.id)
    # assert txn.json() == expected_transaction

    c.wallets.delete()
    c.delete()
コード例 #8
0
def main(self):
    """
    to run:

    kosmos 'j.clients.goldchain.test(name="minter_condition_set")'
    """

    cleanup("devnet_unittest_client")

    # create a goldchain client for devnet
    c = j.clients.goldchain.new("devnet_unittest_client", network_type="DEV")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = GoldChainExplorerGetClientStub()
    # define current block height
    explorer_client.chain_info = '{"blockid":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","difficulty":"27801","estimatedactivebs":"59","height":3644,"maturitytimestamp":1549012510,"target":[0,2,91,116,78,165,130,72,116,162,127,4,125,67,108,16,140,247,132,198,107,159,114,177,44,25,18,162,38,157,169,245],"totalcoins":"0","arbitrarydatatotalsize":6,"minerpayoutcount":3650,"transactioncount":3652,"coininputcount":12,"coinoutputcount":15,"blockstakeinputcount":3644,"blockstakeoutputcount":3645,"minerfeecount":7,"arbitrarydatacount":1}'
    explorer_client.hash_add(
        "552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e",
        '{"hashtype":"blockid","block":{"minerpayoutids":["468db689f752414702ef3a5aa06238f03a4539434a61624b3b8a0fb5dc38a211"],"transactions":[{"id":"2396f8e57bbb9b22bd1d749d5de3fd532ea6886e9660a556a13571d701d83e27","height":3644,"parent":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ff5a002ec356b7cb24fbee9f076f239fb8c72d5a8a448cee92ee6d29a87aef52","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"7bec94dfb87640726c6a14de2110599db0f81cf9fa456249e7bf79b0c74b79517edde25c4ee87f181880af44fe6ee054ff20b74eda2144fe07fa5bfb9d884208"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["f683e7319659c61f54e93546bc41b57c5bffe79de26c06ec7371034465804c81"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"47db4274551b0372564f8d1ab89c596428f00e460c0b416327e53983c8765198","timestamp":1549012665,"pobsindexes":{"BlockHeight":3643,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ff5a002ec356b7cb24fbee9f076f239fb8c72d5a8a448cee92ee6d29a87aef52","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"7bec94dfb87640726c6a14de2110599db0f81cf9fa456249e7bf79b0c74b79517edde25c4ee87f181880af44fe6ee054ff20b74eda2144fe07fa5bfb9d884208"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","difficulty":"27801","estimatedactivebs":"59","height":3644,"maturitytimestamp":1549012510,"target":[0,2,91,116,78,165,130,72,116,162,127,4,125,67,108,16,140,247,132,198,107,159,114,177,44,25,18,162,38,157,169,245],"totalcoins":"0","arbitrarydatatotalsize":6,"minerpayoutcount":3650,"transactioncount":3652,"coininputcount":12,"coinoutputcount":15,"blockstakeinputcount":3644,"blockstakeoutputcount":3645,"minerfeecount":7,"arbitrarydatacount":1},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    # add initial condition
    explorer_client.mint_condition_add(
        condition=j.clients.goldchain.types.conditions.from_recipient(
            "01a006599af1155f43d687635e9680650003a6c506934996b90ae84d07648927414046f9f0e936"
        ),
        height=0,
    )
    # overwrite get/post logic
    c._explorer_get = explorer_client.explorer_get
    c._explorer_post = explorer_client.explorer_post

    # the devnet genesis seed is the seed of the wallet,
    # which receives all block stakes and coins in the genesis block of the goldchain devnet
    DEVNET_GENESIS_SEED = "image orchard airport business cost work mountain obscure flee alpha alert salmon damage engage trumpet route marble subway immune short tide young cycle attract"

    # create a new devnet wallet
    w = c.wallets.new("mywallet", seed=DEVNET_GENESIS_SEED)
    # we create a new wallet using an existing seed,
    # such that our seed is used and not a new randomly generated seed

    # only if you have the correct minting powers,
    # you can set a new minter definition, otherwise an error will be raised

    # set another mint condition manually
    explorer_client.mint_condition_add(
        condition=j.clients.goldchain.types.conditions.from_recipient(
            "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
        ),
        height=3643,
    )

    condition = c.minter.condition_get()
    assert condition.unlockhash == w.address

    # (1) once you have the correct powers, you can can overwrite it as follows:
    result = w.minter.definition_set(minter=(
        1,
        [
            "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
            "011cf61451b58970eeead00819e33f7fc812bd9b2d4e66914efa6163e238752d34be252ac8667f",
        ],
    ))
    # check if the current transaction is submitted
    assert result.submitted  # it is expected

    # check if all is fulfilled
    assert result.transaction.is_fulfilled()
    assert result.transaction.mint_fulfillment.is_fulfilled(
        parent_condition=c.minter.condition_get())
    assert isinstance(result.transaction.mint_fulfillment,
                      FulfillmentSingleSignature)
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == result.transaction.json()

    # set another mint condition manually
    explorer_client.mint_condition_add(
        condition=j.clients.goldchain.types.conditions.from_recipient((
            1,
            [
                "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
                "011cf61451b58970eeead00819e33f7fc812bd9b2d4e66914efa6163e238752d34be252ac8667f",
            ],
        )),
        height=3644,
    )

    # (2) when defining a new minter definition you can also attach data if desired
    result = w.minter.definition_set(
        minter=
        "011cf61451b58970eeead00819e33f7fc812bd9b2d4e66914efa6163e238752d34be252ac8667f",  # new minter power
        data=
        "redefine minter conditions",  # optional data, can also be as binary data
    )
    assert result.submitted  # it is expected the transaction is submitted
    assert result.transaction.is_fulfilled()
    assert result.transaction.mint_fulfillment.is_fulfilled(
        parent_condition=c.minter.condition_get())
    assert isinstance(result.transaction.mint_fulfillment,
                      FulfillmentMultiSignature)
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == result.transaction.json()

    # set another mint condition manually
    explorer_client.mint_condition_add(
        condition=j.clients.goldchain.types.conditions.from_recipient(
            "011cf61451b58970eeead00819e33f7fc812bd9b2d4e66914efa6163e238752d34be252ac8667f"
        ),
        height=3645,
    )

    # if an invalid recipient is given it, a ValueError or TypeError is raised
    with pytest.raises(j.exceptions.Value):
        w.minter.definition_set(minter=None)
    with pytest.raises(j.exceptions.Value):
        w.minter.definition_set(minter="0123bla")
    with pytest.raises(j.exceptions.Value):
        w.minter.definition_set(minter=1)

    # (3) if the wallet has no powers to redefine the powers,
    # the transaction will be not be submitted as the transaction won't be fulfilled
    result = w.minter.definition_set(
        minter=
        "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
    )
    assert not result.submitted
    assert not result.transaction.is_fulfilled()
    assert not result.transaction.mint_fulfillment.is_fulfilled(
        parent_condition=c.minter.condition_get())
    assert isinstance(result.transaction.mint_fulfillment,
                      FulfillmentSingleSignature)

    c.wallets.delete()
    c.delete()
コード例 #9
0
def main(self):
    """
    to run:

    kosmos 'j.clients.goldchain.test(name="atomicswap_verify_sender")'
    """

    cleanup("testnet_unittest_client")

    # create a goldchain client for devnet
    c = j.clients.goldchain.new("testnet_unittest_client", network_type="TEST")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = GoldChainExplorerGetClientStub()
    # add the blockchain info
    explorer_client.chain_info = '{"blockid":"5c86c987668ca47948a149413f4f004651249073eff4f144fd26b50e218705a8","difficulty":"30203","estimatedactivebs":"2365","height":16639,"maturitytimestamp":1549646167,"target":[0,2,43,120,39,20,204,42,102,32,125,110,53,77,39,71,99,124,13,223,197,154,115,42,126,62,185,120,208,177,21,190],"totalcoins":"0","arbitrarydatatotalsize":4328,"minerpayoutcount":16721,"transactioncount":17262,"coininputcount":633,"coinoutputcount":1225,"blockstakeinputcount":16639,"blockstakeoutputcount":16640,"minerfeecount":622,"arbitrarydatacount":572}'
    explorer_client.hash_add(
        "5c86c987668ca47948a149413f4f004651249073eff4f144fd26b50e218705a8",
        '{"hashtype":"blockid","block":{"minerpayoutids":["84b378d60cbdd78430b39c8eddf226119b6f28256388557dd15f0b046bf3c3ed"],"transactions":[{"id":"9aec9f849e35f0bdd14c5ea9daed20c8fbfa09f5a6771bb46ce787eb7e2b00a0","height":16639,"parent":"5c86c987668ca47948a149413f4f004651249073eff4f144fd26b50e218705a8","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"144b2b7711fda335cdae5865ab3729d641266087bc4e088d9fba806345045903","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"f09af1c62026aed18d1d8f80e5a7bd4947a6cb5b6b69097c5b10cb983f0d729662c511a4852fa63690884e2b5c600e3935e08b81aaa757d9f0eb740292ec8309"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["83aa29b3e77f703526e28fbc0d2bfcf2b66c06b665e11cb5535b9575fd0e8105"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"8485f94209bf3e01ed169244ab2072ebb0d1c5dc589c95b39a3fbab3641b7a7e","timestamp":1549646257,"pobsindexes":{"BlockHeight":16638,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"144b2b7711fda335cdae5865ab3729d641266087bc4e088d9fba806345045903","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"f09af1c62026aed18d1d8f80e5a7bd4947a6cb5b6b69097c5b10cb983f0d729662c511a4852fa63690884e2b5c600e3935e08b81aaa757d9f0eb740292ec8309"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"5c86c987668ca47948a149413f4f004651249073eff4f144fd26b50e218705a8","difficulty":"30203","estimatedactivebs":"2365","height":16639,"maturitytimestamp":1549646167,"target":[0,2,43,120,39,20,204,42,102,32,125,110,53,77,39,71,99,124,13,223,197,154,115,42,126,62,185,120,208,177,21,190],"totalcoins":"0","arbitrarydatatotalsize":4328,"minerpayoutcount":16721,"transactioncount":17262,"coininputcount":633,"coinoutputcount":1225,"blockstakeinputcount":16639,"blockstakeoutputcount":16640,"minerfeecount":622,"arbitrarydatacount":572},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    # override internal functionality, as to use our stub client
    c._explorer_get = explorer_client.explorer_get
    c._explorer_post = explorer_client.explorer_post

    # a wallet is required to initiate an atomic swap contract
    w = c.wallets.new(
        "mytestwallet",
        seed=
        "remain solar kangaroo welcome clean object friend later bounce strong ship lift hamster afraid you super dolphin warm emotion curve smooth kiss stem diet",
    )

    # one can verify that its transaction is sent as sender,
    # not super useful, but it does also contain an optional check to know if it is already refundable

    # verification will fail if the contract could not be found
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapContractNotFound):
        w.atomicswap.verify(
            "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890")

    # add the coin output info of the submitted atomic swap contract
    explorer_client.hash_add(
        "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
        '{"hashtype":"coinoutputid","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"4a7ac7930379675c82d0462a86e6d6f4018bdb2bdabaf49f4c177b8de19b4e7c","height":16930,"parent":"c25f345403080b8372a38f66608aa5a2287bdc61b82efe5ee6503ce85e8bcd35","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"753aaeaa0c9e6c9f1f8da1974c83d8ca067ad536f464a2e2fc038bbd0404d084","fulfillment":{"type":1,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"b5081e41797f53233c727c344698400a73f2cdd364e241df915df413d3eeafb425ce9b51de3731bcbf830c399a706f4d24ae7066f947a4a36ae1b25415bcde00"}}}],"coinoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c","hashedsecret":"4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba","timelock":1549736249}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"51000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}},"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}],"coinoutputids":["023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890"],"coinoutputunlockhashes":["02fb27c67c373c2f30611e0b98bf92ed6e6eb0a69b471457b282903945180cd5c5b8068731f767"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )

    # one can verify it all manually
    contract = w.atomicswap.verify(
        "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890")
    assert contract.outputid == "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890"
    assert contract.amount == "50 GFT"
    assert contract.refund_timestamp == 1549736249
    assert contract.sender == "01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"
    assert contract.receiver == "01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c"
    assert contract.secret_hash == "4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba"

    # the amount can however be verified automatically
    w.atomicswap.verify(
        "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
        amount=50)
    # which will fail if the amount is wrong
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapContractInvalid):
        w.atomicswap.verify(
            "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
            amount=42)

    # the secret hash can be verified as well, not so important as the sender,
    # would be more used if one is the receiver, but it is possible none the less.
    w.atomicswap.verify(
        "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
        secret_hash=
        "4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba",
    )
    # which will fail if the secret hash is wrong
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapContractInvalid):
        w.atomicswap.verify(
            "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
            secret_hash=
            "4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdbb",
        )

    # a minimum duration can also be defined, where the duration defines how long it takes until the
    # contract becomes refundable, 0 if already assumed to be refundable
    w.atomicswap.verify(
        "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
        min_refund_time="+1d")
    # which will fail if assumed wrong
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapContractInvalid):
        w.atomicswap.verify(
            "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
            min_refund_time=0)

    # if one is assumed to be the sender, it can also be verified automatically
    w.atomicswap.verify(
        "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
        sender=True)
    # if one assumed its position wrong, it will however fail
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapContractInvalid):
        w.atomicswap.verify(
            "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
            receiver=True)

    # all can be verified at once of course
    w.atomicswap.verify(
        "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
        amount=50,
        secret_hash=
        "4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba",
        min_refund_time="+1d",
        sender=True,
    )

    # once the refund time has been reached, it does become refundable, and min_refund_time=0 should validate correctly
    explorer_client.hash_add(
        "5c86c987668ca47948a149413f4f004651249073eff4f144fd26b50e218705a8",
        '{"hashtype":"blockid","block":{"minerpayoutids":["84b378d60cbdd78430b39c8eddf226119b6f28256388557dd15f0b046bf3c3ed"],"transactions":[{"id":"9aec9f849e35f0bdd14c5ea9daed20c8fbfa09f5a6771bb46ce787eb7e2b00a0","height":16639,"parent":"5c86c987668ca47948a149413f4f004651249073eff4f144fd26b50e218705a8","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"144b2b7711fda335cdae5865ab3729d641266087bc4e088d9fba806345045903","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"f09af1c62026aed18d1d8f80e5a7bd4947a6cb5b6b69097c5b10cb983f0d729662c511a4852fa63690884e2b5c600e3935e08b81aaa757d9f0eb740292ec8309"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["83aa29b3e77f703526e28fbc0d2bfcf2b66c06b665e11cb5535b9575fd0e8105"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"8485f94209bf3e01ed169244ab2072ebb0d1c5dc589c95b39a3fbab3641b7a7e","timestamp":1549791703,"pobsindexes":{"BlockHeight":16638,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"144b2b7711fda335cdae5865ab3729d641266087bc4e088d9fba806345045903","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"f09af1c62026aed18d1d8f80e5a7bd4947a6cb5b6b69097c5b10cb983f0d729662c511a4852fa63690884e2b5c600e3935e08b81aaa757d9f0eb740292ec8309"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"5c86c987668ca47948a149413f4f004651249073eff4f144fd26b50e218705a8","difficulty":"30203","estimatedactivebs":"2365","height":16639,"maturitytimestamp":1549646167,"target":[0,2,43,120,39,20,204,42,102,32,125,110,53,77,39,71,99,124,13,223,197,154,115,42,126,62,185,120,208,177,21,190],"totalcoins":"0","arbitrarydatatotalsize":4328,"minerpayoutcount":16721,"transactioncount":17262,"coininputcount":633,"coinoutputcount":1225,"blockstakeinputcount":16639,"blockstakeoutputcount":16640,"minerfeecount":622,"arbitrarydatacount":572},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
        force=True,
    )
    # we should be able to refund at this point
    w.atomicswap.verify(
        "023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890",
        amount=50,
        secret_hash=
        "4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba",
        min_refund_time=0,
        sender=True,
    )

    c.wallets.delete()
    c.delete()
コード例 #10
0
def main(self):
    """
    to run:

    kosmos 'j.clients.goldchain.test(name="atomicswap_participate")'
    """

    cleanup("testnet_unittest_client")

    # create a goldchain client for devnet
    c = j.clients.goldchain.new("testnet_unittest_client", network_type="TEST")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = GoldChainExplorerGetClientStub()
    # add the blockchain info
    explorer_client.chain_info = '{"blockid":"583266f598044ebd971110bd03510e950361c22b4ed818e7644b6d59c36fd5bc","difficulty":"29305","estimatedactivebs":"2067","height":16922,"maturitytimestamp":1549649615,"target":[0,2,60,124,18,9,53,143,255,130,219,75,17,252,30,24,177,101,116,228,26,221,54,224,30,251,45,78,1,199,78,60],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17006,"transactioncount":17547,"coininputcount":635,"coinoutputcount":1228,"blockstakeinputcount":16922,"blockstakeoutputcount":16923,"minerfeecount":624,"arbitrarydatacount":573}'
    explorer_client.hash_add(
        "583266f598044ebd971110bd03510e950361c22b4ed818e7644b6d59c36fd5bc",
        '{"hashtype":"blockid","block":{"minerpayoutids":["eb538b38d8fcf7b0ef037eccf8cab1096c2b98031311453c150b2b150c483941"],"transactions":[{"id":"92132a65558684f154a56232acf9b7dd1e003d0f3ebdb2c4b44494d3c5e7f658","height":16922,"parent":"583266f598044ebd971110bd03510e950361c22b4ed818e7644b6d59c36fd5bc","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ca1da3d88904a532692ad2bb67122747eea4d91ead119043253ecb34410bbcc3","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"120c7bdf823a45fde303a725a1d757b3ece975abcd326ec036c056c6499b6de6cd798f18f8dff8c7adebcf19901e358609e675871335a71678c17de3e1dadb04"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["615f6f9d28d97082b423de7a878830b739b8fc4737c7ed20d3923a0019dbaed6"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"35879735f395c25fa7c0366bec7002f960798517e5335b5f27348c3a1b1923d4","timestamp":1549649728,"pobsindexes":{"BlockHeight":16921,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ca1da3d88904a532692ad2bb67122747eea4d91ead119043253ecb34410bbcc3","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"120c7bdf823a45fde303a725a1d757b3ece975abcd326ec036c056c6499b6de6cd798f18f8dff8c7adebcf19901e358609e675871335a71678c17de3e1dadb04"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"583266f598044ebd971110bd03510e950361c22b4ed818e7644b6d59c36fd5bc","difficulty":"29305","estimatedactivebs":"2067","height":16922,"maturitytimestamp":1549649615,"target":[0,2,60,124,18,9,53,143,255,130,219,75,17,252,30,24,177,101,116,228,26,221,54,224,30,251,45,78,1,199,78,60],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17006,"transactioncount":17547,"coininputcount":635,"coinoutputcount":1228,"blockstakeinputcount":16922,"blockstakeoutputcount":16923,"minerfeecount":624,"arbitrarydatacount":573},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    # add the wallet info
    explorer_client.hash_add(
        "01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"bca044302e018e67600bd0bd3223ae8dbb702eb528e73d6cfa9d057d4f73b03a","height":16911,"parent":"b4882a0b8632396a9c5d83a5c8684ab76736f4bff6d971795ed7334fac8aa339","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"357451c3f3a15f6150aedede9d5228ec5dfc2d32c9b62c2a46128533a7845c72","fulfillment":{"type":1,"data":{"publickey":"ed25519:fdb2e1b898dda304f748c0ff812a24729b2aafd344512079ab778eb368b18645","signature":"bd9dd36e86c08a5990ad5282d1079705c3a4b1cf3896e96791aa7db97002d5eb002c50467f45bd3ac1086292932cd2ab53c91b2e8bb74b9d9c9c0d558082ef08"}}}],"coinoutputs":[{"value":"51000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}},{"value":"99994187000000000","condition":{"type":1,"data":{"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99994239000000000","condition":{"type":1,"data":{"unlockhash":"019bb005b78a47fd084f4f3a088d83da4fadfc8e494ce4dae0d6f70a048a0a745d88ace6ce6f1c"}},"unlockhash":"019bb005b78a47fd084f4f3a088d83da4fadfc8e494ce4dae0d6f70a048a0a745d88ace6ce6f1c"}],"coinoutputids":["753aaeaa0c9e6c9f1f8da1974c83d8ca067ad536f464a2e2fc038bbd0404d084","8c8dbd70c6eb2d5d181aa5ae430f2cc86e038b92e45dd6f6d5a28400efad4511"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    # override internal functionality, as to use our stub client
    c._explorer_get = explorer_client.explorer_get
    c._explorer_post = explorer_client.explorer_post

    # a wallet is required to initiate an atomic swap contract
    w = c.wallets.new(
        "mytestwallet",
        seed=
        "remain solar kangaroo welcome clean object friend later bounce strong ship lift hamster afraid you super dolphin warm emotion curve smooth kiss stem diet",
    )
    # money is required to be available in the wallet
    assert str(w.balance.available) == "51"

    # a participation atomic swap contract can be created and signed as follows:
    result = w.atomicswap.participate(
        initiator=
        "01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c",
        amount=50,
        secret_hash=
        "4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba",
        submit=False,
    )  # submit=True is the default
    assert not result.submitted
    assert result.transaction.is_fulfilled()
    # the contract is returned as part of the result
    assert str(result.contract.amount) == "50"
    assert (
        str(result.contract.sender) ==
        "01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"
    )
    assert (
        str(result.contract.receiver) ==
        "01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c"
    )
    assert result.contract.refund_timestamp > 1549649728
    assert result.contract.secret_hash == "4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba"
    # one would than use `w.transaction_sign(result.transaction)` to submit it for real

    # however, usually an atomic swap contract is participated as follows:
    result = w.atomicswap.participate(
        initiator=
        "01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c",
        amount=50,
        secret_hash=
        "4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba",
    )
    assert result.submitted
    # the contract is returned as part of the result
    assert str(result.contract.amount) == "50"
    assert (
        str(result.contract.sender) ==
        "01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"
    )
    assert (
        str(result.contract.receiver) ==
        "01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c"
    )
    assert result.contract.refund_timestamp > 1549649728
    assert result.contract.secret_hash == "4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba"

    # ensure our contract was submitted
    transaction = explorer_client.posted_transaction_get(result.transaction.id)
    contract = AtomicSwapContract(transaction.coin_outputs[0], unspent=True)
    assert contract == result.contract
    # and ensure the transaction is fully signed
    for ci in transaction.coin_inputs:
        assert len(ci.fulfillment.signature.value) == 64

    # FYI: a contract's amount has to be greater than the network's minimum miner fee,
    # while goldchain does allow it, this client will raise an exception when you
    # do try to give a value equal to or less than the networks' miner fee.
    # This because such a contract cannot be redeemed or refunded.
    with pytest.raises(
            j.clients.goldchain.errors.AtomicSwapInsufficientAmountError):
        w.atomicswap.participate(
            initiator=
            "01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c",
            amount=c.minimum_miner_fee - "0.000000001 GFT",
            secret_hash=
            "4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba",
        )

    c.wallets.delete()
    c.delete()
コード例 #11
0
def main(self):
    """
    to run:

    kosmos 'j.clients.goldchain.test(name="wallet_coins_send")'
    """

    cleanup("devnet_unittest_client")

    # create a goldchain client for devnet
    c = j.clients.goldchain.new("devnet_unittest_client", network_type="DEV")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = GoldChainExplorerGetClientStub()
    # set the current block chain info
    explorer_client.chain_info = '{"blockid":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","difficulty":"27801","estimatedactivebs":"59","height":3644,"maturitytimestamp":1549012510,"target":[0,2,91,116,78,165,130,72,116,162,127,4,125,67,108,16,140,247,132,198,107,159,114,177,44,25,18,162,38,157,169,245],"totalcoins":"0","arbitrarydatatotalsize":6,"minerpayoutcount":3650,"transactioncount":3652,"coininputcount":12,"coinoutputcount":15,"blockstakeinputcount":3644,"blockstakeoutputcount":3645,"minerfeecount":7,"arbitrarydatacount":1}'
    explorer_client.hash_add(
        "552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e",
        '{"hashtype":"blockid","block":{"minerpayoutids":["468db689f752414702ef3a5aa06238f03a4539434a61624b3b8a0fb5dc38a211"],"transactions":[{"id":"2396f8e57bbb9b22bd1d749d5de3fd532ea6886e9660a556a13571d701d83e27","height":3644,"parent":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ff5a002ec356b7cb24fbee9f076f239fb8c72d5a8a448cee92ee6d29a87aef52","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"7bec94dfb87640726c6a14de2110599db0f81cf9fa456249e7bf79b0c74b79517edde25c4ee87f181880af44fe6ee054ff20b74eda2144fe07fa5bfb9d884208"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["f683e7319659c61f54e93546bc41b57c5bffe79de26c06ec7371034465804c81"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"47db4274551b0372564f8d1ab89c596428f00e460c0b416327e53983c8765198","timestamp":1549012665,"pobsindexes":{"BlockHeight":3643,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ff5a002ec356b7cb24fbee9f076f239fb8c72d5a8a448cee92ee6d29a87aef52","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"7bec94dfb87640726c6a14de2110599db0f81cf9fa456249e7bf79b0c74b79517edde25c4ee87f181880af44fe6ee054ff20b74eda2144fe07fa5bfb9d884208"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","difficulty":"27801","estimatedactivebs":"59","height":3644,"maturitytimestamp":1549012510,"target":[0,2,91,116,78,165,130,72,116,162,127,4,125,67,108,16,140,247,132,198,107,159,114,177,44,25,18,162,38,157,169,245],"totalcoins":"0","arbitrarydatatotalsize":6,"minerpayoutcount":3650,"transactioncount":3652,"coininputcount":12,"coinoutputcount":15,"blockstakeinputcount":3644,"blockstakeoutputcount":3645,"minerfeecount":7,"arbitrarydatacount":1},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    # add initial condition
    explorer_client.mint_condition_add(
        condition=j.clients.goldchain.types.conditions.from_recipient(
            "01a006599af1155f43d687635e9680650003a6c506934996b90ae84d07648927414046f9f0e936"
        ),
        height=0,
    )
    # overwrite the explorer get/post logic
    c._explorer_get = explorer_client.explorer_get
    c._explorer_post = explorer_client.explorer_post

    # the devnet genesis seed is the seed of the wallet,
    # which receives all block stakes and coins in the genesis block of the goldchain devnet
    DEVNET_GENESIS_SEED = "image orchard airport business cost work mountain obscure flee alpha alert salmon damage engage trumpet route marble subway immune short tide young cycle attract"

    # create a new devnet wallet
    w = c.wallets.new("mywallet", seed=DEVNET_GENESIS_SEED)
    # we create a new wallet using an existing seed,
    # such that our seed is used and not a new randomly generated seed

    # a goldchain (JS) wallet uses the underlying goldchain client for all its
    # interaction with the goldchain network
    assert w.network_type == "DEV"

    # balance will be fully 0 for wallet due to our stub state
    assert w.balance.available == 0
    assert w.balance.unconfirmed == 0
    assert w.balance.locked == 0

    # (1) if the wallet has no powers to mint coins,
    # the transaction will be not be submitted as the transaction won't be fulfilled
    result = w.minter.coins_new(
        recipient=
        "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
        amount=100)
    assert not result.submitted
    assert not result.transaction.is_fulfilled()
    assert not result.transaction.mint_fulfillment.is_fulfilled(
        parent_condition=c.minter.condition_get())
    assert isinstance(result.transaction.mint_fulfillment,
                      FulfillmentSingleSignature)

    # define the current mint condition to be ours
    explorer_client.mint_condition_add(
        condition=j.clients.goldchain.types.conditions.from_recipient(
            "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
        ),
        height=3643,
    )

    # (2) creating coins and sending it to a personal wallet on the used goldchain network can be done as follows:
    result = w.minter.coins_new(
        recipient=
        "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
        amount="108.24",  # the amount of GFT to send
    )
    assert result.submitted  # it is expected the transaction is submitted

    # validate more for testing purposes
    assert result.transaction.is_fulfilled()
    assert result.transaction.mint_fulfillment.is_fulfilled(
        parent_condition=c.minter.condition_get())
    assert isinstance(result.transaction.mint_fulfillment,
                      FulfillmentSingleSignature)
    assert (
        result.transaction.parent_mint_condition.unlockhash ==
        "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
    )
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == result.transaction.json()

    # (3) creating coins and sending it to a personal wallet with a lock and data is possible as well
    result = w.minter.coins_new(
        recipient=
        "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
        amount=200,  # the amount of GFT to send
        lock=
        "07/12/2020 14:35",  # a lock can be a timestamp, data-time str, duration str, or block height
        data="maximum 83 bytes can be used as optional data",
    )
    assert result.submitted  # it is expected the transaction is submitted

    # validate more for testing purposes
    assert result.transaction.is_fulfilled()
    assert result.transaction.mint_fulfillment.is_fulfilled(
        parent_condition=c.minter.condition_get())
    assert isinstance(result.transaction.mint_fulfillment,
                      FulfillmentSingleSignature)
    assert (
        result.transaction.parent_mint_condition.unlockhash ==
        "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
    )
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == result.transaction.json()

    # (4) one can also send to a full multi-sig wallet, when creating coins
    result = w.minter.coins_new(
        recipient=[
            "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
            "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
        ],
        amount="50 GFT",  # the amount of GFT to send
        lock=
        1550665225,  # a lock can be a timestamp, data-time str, duration str, or block height
        data=b"binary data can be added as well",
    )
    assert result.submitted  # it is expected the transaction is submitted

    # validate more for testing purposes
    assert result.transaction.is_fulfilled()
    assert result.transaction.mint_fulfillment.is_fulfilled(
        parent_condition=c.minter.condition_get())
    assert isinstance(result.transaction.mint_fulfillment,
                      FulfillmentSingleSignature)
    assert (
        result.transaction.parent_mint_condition.unlockhash ==
        "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
    )
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == result.transaction.json()

    # (5) one can also send to a x-out-of-n multisig wallet, when creating coins
    result = w.minter.coins_new(
        recipient=(
            1,
            [
                "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
                "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
            ],
        ),
        amount="300.0",  # the amount of GFT to send
        lock=
        35000,  # a lock can be a timestamp, data-time str, duration str, or block height
        data=bytearray(b"binary data can be added as well"),
    )
    assert result.submitted  # it is expected the transaction is submitted

    # validate more for testing purposes
    assert result.transaction.is_fulfilled()
    assert result.transaction.mint_fulfillment.is_fulfilled(
        parent_condition=c.minter.condition_get())
    assert isinstance(result.transaction.mint_fulfillment,
                      FulfillmentSingleSignature)
    assert (
        result.transaction.parent_mint_condition.unlockhash ==
        "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a"
    )
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == result.transaction.json()

    # define the minter condition as multi-sig
    explorer_client.mint_condition_add(
        condition=j.clients.goldchain.types.conditions.from_recipient((
            1,
            [
                "014ad318772a09de75fb62f084a33188a7f6fb5e7b68c0ed85a5f90fe11246386b7e6fe97a5a6a",
                "011cf61451b58970eeead00819e33f7fc812bd9b2d4e66914efa6163e238752d34be252ac8667f",
            ],
        )),
        height=3643,
        force=True,
    )

    # (6) creating coins and sending works the same if the condition is multi-sig,
    #     the only difference is that it might be possible that the transaction is not submitted yet,
    #     should more signatures be required in order to fulfill the mint fulfillment
    result = w.minter.coins_new(
        recipient=
        "015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f",
        amount="108.24",  # the amount of GFT to send
    )
    assert result.submitted  # it is expected the transaction is submitted

    # validate more for testing purposes
    assert result.transaction.is_fulfilled()
    assert result.transaction.mint_fulfillment.is_fulfilled(
        parent_condition=c.minter.condition_get())
    assert isinstance(result.transaction.mint_fulfillment,
                      FulfillmentMultiSignature)
    assert (
        result.transaction.parent_mint_condition.unlockhash ==
        "039481e77f55a2a4aee707c07d69a11b1d9dc4100ccc50b9f82d56b411826014e5ea1f477be065"
    )
    # ensure the transaction is posted and as expected there as well
    txn = explorer_client.posted_transaction_get(result.transaction.id)
    assert txn.json() == result.transaction.json()

    c.wallets.delete()
    c.delete()
コード例 #12
0
def main(self):
    """
    to run:

    kosmos 'j.clients.goldchain.test(name="atomicswap_refund")'
    """

    cleanup("testnet_unittest_client")

    # create a goldchain client for devnet
    c = j.clients.goldchain.new("testnet_unittest_client", network_type="DEV")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = GoldChainExplorerGetClientStub()
    # add the blockchain info
    explorer_client.chain_info = '{"blockid":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","difficulty":"23546","estimatedactivebs":"146","height":17384,"maturitytimestamp":1549705634,"target":[0,2,200,131,232,66,109,128,132,97,252,155,147,77,241,96,113,131,22,176,230,53,191,80,170,156,189,0,160,84,41,168],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17470,"transactioncount":18011,"coininputcount":637,"coinoutputcount":1231,"blockstakeinputcount":17384,"blockstakeoutputcount":17385,"minerfeecount":626,"arbitrarydatacount":573}'
    explorer_client.hash_add(
        "5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c",
        '{"hashtype":"blockid","block":{"minerpayoutids":["c8f3f82e4c5be07c667f140456e188336dc5c86319260ad9964c1b2a553d7031"],"transactions":[{"id":"9d8823855c59ac903238849e2f31600a9bec2c27d36071402815046dbf8000e7","height":17384,"parent":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"7c111a656be26b42215d13df330aa46c30d9f84d8b47ca5f41c4a5a1f89c782d","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"8de764af61c2e404f246482a70e29881929a71e4644a4c6f3a620889b1339a3eb789b0e2b5dad4ba26d1862bbee3a62a6f42be8106867722488aed352b414d00"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["be4408fecfa7fb88831d6ff1ff2d32377c25ac6cdafcdec1a16644ef3540d0ea"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"d329ebc493b75521db55b6595a7bfcbe5c1f94eb0ab1f7646bf39a42a8f7dddf","timestamp":1549705757,"pobsindexes":{"BlockHeight":17383,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"7c111a656be26b42215d13df330aa46c30d9f84d8b47ca5f41c4a5a1f89c782d","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"8de764af61c2e404f246482a70e29881929a71e4644a4c6f3a620889b1339a3eb789b0e2b5dad4ba26d1862bbee3a62a6f42be8106867722488aed352b414d00"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","difficulty":"23546","estimatedactivebs":"146","height":17384,"maturitytimestamp":1549705634,"target":[0,2,200,131,232,66,109,128,132,97,252,155,147,77,241,96,113,131,22,176,230,53,191,80,170,156,189,0,160,84,41,168],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17470,"transactioncount":18011,"coininputcount":637,"coinoutputcount":1231,"blockstakeinputcount":17384,"blockstakeoutputcount":17385,"minerfeecount":626,"arbitrarydatacount":573},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    # add the coin output info of the submitted atomic swap contract
    explorer_client.hash_add(
        "a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0",
        '{"hashtype":"coinoutputid","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"298b0a1d2da4ba13b3a787daea96da9e50ae6c299f6e3bea5ec3d50ee131c381","height":17740,"parent":"fa81bd33c4115e6a51f6f80107493a1b7e7591001d61948e88ef3cbb660e6fbe","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"b0e64c6e9d0d6d515856e15fcdfd869721f5b14ffc7599204f1e6ec174fb3631","fulfillment":{"type":1,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"1137db84e433980d51d66524dba5eec1c622c58099b9a1608f47293e506fa5338a0cd2d2d068506aed7de2a702025d9f7ec639ab712a1b32417677d4ab7ad50f"}}}],"coinoutputs":[{"value":"20000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"2c9b9fda14a1319a9c391d1f87df0333f56cf6804222bfd7c29d03829e0fa3b0","timelock":1549710071}}},{"value":"28000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"],"arbitrarydata":"YSBjb250cmFjdCB0aGF0IGlzIG5vdCBhIGNvbnRyYWN0"}},"coininputoutputs":[{"value":"49000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}},"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}],"coinoutputids":["a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0","deb0edcd4f4971819dd07aff0ff5565a53cd939f71f0a44d43f1deac1721dcc6"],"coinoutputunlockhashes":["025e64af6ec54312135ede1140e774da2ecadc9b2fb7ed8c0a7077035463d5049350c141597527","01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    # add initial wallet info
    explorer_client.hash_add(
        "01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"298b0a1d2da4ba13b3a787daea96da9e50ae6c299f6e3bea5ec3d50ee131c381","height":17740,"parent":"fa81bd33c4115e6a51f6f80107493a1b7e7591001d61948e88ef3cbb660e6fbe","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"b0e64c6e9d0d6d515856e15fcdfd869721f5b14ffc7599204f1e6ec174fb3631","fulfillment":{"type":1,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"1137db84e433980d51d66524dba5eec1c622c58099b9a1608f47293e506fa5338a0cd2d2d068506aed7de2a702025d9f7ec639ab712a1b32417677d4ab7ad50f"}}}],"coinoutputs":[{"value":"20000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"2c9b9fda14a1319a9c391d1f87df0333f56cf6804222bfd7c29d03829e0fa3b0","timelock":1549710071}}},{"value":"28000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"],"arbitrarydata":"YSBjb250cmFjdCB0aGF0IGlzIG5vdCBhIGNvbnRyYWN0"}},"coininputoutputs":[{"value":"49000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}},"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}],"coinoutputids":["a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0","deb0edcd4f4971819dd07aff0ff5565a53cd939f71f0a44d43f1deac1721dcc6"],"coinoutputunlockhashes":["025e64af6ec54312135ede1140e774da2ecadc9b2fb7ed8c0a7077035463d5049350c141597527","01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"4a7ac7930379675c82d0462a86e6d6f4018bdb2bdabaf49f4c177b8de19b4e7c","height":16930,"parent":"c25f345403080b8372a38f66608aa5a2287bdc61b82efe5ee6503ce85e8bcd35","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"753aaeaa0c9e6c9f1f8da1974c83d8ca067ad536f464a2e2fc038bbd0404d084","fulfillment":{"type":1,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"b5081e41797f53233c727c344698400a73f2cdd364e241df915df413d3eeafb425ce9b51de3731bcbf830c399a706f4d24ae7066f947a4a36ae1b25415bcde00"}}}],"coinoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c","hashedsecret":"4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba","timelock":1549736249}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"51000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}},"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}],"coinoutputids":["023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890"],"coinoutputunlockhashes":["02fb27c67c373c2f30611e0b98bf92ed6e6eb0a69b471457b282903945180cd5c5b8068731f767"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"b147985d381bc626ef79219ca988b5b1e2d328ade10cd7f3d48b96ca67928155","height":17698,"parent":"e8656ff72f9288c9ece3f85e489389f3c77e84052db13702b03dcff266a4d844","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486","fulfillment":{"type":2,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"4a7a15125f4e8819b4cf57dfe5f0389f45b0779b2a4bf27d885b4de8659ad363eb5be8c38ec88b33fc6fe1d18c55a9c0220f21977d36d1c8f63d582c8c126b0d","secret":"f68d8b238c193bc6765b8e355c53e4f574a2c9da458e55d4402edca621e53756"}}}],"coinoutputs":[{"value":"49000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b88206a3300dea3dd5f6cd73568ac5797b078910c78cbce6a71fcd0837a3ea5a4f2ed9fc70a1","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1","timelock":1549878527}},"unlockhash":"02f6d25603d232512ade46cdec3160301d8bd4880f2d4e8e20f54aff24f94dac5792ab1b325c3d"}],"coinoutputids":["b0e64c6e9d0d6d515856e15fcdfd869721f5b14ffc7599204f1e6ec174fb3631"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"bca044302e018e67600bd0bd3223ae8dbb702eb528e73d6cfa9d057d4f73b03a","height":16911,"parent":"b4882a0b8632396a9c5d83a5c8684ab76736f4bff6d971795ed7334fac8aa339","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"357451c3f3a15f6150aedede9d5228ec5dfc2d32c9b62c2a46128533a7845c72","fulfillment":{"type":1,"data":{"publickey":"ed25519:fdb2e1b898dda304f748c0ff812a24729b2aafd344512079ab778eb368b18645","signature":"bd9dd36e86c08a5990ad5282d1079705c3a4b1cf3896e96791aa7db97002d5eb002c50467f45bd3ac1086292932cd2ab53c91b2e8bb74b9d9c9c0d558082ef08"}}}],"coinoutputs":[{"value":"51000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}},{"value":"99994187000000000","condition":{"type":1,"data":{"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99994239000000000","condition":{"type":1,"data":{"unlockhash":"019bb005b78a47fd084f4f3a088d83da4fadfc8e494ce4dae0d6f70a048a0a745d88ace6ce6f1c"}},"unlockhash":"019bb005b78a47fd084f4f3a088d83da4fadfc8e494ce4dae0d6f70a048a0a745d88ace6ce6f1c"}],"coinoutputids":["753aaeaa0c9e6c9f1f8da1974c83d8ca067ad536f464a2e2fc038bbd0404d084","8c8dbd70c6eb2d5d181aa5ae430f2cc86e038b92e45dd6f6d5a28400efad4511"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    # override internal functionality, as to use our stub client
    c._explorer_get = explorer_client.explorer_get
    c._explorer_post = explorer_client.explorer_post

    # a wallet is required to redeem a contract
    w = c.wallets.new(
        "mytestwallet",
        seed=
        "remain solar kangaroo welcome clean object friend later bounce strong ship lift hamster afraid you super dolphin warm emotion curve smooth kiss stem diet",
    )

    # balance should be 0 at this point
    assert w.balance.available == "28 GFT"

    # if the output identifier is wrong, the refund will fail
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapContractNotFound):
        w.atomicswap.refund(
            "a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d5")

    # if not authorized, refund will also fail
    fw = c.wallets.new("foobar")
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapForbidden):
        fw.atomicswap.refund(
            "a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0")

    # if not refundable yet, refund will still fail
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapForbidden):
        w.atomicswap.refund(
            "a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0")

    # if the blockchain is updated, and the time for refund has reached, things will become possible
    explorer_client.chain_info = '{"blockid":"325adb8b1198071b0873fdf3cd14c2090ab41b1ddf04556929513ac9b993de00","difficulty":"25314","estimatedactivebs":"2473","height":17776,"maturitytimestamp":1549710377,"target":[0,2,150,191,242,114,194,147,165,155,81,115,131,110,151,69,195,82,72,171,51,207,157,226,142,254,6,122,72,56,5,109],"totalcoins":"0","arbitrarydatatotalsize":4384,"minerpayoutcount":17864,"transactioncount":18405,"coininputcount":639,"coinoutputcount":1234,"blockstakeinputcount":17776,"blockstakeoutputcount":17777,"minerfeecount":628,"arbitrarydatacount":574}'
    explorer_client.hash_add(
        "325adb8b1198071b0873fdf3cd14c2090ab41b1ddf04556929513ac9b993de00",
        '{"hashtype":"blockid","block":{"minerpayoutids":["4c506e8cf50539ebd988de20892166f8aca71038e47817e5881dfbb7b5a72d1f"],"transactions":[{"id":"e28f35ab114ba22a889b2cd7027333fc4689b2b0dde5fd459614805f0eed2677","height":17776,"parent":"325adb8b1198071b0873fdf3cd14c2090ab41b1ddf04556929513ac9b993de00","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"9827b96889c6f6e97cfea0f44602b5e4a5ce53f6769a5d8d7153348836708fba","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"51abf8ae9cf011cc9c630fb64482214a4fea5928282192ee75c597e5db415b10bbd06c276a41c45d0b20b692093ceb6afd9014b31828cbc64a68e9ae533e260a"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["79ccce665ca8bfc1c277418ebfc2c488cd545469fcdaff009edee9ac32fcb747"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"7651b16bcf6c0672a212c1846a142888b3beb1087cdc72c2c45d9c49ab55b890","timestamp":1549710522,"pobsindexes":{"BlockHeight":17775,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"9827b96889c6f6e97cfea0f44602b5e4a5ce53f6769a5d8d7153348836708fba","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"51abf8ae9cf011cc9c630fb64482214a4fea5928282192ee75c597e5db415b10bbd06c276a41c45d0b20b692093ceb6afd9014b31828cbc64a68e9ae533e260a"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"325adb8b1198071b0873fdf3cd14c2090ab41b1ddf04556929513ac9b993de00","difficulty":"25314","estimatedactivebs":"2473","height":17776,"maturitytimestamp":1549710377,"target":[0,2,150,191,242,114,194,147,165,155,81,115,131,110,151,69,195,82,72,171,51,207,157,226,142,254,6,122,72,56,5,109],"totalcoins":"0","arbitrarydatatotalsize":4384,"minerpayoutcount":17864,"transactioncount":18405,"coininputcount":639,"coinoutputcount":1234,"blockstakeinputcount":17776,"blockstakeoutputcount":17777,"minerfeecount":628,"arbitrarydatacount":574},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )

    # once the contract can be refunded and you are authorized to refund the contract,
    # you can refund the atomic swap contract as follows:
    w.atomicswap.refund(
        "a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0")

    # once it becomes registered on the chain
    explorer_client.hash_add(
        "a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0",
        '{"hashtype":"coinoutputid","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"298b0a1d2da4ba13b3a787daea96da9e50ae6c299f6e3bea5ec3d50ee131c381","height":17740,"parent":"fa81bd33c4115e6a51f6f80107493a1b7e7591001d61948e88ef3cbb660e6fbe","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"b0e64c6e9d0d6d515856e15fcdfd869721f5b14ffc7599204f1e6ec174fb3631","fulfillment":{"type":1,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"1137db84e433980d51d66524dba5eec1c622c58099b9a1608f47293e506fa5338a0cd2d2d068506aed7de2a702025d9f7ec639ab712a1b32417677d4ab7ad50f"}}}],"coinoutputs":[{"value":"20000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"2c9b9fda14a1319a9c391d1f87df0333f56cf6804222bfd7c29d03829e0fa3b0","timelock":1549710071}}},{"value":"28000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"],"arbitrarydata":"YSBjb250cmFjdCB0aGF0IGlzIG5vdCBhIGNvbnRyYWN0"}},"coininputoutputs":[{"value":"49000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}},"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}],"coinoutputids":["a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0","deb0edcd4f4971819dd07aff0ff5565a53cd939f71f0a44d43f1deac1721dcc6"],"coinoutputunlockhashes":["025e64af6ec54312135ede1140e774da2ecadc9b2fb7ed8c0a7077035463d5049350c141597527","01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"e9a909b0198328b38da003c31571d26eb6a0df35c31eee7fd087bc6ffcfd3501","height":17821,"parent":"c92c56e9520c63d7cb3061319eaf46d22e69e7f93d73ea73596d8651a7834fa2","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0","fulfillment":{"type":2,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"b2d98b7d6e3c3634ed1f9fb992ac4f1bfa844126d8addac8ee764ef995a656b064c674803c646fba6c7201bf0f16c44b36c0e45702cc9e66fc5ed73934eadd09","secret":"0000000000000000000000000000000000000000000000000000000000000000"}}}],"coinoutputs":[{"value":"19000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"20000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"2c9b9fda14a1319a9c391d1f87df0333f56cf6804222bfd7c29d03829e0fa3b0","timelock":1549710071}},"unlockhash":"025e64af6ec54312135ede1140e774da2ecadc9b2fb7ed8c0a7077035463d5049350c141597527"}],"coinoutputids":["4a3602e082b5038f72254976ec9a833300e0a87571a4956b33faf126198e579a"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
        force=True,
    )
    explorer_client.hash_add(
        "01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"298b0a1d2da4ba13b3a787daea96da9e50ae6c299f6e3bea5ec3d50ee131c381","height":17740,"parent":"fa81bd33c4115e6a51f6f80107493a1b7e7591001d61948e88ef3cbb660e6fbe","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"b0e64c6e9d0d6d515856e15fcdfd869721f5b14ffc7599204f1e6ec174fb3631","fulfillment":{"type":1,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"1137db84e433980d51d66524dba5eec1c622c58099b9a1608f47293e506fa5338a0cd2d2d068506aed7de2a702025d9f7ec639ab712a1b32417677d4ab7ad50f"}}}],"coinoutputs":[{"value":"20000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"2c9b9fda14a1319a9c391d1f87df0333f56cf6804222bfd7c29d03829e0fa3b0","timelock":1549710071}}},{"value":"28000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"],"arbitrarydata":"YSBjb250cmFjdCB0aGF0IGlzIG5vdCBhIGNvbnRyYWN0"}},"coininputoutputs":[{"value":"49000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}},"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}],"coinoutputids":["a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0","deb0edcd4f4971819dd07aff0ff5565a53cd939f71f0a44d43f1deac1721dcc6"],"coinoutputunlockhashes":["025e64af6ec54312135ede1140e774da2ecadc9b2fb7ed8c0a7077035463d5049350c141597527","01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"4a7ac7930379675c82d0462a86e6d6f4018bdb2bdabaf49f4c177b8de19b4e7c","height":16930,"parent":"c25f345403080b8372a38f66608aa5a2287bdc61b82efe5ee6503ce85e8bcd35","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"753aaeaa0c9e6c9f1f8da1974c83d8ca067ad536f464a2e2fc038bbd0404d084","fulfillment":{"type":1,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"b5081e41797f53233c727c344698400a73f2cdd364e241df915df413d3eeafb425ce9b51de3731bcbf830c399a706f4d24ae7066f947a4a36ae1b25415bcde00"}}}],"coinoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c","hashedsecret":"4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba","timelock":1549736249}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"51000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}},"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}],"coinoutputids":["023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890"],"coinoutputunlockhashes":["02fb27c67c373c2f30611e0b98bf92ed6e6eb0a69b471457b282903945180cd5c5b8068731f767"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"b147985d381bc626ef79219ca988b5b1e2d328ade10cd7f3d48b96ca67928155","height":17698,"parent":"e8656ff72f9288c9ece3f85e489389f3c77e84052db13702b03dcff266a4d844","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486","fulfillment":{"type":2,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"4a7a15125f4e8819b4cf57dfe5f0389f45b0779b2a4bf27d885b4de8659ad363eb5be8c38ec88b33fc6fe1d18c55a9c0220f21977d36d1c8f63d582c8c126b0d","secret":"f68d8b238c193bc6765b8e355c53e4f574a2c9da458e55d4402edca621e53756"}}}],"coinoutputs":[{"value":"49000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b88206a3300dea3dd5f6cd73568ac5797b078910c78cbce6a71fcd0837a3ea5a4f2ed9fc70a1","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1","timelock":1549878527}},"unlockhash":"02f6d25603d232512ade46cdec3160301d8bd4880f2d4e8e20f54aff24f94dac5792ab1b325c3d"}],"coinoutputids":["b0e64c6e9d0d6d515856e15fcdfd869721f5b14ffc7599204f1e6ec174fb3631"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"bca044302e018e67600bd0bd3223ae8dbb702eb528e73d6cfa9d057d4f73b03a","height":16911,"parent":"b4882a0b8632396a9c5d83a5c8684ab76736f4bff6d971795ed7334fac8aa339","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"357451c3f3a15f6150aedede9d5228ec5dfc2d32c9b62c2a46128533a7845c72","fulfillment":{"type":1,"data":{"publickey":"ed25519:fdb2e1b898dda304f748c0ff812a24729b2aafd344512079ab778eb368b18645","signature":"bd9dd36e86c08a5990ad5282d1079705c3a4b1cf3896e96791aa7db97002d5eb002c50467f45bd3ac1086292932cd2ab53c91b2e8bb74b9d9c9c0d558082ef08"}}}],"coinoutputs":[{"value":"51000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}},{"value":"99994187000000000","condition":{"type":1,"data":{"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99994239000000000","condition":{"type":1,"data":{"unlockhash":"019bb005b78a47fd084f4f3a088d83da4fadfc8e494ce4dae0d6f70a048a0a745d88ace6ce6f1c"}},"unlockhash":"019bb005b78a47fd084f4f3a088d83da4fadfc8e494ce4dae0d6f70a048a0a745d88ace6ce6f1c"}],"coinoutputids":["753aaeaa0c9e6c9f1f8da1974c83d8ca067ad536f464a2e2fc038bbd0404d084","8c8dbd70c6eb2d5d181aa5ae430f2cc86e038b92e45dd6f6d5a28400efad4511"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"e9a909b0198328b38da003c31571d26eb6a0df35c31eee7fd087bc6ffcfd3501","height":17821,"parent":"c92c56e9520c63d7cb3061319eaf46d22e69e7f93d73ea73596d8651a7834fa2","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0","fulfillment":{"type":2,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"b2d98b7d6e3c3634ed1f9fb992ac4f1bfa844126d8addac8ee764ef995a656b064c674803c646fba6c7201bf0f16c44b36c0e45702cc9e66fc5ed73934eadd09","secret":"0000000000000000000000000000000000000000000000000000000000000000"}}}],"coinoutputs":[{"value":"19000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"20000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"2c9b9fda14a1319a9c391d1f87df0333f56cf6804222bfd7c29d03829e0fa3b0","timelock":1549710071}},"unlockhash":"025e64af6ec54312135ede1140e774da2ecadc9b2fb7ed8c0a7077035463d5049350c141597527"}],"coinoutputids":["4a3602e082b5038f72254976ec9a833300e0a87571a4956b33faf126198e579a"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
        force=True,
    )
    explorer_client.chain_info = '{"blockid":"e7113d9220ed1d2b9580db56900275a84cae37f4a05d114f7c2e390e5548a748","difficulty":"16357","estimatedactivebs":"2062","height":17826,"maturitytimestamp":1549711238,"target":[0,4,1,160,229,117,42,154,91,220,26,179,144,72,8,24,83,164,54,113,254,108,169,110,240,86,243,41,58,188,99,94],"totalcoins":"0","arbitrarydatatotalsize":4384,"minerpayoutcount":17915,"transactioncount":18456,"coininputcount":640,"coinoutputcount":1235,"blockstakeinputcount":17826,"blockstakeoutputcount":17827,"minerfeecount":629,"arbitrarydatacount":574}'
    explorer_client.hash_add(
        "e7113d9220ed1d2b9580db56900275a84cae37f4a05d114f7c2e390e5548a748",
        '{"hashtype":"blockid","block":{"minerpayoutids":["dbddb3ae78bd05ae1673eb3dcd13bd9df54dd0e9fead56311cb53aeca4e8fff7"],"transactions":[{"id":"568969fac665b480b364f50c42920019e27c194ed876b36093bb3a5456b99f48","height":17826,"parent":"e7113d9220ed1d2b9580db56900275a84cae37f4a05d114f7c2e390e5548a748","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"efebc1649846007eacab3d119cd42daed8a240da8f9ebd31f2472df442467adb","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"28012952f77113862a48698af74d77055dd895c60ee6b07d583c3fe6db2fc70cc8ac5a72fa9d67acb7814df1409be26e5afd24dd9658a0aca8be4ef9bbb9230d"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["ad28a30a1846d1773070ca1ab0959344673402d211403b016bcdee6e85ed6ead"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"4df6fa9d77b675b1562740d602f42fa45a9f3d9458a2fa81959acc631db1c05e","timestamp":1549711355,"pobsindexes":{"BlockHeight":17825,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"efebc1649846007eacab3d119cd42daed8a240da8f9ebd31f2472df442467adb","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"28012952f77113862a48698af74d77055dd895c60ee6b07d583c3fe6db2fc70cc8ac5a72fa9d67acb7814df1409be26e5afd24dd9658a0aca8be4ef9bbb9230d"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"e7113d9220ed1d2b9580db56900275a84cae37f4a05d114f7c2e390e5548a748","difficulty":"16357","estimatedactivebs":"2062","height":17826,"maturitytimestamp":1549711238,"target":[0,4,1,160,229,117,42,154,91,220,26,179,144,72,8,24,83,164,54,113,254,108,169,110,240,86,243,41,58,188,99,94],"totalcoins":"0","arbitrarydatatotalsize":4384,"minerpayoutcount":17915,"transactioncount":18456,"coininputcount":640,"coinoutputcount":1235,"blockstakeinputcount":17826,"blockstakeoutputcount":17827,"minerfeecount":629,"arbitrarydatacount":574},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )

    # and the contract can no longer be refunded
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapContractSpent):
        w.atomicswap.refund(
            "a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0")

    # should you verify it at this point, you'll get the same exception
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapContractSpent):
        w.atomicswap.verify(
            "a5e0159688d300ed7a8f2685829192d8dd1266ce6e82a0d04a3bbbb080de30d0")

    c.wallets.delete()
    c.delete()
コード例 #13
0
def main(self):
    """
    to run:

    kosmos 'j.clients.goldchain.test(name="atomicswap_verify_receiver")'
    """

    cleanup("testnet_unittest_client")

    # create a goldchain client for devnet
    c = j.clients.goldchain.new("testnet_unittest_client", network_type="TEST")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = GoldChainExplorerGetClientStub()
    # add the blockchain info
    explorer_client.chain_info = '{"blockid":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","difficulty":"23546","estimatedactivebs":"146","height":17384,"maturitytimestamp":1549705634,"target":[0,2,200,131,232,66,109,128,132,97,252,155,147,77,241,96,113,131,22,176,230,53,191,80,170,156,189,0,160,84,41,168],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17470,"transactioncount":18011,"coininputcount":637,"coinoutputcount":1231,"blockstakeinputcount":17384,"blockstakeoutputcount":17385,"minerfeecount":626,"arbitrarydatacount":573}'
    explorer_client.hash_add(
        "5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c",
        '{"hashtype":"blockid","block":{"minerpayoutids":["c8f3f82e4c5be07c667f140456e188336dc5c86319260ad9964c1b2a553d7031"],"transactions":[{"id":"9d8823855c59ac903238849e2f31600a9bec2c27d36071402815046dbf8000e7","height":17384,"parent":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"7c111a656be26b42215d13df330aa46c30d9f84d8b47ca5f41c4a5a1f89c782d","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"8de764af61c2e404f246482a70e29881929a71e4644a4c6f3a620889b1339a3eb789b0e2b5dad4ba26d1862bbee3a62a6f42be8106867722488aed352b414d00"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["be4408fecfa7fb88831d6ff1ff2d32377c25ac6cdafcdec1a16644ef3540d0ea"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"d329ebc493b75521db55b6595a7bfcbe5c1f94eb0ab1f7646bf39a42a8f7dddf","timestamp":1549705757,"pobsindexes":{"BlockHeight":17383,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"7c111a656be26b42215d13df330aa46c30d9f84d8b47ca5f41c4a5a1f89c782d","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"8de764af61c2e404f246482a70e29881929a71e4644a4c6f3a620889b1339a3eb789b0e2b5dad4ba26d1862bbee3a62a6f42be8106867722488aed352b414d00"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","difficulty":"23546","estimatedactivebs":"146","height":17384,"maturitytimestamp":1549705634,"target":[0,2,200,131,232,66,109,128,132,97,252,155,147,77,241,96,113,131,22,176,230,53,191,80,170,156,189,0,160,84,41,168],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17470,"transactioncount":18011,"coininputcount":637,"coinoutputcount":1231,"blockstakeinputcount":17384,"blockstakeoutputcount":17385,"minerfeecount":626,"arbitrarydatacount":573},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    # override internal functionality, as to use our stub client
    c._explorer_get = explorer_client.explorer_get
    c._explorer_post = explorer_client.explorer_post

    # a wallet is required to initiate an atomic swap contract
    w = c.wallets.new(
        "mytestwallet",
        seed=
        "remain solar kangaroo welcome clean object friend later bounce strong ship lift hamster afraid you super dolphin warm emotion curve smooth kiss stem diet",
    )

    # one can verify that its transaction is sent as receiver,
    # usually done when someone is the receiver of an intiation contract,
    # such that all details can be verified prior to the creation of the
    # participation contract on the other chain

    # verification will fail if the contract could not be found
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapContractNotFound):
        w.atomicswap.verify(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486")

    # add the coin output info of the submitted atomic swap contract
    explorer_client.hash_add(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        '{"hashtype":"coinoutputid","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"fd583a124677a3ea7ed7981d008ca79bd9f93cedbee97af2bcfd28b3f31093cc","height":17383,"parent":"d329ebc493b75521db55b6595a7bfcbe5c1f94eb0ab1f7646bf39a42a8f7dddf","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"8c8dbd70c6eb2d5d181aa5ae430f2cc86e038b92e45dd6f6d5a28400efad4511","fulfillment":{"type":1,"data":{"publickey":"ed25519:cf87843f9c9014700eaa2dc28a80e4a54587d8cca0baa717805ce117cecd9bb4","signature":"b9ce44b1e0f9e3fae9f21111ddc08333f6ba32675fc971893f6ab7ca3e5ab664883794fd3a35aef59ba54242d9be92fbcf65cefb5eede3709dd57226203b6601"}}}],"coinoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b88206a3300dea3dd5f6cd73568ac5797b078910c78cbce6a71fcd0837a3ea5a4f2ed9fc70a1","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1","timelock":1549878527}}},{"value":"99994136000000000","condition":{"type":1,"data":{"unlockhash":"017cb06fa6f44828617b92603e95171044d9dc7c4966ffa0d8f6f97171558735974e7ecc623ff7"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99994187000000000","condition":{"type":1,"data":{"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}},"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}],"coinoutputids":["dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486","75bbe54aca26d5a5afbc442c0e033a3ad18efa1e130f0776a9e4b68cdbe24fb7"],"coinoutputunlockhashes":["02f6d25603d232512ade46cdec3160301d8bd4880f2d4e8e20f54aff24f94dac5792ab1b325c3d","017cb06fa6f44828617b92603e95171044d9dc7c4966ffa0d8f6f97171558735974e7ecc623ff7"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )

    # one can verify it all manually
    contract = w.atomicswap.verify(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486")
    assert contract.outputid == "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486"
    assert contract.amount == "50 GFT"
    assert contract.refund_timestamp == 1549878527
    assert contract.sender == "01b88206a3300dea3dd5f6cd73568ac5797b078910c78cbce6a71fcd0837a3ea5a4f2ed9fc70a1"
    assert contract.receiver == "01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"
    assert contract.secret_hash == "e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1"

    # the amount can however be verified automatically
    w.atomicswap.verify(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        amount=50)
    # which will fail if the amount is wrong
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapContractInvalid):
        w.atomicswap.verify(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
            amount=42)

    # the secret hash can be verified as well, very important
    w.atomicswap.verify(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        secret_hash=
        "e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1",
    )
    # which will fail if the secret hash is wrong
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapContractInvalid):
        w.atomicswap.verify(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
            secret_hash=
            "e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c2",
        )

    # a minimum duration can also be defined, where the duration defines how long it takes until the
    # contract becomes refundable, 0 if already assumed to be refundable
    w.atomicswap.verify(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        min_refund_time="+1d12h")
    # which will fail if assumed wrong
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapContractInvalid):
        w.atomicswap.verify(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
            min_refund_time="+2d")

    # if one is assumed to be the receiver, it can also be verified automatically
    w.atomicswap.verify(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        receiver=True)
    # if one assumed its position wrong, it will however fail
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapContractInvalid):
        w.atomicswap.verify(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
            sender=True)

    # all can be verified at once of course
    contract = w.atomicswap.verify(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        amount=50,
        secret_hash=
        "e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1",
        min_refund_time="+1d12h",
        receiver=True,
    )

    # once the expected min duration has been surpassed, validation will fail
    explorer_client.hash_add(
        "5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c",
        '{"hashtype":"blockid","block":{"minerpayoutids":["c8f3f82e4c5be07c667f140456e188336dc5c86319260ad9964c1b2a553d7031"],"transactions":[{"id":"9d8823855c59ac903238849e2f31600a9bec2c27d36071402815046dbf8000e7","height":17384,"parent":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"7c111a656be26b42215d13df330aa46c30d9f84d8b47ca5f41c4a5a1f89c782d","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"8de764af61c2e404f246482a70e29881929a71e4644a4c6f3a620889b1339a3eb789b0e2b5dad4ba26d1862bbee3a62a6f42be8106867722488aed352b414d00"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["be4408fecfa7fb88831d6ff1ff2d32377c25ac6cdafcdec1a16644ef3540d0ea"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"d329ebc493b75521db55b6595a7bfcbe5c1f94eb0ab1f7646bf39a42a8f7dddf","timestamp":1549791703,"pobsindexes":{"BlockHeight":17383,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"7c111a656be26b42215d13df330aa46c30d9f84d8b47ca5f41c4a5a1f89c782d","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"8de764af61c2e404f246482a70e29881929a71e4644a4c6f3a620889b1339a3eb789b0e2b5dad4ba26d1862bbee3a62a6f42be8106867722488aed352b414d00"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","difficulty":"23546","estimatedactivebs":"146","height":17384,"maturitytimestamp":1549705634,"target":[0,2,200,131,232,66,109,128,132,97,252,155,147,77,241,96,113,131,22,176,230,53,191,80,170,156,189,0,160,84,41,168],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17470,"transactioncount":18011,"coininputcount":637,"coinoutputcount":1231,"blockstakeinputcount":17384,"blockstakeoutputcount":17385,"minerfeecount":626,"arbitrarydatacount":573},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
        force=True,
    )
    # our initial hope would be wrong now
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapContractInvalid):
        w.atomicswap.verify(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
            amount=50,
            secret_hash=
            "e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1",
            min_refund_time="+1d12h",
            receiver=True,
        )
    # it is still not refundable however,
    # and for multiple checks one can pass the contract that was already fetched
    w.atomicswap.verify(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        amount=50,
        secret_hash=
        "e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1",
        min_refund_time="+1d",
        receiver=True,
        contract=contract,
    )

    c.wallets.delete()
    c.delete()
コード例 #14
0
def main(self):
    """
    to run:

    kosmos 'j.clients.goldchain.test(name="atomicswap_redeem")'
    """

    cleanup("testnet_unittest_client")

    # create a goldchain client for devnet
    c = j.clients.goldchain.new("testnet_unittest_client", network_type="DEV")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = GoldChainExplorerGetClientStub()
    # add the blockchain info
    explorer_client.chain_info = '{"blockid":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","difficulty":"23546","estimatedactivebs":"146","height":17384,"maturitytimestamp":1549705634,"target":[0,2,200,131,232,66,109,128,132,97,252,155,147,77,241,96,113,131,22,176,230,53,191,80,170,156,189,0,160,84,41,168],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17470,"transactioncount":18011,"coininputcount":637,"coinoutputcount":1231,"blockstakeinputcount":17384,"blockstakeoutputcount":17385,"minerfeecount":626,"arbitrarydatacount":573}'
    explorer_client.hash_add(
        "5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c",
        '{"hashtype":"blockid","block":{"minerpayoutids":["c8f3f82e4c5be07c667f140456e188336dc5c86319260ad9964c1b2a553d7031"],"transactions":[{"id":"9d8823855c59ac903238849e2f31600a9bec2c27d36071402815046dbf8000e7","height":17384,"parent":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"7c111a656be26b42215d13df330aa46c30d9f84d8b47ca5f41c4a5a1f89c782d","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"8de764af61c2e404f246482a70e29881929a71e4644a4c6f3a620889b1339a3eb789b0e2b5dad4ba26d1862bbee3a62a6f42be8106867722488aed352b414d00"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["be4408fecfa7fb88831d6ff1ff2d32377c25ac6cdafcdec1a16644ef3540d0ea"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"d329ebc493b75521db55b6595a7bfcbe5c1f94eb0ab1f7646bf39a42a8f7dddf","timestamp":1549705757,"pobsindexes":{"BlockHeight":17383,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"7c111a656be26b42215d13df330aa46c30d9f84d8b47ca5f41c4a5a1f89c782d","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"8de764af61c2e404f246482a70e29881929a71e4644a4c6f3a620889b1339a3eb789b0e2b5dad4ba26d1862bbee3a62a6f42be8106867722488aed352b414d00"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"5c180121d6dbbbc8480ee63d58933a4e0d9eae664c0b8662c3ef81102c3fe82c","difficulty":"23546","estimatedactivebs":"146","height":17384,"maturitytimestamp":1549705634,"target":[0,2,200,131,232,66,109,128,132,97,252,155,147,77,241,96,113,131,22,176,230,53,191,80,170,156,189,0,160,84,41,168],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17470,"transactioncount":18011,"coininputcount":637,"coinoutputcount":1231,"blockstakeinputcount":17384,"blockstakeoutputcount":17385,"minerfeecount":626,"arbitrarydatacount":573},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    # add the coin output info of the submitted atomic swap contract
    explorer_client.hash_add(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        '{"hashtype":"coinoutputid","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"fd583a124677a3ea7ed7981d008ca79bd9f93cedbee97af2bcfd28b3f31093cc","height":17383,"parent":"d329ebc493b75521db55b6595a7bfcbe5c1f94eb0ab1f7646bf39a42a8f7dddf","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"8c8dbd70c6eb2d5d181aa5ae430f2cc86e038b92e45dd6f6d5a28400efad4511","fulfillment":{"type":1,"data":{"publickey":"ed25519:cf87843f9c9014700eaa2dc28a80e4a54587d8cca0baa717805ce117cecd9bb4","signature":"b9ce44b1e0f9e3fae9f21111ddc08333f6ba32675fc971893f6ab7ca3e5ab664883794fd3a35aef59ba54242d9be92fbcf65cefb5eede3709dd57226203b6601"}}}],"coinoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1","timelock":1549878527}}},{"value":"99994136000000000","condition":{"type":1,"data":{"unlockhash":"017cb06fa6f44828617b92603e95171044d9dc7c4966ffa0d8f6f97171558735974e7ecc623ff7"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99994187000000000","condition":{"type":1,"data":{"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}},"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}],"coinoutputids":["dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486","75bbe54aca26d5a5afbc442c0e033a3ad18efa1e130f0776a9e4b68cdbe24fb7"],"coinoutputunlockhashes":["02f6d25603d232512ade46cdec3160301d8bd4880f2d4e8e20f54aff24f94dac5792ab1b325c3d","017cb06fa6f44828617b92603e95171044d9dc7c4966ffa0d8f6f97171558735974e7ecc623ff7"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    # override internal functionality, as to use our stub client
    c._explorer_get = explorer_client.explorer_get
    c._explorer_post = explorer_client.explorer_post

    # a wallet is required to redeem a contract
    w = c.wallets.new(
        "mytestwallet",
        seed=
        "remain solar kangaroo welcome clean object friend later bounce strong ship lift hamster afraid you super dolphin warm emotion curve smooth kiss stem diet",
    )

    # balance should be 0 at this point
    assert w.balance.available == "0 GFT"

    # if the output identifier is wrong, the redemption will fail
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapContractNotFound):
        w.atomicswap.redeem(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb483",
            secret=
            "f68d8b238c193bc6765b8e355c53e4f574a2c9da458e55d4402edca621e53756",
        )

    # if the secret is wrong, the redemption will fail as well
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapInvalidSecret):
        w.atomicswap.redeem(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
            secret=
            "f68d8b238c193bc6765b8e355c53e4f574a2c9da458e55d4402edca621e53754",
        )

    # if not authorized, redemption will also fail
    fw = c.wallets.new("foobar")
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapForbidden):
        fw.atomicswap.redeem(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
            secret=
            "f68d8b238c193bc6765b8e355c53e4f574a2c9da458e55d4402edca621e53756",
        )

    # once you know the secret, and you are authorized to receive the contract,
    # you can redeem the atomic swap contract as follows:
    w.atomicswap.redeem(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        secret=
        "f68d8b238c193bc6765b8e355c53e4f574a2c9da458e55d4402edca621e53756",
    )

    # once it becomes registered on the chain
    explorer_client.hash_add(
        "01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"4a7ac7930379675c82d0462a86e6d6f4018bdb2bdabaf49f4c177b8de19b4e7c","height":16930,"parent":"c25f345403080b8372a38f66608aa5a2287bdc61b82efe5ee6503ce85e8bcd35","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"753aaeaa0c9e6c9f1f8da1974c83d8ca067ad536f464a2e2fc038bbd0404d084","fulfillment":{"type":1,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"b5081e41797f53233c727c344698400a73f2cdd364e241df915df413d3eeafb425ce9b51de3731bcbf830c399a706f4d24ae7066f947a4a36ae1b25415bcde00"}}}],"coinoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01746b199781ea316a44183726f81e0734d93e7cefc18e9a913989821100aafa33e6eb7343fa8c","hashedsecret":"4163d4b31a1708cd3bb95a0a8117417bdde69fd1132909f92a8ec1e3fe2ccdba","timelock":1549736249}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"51000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}},"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}],"coinoutputids":["023b1c17a01945573933e62ca7a1297057681622aaea52c4c4e198077a263890"],"coinoutputunlockhashes":["02fb27c67c373c2f30611e0b98bf92ed6e6eb0a69b471457b282903945180cd5c5b8068731f767"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"b147985d381bc626ef79219ca988b5b1e2d328ade10cd7f3d48b96ca67928155","height":17698,"parent":"e8656ff72f9288c9ece3f85e489389f3c77e84052db13702b03dcff266a4d844","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486","fulfillment":{"type":2,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"4a7a15125f4e8819b4cf57dfe5f0389f45b0779b2a4bf27d885b4de8659ad363eb5be8c38ec88b33fc6fe1d18c55a9c0220f21977d36d1c8f63d582c8c126b0d","secret":"f68d8b238c193bc6765b8e355c53e4f574a2c9da458e55d4402edca621e53756"}}}],"coinoutputs":[{"value":"49000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1","timelock":1549878527}},"unlockhash":"02f6d25603d232512ade46cdec3160301d8bd4880f2d4e8e20f54aff24f94dac5792ab1b325c3d"}],"coinoutputids":["b0e64c6e9d0d6d515856e15fcdfd869721f5b14ffc7599204f1e6ec174fb3631"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"bca044302e018e67600bd0bd3223ae8dbb702eb528e73d6cfa9d057d4f73b03a","height":16911,"parent":"b4882a0b8632396a9c5d83a5c8684ab76736f4bff6d971795ed7334fac8aa339","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"357451c3f3a15f6150aedede9d5228ec5dfc2d32c9b62c2a46128533a7845c72","fulfillment":{"type":1,"data":{"publickey":"ed25519:fdb2e1b898dda304f748c0ff812a24729b2aafd344512079ab778eb368b18645","signature":"bd9dd36e86c08a5990ad5282d1079705c3a4b1cf3896e96791aa7db97002d5eb002c50467f45bd3ac1086292932cd2ab53c91b2e8bb74b9d9c9c0d558082ef08"}}}],"coinoutputs":[{"value":"51000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}},{"value":"99994187000000000","condition":{"type":1,"data":{"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99994239000000000","condition":{"type":1,"data":{"unlockhash":"019bb005b78a47fd084f4f3a088d83da4fadfc8e494ce4dae0d6f70a048a0a745d88ace6ce6f1c"}},"unlockhash":"019bb005b78a47fd084f4f3a088d83da4fadfc8e494ce4dae0d6f70a048a0a745d88ace6ce6f1c"}],"coinoutputids":["753aaeaa0c9e6c9f1f8da1974c83d8ca067ad536f464a2e2fc038bbd0404d084","8c8dbd70c6eb2d5d181aa5ae430f2cc86e038b92e45dd6f6d5a28400efad4511"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    explorer_client.hash_add(
        "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
        '{"hashtype":"coinoutputid","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"b147985d381bc626ef79219ca988b5b1e2d328ade10cd7f3d48b96ca67928155","height":17698,"parent":"e8656ff72f9288c9ece3f85e489389f3c77e84052db13702b03dcff266a4d844","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486","fulfillment":{"type":2,"data":{"publickey":"ed25519:e4f55bc46b5feb37c03a0faa2d624a9ee1d0deb5059aaa9625d8b4f60f29bcab","signature":"4a7a15125f4e8819b4cf57dfe5f0389f45b0779b2a4bf27d885b4de8659ad363eb5be8c38ec88b33fc6fe1d18c55a9c0220f21977d36d1c8f63d582c8c126b0d","secret":"f68d8b238c193bc6765b8e355c53e4f574a2c9da458e55d4402edca621e53756"}}}],"coinoutputs":[{"value":"49000000000","condition":{"type":1,"data":{"unlockhash":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1","timelock":1549878527}},"unlockhash":"02f6d25603d232512ade46cdec3160301d8bd4880f2d4e8e20f54aff24f94dac5792ab1b325c3d"}],"coinoutputids":["b0e64c6e9d0d6d515856e15fcdfd869721f5b14ffc7599204f1e6ec174fb3631"],"coinoutputunlockhashes":["01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"fd583a124677a3ea7ed7981d008ca79bd9f93cedbee97af2bcfd28b3f31093cc","height":17383,"parent":"d329ebc493b75521db55b6595a7bfcbe5c1f94eb0ab1f7646bf39a42a8f7dddf","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"8c8dbd70c6eb2d5d181aa5ae430f2cc86e038b92e45dd6f6d5a28400efad4511","fulfillment":{"type":1,"data":{"publickey":"ed25519:cf87843f9c9014700eaa2dc28a80e4a54587d8cca0baa717805ce117cecd9bb4","signature":"b9ce44b1e0f9e3fae9f21111ddc08333f6ba32675fc971893f6ab7ca3e5ab664883794fd3a35aef59ba54242d9be92fbcf65cefb5eede3709dd57226203b6601"}}}],"coinoutputs":[{"value":"50000000000","condition":{"type":2,"data":{"sender":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","receiver":"01b73c4e869b6167abe6180ebe7a907f56e0357b4a2f65eb53d22baad84650eb62fce66ba036d0","hashedsecret":"e24b6b609b351a958982ba91de7624d3503f428620f5586fbea1f71807b545c1","timelock":1549878527}}},{"value":"99994136000000000","condition":{"type":1,"data":{"unlockhash":"017cb06fa6f44828617b92603e95171044d9dc7c4966ffa0d8f6f97171558735974e7ecc623ff7"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"99994187000000000","condition":{"type":1,"data":{"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}},"unlockhash":"0183841ae8952a2ba72db0d6fce6208df70f2a936ee589ff852e06b20af48b40489572b1a69b2a"}],"coinoutputids":["dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486","75bbe54aca26d5a5afbc442c0e033a3ad18efa1e130f0776a9e4b68cdbe24fb7"],"coinoutputunlockhashes":["02f6d25603d232512ade46cdec3160301d8bd4880f2d4e8e20f54aff24f94dac5792ab1b325c3d","017cb06fa6f44828617b92603e95171044d9dc7c4966ffa0d8f6f97171558735974e7ecc623ff7"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
        force=True,
    )
    explorer_client.chain_info = '{"blockid":"5de1f56636bde6d724c717a3eda954117ad647930a55125a210cd7da8986c365","difficulty":"33956","estimatedactivebs":"2680","height":17712,"maturitytimestamp":1549709563,"target":[0,1,238,19,74,206,147,40,0,177,159,111,31,15,189,145,26,160,171,28,217,59,25,165,140,61,86,216,188,238,159,35],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17799,"transactioncount":18340,"coininputcount":638,"coinoutputcount":1232,"blockstakeinputcount":17712,"blockstakeoutputcount":17713,"minerfeecount":627,"arbitrarydatacount":573}'
    explorer_client.hash_add(
        "5de1f56636bde6d724c717a3eda954117ad647930a55125a210cd7da8986c365",
        '{"hashtype":"blockid","block":{"minerpayoutids":["f66f6bde0f026d68f7ce64cbb0ce0169a48e7abd636536ade754d152dbe64e5c"],"transactions":[{"id":"c7b2f558cd8e6ac0d94e2f0c0b025682d142b78457acfed3b89dca493451f15a","height":17712,"parent":"5de1f56636bde6d724c717a3eda954117ad647930a55125a210cd7da8986c365","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"2bbf77cb889cafc8df69293c016c03c0b10420e6ed1d83bbe6e79529ed49ba00","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"b3c41e1964f055c027437576943bce92808ff24411a0bf19a56e81b74e6f5fd5d027f8aabe836a56cc2a81837fd73cfc09473a97ac0746b319f4a906f7bc7c02"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["9830f9a00955c797289a9ab17211a05f3e393c2d8728e7fcc6c25b9fe7afce74"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"a32ed0392681c2faccffb818dd14aa92c405315f9b538500d9d4d840834d3438","timestamp":1549709657,"pobsindexes":{"BlockHeight":17711,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"2bbf77cb889cafc8df69293c016c03c0b10420e6ed1d83bbe6e79529ed49ba00","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"b3c41e1964f055c027437576943bce92808ff24411a0bf19a56e81b74e6f5fd5d027f8aabe836a56cc2a81837fd73cfc09473a97ac0746b319f4a906f7bc7c02"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"5de1f56636bde6d724c717a3eda954117ad647930a55125a210cd7da8986c365","difficulty":"33956","estimatedactivebs":"2680","height":17712,"maturitytimestamp":1549709563,"target":[0,1,238,19,74,206,147,40,0,177,159,111,31,15,189,145,26,160,171,28,217,59,25,165,140,61,86,216,188,238,159,35],"totalcoins":"0","arbitrarydatatotalsize":4351,"minerpayoutcount":17799,"transactioncount":18340,"coininputcount":638,"coinoutputcount":1232,"blockstakeinputcount":17712,"blockstakeoutputcount":17713,"minerfeecount":627,"arbitrarydatacount":573},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )

    # and the contract can no longer be redeemed
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapContractSpent):
        w.atomicswap.redeem(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486",
            secret=
            "f68d8b238c193bc6765b8e355c53e4f574a2c9da458e55d4402edca621e53756",
        )

    # should you verify it at this point, you'll get the same exception
    with pytest.raises(j.clients.goldchain.errors.AtomicSwapContractSpent):
        w.atomicswap.verify(
            "dd1babcbab492c742983b887a7408742ad0054ec8586541dd6ee6202877cb486")

    c.wallets.delete()
    c.delete()
コード例 #15
0
def main(self):
    """
    to run:

    kosmos 'j.clients.goldchain.test(name="balance_drain")'
    """

    cleanup("devnet_unitttest_client")

    # create a goldchain client for devnet
    c = j.clients.goldchain.new("devnet_unittest_client", network_type="DEV")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = GoldChainExplorerGetClientStub()
    explorer_client.hash_add(
        "000000000000000000000000000000000000000000000000000000000000000000000000000000",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"00d1eb537582e31f86a818b32e3a8e10110c1e4348b2d1d0c6746b4b75f3ddc8","height":8887,"parent":"09548093238b2592cc88e0e834a641bf2bcc6fe85275e50d0e179f720a5157c7","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"fb0ce589309af98870f7aa1b620948f8fbca2900d0729bfe1e4f501b45ae87c3","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"d0ff7079fcf804a011c7bfc226a2d9fc3ab07fbe135abbe44ebb81d64a59cb90bd647c48747e305d8af2c13ac04b8e4eb992156beeef3f31a74566684ad0c009"}}}],"coinoutputs":[{"value":"1","condition":{}},{"value":"2999999999","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"4000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["4be59838a2baaf69afbc558e961aae584f69b74ab72321799f380d02d5adea01","1744c053787a5662fad3651c0ed6c68b8bb5584370a81c95aa15cfcf220bfe13"],"coinoutputunlockhashes":["","0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"040e33a58c70e3f912b0851650ba6708c6e167b05bbe1f15fc5e870e46de435a","height":8830,"parent":"a06da42631ed8bc80ba9b383474172900fa6b804758b2f6d866d95542b4b4a28","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"0846ce4e40bd153f4b24c1131908ba87e2c99d78615c16eaac846cb3ca033562","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"90e6d2c8bb8d5ba7d5edcf38cf87d7ce1ec9d936b6939c05571f5317fd83ba495f895adc8695eedd35087c08f780eff05a74240bf1245eac920971c604892802"}}}],"coinoutputs":[{"value":"1000000000","condition":{}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"2000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["6eb896edab9539b41077a7fb540a4987d5e8b434ec77e150c1e571d2883652f2"],"coinoutputunlockhashes":[""],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"3d3ef900a0c54b45430c6248cf7bfbbbf92da663c84b73b10794eb2a9b0a74f5","height":7023,"parent":"e12271a40b3959d64cdf5d3845546c568a7db9313ca7b117a03454469cd6b348","rawtransaction":{"version":129,"data":{"nonce":"kyA3WfkRL6M=","mintfulfillment":{"type":3,"data":{"pairs":[{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"fa5560db80a0dcf7676885cf3517685c18bc82d787337299179d7c06271cbf724ced43d45f7bed7364c89f5adf5231264f322dee8d851606db8fd0494b45960e"}]}},"coinoutputs":[{"value":"1000000000","condition":{}}],"minerfees":["1000000000"],"arbitrarydata":"bW9yZSBmb3IgYWxs"}},"coininputoutputs":null,"coinoutputids":["0ffc3aceee0f3f695d1173056998e49e964c72c6b9d9ce08258f51cce6d9cd18"],"coinoutputunlockhashes":[""],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"422ff9ec3d34e263a9eb910c41b4c031e5ff0b8ba9dc5377518e7ed2cfda72ec","height":8872,"parent":"2b465d727d65da5c2986ed8b9b1a3211cd27f7b99f4bc887c801f7bbfb05f884","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"b4c0b5d51891608fc2bf0c93c001325ee5048ffdaf6239bca99b9cf46cbe6932","fulfillment":{"type":3,"data":{"pairs":[{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"7303e9e048ee66def55305fb069d9a75cc15e96168bd85ca102dfdea2c26a4e3776adcae341610e85217508cf24a3a82f711f12286d1de37fc248b375556fd08"},{"publickey":"ed25519:9e310aa31e236f4f1da9c5384138674dc68323da2d8d6cf6e8ee5055b88b61e3","signature":"acd50c4825e639e6423b07022b5b69125ee04014adc6b870e358222dc4a7b2733200ad68aa4f978fba2e306acb06912ae625cfd697f42d9d20bdac3e7faf5f0f"}]}}}],"coinoutputs":[{"value":"42000000000","condition":{}},{"value":"390999999534","condition":{"type":4,"data":{"unlockhashes":["0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab","01822fd5fefd2748972ea828a5c56044dec9a2b2275229ce5b212f926cd52fba015846451e4e46"],"minimumsignaturecount":2}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"433999999534","condition":{"type":4,"data":{"unlockhashes":["0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab","01822fd5fefd2748972ea828a5c56044dec9a2b2275229ce5b212f926cd52fba015846451e4e46"],"minimumsignaturecount":2}},"unlockhash":"03e9dbb15388d815ecb1d898bf94cc60e37053d12c7fe97bba2578c8b6a7dbdfb0b3caff77c6c6"}],"coinoutputids":["170815e3fd93f34e5b40644dd116efcfa27fd3e4f6992a68759978336a16fe5e","8ffb6836d68e12a9eb99b8b312399832cdfcbe461d75c3ceca6256b5afabe29e"],"coinoutputunlockhashes":["","03e9dbb15388d815ecb1d898bf94cc60e37053d12c7fe97bba2578c8b6a7dbdfb0b3caff77c6c6"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"617c2fd23b25a55c688e0cdb97c456b51bda09fdac24bc08e20196c25a3f4f95","height":6825,"parent":"7798fefb7ff9d07672c10028b1e26c1fe44865bbf47c150cb7dabb539dce8cb3","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"d5b4eddf4472bb5014b132ec331fd5e09421917d183ce31a58fa7a272b01b25d","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"f15072fedb61b6526c65f8dc0bee871bf51fe413de8bddf6a74edc0985aec41784cb54c4d756f0bc36e871a981e46ce23361345d8d092c9212ea92a995897c06"}}}],"coinoutputs":[{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"01f7e0686b2d38b3dee9295416857b06037a632ffe1d769153abcd522ab03d6a11b2a7d9383214"}}},{"value":"89000000000","condition":{}}],"minerfees":["1000000000"],"arbitrarydata":"ZnJvbSBtZSAoMik="}},"coininputoutputs":[{"value":"100000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["b910bb831df2454bc739f90a9854649f0f6a6be215497e14205a8e25d159d551","445579891a0c84b3b362f5266204c7b34cebe50b9d55ea6c9a05048baf7b5bf2"],"coinoutputunlockhashes":["01f7e0686b2d38b3dee9295416857b06037a632ffe1d769153abcd522ab03d6a11b2a7d9383214",""],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"7273cb1475fe04ea9f0ba1fd3e201fc39b416a580a5d0b3b8444e2e49b75bd95","height":8766,"parent":"c7db16c052e7899b03ff2e31d1dbd176420f816199c884a5ca080a328b028965","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"d3446e886a480405f74a78bc8347f5b822abc58622fa0ef102f4f4272dede799","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"5206f05fe42b4ba41658284dab74ab7f70ef47513d4ef4e0e9a9f361df8eee16d524ffdb311593d1373fa838447c7a36434568c833ed5820224b64334fd6ab0c"}}}],"coinoutputs":[{"value":"1000000000","condition":{}},{"value":"2000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"4000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["4f524b591aea65c5b36c8ef18102f2a69d6a7e07c54e3cedbd6fc85ac8ed2611","0846ce4e40bd153f4b24c1131908ba87e2c99d78615c16eaac846cb3ca033562"],"coinoutputunlockhashes":["","0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"8603ede968d434a5c61cf6cc8bf474aa6225823e72d500ad20b90293408a2694","height":11264,"parent":"ff6d7607ae89047482eb647ba915a1e305fcc5d0115686ab69d6cbf35f6b82b6","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"e2a567179c6e9fda9d30d5476a74cbc297829852afc23c644b566555a71e2a3b","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"77b026caf2cb18ccd628043e9f8728a064036d1ee845eb638b9dc44a4c7a7171e2513d2161172b574341268d7c142d78e20af978576265c1c0bd37a2327b250e"}}},{"parentid":"996d4956f5de5354a63ff644bcac26c30f3fe1f2a18ae17a457cd999bd8e9447","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"658dc60c13bd677679a904b0e7dc847b471841648679de40586aa2542a2b235c3dd3ece8e6b7b74678107d782c7608db4c6695f18ab1192a6048d1a9c423da09"}}}],"coinoutputs":[{"value":"100000000000","condition":{}},{"value":"15000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"31000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"},{"value":"85000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["ea75d01b64a05e1652bbc334a9fabf8ec0fa11f02c7d3657b4be3f3270a927d5","cf83f6453aaa7a49db8c448a86bf5e26715075a5b608e15d1628df5d2e1ed4ae"],"coinoutputunlockhashes":["","0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"972482a9407b16272b6f79e7df27d1ebe29587ab76081c8569f098fc33998768","height":11264,"parent":"ff6d7607ae89047482eb647ba915a1e305fcc5d0115686ab69d6cbf35f6b82b6","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"1744c053787a5662fad3651c0ed6c68b8bb5584370a81c95aa15cfcf220bfe13","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"9085545b4884a0724925ad88e311199961a51e018f985ba262d7516a0293c416e774ead5f1de44012e784522b12cc43bc3ba1680b4df1bf25785ab2e7094c200"}}}],"coinoutputs":[{"value":"1000000000","condition":{}},{"value":"999999999","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"2999999999","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["4834fadc322aa9cfdef0294e98624424c1f972523d335f8ae45175b1035f8958","de7ce2184e2a5c6f2f0d643a1ea08902459c2ee983127051f240a6819ae4bc35"],"coinoutputunlockhashes":["","0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"9e537af0eb87f6820341a7b435195ed89f0b3e003bb4c3715f30d6a713645bb7","height":7055,"parent":"fd5cfca2da14430c6e42ae65d15af9268addc469258cdb62d14553c8f05757a3","rawtransaction":{"version":129,"data":{"nonce":"IBKoTH6nDgM=","mintfulfillment":{"type":1,"data":{"publickey":"ed25519:32b9bdde2a079a4e0b75ab38b281ed67baabeff5dc27b1792190a0be900f6d90","signature":"e679cbddecb145d3d79fc4604c1ddd1443f59340e0e2f968623713b1d540615cd253a305bd456cb0f0cc125d3a2a2aa60408518927233884c53b3dba045a1e02"}},"coinoutputs":[{"value":"1000000000","condition":{}}],"minerfees":["1000000000"],"arbitrarydata":"bW9yZSBmb3IgYWxs"}},"coininputoutputs":null,"coinoutputids":["ebd166582e892cdbbc01b71c29b9a0e64f0f69eb91e7a1d99ffde99307ecaa2e"],"coinoutputunlockhashes":[""],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"9fcf663997809994acf89899f029e9e1eccb4ee64390af3797f771a61ea14575","height":6805,"parent":"ef827bb13a75e61126fe75d9a6fd1956a10a5feb824259c03fe04e1dc9a57968","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"47e816e82e699e4e15c2d03d1a69d24a8c49933a4fc09f2d28d23c3fbf3b8c90","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"99904e9745db92a8ac155ac9b4a59de8fde2757269ce76ed2640f010cc9b6235774115193fc55c96cdced3997f6688ffad7a4db56a2809c41cc591b46d746b02"}}}],"coinoutputs":[{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"01f7e0686b2d38b3dee9295416857b06037a632ffe1d769153abcd522ab03d6a11b2a7d9383214"}}},{"value":"475999999500","condition":{}}],"minerfees":["1000000000"],"arbitrarydata":"ZnJvbSBtZSgxKQ=="}},"coininputoutputs":[{"value":"486999999500","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["d4d8124abbecf29f965dc4186bbaa4c42758202775310522e9168609e85952ad","28bcc4bdef67f304b64b4525443c5257f775ea89122a6b9f2f4526af701aaeff"],"coinoutputunlockhashes":["01f7e0686b2d38b3dee9295416857b06037a632ffe1d769153abcd522ab03d6a11b2a7d9383214",""],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"c15ccc0e6120d156104b9b2fa64adf6688a4d6b9bfaa56b87215b5d1b92c076a","height":12165,"parent":"231f22fab108316d06bd3c33a8189560ea5e7322dfb62dcaf6f21ea437ceedfc","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"8908d1b7af0ed9d9a16c00dcbccd583c027c737df4233cd70c5c94abf6f177ff","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"bb0cef5bef645b4a8cd77986bf5923dbb54415157bb113615da71fdded9109f8e30e04264066381c3d2782f1733063076974596d9c9faf76e420fc9dcd763704"}}}],"coinoutputs":[{"value":"1000000000","condition":{"type":3,"data":{"locktime":1609412400,"condition":{}}}},{"value":"11000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}}}],"minerfees":["1000000000"],"arbitrarydata":"aGFwcHkgZWFybHkgbmV3IHllYXI="}},"coininputoutputs":[{"value":"13000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["ed1a8a793203d59c9a43483a78fc0143f5cab3881e94c928ecc46443127ae14f","efc235db4100bc88a01bf48cb15df0ac5f3efc2aa634c563dc7b61b9c837e083"],"coinoutputunlockhashes":["","0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"c1faca5dbf14484df8ea5ee9555946d34853f1af154fb2ecf45802af3fd58390","height":7011,"parent":"97e2632ca8941a04ceaf688aec591926726a5786adba5887d3372bf98c5c3bd0","rawtransaction":{"version":129,"data":{"nonce":"Q9QjsC/7ixI=","mintfulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"8e0fd7a3f710b6bece93e9fcdf0da742512bd3010f068348f242cda97f914dad3fac922f7225023d501c42e3a944910d5baa4df5b0e23f777332f86b329b3408"}},"coinoutputs":[{"value":"1000000000000000","condition":{"type":3,"data":{"locktime":42,"condition":{}}}}],"minerfees":["1000000000"],"arbitrarydata":"Y29pbnMgZm9yIGFsbCB0aGUgcGVvcGxl"}},"coininputoutputs":null,"coinoutputids":["5cc1cdcd0962403ee112509033c87eca5e07468f3c996f1f1e3240a6e806a920"],"coinoutputunlockhashes":[""],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"c4c17978c29e4fbc1c202c9b46b641efad059250f0fa4009d19ff252425f7e40","height":12181,"parent":"1cae514a987b8d5d5f13ee9d22998146c75bc633078f43df3540ab8f8ad1f7a4","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"e4691377980ad92560769a1ae7161f7e4cceec065542ae72000a66fbb3154232","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"aa489200decf5b2c7b9623f0c5819d9ece8cbd8115e71b65e5965ddd10521ab28a5a12d829010d88524a46783bd04ab60de21e5d7f85f057b2290c32b06aa009"}}}],"coinoutputs":[{"value":"1000000000","condition":{}},{"value":"2000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}}}],"minerfees":["1000000000"],"arbitrarydata":"bW9yZSBmcmVlIG1vbmV5"}},"coininputoutputs":[{"value":"4000000000","condition":{"type":3,"data":{"locktime":1262300400,"condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}}}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["126e7a270a3548a67e7756497506a4a53e578d5b818d7dec28117f92f8b74a6d","e04651829ae0e4636a958057c1426c4fc63569ccb04406b54bce472c3322af86"],"coinoutputunlockhashes":["","0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"ce1b49ec09d52e18b8e9038f6fc4a51627f1a417cfc044d995cce416f06b7802","height":6827,"parent":"dbd1bc09dd3c501a8674a699c297cd1dd50bf3d0d87a2c79a80c313f85375361","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"fe236bf66b542be84d50e0445449f6eddb11ffd93aa044040a73e35a3b33d8d9","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"116602636fa757b92b1ac06837cbcfecb7e0ceb553cc07ef819b557b872cc671ec27971171ba180595fa4d35bc748d6be9e899d0802179a355c07f2d9739100e"}}}],"coinoutputs":[{"value":"10000000000","condition":{"type":1,"data":{"unlockhash":"01f7e0686b2d38b3dee9295416857b06037a632ffe1d769153abcd522ab03d6a11b2a7d9383214"}}},{"value":"89000000000","condition":{}}],"minerfees":["1000000000"],"arbitrarydata":"ZnJvbSBtZSAoMyk="}},"coininputoutputs":[{"value":"100000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["de63dc7d73748cb41909688a29f52e7eb32aef37c30738d1e5c993bab26c7066","5ff190d50ea0d63ecfdd1500aa146344864c82512e1492947405552e1689d31a"],"coinoutputunlockhashes":["01f7e0686b2d38b3dee9295416857b06037a632ffe1d769153abcd522ab03d6a11b2a7d9383214",""],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"ce8f3ee3835afb7f587ab2473bf9eaacda7dbd27f8f36761ca62f9f12af68ecc","height":7026,"parent":"b38334513e11a5b93988af07b6ea8f39c808be6a3b0478f9f8a6bd7728a5f235","rawtransaction":{"version":129,"data":{"nonce":"Ewj99diiO6U=","mintfulfillment":{"type":3,"data":{"pairs":[{"publickey":"ed25519:9e310aa31e236f4f1da9c5384138674dc68323da2d8d6cf6e8ee5055b88b61e3","signature":"d39465e4522a08de394001160d0da5fd3dc4c2ca53ee6c571bf368786a66d137ace2b2ac927d09195ea32bd9e4cb6fc979e7994b8ea99b638f29408f41388207"},{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"d5bf7d9948d9125fdb15a17cf03c30405ebd4d4dbbbb3d86884edd5062d6ceddd7b0a54c1c2f5d80f4e6ca352a9a66c2642a89d1b9ae185face9af6c740bfe00"}]}},"coinoutputs":[{"value":"42000000000","condition":{}}],"minerfees":["1000000000"]}},"coininputoutputs":null,"coinoutputids":["63891de50dcb285689e1cd02618917ab9df4c6001f14e63532a5a75716ec0b6c"],"coinoutputunlockhashes":[""],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"ffd4ebd18d71c58674b28b116fc1cf67385a71b01b43104d817488dfd7e1c4c1","height":12159,"parent":"b93a31ee0eb16200101b07a4fd962bb8a8d928682b8d252a818fd7b56ff459e3","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"cf83f6453aaa7a49db8c448a86bf5e26715075a5b608e15d1628df5d2e1ed4ae","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"59cc566ac52b46eccf63480530dede3f773f289137ae3b1b333bdb09ae2d065983828af1751b28be76c31d61e445ca0e24abda60d1403b08b9edaaeab9e91402"}}}],"coinoutputs":[{"value":"1000000000","condition":{"type":3,"data":{"locktime":1549571431,"condition":{}}}},{"value":"13000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"15000000000","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["9a8f6b4524e07d7f0d2ece2a0d00c31fad9082ee21d4966af0ba9130c6f4eb6f","8908d1b7af0ed9d9a16c00dcbccd583c027c737df4233cd70c5c94abf6f177ff"],"coinoutputunlockhashes":["","0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    explorer_client.chain_info = '{"blockid":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","difficulty":"27801","estimatedactivebs":"59","height":3644,"maturitytimestamp":1549012510,"target":[0,2,91,116,78,165,130,72,116,162,127,4,125,67,108,16,140,247,132,198,107,159,114,177,44,25,18,162,38,157,169,245],"totalcoins":"0","arbitrarydatatotalsize":6,"minerpayoutcount":3650,"transactioncount":3652,"coininputcount":12,"coinoutputcount":15,"blockstakeinputcount":3644,"blockstakeoutputcount":3645,"minerfeecount":7,"arbitrarydatacount":1}'
    explorer_client.hash_add(
        "552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e",
        '{"hashtype":"blockid","block":{"minerpayoutids":["468db689f752414702ef3a5aa06238f03a4539434a61624b3b8a0fb5dc38a211"],"transactions":[{"id":"2396f8e57bbb9b22bd1d749d5de3fd532ea6886e9660a556a13571d701d83e27","height":3644,"parent":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ff5a002ec356b7cb24fbee9f076f239fb8c72d5a8a448cee92ee6d29a87aef52","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"7bec94dfb87640726c6a14de2110599db0f81cf9fa456249e7bf79b0c74b79517edde25c4ee87f181880af44fe6ee054ff20b74eda2144fe07fa5bfb9d884208"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["f683e7319659c61f54e93546bc41b57c5bffe79de26c06ec7371034465804c81"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"47db4274551b0372564f8d1ab89c596428f00e460c0b416327e53983c8765198","timestamp":1549012665,"pobsindexes":{"BlockHeight":3643,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"ff5a002ec356b7cb24fbee9f076f239fb8c72d5a8a448cee92ee6d29a87aef52","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"7bec94dfb87640726c6a14de2110599db0f81cf9fa456249e7bf79b0c74b79517edde25c4ee87f181880af44fe6ee054ff20b74eda2144fe07fa5bfb9d884208"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"552e410481cce1358ffcd4687f4199dd2181c799d55da26178e55643355bbd2e","difficulty":"27801","estimatedactivebs":"59","height":3644,"maturitytimestamp":1549012510,"target":[0,2,91,116,78,165,130,72,116,162,127,4,125,67,108,16,140,247,132,198,107,159,114,177,44,25,18,162,38,157,169,245],"totalcoins":"0","arbitrarydatatotalsize":6,"minerpayoutcount":3650,"transactioncount":3652,"coininputcount":12,"coinoutputcount":15,"blockstakeinputcount":3644,"blockstakeoutputcount":3645,"minerfeecount":7,"arbitrarydatacount":1},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    c._explorer_get = explorer_client.explorer_get

    # you can also get the balance from an unlock hash results
    balance = c.unlockhash_get(
        "000000000000000000000000000000000000000000000000000000000000000000000000000000"
    ).balance()
    assert len(balance.outputs_spent) == 0
    assert str(balance.available) == "1000843.999999501"
    assert str(balance.locked) == "2"

    # a balance can be drained,
    # meaning all confirmed outputs are spent
    txns = balance.drain(
        recipient=
        "01ffd7c884aa869056bfb832d957bb71a0005fee13c19046cebec84b3a5047ee8829eab070374b",
        miner_fee=c.minimum_miner_fee,
        data="drain the swamp",
        lock="06/06/2018 06:58",
    )
    assert len(txns) == 1
    txn = txns[0]
    # the given miner fee is used as the only miner fee
    assert len(txn.miner_fees) == 1
    assert txn.miner_fees[0] == c.minimum_miner_fee
    # the data should be asigned
    assert txn.data.value == b"drain the swamp"
    # all inputs should be orinating from the balance's available outputs
    assert [ci.parentid for ci in txn.coin_inputs
            ] == [co.id for co in balance.outputs_available]
    assert len(txn.coin_outputs) == 2
    # the only personal output should be the drain output
    co = txn.coin_outputs[0]
    assert co.condition.unlockhash == "01ffd7c884aa869056bfb832d957bb71a0005fee13c19046cebec84b3a5047ee8829eab070374b"
    assert co.value == (balance.available - c.minimum_miner_fee)
    # the other output is the custody fee
    co = txn.coin_outputs[1]
    assert co.condition.unlockhash == "800000000000000000000000000000000000000000000000000000000000000000af7bedde1fea"
    assert co.value == balance.custody_fee_debt_unlocked
    # no block stake inputs or outputs are obviously defined
    assert len(txn.blockstake_inputs) == 0
    assert len(txn.blockstake_outputs) == 0

    # NOTE: balance.drain also takes an optional parameter 'unconfirmed` which is False by default,
    # if True unconfirmed outputs will also be used when available.

    c.delete()
コード例 #16
0
def main(self):
    """
    to run:

    kosmos 'j.clients.goldchain.test(name="atomicswap_initiate")'
    """

    cleanup("testnet_unittest_client")

    # create a goldchain client for devnet
    c = j.clients.goldchain.new("testnet_unittest_client", network_type="TEST")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = GoldChainExplorerGetClientStub()
    # add the blockchain info
    explorer_client.chain_info = '{"blockid":"5c86c987668ca47948a149413f4f004651249073eff4f144fd26b50e218705a8","difficulty":"30203","estimatedactivebs":"2365","height":16639,"maturitytimestamp":1549646167,"target":[0,2,43,120,39,20,204,42,102,32,125,110,53,77,39,71,99,124,13,223,197,154,115,42,126,62,185,120,208,177,21,190],"totalcoins":"0","arbitrarydatatotalsize":4328,"minerpayoutcount":16721,"transactioncount":17262,"coininputcount":633,"coinoutputcount":1225,"blockstakeinputcount":16639,"blockstakeoutputcount":16640,"minerfeecount":622,"arbitrarydatacount":572}'
    explorer_client.hash_add(
        "5c86c987668ca47948a149413f4f004651249073eff4f144fd26b50e218705a8",
        '{"hashtype":"blockid","block":{"minerpayoutids":["84b378d60cbdd78430b39c8eddf226119b6f28256388557dd15f0b046bf3c3ed"],"transactions":[{"id":"9aec9f849e35f0bdd14c5ea9daed20c8fbfa09f5a6771bb46ce787eb7e2b00a0","height":16639,"parent":"5c86c987668ca47948a149413f4f004651249073eff4f144fd26b50e218705a8","rawtransaction":{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"144b2b7711fda335cdae5865ab3729d641266087bc4e088d9fba806345045903","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"f09af1c62026aed18d1d8f80e5a7bd4947a6cb5b6b69097c5b10cb983f0d729662c511a4852fa63690884e2b5c600e3935e08b81aaa757d9f0eb740292ec8309"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}},"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"blockstakeoutputids":["83aa29b3e77f703526e28fbc0d2bfcf2b66c06b665e11cb5535b9575fd0e8105"],"blockstakeunlockhashes":["015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"],"unconfirmed":false}],"rawblock":{"parentid":"8485f94209bf3e01ed169244ab2072ebb0d1c5dc589c95b39a3fbab3641b7a7e","timestamp":1549646257,"pobsindexes":{"BlockHeight":16638,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":[{"value":"10000000000","unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}],"transactions":[{"version":1,"data":{"coininputs":null,"blockstakeinputs":[{"parentid":"144b2b7711fda335cdae5865ab3729d641266087bc4e088d9fba806345045903","fulfillment":{"type":1,"data":{"publickey":"ed25519:d285f92d6d449d9abb27f4c6cf82713cec0696d62b8c123f1627e054dc6d7780","signature":"f09af1c62026aed18d1d8f80e5a7bd4947a6cb5b6b69097c5b10cb983f0d729662c511a4852fa63690884e2b5c600e3935e08b81aaa757d9f0eb740292ec8309"}}}],"blockstakeoutputs":[{"value":"3000","condition":{"type":1,"data":{"unlockhash":"015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f"}}}],"minerfees":null}}]},"blockid":"5c86c987668ca47948a149413f4f004651249073eff4f144fd26b50e218705a8","difficulty":"30203","estimatedactivebs":"2365","height":16639,"maturitytimestamp":1549646167,"target":[0,2,43,120,39,20,204,42,102,32,125,110,53,77,39,71,99,124,13,223,197,154,115,42,126,62,185,120,208,177,21,190],"totalcoins":"0","arbitrarydatatotalsize":4328,"minerpayoutcount":16721,"transactioncount":17262,"coininputcount":633,"coinoutputcount":1225,"blockstakeinputcount":16639,"blockstakeoutputcount":16640,"minerfeecount":622,"arbitrarydatacount":572},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":null,"multisigaddresses":null,"unconfirmed":false}',
    )
    # add the wallet info
    explorer_client.hash_add(
        "011dcc29c37e564ef1b0ae6273bddd6fa9c5fe5443f3a18827d3e5733892f37b2439da663e1e6f",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"4d64c4f184ef5c7267585df8bc6af8a3e9f5963903c30ff23cfdfb068cccded7","height":16623,"parent":"95caf23ce383e01bd8af5d9391123091426278716ec5eb01a986c833119511df","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"c61aebcc2555ea16ef25152966fbbdaf2e7ba6a33c75c1033249cacc6331b2e8","fulfillment":{"type":1,"data":{"publickey":"ed25519:89ba466d80af1b453a435175dbba6da7718e9cb19c64c0ed41fca3e6982e3636","signature":"3f7c30fe4bdfc37a3f483487ef7450ee63fb6d28a7e173d6b372d895f8442ce198bf3b171cfc6315d6f03a37f00675f336a91c25b179f153237330491845f00c"}}}],"coinoutputs":[{"value":"51000000000","condition":{"type":1,"data":{"unlockhash":"011dcc29c37e564ef1b0ae6273bddd6fa9c5fe5443f3a18827d3e5733892f37b2439da663e1e6f"}}},{"value":"999627999999501","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}}}],"minerfees":["1000000000"]}},"coininputoutputs":[{"value":"999679999999501","condition":{"type":1,"data":{"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}},"unlockhash":"0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"}],"coinoutputids":["243c1bb1c7dcc18a612cf1cba4ec433f25aaedbd9916b203a66b95635f9e28b2","9516f1c1cafd58e475f424931c2f2ab9d2df62fdd263d0b075b260df80284b47"],"coinoutputunlockhashes":["011dcc29c37e564ef1b0ae6273bddd6fa9c5fe5443f3a18827d3e5733892f37b2439da663e1e6f","0107e83d2bd8a7aad7ab0af0c0a0f1f116fb42335f64eeeb5ed1b76bd63e62ce59a3872a7279ab"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    # override internal functionality, as to use our stub client
    c._explorer_get = explorer_client.explorer_get
    c._explorer_post = explorer_client.explorer_post

    # a wallet is required to initiate an atomic swap contract
    w = c.wallets.new(
        "mytestwallet",
        seed=
        "survey exile lab cook license sock rose squirrel noodle point they lounge oval kit tape virus loop scare water gorilla baby educate program wish",
    )
    # money is required to be available in the wallet
    assert str(w.balance.available) == "51"

    # an atomic swap contract can be created and signed without being submitted as follows:
    result = w.atomicswap.initiate(
        participator=
        "0131cb8e9b5214096fd23c8d88795b2887fbc898aa37125a406fc4769a4f9b3c1dc423852868f6",
        amount=50,
        submit=False,
    )  # submit=True is the default
    assert not result.submitted
    assert result.transaction.is_fulfilled()
    # the contract is returned as part of the result
    assert str(result.contract.amount) == "50"
    assert (
        str(result.contract.sender) ==
        "011dcc29c37e564ef1b0ae6273bddd6fa9c5fe5443f3a18827d3e5733892f37b2439da663e1e6f"
    )
    assert (
        str(result.contract.receiver) ==
        "0131cb8e9b5214096fd23c8d88795b2887fbc898aa37125a406fc4769a4f9b3c1dc423852868f6"
    )
    assert result.contract.refund_timestamp > 1549646257
    assert result.contract.secret_hash == AtomicSwapSecretHash.from_secret(
        result.secret)
    # one would than use `w.transaction_sign(result.transaction)` to submit it for real

    # However, usually an atomic swap contract is initiated as follows:
    result = w.atomicswap.initiate(
        participator=
        "0131cb8e9b5214096fd23c8d88795b2887fbc898aa37125a406fc4769a4f9b3c1dc423852868f6",
        amount=50,
        data="the beginning of it all",
    )  # data is optional
    assert result.submitted
    # the contract is returned as part of the result
    assert str(result.contract.amount) == "50"
    assert (
        str(result.contract.sender) ==
        "011dcc29c37e564ef1b0ae6273bddd6fa9c5fe5443f3a18827d3e5733892f37b2439da663e1e6f"
    )
    assert (
        str(result.contract.receiver) ==
        "0131cb8e9b5214096fd23c8d88795b2887fbc898aa37125a406fc4769a4f9b3c1dc423852868f6"
    )
    assert result.contract.refund_timestamp > 1549646257
    assert result.contract.secret_hash == AtomicSwapSecretHash.from_secret(
        result.secret)

    # ensure our contract was submitted
    transaction = explorer_client.posted_transaction_get(result.transaction.id)
    contract = AtomicSwapContract(transaction.coin_outputs[0], unspent=True)
    assert contract == result.contract
    # and ensure the transaction is fully signed
    for ci in transaction.coin_inputs:
        assert len(ci.fulfillment.signature.value) == 64

    # FYI: a contract's amount has to be greater than the network's minimum miner fee,
    # while goldchain does allow it, this client will raise an exception when you
    # do try to give a value equal to or less than the networks' miner fee.
    # This because such a contract cannot be redeemed or refunded.
    with pytest.raises(
            j.clients.goldchain.errors.AtomicSwapInsufficientAmountError):
        w.atomicswap.initiate(
            participator=
            "0131cb8e9b5214096fd23c8d88795b2887fbc898aa37125a406fc4769a4f9b3c1dc423852868f6",
            amount=c.minimum_miner_fee - "0.000000001 GFT",
        )

    c.wallets.delete()
    c.delete()
コード例 #17
0
def main(self):
    """
    to run:

    kosmos 'j.clients.goldchain.test(name="unlockhash_get")'
    """

    cleanup("testnet_unittest_client")

    # create a goldchain client for devnet
    c = j.clients.goldchain.new("testnet_unittest_client", network_type="TEST")

    # (we replace internal client logic with custom logic as to ensure we can test without requiring an active network)
    explorer_client = GoldChainExplorerGetClientStub()
    explorer_client.hash_add(
        "01d1c4dd242e3badf45004be9a3b86c613923c6d872bab5ec92e4f076114d4c3a15b7b43e1c00f",
        '{"hashtype":"unlockhash","block":{"minerpayoutids":null,"transactions":null,"rawblock":{"parentid":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":0,"pobsindexes":{"BlockHeight":0,"TransactionIndex":0,"OutputIndex":0},"minerpayouts":null,"transactions":null},"blockid":"0000000000000000000000000000000000000000000000000000000000000000","difficulty":"0","estimatedactivebs":"0","height":0,"maturitytimestamp":0,"target":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"totalcoins":"0","arbitrarydatatotalsize":0,"minerpayoutcount":0,"transactioncount":0,"coininputcount":0,"coinoutputcount":0,"blockstakeinputcount":0,"blockstakeoutputcount":0,"minerfeecount":0,"arbitrarydatacount":0},"blocks":null,"transaction":{"id":"0000000000000000000000000000000000000000000000000000000000000000","height":0,"parent":"0000000000000000000000000000000000000000000000000000000000000000","rawtransaction":{"version":0,"data":{"coininputs":[],"minerfees":null}},"coininputoutputs":null,"coinoutputids":null,"coinoutputunlockhashes":null,"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},"transactions":[{"id":"0add5d695e01525be854a3c404503e60fd1245b4602cad9608c5d5fdfb3e028e","height":1873,"parent":"ba6dcf696aff09f5b558e63dde2554edf948e66c1295b11324951647e9ad467a","rawtransaction":{"version":0,"data":{"coininputs":[{"parentid":"6c97c4e0bf832133ad370b9a5daff1309b00b570484a922329ef91e9f7ffa7fe","unlocker":{"type":1,"condition":{"publickey":"ed25519:b86e9efbf7442e353ad7f98f159eb23fe66a1722e11f547876f55b5521d6e350"},"fulfillment":{"signature":"89e6f578416c0db8c399bc8010cd3f11c936931007b1299bb6e436e933f1b7e26702ecb58a04c2d81802d13737e73745fb7657cc4b5c8e0c1d0fddfb6c71ef05"}}}],"coinoutputs":[{"value":"10000000000000000","unlockhash":"015df22a2e82a3323bc6ffbd1730450ed844feca711c8fe0c15e218c171962fd17b206263220ee"},{"value":"89839999300000000","unlockhash":"01d1c4dd242e3badf45004be9a3b86c613923c6d872bab5ec92e4f076114d4c3a15b7b43e1c00f"}],"minerfees":["100000000"]}},"coininputoutputs":[{"value":"99839999400000000","condition":{"type":1,"data":{"unlockhash":"01c389c2b8e097bc4970754b440a962326340eba85dff7a8dd96f7b14bbe0be8e79318c4b6c564"}},"unlockhash":"01c389c2b8e097bc4970754b440a962326340eba85dff7a8dd96f7b14bbe0be8e79318c4b6c564"}],"coinoutputids":["113e7113a436aaa3d43f29afa382706e820e2747ca74bec62646bc35049e68d6","c1df239aba64ca0c6a241ddf18f3dd18b75e2c650874dd4c8c7dbbb56bd73683"],"coinoutputunlockhashes":["015df22a2e82a3323bc6ffbd1730450ed844feca711c8fe0c15e218c171962fd17b206263220ee","01d1c4dd242e3badf45004be9a3b86c613923c6d872bab5ec92e4f076114d4c3a15b7b43e1c00f"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"513f3542c91f1be112ea4b36d3204afea9bb43d5c32295896d94cae96078714c","height":1878,"parent":"cd00da19a01822ad5c73279775a06c902832835c865ae7c5aa6bbbc01c8882f7","rawtransaction":{"version":0,"data":{"coininputs":[{"parentid":"113e7113a436aaa3d43f29afa382706e820e2747ca74bec62646bc35049e68d6","unlocker":{"type":1,"condition":{"publickey":"ed25519:ef8c1f52aa64f837b50b9bfb85106906d05f43a5768dbf8320b87bce14dc00cc"},"fulfillment":{"signature":"8bcb889b30735b546cbbe6328d38f130f77e7c93b07d6cfdd09124bbda589c61a444d0e8126d614031237d85b8995476cb02c756f860ef3c57f1d48722426408"}}}],"coinoutputs":[{"value":"9999989999990000","unlockhash":"01d1c4dd242e3badf45004be9a3b86c613923c6d872bab5ec92e4f076114d4c3a15b7b43e1c00f"},{"value":"9900010000","unlockhash":"015df22a2e82a3323bc6ffbd1730450ed844feca711c8fe0c15e218c171962fd17b206263220ee"}],"minerfees":["100000000"]}},"coininputoutputs":[{"value":"10000000000000000","condition":{"type":1,"data":{"unlockhash":"015df22a2e82a3323bc6ffbd1730450ed844feca711c8fe0c15e218c171962fd17b206263220ee"}},"unlockhash":"015df22a2e82a3323bc6ffbd1730450ed844feca711c8fe0c15e218c171962fd17b206263220ee"}],"coinoutputids":["9101b35ad291ba03ec16699abaf2422ef3f11d82b7e20e4921af05274f8495a4","440f6d91460143162d55a732e48ab3ab179a2375af8317b37b28f8d4a66de2e4"],"coinoutputunlockhashes":["01d1c4dd242e3badf45004be9a3b86c613923c6d872bab5ec92e4f076114d4c3a15b7b43e1c00f","015df22a2e82a3323bc6ffbd1730450ed844feca711c8fe0c15e218c171962fd17b206263220ee"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"96df1e34533ffcd42ee1db995e165538edd275ba0c065ef9293ead84ff923eec","height":2662,"parent":"b69bc0a12308938cbc8207483f39df63a2295142875944d6a2db3930d5c2564f","rawtransaction":{"version":0,"data":{"coininputs":[{"parentid":"c1df239aba64ca0c6a241ddf18f3dd18b75e2c650874dd4c8c7dbbb56bd73683","unlocker":{"type":1,"condition":{"publickey":"ed25519:25b6aae78d545d64746f4a7310230e7b7bce263dcaa9dd5b3b6dd614d0f46413"},"fulfillment":{"signature":"7453f27cca1381f0cc05a6142b8d4ded5c1f84132742ba359df99ea7c17b2f304f8b9c8f3722da9ceb632fb7f526c8022c71e385bb75df9542cf94a7f3f3cc06"}}}],"coinoutputs":[{"value":"1000000000000000","unlockhash":"0199f4f21fc13ceb22da91d4b1701e67556a7c23f118bc5b1b15b132433d07b2496e093c4f4cd6"},{"value":"88839999200000000","unlockhash":"0175c11c8124e325cdba4f6843e917ba90519e9580adde5b10de5a7cabcc3251292194c5a0e6d2"}],"minerfees":["100000000"]}},"coininputoutputs":[{"value":"89839999300000000","condition":{"type":1,"data":{"unlockhash":"01d1c4dd242e3badf45004be9a3b86c613923c6d872bab5ec92e4f076114d4c3a15b7b43e1c00f"}},"unlockhash":"01d1c4dd242e3badf45004be9a3b86c613923c6d872bab5ec92e4f076114d4c3a15b7b43e1c00f"}],"coinoutputids":["90513506d1216f89e73a361b6306d8543c81aff092e376ee8d8bb9b7ea024de6","7daf8035a6697701aeed36b4d6fe8de6ff4bbf9fd1ba9b0933d87e260f924783"],"coinoutputunlockhashes":["0199f4f21fc13ceb22da91d4b1701e67556a7c23f118bc5b1b15b132433d07b2496e093c4f4cd6","0175c11c8124e325cdba4f6843e917ba90519e9580adde5b10de5a7cabcc3251292194c5a0e6d2"],"blockstakeinputoutputs":null,"blockstakeoutputids":null,"blockstakeunlockhashes":null,"unconfirmed":false},{"id":"ace08f4a5977c281db617fa48409ff9207357e851ddfd30f89c5edb783a03199","height":48274,"parent":"c4589dfd355674cfe58edb52234b76c262d615673b97edb8231723287af0581d","rawtransaction":{"version":1,"data":{"coininputs":[{"parentid":"9101b35ad291ba03ec16699abaf2422ef3f11d82b7e20e4921af05274f8495a4","fulfillment":{"type":1,"data":{"publickey":"ed25519:25b6aae78d545d64746f4a7310230e7b7bce263dcaa9dd5b3b6dd614d0f46413","signature":"fc5dbfcd29683f194bc2dd231d978189eb5e0ca049cc75e24cc72bdde36c7ed985c7bf271e6c946a58b23ef53193fb0cc754d6b4764e7637cfbff34581170f08"}}}],"coinoutputs":[{"value":"9999989899990000","condition":{"type":1,"data":{"unlockhash":"0135e3b63e97352539b99d3517629b1ba1f80ae5753a14558e9ed53e067372257689de877a8669"}}}],"blockstakeinputs":[{"parentid":"72ca786c954c743345895ca8e077d47fb90e8df03cd10511b6a53e19218e5761","fulfillment":{"type":1,"data":{"publickey":"ed25519:947363721019b146de2830fb94e00203568e93fa9c0f18d7c4196619d7209716","signature":"3b7add54388b416239004ca1f5676c3dffcfc8f585dc54477c77d299bd9f5e016d122746943883a4b1590c3aa27ef8bdaf9ab7284a12cc9e0f36061085b6dd01"}}}],"blockstakeoutputs":[{"value":"100","condition":{"type":1,"data":{"unlockhash":"01046b3927877c8f0482e32b5bdd99a021fc32dd0fce980c4bab454502534dbe91ddec7867a91d"}}},{"value":"100","condition":{"type":1,"data":{"unlockhash":"010fc30ec4ea7441424fc2e9ca061c7c0ed3a1a3b0bb756c1c0a4d296a2b45414443e1927ecd8a"}}},{"value":"100","condition":{"type":1,"data":{"unlockhash":"01019557b45c1644454b81568c6f640058f95bf1d6b82b13f4f5607a35a2a7e87c77df68aa59fb"}}},{"value":"100","condition":{"type":1,"data":{"unlockhash":"010027e8215ddc5ccbaa2968f3c02efb3f6c96da53aca30b6c20af29a8db83c6f0dae5ceca3914"}}},{"value":"100","condition":{"type":1,"data":{"unlockhash":"010b375bef59fd7cc40ace960c81323e2b2ea052408a210126655081a75b801bbc82706fb18e5b"}}},{"value":"100","condition":{"type":1,"data":{"unlockhash":"01011b823090c865dfc4d227194b48931cfc06049ed4bf3581ef31c5340e9e1eb3ce5926139186"}}},{"value":"100","condition":{"type":1,"data":{"unlockhash":"010e23596270ca9ca9fdef5ec9460e5ae2985e7fd523221c7ba49c1fe86d8049513ef2701bf3b0"}}},{"value":"100","condition":{"type":1,"data":{"unlockhash":"01054edb99d92d73b63a89cee82e6b5326e5b12477f70d3983d87a14199aa3752877f1cfe30325"}}},{"value":"100","condition":{"type":1,"data":{"unlockhash":"010ac443f407ed17620471d8533bb0c119dd6068960b96f5b5e67da7dba716e0fc922365b6db3f"}}},{"value":"100","condition":{"type":1,"data":{"unlockhash":"01009a4409b0aa789cbe3b38ae54268557201eb0439c68b61603685794c4a5d024dd1de070a113"}}}],"minerfees":["100000000"]}},"coininputoutputs":[{"value":"9999989999990000","condition":{"type":1,"data":{"unlockhash":"01d1c4dd242e3badf45004be9a3b86c613923c6d872bab5ec92e4f076114d4c3a15b7b43e1c00f"}},"unlockhash":"01d1c4dd242e3badf45004be9a3b86c613923c6d872bab5ec92e4f076114d4c3a15b7b43e1c00f"}],"coinoutputids":["512923b5fab87d2fe56e5a6560d699edb489b2fa55d2d23d9637ae0b79b803a8"],"coinoutputunlockhashes":["0135e3b63e97352539b99d3517629b1ba1f80ae5753a14558e9ed53e067372257689de877a8669"],"blockstakeinputoutputs":[{"value":"1000","condition":{"type":1,"data":{"unlockhash":"01e34588bee49b2cbd53f2198cd5022fbbe78aecb8125a39efb8699720b946e84ead718daf0cd6"}},"unlockhash":"01e34588bee49b2cbd53f2198cd5022fbbe78aecb8125a39efb8699720b946e84ead718daf0cd6"}],"blockstakeoutputids":["7e3bff69d2df91b096ffa2b7850492d7fbe6b97d898383d5901b8668e78b06a3","6cb28b29a22cb1f7c091bf9d301715b69a4eb9de94ba4326d448f74c326aac4b","a080392691d4600f1befade214fe58c8ad400fd675508123268a84df47acd378","1ad0bb99aebb90003d00d577b4ca6a2b09f23f83a157d8594b23b0d49cf3db73","dcdff507fa3286f9ad34851e0e652a7ec5cd7a733d510e98637db4cb81c0f3c0","8960cd3603b72604970be8b3e67d6408a3acf5525f183204ecddcccd17502488","dbe17310db33d643f059854d688ffa00ca77e62760bd11444c58406c8e94e3dd","021629a2b93a1d0200e21419cdedd41d115dc66e2e8323259eec4b7ae7c72393","aaccae5d65a5552bc0541830069c07ca8e4f048296e53c9a16cd237a01339845","9daf6b9f2a053f3d3340a8f10b3ec82fd581ebc3b3a9fccb1ab06a4db005fbf6"],"blockstakeunlockhashes":["01046b3927877c8f0482e32b5bdd99a021fc32dd0fce980c4bab454502534dbe91ddec7867a91d","010fc30ec4ea7441424fc2e9ca061c7c0ed3a1a3b0bb756c1c0a4d296a2b45414443e1927ecd8a","01019557b45c1644454b81568c6f640058f95bf1d6b82b13f4f5607a35a2a7e87c77df68aa59fb","010027e8215ddc5ccbaa2968f3c02efb3f6c96da53aca30b6c20af29a8db83c6f0dae5ceca3914","010b375bef59fd7cc40ace960c81323e2b2ea052408a210126655081a75b801bbc82706fb18e5b","01011b823090c865dfc4d227194b48931cfc06049ed4bf3581ef31c5340e9e1eb3ce5926139186","010e23596270ca9ca9fdef5ec9460e5ae2985e7fd523221c7ba49c1fe86d8049513ef2701bf3b0","01054edb99d92d73b63a89cee82e6b5326e5b12477f70d3983d87a14199aa3752877f1cfe30325","010ac443f407ed17620471d8533bb0c119dd6068960b96f5b5e67da7dba716e0fc922365b6db3f","01009a4409b0aa789cbe3b38ae54268557201eb0439c68b61603685794c4a5d024dd1de070a113"],"unconfirmed":false}],"multisigaddresses":null,"unconfirmed":false}',
    )
    c._explorer_get = explorer_client.explorer_get

    # get a transaction
    result = c.unlockhash_get(
        "01d1c4dd242e3badf45004be9a3b86c613923c6d872bab5ec92e4f076114d4c3a15b7b43e1c00f"
    )

    # you can go through all transactions that are somehow linked to the given transactions
    assert isinstance(result.transactions,
                      list) and len(result.transactions) > 0
    txn = None
    for rtxn in result.transactions:
        if str(
                rtxn.id
        ) == "96df1e34533ffcd42ee1db995e165538edd275ba0c065ef9293ead84ff923eec":
            txn = rtxn
            break
    assert txn is not None

    # from the transaction you can get all kind of info
    assert str(
        txn.id
    ) == "96df1e34533ffcd42ee1db995e165538edd275ba0c065ef9293ead84ff923eec"
    assert txn.height == 2662
    assert (
        txn.version == 1
    )  # in reality it is 0, but the JSX goldchain client converts v0 transactions automatically to v1 transactions
    assert len(txn.coin_inputs) == 1
    assert str(
        txn.coin_inputs[0].parentid
    ) == "c1df239aba64ca0c6a241ddf18f3dd18b75e2c650874dd4c8c7dbbb56bd73683"
    assert len(txn.coin_outputs) == 2
    assert str(txn.coin_outputs[0].value) == "1000000"
    assert (
        str(txn.coin_outputs[1].condition.unlockhash) ==
        "0175c11c8124e325cdba4f6843e917ba90519e9580adde5b10de5a7cabcc3251292194c5a0e6d2"
    )
    assert str(txn.miner_fees[0]) == "0.1"
    assert len(txn.miner_fees) == 1

    # the explorer provides us also with info that is not part of a goldchain txn,
    # the goldchain client injects this into the txn as well for easy look-up
    assert str(txn.coin_inputs[0].parent_output.value) == "89839999.3"
    assert (
        str(txn.coin_inputs[0].parent_output.condition.unlockhash) ==
        "01d1c4dd242e3badf45004be9a3b86c613923c6d872bab5ec92e4f076114d4c3a15b7b43e1c00f"
    )
    assert str(
        txn.coin_outputs[0].id
    ) == "90513506d1216f89e73a361b6306d8543c81aff092e376ee8d8bb9b7ea024de6"
    assert str(
        txn.coin_outputs[1].id
    ) == "7daf8035a6697701aeed36b4d6fe8de6ff4bbf9fd1ba9b0933d87e260f924783"
    assert txn.unconfirmed == False

    # you can also get multisig addresses linked to the looked up unlockhash
    assert isinstance(result.multisig_addresses, list)

    c.delete()