def test_search_raw_transactions_unconfirmed(server_db): assert len(backend.search_raw_transactions(ADDR[0], unconfirmed=True)) == 27 assert len(backend.search_raw_transactions(ADDR[0], unconfirmed=False)) == 27 # create send v = int(100 * 1e8) send1hex = util.api('create_send', {'source': ADDR[0], 'destination': ADDR[1], 'asset': 'XCP', 'quantity': v}) # insert send, this automatically also creates a block tx1 = util_test.insert_raw_transaction(send1hex, server_db) assert len(backend.search_raw_transactions(ADDR[0], unconfirmed=True)) == 28 assert len(backend.search_raw_transactions(ADDR[0], unconfirmed=False)) == 28 # create send v = int(100 * 1e8) send2hex = util.api('create_send', {'source': ADDR[0], 'destination': ADDR[1], 'asset': 'XCP', 'quantity': v}) # insert send, this automatically also creates a block tx2 = util_test.insert_unconfirmed_raw_transaction(send2hex, server_db) assert len(backend.search_raw_transactions(ADDR[0], unconfirmed=True)) == 29 assert len(backend.search_raw_transactions(ADDR[0], unconfirmed=False)) == 28
def sendrawtransaction(tx_hex): util_test.insert_raw_transaction(tx_hex, server_db) return gettxid(tx_hex)
def sendrawtransaction(tx_hex): validate.tx_signature(dispatcher, tx_hex) result = util_test.insert_raw_transaction(tx_hex, server_db) return result["tx_hash"]
def test_p2sh_encoding_manual_multisig_transaction(server_db): source = P2SH_ADDR[0] destination = ADDR[1] with util_test.ConfigContext( OLD_STYLE_API=True), util_test.MockProtocolChangesContext( enhanced_sends=True, p2sh_encoding=True): p2sh_source_multisig_pubkeys_binary = [ binascii.unhexlify(p) for p in [ DP['pubkey'][ADDR[0]], DP['pubkey'][ADDR[1]], DP['pubkey'][ ADDR[2]] ] ] scriptSig, redeemScript, outputScript = p2sh_encoding.make_p2sh_encoding_redeemscript( b'deadbeef01', n=0, pubKey=None, multisig_pubkeys=p2sh_source_multisig_pubkeys_binary, multisig_pubkeys_required=2) redeemScript = bitcoinlib.core.script.CScript(redeemScript) assert repr( redeemScript ) == "CScript([OP_DROP, 2, x('{}'), x('{}'), x('{}'), 3, OP_CHECKMULTISIGVERIFY, 0, OP_DROP, OP_DEPTH, 0, OP_EQUAL])".format( DP['pubkey'][ADDR[0]], DP['pubkey'][ADDR[1]], DP['pubkey'][ADDR[2]]) # setup transaction fee = 20000 fee_per_kb = 50000 pretxhex = api.compose_transaction( server_db, 'send', { 'source': source, 'destination': destination, 'asset': 'XCP', 'quantity': 100, }, p2sh_source_multisig_pubkeys=[ DP['pubkey'][ADDR[0]], DP['pubkey'][ADDR[1]], DP['pubkey'][ADDR[2]] ], p2sh_source_multisig_pubkeys_required=2, encoding='p2sh', fee_per_kb=fee_per_kb, fee=fee) # debugTransaction = bitcoinlib.core.CTransaction.deserialize(binascii.unhexlify(pretxhex)) # store transaction pretxid, _ = util_test.insert_raw_transaction(pretxhex, server_db) logger.debug('pretxid %s' % (pretxid)) # now compose the data transaction result = api.compose_transaction( server_db, 'send', { 'source': source, 'destination': destination, 'asset': 'XCP', 'quantity': 100 }, p2sh_source_multisig_pubkeys=[ DP['pubkey'][ADDR[0]], DP['pubkey'][ADDR[1]], DP['pubkey'][ADDR[2]] ], p2sh_source_multisig_pubkeys_required=2, p2sh_pretx_txid=pretxid, # pass the pretxid encoding='p2sh', fee_per_kb=fee_per_kb) assert not isinstance(result, list) datatxhex = result datatx = bitcoinlib.core.CTransaction.deserialize( binascii.unhexlify(datatxhex)) # parse the transaction parsed_source, parsed_destination, parsed_btc_amount, parsed_fee, parsed_data, extra = blocks._get_tx_info( datatxhex) assert parsed_source == source assert parsed_data == binascii.unhexlify( "00000002" "0000000000000001" "0000000000000064" "6f8d6ae8a3b381663118b4e1eff4cfc7d0954dd6ec" ) # ID=enhanced_send(0x02) ASSET=XCP(0x01) VALUE=100(0x64) destination_pubkey(0x6f8d...d6ec) assert parsed_btc_amount == 0
def test_p2sh_encoding(server_db): source = ADDR[0] destination = ADDR[1] with util_test.ConfigContext( OLD_STYLE_API=True), util_test.MockProtocolChangesContext( enhanced_sends=True, p2sh_encoding=True): utxos = dict(((utxo['txid'], utxo['vout']), utxo) for utxo in backend.get_unspent_txouts(source)) # pprint.pprint(utxos) fee = 20000 fee_per_kb = 50000 result = api.compose_transaction(server_db, 'send', { 'source': source, 'destination': destination, 'asset': 'XCP', 'quantity': 100 }, encoding='p2sh', fee_per_kb=fee_per_kb, fee=fee) assert not isinstance(result, list) pretxhex = result pretx = bitcoinlib.core.CTransaction.deserialize( binascii.unhexlify(pretxhex)) sumvin = sum([ int(utxos[(bitcoinlib.core.b2lx( vin.prevout.hash), vin.prevout.n)]['amount'] * 1e8) for vin in pretx.vin ]) sumvout = sum([vout.nValue for vout in pretx.vout]) assert len(pretx.vout) == 2 assert len(pretxhex) / 2 == 142 assert sumvin == 199909140 assert sumvout < sumvin assert sumvout == (sumvin - fee) # data P2SH output expected_datatx_length = 435 expected_datatx_fee = int(expected_datatx_length / 1000 * fee_per_kb) assert repr( pretx.vout[0].scriptPubKey ) == "CScript([OP_HASH160, x('7698101f9b9e5cdf0a0e11c2972dbc4860f374bf'), OP_EQUAL])" assert pretx.vout[0].nValue == expected_datatx_fee # change output assert pretx.vout[1].nValue == sumvin - expected_datatx_fee - fee assert pretxhex == "0100000001c1d8c075936c3495f6d653c50f73d987f75448d97a750249b1eb83bee71b24ae000000001976a9144838d8b3588c4c7ba7c1d06f866e9b3739c6303788acffffffff02f65400000000000017a9147698101f9b9e5cdf0a0e11c2972dbc4860f374bf87febbe90b000000001976a9144838d8b3588c4c7ba7c1d06f866e9b3739c6303788ac00000000" # 01000000 | version # 01 | inputs # c1d8c075936c3495f6d653c50f73d987f75448d97a750249b1eb83bee71b24ae | txout hash # 00000000 | txout index # 19 | script length # 76a9144838d8b3588c4c7ba7c1d06f866e9b3739c6303788ac | tx_script # ffffffff | Sequence # 02 | number of outputs # f654000000000000 | output 1 value (21750) # 17 | output 1 length (23 bytes) # a9147698101f9b9e5cdf0a0e11c2972dbc4860f374bf87 | output 1 script # febbe90b00000000 | output 2 value (199867390) # 19 | output 2 length (25 bytes) # 76a9144838d8b3588c4c7ba7c1d06f866e9b3739c6303788ac | output 2 script # 00000000 | locktime # first transaction should be considered BTC only with pytest.raises(exceptions.BTCOnlyError): blocks._get_tx_info(pretxhex) # store transaction pretxid, _ = util_test.insert_raw_transaction(pretxhex, server_db) logger.debug('pretxid %s' % (pretxid)) # check that when we do another, unrelated, send that it won't use our UTXO result = api.compose_transaction( server_db, 'send', { 'source': source, 'destination': destination, 'asset': 'XCP', 'quantity': 100 }) othertx = bitcoinlib.core.CTransaction.deserialize( binascii.unhexlify(result)) othertxid = bitcoinlib.core.lx( bitcoinlib.core.b2x(othertx.vin[0].prevout.hash)) # reverse hash assert not (binascii.hexlify(othertxid).decode('ascii') == pretxid and othertx.vin[0].prevout.n == 0) # now compose the data transaction result = api.compose_transaction( server_db, 'send', { 'source': source, 'destination': destination, 'asset': 'XCP', 'quantity': 100 }, p2sh_pretx_txid=pretxid, # pass the pretxid encoding='p2sh', fee_per_kb=fee_per_kb) assert not isinstance(result, list) datatxhex = result datatx = bitcoinlib.core.CTransaction.deserialize( binascii.unhexlify(datatxhex)) sumvin = sum( [pretx.vout[n].nValue for n, vin in enumerate(datatx.vin)]) sumvout = sum([vout.nValue for vout in datatx.vout]) fee = 10000 assert len(datatxhex) / 2 == 190 assert sumvin == expected_datatx_fee assert sumvout < sumvin assert sumvout == sumvin - expected_datatx_fee assert len(datatx.vout) == 1 # opreturn signalling P2SH assert repr( datatx.vout[0].scriptPubKey ) == "CScript([OP_RETURN, x('8a5dda15fb6f0562da344d2f')])" # arc4(PREFIX + 'P2SH') assert datatx.vout[0].nValue == 0 assert datatxhex == "01000000010a0746fe9308ac6e753fb85780a8b788b40655148dcde1435f2048783b784f06000000007431544553545858585800000002000000000000000100000000000000646f8d6ae8a3b381663118b4e1eff4cfc7d0954dd6ec2975210282b886c087eb37dc8182f14ba6cc3e9485ed618b95804d44aecc17c300b585b0ad007574008717a9147698101f9b9e5cdf0a0e11c2972dbc4860f374bf87ffffffff0100000000000000000e6a0c8a5dda15fb6f0562da344d2f00000000" # 01000000 | version # 01 | inputs # 0a0746fe9308ac6e753fb85780a8b788b40655148dcde1435f2048783b784f06 | txout hash # 00000000 | txout index (0) # 74 | script length (116) # 31544553545858585800000002000000000000000100000000000000 | tx_script # 646f8d6ae8a3b381663118b4e1eff4cfc7d0954dd6ec2975210282b886c087eb37dc8182f14ba6cc | ... # 3e9485ed618b95804d44aecc17c300b585b0ad007574008717a9147698101f9b9e5cdf0a0e11c297 | ... # 2dbc4860f374bf87 | ... # ffffffff | Sequence # 01 | number of outputs # 0000000000000000 | output 1 value (0) # 0e | output 1 length (14 bytes) # 6a0c8a5dda15fb6f0562da344d2f | output 1 script # 00000000 | locktime # verify parsed result parsed_source, parsed_destination, parsed_btc_amount, parsed_fee, parsed_data, extra = blocks._get_tx_info( datatxhex) assert parsed_source == source assert parsed_data == binascii.unhexlify( "00000002" "0000000000000001" "0000000000000064" "6f8d6ae8a3b381663118b4e1eff4cfc7d0954dd6ec" ) # ID=enhanced_send(0x02) ASSET=XCP(0x01) VALUE=100(0x64) destination_pubkey(0x6f8d...d6ec) assert parsed_btc_amount == 0 assert parsed_fee == expected_datatx_fee # check signing pubkey tx_script_start = 8 + 2 + 64 + 8 tx_script_length = int(datatxhex[tx_script_start:tx_script_start + 2], 16) * 2 tx_script = datatxhex[tx_script_start + 2:tx_script_start + 2 + tx_script_length] signing_pubkey_hash = tx_script[-44:-4] address = script.base58_check_encode(signing_pubkey_hash, config.ADDRESSVERSION)
def test_p2sh_encoding_long_data(server_db): source = ADDR[0] destination = ADDR[1] with util_test.ConfigContext( OLD_STYLE_API=True), util_test.MockProtocolChangesContext( enhanced_sends=True, p2sh_encoding=True): utxos = dict(((utxo['txid'], utxo['vout']), utxo) for utxo in backend.get_unspent_txouts(source)) # pprint.pprint(utxos) fee_per_kb = 50000 result = api.compose_transaction( server_db, 'broadcast', { 'source': source, 'text': 'The quick brown fox jumped over the lazy dog. ' * 12, 'fee_fraction': 0, 'timestamp': 1512155862, 'value': 0, }, encoding='p2sh', fee_per_kb=fee_per_kb) assert not isinstance(result, list) pretxhex = result pretx = bitcoinlib.core.CTransaction.deserialize( binascii.unhexlify(pretxhex)) actual_fee = int(len(pretxhex) / 2 * fee_per_kb / 1000) sumvin = sum([ int(utxos[(bitcoinlib.core.b2lx( vin.prevout.hash), vin.prevout.n)]['amount'] * 1e8) for vin in pretx.vin ]) sumvout = sum([vout.nValue for vout in pretx.vout]) pretx_fee = 12950 assert len(pretx.vout) == 3 assert len(pretxhex) / 2 == 174 assert sumvin == 199909140 assert sumvout < sumvin assert sumvout == (sumvin - pretx_fee) # data P2SH output expected_datatx_length = 1156 expected_datatx_fee = int(expected_datatx_length / 1000 * fee_per_kb) expected_datatx_fee_rounded = int(math.ceil( expected_datatx_fee / 2)) * 2 assert repr( pretx.vout[0].scriptPubKey ) == "CScript([OP_HASH160, x('7698101f9b9e5cdf0a0e11c2972dbc4860f374bf'), OP_EQUAL])" assert pretx.vout[0].nValue == int(math.ceil(expected_datatx_fee / 2)) assert pretx.vout[1].nValue == int(math.ceil(expected_datatx_fee / 2)) # change output assert pretx.vout[ 2].nValue == sumvin - expected_datatx_fee_rounded - pretx_fee assert pretxhex == "0100000001c1d8c075936c3495f6d653c50f73d987f75448d97a750249b1eb83bee71b24ae000000001976a9144838d8b3588c4c7ba7c1d06f866e9b3739c6303788acffffffff03e47000000000000017a9147698101f9b9e5cdf0a0e11c2972dbc4860f374bf87e47000000000000017a914676d587edf25cf01d3b153ff0b71f5e9b622386387b64ae90b000000001976a9144838d8b3588c4c7ba7c1d06f866e9b3739c6303788ac00000000" # 00000001 | version # 01 | inputs # c1d8c075936c3495f6d653c50f73d987f75448d97a750249b1eb83bee71b24ae | txout hash # 00000000 | txout index # 19 | script length # 76a9144838d8b3588c4c7ba7c1d06f866e9b3739c6303788ac | tx_script # ffffffff | Sequence # 03 | number of outputs (3) # e470000000000000 | output 1 value (28900) # 17 | output 1 length (23 bytes) # a9147698101f9b9e5cdf0a0e11c2972dbc4860f374bf87 | output 1 script # e470000000000000 | output 2 value (28900) # 17 | output 2 length (23 bytes) # a914676d587edf25cf01d3b153ff0b71f5e9b622386387 | output 2 script # b64ae90b00000000 | output 3 value (199838390) # 19 | output 3 length (25 bytes) # 76a9144838d8b3588c4c7ba7c1d06f866e9b3739c6303788ac | output 3 script # 00000000 | locktime # store transaction pretxid, _ = util_test.insert_raw_transaction(pretxhex, server_db) logger.debug('pretxid %s' % (pretxid)) # now compose the data transaction result = api.compose_transaction( server_db, 'broadcast', { 'source': source, 'text': 'The quick brown fox jumped over the lazy dog. ' * 12, 'fee_fraction': 0, 'timestamp': 1512155862, 'value': 0, }, p2sh_pretx_txid=pretxid, # pass the pretxid encoding='p2sh', fee_per_kb=fee_per_kb) assert not isinstance(result, list) datatxhex = result datatx = bitcoinlib.core.CTransaction.deserialize( binascii.unhexlify(datatxhex)) sumvin = sum( [pretx.vout[n].nValue for n, vin in enumerate(datatx.vin)]) sumvout = sum([vout.nValue for vout in datatx.vout]) assert len(datatx.vin) == 2 assert len(datatxhex) / 2 == 1682 / 2 assert sumvin == expected_datatx_fee_rounded assert sumvout < sumvin assert sumvout == sumvin - expected_datatx_fee_rounded assert len(datatx.vout) == 1 # opreturn signalling P2SH assert repr( datatx.vout[0].scriptPubKey ) == "CScript([OP_RETURN, x('8a5dda15fb6f0562da344d2f')])" # arc4(PREFIX + 'P2SH') assert datatx.vout[0].nValue == 0 assert datatxhex == "0100000002f33f677de4180f1b0c261a991974c57de97f082a7e62332b77ec5d193d13d1a300000000fd4d024d080254455354585858580000001e5a21aad600000000000000000000000054686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e2054686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e2054686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e2054686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e2054686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e2054686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e2054686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e2054686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e2054686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e2054686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e2054686520717569636b2062726f776e20666f78206a756d706564206f766572202975210282b886c087eb37dc8182f14ba6cc3e9485ed618b95804d44aecc17c300b585b0ad007574008717a9147698101f9b9e5cdf0a0e11c2972dbc4860f374bf87fffffffff33f677de4180f1b0c261a991974c57de97f082a7e62332b77ec5d193d13d1a30100000087445445535458585858746865206c617a7920646f672e2054686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e202975210282b886c087eb37dc8182f14ba6cc3e9485ed618b95804d44aecc17c300b585b0ad517574008717a914676d587edf25cf01d3b153ff0b71f5e9b622386387ffffffff0100000000000000000e6a0c8a5dda15fb6f0562da344d2f00000000" # 01000000 | version # 02 | inputs # f33f677de4180f1b0c261a991974c57de97f082a7e62332b77ec5d193d13d1a3 | txout hash # 00000000 | txout index (0) # fd | script length (253) # 4d024d080254455354585858580000001e5a21aad6000000000000000000000000 | tx_script # 54686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e20 | ... # 54686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e20 | ... # 54686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e20 | ... # 54686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e20 | ... # 54686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e20 | ... # 54686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e20 | ... # 54686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e20 | ... # 54686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e20 | ... # 54686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e20 | ... # 54686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e20 | ... # 54686520717569636b2062726f776e20666f78206a756d706564206f766572202975210282b886c087eb37dc8182 | ... # f14ba6cc3e9485ed618b95804d44aecc17c300b585b0ad007574008717a9147698101f9b9e5cdf0a0e11c2972dbc | ... # 4860f374bf87 | ... # ffffffff | Sequence # f33f677de4180f1b0c261a991974c57de97f082a7e62332b77ec5d193d13d1a3 | txout hash # 01000000 | txout index (1) # 87 | script length (135) # 445445535458585858746865206c617a7920646f672e20 | tx_script # 54686520717569636b2062726f776e20666f78206a756d706564206f76657220746865206c617a7920646f672e202975 | ... # 210282b886c087eb37dc8182f14ba6cc3e9485ed618b95804d44aecc17c300b585b0ad517574008717a914676d587edf | ... # 25cf01d3b153ff0b71f5e9b622386387 | ... # ffffffff | Sequence # 01 | number of outputs # 0000000000000000 | output 1 value (0) # 0e | output 1 length (14 bytes) # 6a0c8a5dda15fb6f0562da344d2f | output 1 script # 00000000 | locktime # verify parsed result parsed_source, parsed_destination, parsed_btc_amount, parsed_fee, parsed_data, extra = blocks._get_tx_info( datatxhex) assert parsed_source == source assert parsed_data == binascii.unhexlify( "0000001e5a21aad6000000000000000000000000" ) + b'The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. ' # ID=enhanced_send(0x1e) ASSET=XCP(0x01) VALUE=100(0x64) destination_pubkey(0x6f8d...d6ec) assert parsed_btc_amount == 0 assert parsed_fee == expected_datatx_fee_rounded
def test_alice_bob(server_db): alice = ADDR[0] bob = "miJqNkHhC5xsB61gsiSWXeTLnEGSQnWbXB" # check alices UTXOs utxos = util.api('get_unspent_txouts', {"address": alice}) assert len(utxos) == 1 assert utxos[0]['address'] == alice assert utxos[0][ 'txid'] == "ae241be7be83ebb14902757ad94854f787d9730fc553d6f695346c9375c0d8c1" assert utxos[0]['amount'] == 1.9990914 assert utxos[0]['confirmations'] == 74 # balance before send alice_balance = util.get_balance(server_db, alice, 'XCP') bob_balance = util.get_balance(server_db, bob, 'XCP') assert alice_balance == 91875000000 assert bob_balance == 0 # create send v = int(100 * 1e8) send1hex = util.api('create_send', { 'source': alice, 'destination': bob, 'asset': 'XCP', 'quantity': v }) assert send1hex == "0100000001c1d8c075936c3495f6d653c50f73d987f75448d97a750249b1eb83bee71b24ae000000001976a9144838d8b3588c4c7ba7c1d06f866e9b3739c6303788acffffffff0336150000000000001976a9141e9d9c2c34d4dda3cd71603d9ce1e447c3cc5c0588ac00000000000000001e6a1c8a5dda15fb6f05628a061e67576e926dc71a7fa2f0cceb951120a9322f30ea0b000000001976a9144838d8b3588c4c7ba7c1d06f866e9b3739c6303788ac00000000" # insert send, this automatically also creates a block tx1hash, tx1 = util_test.insert_raw_transaction(send1hex, server_db) # balances after send alice_balance2 = util.get_balance(server_db, alice, 'XCP') bob_balance2 = util.get_balance(server_db, bob, 'XCP') assert alice_balance2 == alice_balance - v assert bob_balance2 == bob_balance + v # check API result result = util.api( "get_balances", { "filters": [ { 'field': 'address', 'op': '==', 'value': alice }, { 'field': 'asset', 'op': '==', 'value': 'XCP' }, ] }) assert result[0]['quantity'] == alice_balance2 # -- do another TX # check alices UTXOs utxos = util.api('get_unspent_txouts', {"address": alice}) assert len(utxos) == 1 assert utxos[0]['address'] == alice assert utxos[0]['txid'] == tx1['tx_hash'] assert utxos[0]['amount'] == 1.99897135 assert utxos[0]['confirmations'] == 1 # balances before send alice_balance = util.get_balance(server_db, alice, 'XCP') bob_balance = util.get_balance(server_db, bob, 'XCP') assert alice_balance == alice_balance2 assert bob_balance == bob_balance2 # create send v = int(100 * 1e8) send2hex = util.api('create_send', { 'source': alice, 'destination': bob, 'asset': 'XCP', 'quantity': v }) assert send2hex == "0100000001cd2d431037d1d0cfe05daeb1d08b975f27488e383f7f169e09d2f405fb618f39020000001976a9144838d8b3588c4c7ba7c1d06f866e9b3739c6303788acffffffff0336150000000000001976a9141e9d9c2c34d4dda3cd71603d9ce1e447c3cc5c0588ac00000000000000001e6a1c8a5dda15fb6f05628a061e67576e926dc71a7fa2f0cceb951120a9324a01ea0b000000001976a9144838d8b3588c4c7ba7c1d06f866e9b3739c6303788ac00000000" # insert send, this automatically also creates a block tx2hash, tx2 = util_test.insert_raw_transaction(send2hex, server_db) # balances after send alice_balance2 = util.get_balance(server_db, alice, 'XCP') bob_balance2 = util.get_balance(server_db, bob, 'XCP') assert alice_balance2 == alice_balance - v assert bob_balance2 == bob_balance + v # -- do another TX, now unconfirmed # check alices UTXOs utxos = util.api('get_unspent_txouts', {"address": alice}) assert len(utxos) == 1 assert utxos[0]['address'] == alice assert utxos[0]['txid'] == tx2['tx_hash'] assert utxos[0]['amount'] == 1.9988513 assert utxos[0]['confirmations'] == 1 # balances before send alice_balance = util.get_balance(server_db, alice, 'XCP') bob_balance = util.get_balance(server_db, bob, 'XCP') assert alice_balance == alice_balance2 assert bob_balance == bob_balance2 # create send v = int(100 * 1e8) send3hex = util.api('create_send', { 'source': alice, 'destination': bob, 'asset': 'XCP', 'quantity': v }) assert send3hex == "01000000019aea7b78c8fffa50c51bbadb87824a202b3e6b53727e543e9c6846845205b5ce020000001976a9144838d8b3588c4c7ba7c1d06f866e9b3739c6303788acffffffff0336150000000000001976a9141e9d9c2c34d4dda3cd71603d9ce1e447c3cc5c0588ac00000000000000001e6a1c8a5dda15fb6f05628a061e67576e926dc71a7fa2f0cceb951120a93265d2e90b000000001976a9144838d8b3588c4c7ba7c1d06f866e9b3739c6303788ac00000000" # insert send, as unconfirmed! won't create a block! tx3 = util_test.insert_unconfirmed_raw_transaction(send3hex, server_db) # balances after send, unaffected alice_balance2 = util.get_balance(server_db, alice, 'XCP') bob_balance2 = util.get_balance(server_db, bob, 'XCP') assert alice_balance2 == alice_balance assert bob_balance2 == bob_balance # no confirmed UTXOs left, we use the 1 we had utxos = util.api('get_unspent_txouts', {"address": alice}) assert len(utxos) == 0 # unconfirmed UTXO is there, we can use it! utxos = util.api('get_unspent_txouts', { "address": alice, "unconfirmed": True }) assert len(utxos) == 1 assert utxos[0]['address'] == alice assert utxos[0]['txid'] == tx3['tx_hash'] assert utxos[0]['amount'] == 1.99873125 assert utxos[0]['confirmations'] == 0 # atm there's no way to confirm this unconfirmed TX # even doing this won't make it confirmed because it just mocks an empty block util_test.create_next_block(server_db) utxos = util.api('get_unspent_txouts', {"address": alice}) assert len(utxos) == 1 assert utxos[0]['address'] == alice assert utxos[0]['txid'] == tx3['tx_hash'] assert utxos[0]['amount'] == 1.99873125 assert utxos[0]['confirmations'] == 1 # we can eventually make this mocking better to be able to do that, # but for now you'll have to micro manage if you want to confirm a unconfirmed TX in 1 test # by just calling the `insert_raw_transaction` again for it tx3bhash, tx3b = util_test.insert_raw_transaction(send3hex, server_db) # balances after send alice_balance2 = util.get_balance(server_db, alice, 'XCP') bob_balance2 = util.get_balance(server_db, bob, 'XCP') assert alice_balance2 == alice_balance - v assert bob_balance2 == bob_balance + v
def sendrawtransaction(tx_hex): result = util_test.insert_raw_transaction(tx_hex, server_db) return result["tx_hash"]