def run_test(self): self.node = self.nodes[0] privkey = byte_to_base58(hash256(struct.pack('<I', 0)), 239) self.node.importprivkey(privkey) self.node.generatetoaddress(100 + COINBASE_MATURITY, "qSrM9K6FMhZ29Vkp8Rdk8Jp66bbfpjFETq") """ pragma solidity ^0.4.11; contract Example { function timestamp() external returns(uint) { return now; } } """ bytecode = "60606040523415600b57fe5b5b60928061001a6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063b80777ea14603a575bfe5b3415604157fe5b6047605d565b6040518082815260200191505060405180910390f35b60004290505b905600a165627a7a7230582022b5728b8ca07de23857473e303660ad554d6344c64658ab692d741fa8753b380029" self.contract_address = self.node.createcontract(bytecode)['address'] self.node.generate(1) now = int(time.time()) expected_now = int( self.node.callcontract(self.contract_address, "b80777ea")['executionResult']['output'], 16) print(now, expected_now) assert (expected_now == now or expected_now == now + 1) activate_mpos(self.node) self.node.setmocktime(0) now = int(time.time()) expected_now = int( self.node.callcontract(self.contract_address, "b80777ea")['executionResult']['output'], 16) print(now, expected_now) assert (expected_now == now or expected_now == now + 1)
def initKeys(self): for i in range(self.num_of_nodes): k = key.CECKey() pk_bytes = hashlib.sha256( str(random.getrandbits(256)).encode('utf-8')).digest() k.set_secretbytes(pk_bytes) self.keys.append(k) self.wifs.append(address.byte_to_base58(pk_bytes, 239))
def gen_valid_base58_vector(template): '''Generate valid base58 vector''' prefix = bytearray(template[0]) payload = rand_bytes(size=template[1]) suffix = bytearray(template[2]) dst_prefix = bytearray(template[4]) dst_suffix = bytearray(template[5]) assert len(prefix) == 1 rv = byte_to_base58(payload + suffix, prefix[0]) return rv, dst_prefix + payload + dst_suffix
def gen_invalid_base58_vector(template): '''Generate possibly invalid vector''' # kinds of invalid vectors: # invalid prefix # invalid payload length # invalid (randomized) suffix (add random data) # corrupt checksum corrupt_prefix = randbool(0.2) randomize_payload_size = randbool(0.2) corrupt_suffix = randbool(0.2) if corrupt_prefix: prefix = rand_bytes(size=1) else: prefix = bytearray(template[0]) if randomize_payload_size: payload = rand_bytes(size=max(int(random.expovariate(0.5)), 50)) else: payload = rand_bytes(size=template[1]) if corrupt_suffix: suffix = rand_bytes(size=len(template[2])) else: suffix = bytearray(template[2]) assert len(prefix) == 1 val = byte_to_base58(payload + suffix, prefix[0]) if random.randint(0, 10) < 1: # line corruption if randbool(): # add random character to end val += random.choice(b58chars) else: # replace random character in the middle n = random.randint(0, len(val)) val = val[0:n] + random.choice(b58chars) + val[n + 1:] return val
def wif(pk): # Base58Check version for regtest WIF keys is 0xef = 239 return address.byte_to_base58(pk, 239)
def bytes_to_wif(b, compressed=True): if compressed: b += b'\x01' return byte_to_base58(b, 239)
def wif(pk): # Base58Check version for regtest WIF keys is 0xef = 239 pk_compressed = pk + bytes([0x1]) return address.byte_to_base58(pk_compressed, 239)
def run_test (self): self.nodes[2].importprivkey("cTnxkovLhGbp7VRhMhGThYt8WDwviXgaVAD8DjaVa5G5DApwC6tF") # Check that there's 100 UTXOs on each of the nodes assert_equal(len(self.nodes[0].listunspent()), 100) assert_equal(len(self.nodes[1].listunspent()), 100) assert_equal(len(self.nodes[2].listunspent()), 200) walletinfo = self.nodes[2].getbalance() assert_equal(walletinfo["CBT"], 21000000) assert_equal(walletinfo["ISSUANCE"], 500000) print("Mining blocks...") self.nodes[2].generate(101) self.sync_all() asscript = "76a914bc835aff853179fa88f2900f9003bb674e17ed4288ac"; genhash = self.nodes[2].getblockhash(0) genblock = self.nodes[2].getblock(genhash) for txid in genblock["tx"]: rawtx = self.nodes[2].getrawtransaction(txid,True) if "assetlabel" in rawtx["vout"][0]: if rawtx["vout"][0]["assetlabel"] == "ISSUANCE": asasset = rawtx["vout"][0]["asset"] astxid = txid asvalue = rawtx["vout"][0]["value"] assert_equal(self.nodes[0].getbalance("", 0, False, "CBT"), 21000000) assert_equal(self.nodes[1].getbalance("", 0, False, "CBT"), 21000000) assert_equal(self.nodes[2].getbalance("", 0, False, "CBT"), 21000000) #Set all OP_TRUE genesis outputs to single node self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 21000000, "", "", True) self.nodes[0].generate(101) self.sync_all() assert_equal(self.nodes[0].getbalance("", 0, False, "CBT"), 21000000) assert_equal(self.nodes[1].getbalance("", 0, False, "CBT"), 0) assert_equal(self.nodes[2].getbalance("", 0, False, "CBT"), 0) #self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1000000) #self.nodes[0].generate(1) #self.sync_all() #self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 100000) #self.nodes[0].generate(101) #self.sync_all() #assert_equal(self.nodes[0].getbalance(), 21000000-1100000) #assert_equal(self.nodes[1].getbalance(), 1000000) #assert_equal(self.nodes[2].getbalance(), 100000) # Send 21 BTC from 0 to 2 using sendtoaddress call. txid1 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) txout1v0 = self.nodes[0].gettxout(txid1, 0) rawtx1 = self.nodes[0].getrawtransaction(txid1, 1) #amountcommit1 = rawtx1["vout"][0]["amountcommitment"] assert_equal(txout1v0['confirmations'], 0) assert(not txout1v0['coinbase']) #assert_equal(amountcommit1, txout1v0['amountcommitment']) txid2 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10) txout2v0 = self.nodes[0].gettxout(txid2, 0) rawtx2 = self.nodes[0].getrawtransaction(txid2, 1) #amountcommit2 = rawtx2["vout"][0]["amountcommitment"] assert_equal(txout2v0['confirmations'], 0) assert(not txout2v0['coinbase']) #assert_equal(amountcommit2, txout2v0['amountcommitment']) walletinfo = self.nodes[0].getwalletinfo("CBT") assert_equal(walletinfo['immature_balance'], 0) # Have node0 mine a block, thus it will collect its own fee. Confirm previous transactions. self.nodes[0].generate(1) self.sync_all() # Exercise locking of unspent outputs unspent_0 = self.nodes[2].listunspent(1, 9999999, [], True, "CBT")[0] unspent_0 = {"txid": unspent_0["txid"], "vout": unspent_0["vout"]} self.nodes[2].lockunspent(False, [unspent_0]) assert_raises_message(JSONRPCException, "Insufficient funds", self.nodes[2].sendtoaddress, self.nodes[2].getnewaddress(), 20) assert_equal([unspent_0], self.nodes[2].listlockunspent()) self.nodes[2].lockunspent(True, [unspent_0]) assert_equal(len(self.nodes[2].listlockunspent()), 0) # Have node1 generate 100 blocks (so node0 can recover the fee) self.nodes[1].generate(100) self.sync_all() # node0 should end up with 100 btc in block rewards plus fees, but # minus the 21 plus fees sent to node2 assert_equal(self.nodes[0].getbalance("", 0, False, "CBT"), 21000000-21) assert_equal(self.nodes[2].getbalance("", 0, False, "CBT"), 21) # Node0 should have three spendable outputs since 0-value coinbase outputs will be OP_RETURN. # Create a couple of transactions to send them to node2, submit them through # node1, and make sure both node0 and node2 pick them up properly: node0utxos = self.nodes[0].listunspent(1, 9999999, [], True, "CBT") assert_equal(len(node0utxos), 3) # create both transactions txns_to_send = [] for utxo in node0utxos: if utxo["amount"] <= 3: # arbitrary value of 3? continue inputs = [] outputs = {} inputs.append({ "txid" : utxo["txid"], "vout" : utxo["vout"]}) outputs = {self.nodes[2].getnewaddress("from1"): utxo["amount"] - Decimal('1'), "fee": Decimal('1')} raw_tx = self.nodes[0].createrawtransaction(inputs, outputs) raw_tx = self.nodes[0].blindrawtransaction(raw_tx) txns_to_send.append(self.nodes[0].signrawtransaction(raw_tx)) # Have node 1 (miner) send the transaction txid = self.nodes[1].sendrawtransaction(txns_to_send[0]["hex"], True) # Have node1 mine a block to confirm transaction: self.nodes[1].generate(1) self.sync_all() #test creatation of raw multisig issuance transactions #get a new address and public and private key for each node address_node1 = self.nodes[0].getnewaddress() val_addr_node1 = self.nodes[0].validateaddress(address_node1) privkey_node1 = self.nodes[0].dumpprivkey(address_node1) address_node2 =self.nodes[1].getnewaddress() val_addr_node2 = self.nodes[1].validateaddress(address_node2) privkey_node2 =self.nodes[1].dumpprivkey(address_node2) address_node3 =self.nodes[2].getnewaddress() val_addr_node3 = self.nodes[2].validateaddress(address_node3) privkey_node3 =self.nodes[2].dumpprivkey(address_node3) #create 2 of 3 multisig P2SH script and address multisig = self.nodes[0].createmultisig(2,[val_addr_node1["pubkey"],val_addr_node2["pubkey"],val_addr_node3["pubkey"]]) #send some policy asset to the P2SH address pa_txid = self.nodes[2].sendtoaddress(multisig["address"],1,"","",False,asasset) self.nodes[1].generate(1) self.sync_all() #get the vout and scriptPubKey of the multisig output vout = 0 pa_tx = self.nodes[1].getrawtransaction(pa_txid,1) for val in pa_tx["vout"]: for i,j in val.items(): if i == "n": vout_t = j for i,j in val.items(): if i == "scriptPubKey": for i2,j2 in j.items(): if i2 == "hex": script_t = j2 for i2,j2 in j.items(): if(i2 == "type" and j2 == "scripthash"): script_pk = script_t vout = vout_t #get address to send tokens and re-issuance tokens asset_addr = self.nodes[1].getnewaddress() token_addr = self.nodes[1].getnewaddress() #create an unsigned raw issuance transaction issuance_tx = self.nodes[1].createrawissuance(asset_addr,10.0,token_addr,1.0,multisig["address"],1.0000,'1',pa_txid,str(vout)) #node1 partially sign transaction partial_signed = self.nodes[0].signrawtransaction(issuance_tx["rawtx"],[{"txid":pa_txid,"vout":vout,"scriptPubKey":script_pk,"redeemScript":multisig["redeemScript"]}],[privkey_node1]) assert(not partial_signed["complete"]) #node1 partially sign transaction signed_tx = self.nodes[1].signrawtransaction(partial_signed["hex"],[{"txid":pa_txid,"vout":vout,"scriptPubKey":script_pk,"redeemScript":multisig["redeemScript"]}],[privkey_node2]) assert(signed_tx["complete"]) self.nodes[1].generate(2) self.sync_all() #submit signed transaction to network submit = self.nodes[1].sendrawtransaction(signed_tx["hex"]) #confirm transaction accepted by mempool mempool_tx = self.nodes[1].getrawmempool() assert_equal(mempool_tx[0],submit) self.nodes[1].generate(10) self.sync_all() #confirm asset can be spent by node2 wallet asset_addr2 = self.nodes[0].getnewaddress() asset_tx = self.nodes[1].sendtoaddress(asset_addr2,5,' ',' ',False,issuance_tx["asset"],True) mempool1 = self.nodes[1].getrawmempool() assert_equal(mempool1[0],asset_tx) # Test address prefix values returned by getsidechaininfo rpc addr_prefixes = self.nodes[0].getsidechaininfo()["addr_prefixes"] for prefix in addr_prefixes: assert_greater_than_or_equal(int(addr_prefixes[prefix]), 0) assert_greater_than(255, int(addr_prefixes[prefix])) # Test address reconstruction using address prefixes # p2pkh address correctly formed addr = self.nodes[0].getnewaddress() pubkey = self.nodes[0].validateaddress(addr)['pubkey'] pubkey = hex_str_to_bytes(pubkey) assert_equal(addr,byte_to_base58(hash160(pubkey), addr_prefixes['PUBKEY_ADDRESS'])) # p2sh address isvalid? p2sh = byte_to_base58(hash160(CScript([OP_TRUE])), addr_prefixes['SCRIPT_ADDRESS']) assert(self.nodes[0].validateaddress(p2sh)['isvalid']) # priv key = generate new and test if import successful with SECRET_KEY prefix k = CECKey() k.set_compressed(True) pk_bytes = hashlib.sha256(str(random.getrandbits(256)).encode('utf-8')).digest() pk_bytes = pk_bytes + b'\x01' k.set_secretbytes(pk_bytes) key = byte_to_base58(pk_bytes, addr_prefixes['SECRET_KEY']) assert_equal(self.nodes[0].importprivkey(key), None) # ensure import is successful # test blind prefix - construct expected createblindedaddress() return value and compare multisig_addr = self.nodes[2].createmultisig(2,["0222c31615e457119c2cb33821c150585c8b6a571a511d3cd07d27e7571e02c76e", "039bac374a8cd040ed137d0ce837708864e70012ad5766030aee1eb2f067b43d7f"])['address'] # blinding pubkey blinded_pubkey = self.nodes[2].validateaddress(self.nodes[2].getnewaddress())['pubkey'] blinded_addr = self.nodes[2].createblindedaddress(multisig_addr,blinded_pubkey) conf_addr_prefix = hex(addr_prefixes['BLINDED_ADDRESS'])[2:] if len(hex(addr_prefixes['BLINDED_ADDRESS'])[2:]) == 2 else '0' + str(hex(addr_prefixes['BLINDED_ADDRESS'])[2:]) secret_key_prefix = hex(addr_prefixes['SCRIPT_ADDRESS'])[2:] if len(hex(addr_prefixes['SCRIPT_ADDRESS'])[2:]) == 2 else '0' + str(hex(addr_prefixes['SCRIPT_ADDRESS'])[:2]) # construct expected createblindedaddress() return value expected_addr_bytes = \ str(conf_addr_prefix) + \ str(secret_key_prefix) + \ str(blinded_pubkey) + \ base58_to_bytes(multisig_addr)[2:] assert_equal(expected_addr_bytes,base58_to_bytes(blinded_addr)) ###################################################################### #################### END OF WORKING TESTS ########################### ###################################################################### return #TODO fix the rest txoutv0 = self.nodes[0].gettxout(txid, 0) assert_equal(txoutv0['confirmations'], 1) assert(not txoutv0['coinbase']) assert_equal(self.nodes[0].getbalance(), 0) assert_equal(self.nodes[2].getbalance(), 94) assert_equal(self.nodes[2].getbalance("from1"), 94-21) # Send 10 BTC normal address = self.nodes[0].getnewaddress("test") fee_per_byte = Decimal('0.001') / 1000 self.nodes[2].settxfee(fee_per_byte * 1000) txid = self.nodes[2].sendtoaddress(address, 10, "", "", False) self.nodes[2].generate(1) self.sync_all() node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), Decimal('84'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) assert_equal(self.nodes[0].getbalance(), Decimal('10')) # Send 10 BTC with subtract fee from amount txid = self.nodes[2].sendtoaddress(address, 10, "", "", True) self.nodes[2].generate(1) self.sync_all() node_2_bal -= Decimal('10') assert_equal(self.nodes[2].getbalance(), node_2_bal) node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), Decimal('20'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) # Sendmany 10 BTC txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", [], {'fee': 'CBT'}) self.nodes[2].generate(1) self.sync_all() node_0_bal += Decimal('10') node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), node_2_bal - Decimal('10'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) assert_equal(self.nodes[0].getbalance(), node_0_bal) # Sendmany 10 BTC with subtract fee from amount txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", [address], {'fee': 'CBT'}) self.nodes[2].generate(1) self.sync_all() node_2_bal -= Decimal('10') assert_equal(self.nodes[2].getbalance(), node_2_bal) node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), node_0_bal + Decimal('10'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) # Test ResendWalletTransactions: # Create a couple of transactions, then start up a fourth # node (nodes[3]) and ask nodes[0] to rebroadcast. # EXPECT: nodes[3] should have those transactions in its mempool. txid1 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1) txid2 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1) sync_mempools(self.nodes) self.nodes.append(start_node(3, self.options.tmpdir, self.extra_args[3])) connect_nodes_bi(self.nodes, 0, 3) sync_blocks(self.nodes) relayed = self.nodes[0].resendwallettransactions() assert_equal(set(relayed), {txid1, txid2}) sync_mempools(self.nodes) assert(txid1 in self.nodes[3].getrawmempool()) # Exercise balance rpcs assert_equal(self.nodes[0].getwalletinfo()["unconfirmed_balance"], 1) assert_equal(self.nodes[0].getunconfirmedbalance(), 1) #check if we can list zero value tx as available coins #1. create rawtx #2. hex-changed one output to 0.0 #3. sign and send #4. check if recipient (node0) can list the zero value tx usp = self.nodes[1].listunspent() inputs = [{"txid":usp[0]['txid'], "vout":usp[0]['vout']}] outputs = {self.nodes[1].getnewaddress(): 49.998, self.nodes[0].getnewaddress(): 11.11} rawTx = self.nodes[1].createrawtransaction(inputs, outputs).replace("c0833842", "00000000") #replace 11.11 with 0.0 (int32) decRawTx = self.nodes[1].decoderawtransaction(rawTx) signedRawTx = self.nodes[1].signrawtransaction(rawTx) decRawTx = self.nodes[1].decoderawtransaction(signedRawTx['hex']) zeroValueTxid= decRawTx['txid'] sendResp = self.nodes[1].sendrawtransaction(signedRawTx['hex']) self.sync_all() self.nodes[1].generate(1) #mine a block self.sync_all() unspentTxs = self.nodes[0].listunspent() #zero value tx must be in listunspents output found = False for uTx in unspentTxs: if uTx['txid'] == zeroValueTxid: found = True assert_equal(uTx['amount'], Decimal('0')) assert(found) #do some -walletbroadcast tests stop_nodes(self.nodes) self.nodes = start_nodes(3, self.options.tmpdir, [["-walletbroadcast=0"],["-walletbroadcast=0"],["-walletbroadcast=0"]]) connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,1,2) connect_nodes_bi(self.nodes,0,2) self.sync_all() txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2) txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted) self.nodes[1].generate(1) #mine a block, tx should not be in there self.sync_all() assert_equal(self.nodes[2].getbalance(), node_2_bal) #should not be changed because tx was not broadcasted #now broadcast from another node, mine a block, sync, and check the balance self.nodes[1].sendrawtransaction(txObjNotBroadcasted['hex']) self.nodes[1].generate(1) self.sync_all() node_2_bal += 2 txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted) assert_equal(self.nodes[2].getbalance(), node_2_bal) #create another tx txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2) #restart the nodes with -walletbroadcast=1 stop_nodes(self.nodes) self.nodes = start_nodes(3, self.options.tmpdir) connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,1,2) connect_nodes_bi(self.nodes,0,2) sync_blocks(self.nodes) self.nodes[0].generate(1) sync_blocks(self.nodes) node_2_bal += 2 #tx should be added to balance because after restarting the nodes tx should be broadcastet assert_equal(self.nodes[2].getbalance(), node_2_bal) #send a tx with value in a string (PR#6380 +) txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "2") txObj = self.nodes[0].gettransaction(txId) assert_equal(txObj['amount'], Decimal('-2')) txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "0.0001") txObj = self.nodes[0].gettransaction(txId) assert_equal(txObj['amount'], Decimal('-0.0001')) #check if JSON parser can handle scientific notation in strings txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "1e-4") txObj = self.nodes[0].gettransaction(txId) assert_equal(txObj['amount'], Decimal('-0.0001')) try: txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "1f-4") except JSONRPCException as e: assert("Invalid amount" in e.error['message']) else: raise AssertionError("Must not parse invalid amounts") try: self.nodes[0].generate("2") raise AssertionError("Must not accept strings as numeric") except JSONRPCException as e: assert("not an integer" in e.error['message']) # Import address and private key to check correct behavior of spendable unspents # 1. Send some coins to generate new UTXO address_to_import = self.nodes[2].getnewaddress() txid = self.nodes[0].sendtoaddress(address_to_import, 1) self.nodes[0].generate(1) self.sync_all() # 2. Import address from node2 to node1 self.nodes[1].importaddress(address_to_import) # 3. Validate that the imported address is watch-only on node1 assert(self.nodes[1].validateaddress(address_to_import)["iswatchonly"]) # 4. Check that the unspents after import are not spendable assert_array_result(self.nodes[1].listunspent(), {"address": address_to_import}, {"spendable": False}) # 5. Import private key of the previously imported address on node1 priv_key = self.nodes[2].dumpprivkey(address_to_import) self.nodes[1].importprivkey(priv_key) # 6. Check that the unspents are now spendable on node1 assert_array_result(self.nodes[1].listunspent(), {"address": address_to_import}, {"spendable": True}) # Mine a block from node0 to an address from node1 cbAddr = self.nodes[1].getnewaddress() blkHash = self.nodes[0].generatetoaddress(1, cbAddr)[0] cbTxId = self.nodes[0].getblock(blkHash)['tx'][0] self.sync_all() # Check that the txid and balance is found by node1 self.nodes[1].gettransaction(cbTxId) # check if wallet or blockchain maintenance changes the balance self.sync_all() blocks = self.nodes[0].generate(2) self.sync_all() balance_nodes = [self.nodes[i].getbalance() for i in range(3)] block_count = self.nodes[0].getblockcount() # Check modes: # - True: unicode escaped as \u.... # - False: unicode directly as UTF-8 for mode in [True, False]: self.nodes[0].ensure_ascii = mode # unicode check: Basic Multilingual Plane, Supplementary Plane respectively for s in [u'ббаБаА', u'№ Ё']: addr = self.nodes[0].getaccountaddress(s) label = self.nodes[0].getaccount(addr) assert_equal(label, s) assert(s in self.nodes[0].listaccounts().keys()) self.nodes[0].ensure_ascii = True # restore to default # maintenance tests maintenance = [ '-rescan', '-reindex', '-zapwallettxes=1', '-zapwallettxes=2', # disabled until issue is fixed: https://github.com/bitcoin/bitcoin/issues/7463 # '-salvagewallet', ] chainlimit = 6 for m in maintenance: print("check " + m) stop_nodes(self.nodes) # set lower ancestor limit for later self.nodes = start_nodes(3, self.options.tmpdir, [[m, "-limitancestorcount="+str(chainlimit)]] * 3) while m == '-reindex' and [block_count] * 3 != [self.nodes[i].getblockcount() for i in range(3)]: # reindex will leave rpc warm up "early"; Wait for it to finish time.sleep(0.1) assert_equal(balance_nodes, [self.nodes[i].getbalance() for i in range(3)]) # Exercise listsinceblock with the last two blocks coinbase_tx_1 = self.nodes[0].listsinceblock(blocks[0]) assert_equal(coinbase_tx_1["lastblock"], blocks[1]) assert_equal(len(coinbase_tx_1["transactions"]), 1) assert_equal(coinbase_tx_1["transactions"][0]["blockhash"], blocks[1]) assert_equal(len(self.nodes[0].listsinceblock(blocks[1])["transactions"]), 0) # ==Check that wallet prefers to use coins that don't exceed mempool limits ===== # Get all non-zero utxos together chain_addrs = [self.nodes[0].getnewaddress(), self.nodes[0].getnewaddress()] singletxid = self.nodes[0].sendtoaddress(chain_addrs[0], self.nodes[0].getbalance(), "", "", True) self.nodes[0].generate(1) node0_balance = self.nodes[0].getbalance() # Split into two chains rawtx = self.nodes[0].createrawtransaction([{"txid":singletxid, "vout":0}], {chain_addrs[0]:node0_balance/2-Decimal('0.01'), chain_addrs[1]:node0_balance/2-Decimal('0.01')}) signedtx = self.nodes[0].signrawtransaction(rawtx) singletxid = self.nodes[0].sendrawtransaction(signedtx["hex"]) self.nodes[0].generate(1) # Make a long chain of unconfirmed payments without hitting mempool limit # Each tx we make leaves only one output of change on a chain 1 longer # Since the amount to send is always much less than the outputs, we only ever need one output # So we should be able to generate exactly chainlimit txs for each original output sending_addr = self.nodes[1].getnewaddress() txid_list = [] for i in range(chainlimit*2): txid_list.append(self.nodes[0].sendtoaddress(sending_addr, Decimal('0.0001'))) assert_equal(self.nodes[0].getmempoolinfo()['size'], chainlimit*2) assert_equal(len(txid_list), chainlimit*2) # Without walletrejectlongchains, we will still generate a txid # The tx will be stored in the wallet but not accepted to the mempool extra_txid = self.nodes[0].sendtoaddress(sending_addr, Decimal('0.0001')) assert(extra_txid not in self.nodes[0].getrawmempool()) assert(extra_txid in [tx["txid"] for tx in self.nodes[0].listtransactions()]) self.nodes[0].abandontransaction(extra_txid) total_txs = len(self.nodes[0].listtransactions("*",99999)) # Try with walletrejectlongchains # Double chain limit but require combining inputs, so we pass SelectCoinsMinConf stop_node(self.nodes[0],0) self.nodes[0] = start_node(0, self.options.tmpdir, ["-walletrejectlongchains", "-limitancestorcount="+str(2*chainlimit)]) # wait for loadmempool timeout = 10 while (timeout > 0 and len(self.nodes[0].getrawmempool()) < chainlimit*2): time.sleep(0.5) timeout -= 0.5 assert_equal(len(self.nodes[0].getrawmempool()), chainlimit*2) node0_balance = self.nodes[0].getbalance() # With walletrejectlongchains we will not create the tx and store it in our wallet. assert_raises_message(JSONRPCException, "mempool chain", self.nodes[0].sendtoaddress, sending_addr, node0_balance - Decimal('0.01')) # Verify nothing new in wallet assert_equal(total_txs, len(self.nodes[0].listtransactions("*",99999)))
def test_sendRPC(self, rpcname): self.log.info("Testing %s" % rpcname) #pubkeyhash and script hash for colored addresses on node 1 new_address = self.nodes[1].getnewaddress() pubkeyhash = hash160( hex_str_to_bytes( self.nodes[1].getaddressinfo(new_address)["pubkey"])) scripthash = hash160( CScript( [OP_DUP, OP_HASH160, pubkeyhash, OP_EQUALVERIFY, OP_CHECKSIG])) cp2pkh_address1 = byte_to_base58(pubkeyhash, hex_str_to_bytes(self.colorids[1]), 112) cp2sh_address1 = byte_to_base58(scripthash, hex_str_to_bytes(self.colorids[1]), 197) cp2pkh_address2 = byte_to_base58(pubkeyhash, hex_str_to_bytes(self.colorids[2]), 112) cp2pkh_address3 = byte_to_base58(pubkeyhash, hex_str_to_bytes(self.colorids[3]), 112) cp2sh_address4 = byte_to_base58(scripthash, hex_str_to_bytes(self.colorids[4]), 197) cp2sh_address5 = byte_to_base58(scripthash, hex_str_to_bytes(self.colorids[5]), 197) sendrpc = getattr(self.nodes[0], rpcname, lambda x: print("no method %s" % x)) txid1 = sendrpc(cp2pkh_address1, 10) self.sync_all([self.nodes[0:3]]) assert_array_result(self.nodes[0].listtransactions(), {"txid": txid1}, { "category": "send", "token": self.colorids[1], "amount": -10, "confirmations": 0 }) assert_array_result(self.nodes[1].listtransactions(), {"txid": txid1}, { "category": "receive", "token": self.colorids[1], "amount": 10, "confirmations": 0 }) txid2 = sendrpc(cp2sh_address1, 10) self.sync_all([self.nodes[0:3]]) assert_array_result(self.nodes[0].listtransactions(), {"txid": txid2}, { "category": "send", "token": self.colorids[1], "amount": -10, "confirmations": 0 }) assert_array_result(self.nodes[1].listtransactions(), {"txid": txid2}, { "category": "receive", "token": self.colorids[1], "amount": 10, "confirmations": 0 }) txid3 = sendrpc(cp2pkh_address2, 10) self.sync_all([self.nodes[0:3]]) assert_array_result(self.nodes[0].listtransactions(), {"txid": txid3}, { "category": "send", "token": self.colorids[2], "amount": -10, "confirmations": 0 }) assert_array_result(self.nodes[1].listtransactions(), {"txid": txid3}, { "category": "receive", "token": self.colorids[2], "amount": 10, "confirmations": 0 }) #NFT can be transferred only once. so call it only the first time if (rpcname == "sendtoaddress"): txid4 = sendrpc(cp2pkh_address3, 1) self.sync_all([self.nodes[0:3]]) assert_array_result(self.nodes[0].listtransactions(), {"txid": txid4}, { "category": "send", "token": self.colorids[3], "amount": -1, "confirmations": 0 }) assert_array_result(self.nodes[1].listtransactions(), {"txid": txid4}, { "category": "receive", "token": self.colorids[3], "amount": 1, "confirmations": 0 }) txid5 = sendrpc(cp2sh_address4, 10) self.sync_all([self.nodes[0:3]]) assert_array_result(self.nodes[0].listtransactions(), {"txid": txid5}, { "category": "send", "token": self.colorids[4], "amount": -10, "confirmations": 0 }) assert_array_result(self.nodes[1].listtransactions(), {"txid": txid5}, { "category": "receive", "token": self.colorids[4], "amount": 10, "confirmations": 0 }) #NFT can be transferred only once. so call it only the first time if (rpcname == "sendtoaddress"): txid6 = sendrpc(cp2sh_address5, 1) self.sync_all([self.nodes[0:3]]) assert_array_result(self.nodes[0].listtransactions(), {"txid": txid6}, { "category": "send", "token": self.colorids[5], "amount": -1, "confirmations": 0 }) assert_array_result(self.nodes[1].listtransactions(), {"txid": txid6}, { "category": "receive", "token": self.colorids[5], "amount": 1, "confirmations": 0 }) #mine a block, confirmations should change: self.nodes[2].generate(1, self.signblockprivkey_wif) self.sync_all([self.nodes[0:3]]) unspent = self.nodes[0].listunspent() assert_array_result(unspent, { "txid": txid1, "token": self.colorids[1] }, { "amount": self.balance_expected[0][self.stage][3], "confirmations": 1 }) assert_array_result(unspent, { "txid": txid2, "token": self.colorids[1] }, { "amount": self.balance_expected[0][self.stage][3], "confirmations": 1 }) assert_array_result(unspent, { "txid": txid3, "token": self.colorids[2] }, { "amount": self.balance_expected[0][self.stage][5], "confirmations": 1 }) assert_array_result(unspent, { "txid": txid5, "token": self.colorids[4] }, { "amount": self.balance_expected[0][self.stage][5], "confirmations": 1 }) txlist = self.nodes[0].listtransactions() assert_array_result(txlist, {"txid": txid1}, {"confirmations": 1}) assert_array_result(txlist, {"txid": txid2}, {"confirmations": 1}) assert_array_result(txlist, {"txid": txid3}, {"confirmations": 1}) assert_array_result(txlist, {"txid": txid5}, {"confirmations": 1}) if (rpcname == "sendtoaddress"): assert_array_result(txlist, {"txid": txid4}, {"confirmations": 1}) assert_array_result(txlist, {"txid": txid6}, {"confirmations": 1}) unspent = self.nodes[1].listunspent() assert_array_result(unspent, { "txid": txid4, "token": self.colorids[3] }, { "amount": 1, "confirmations": 1 }) assert_array_result(unspent, { "txid": txid6, "token": self.colorids[5] }, { "amount": 1, "confirmations": 1 }) self.test_nodeBalances() #negative if not self.options.usecli: assert_raises_rpc_error(-3, "Invalid amount", sendrpc, cp2pkh_address1, 'foo') assert_raises_rpc_error(-3, "Invalid amount", sendrpc, cp2pkh_address1, '66ae') assert_raises_rpc_error(-3, "Invalid amount", sendrpc, cp2pkh_address1, 66.99)
def test_createrawtransaction(self, utxos): '''test transaction with colored output using createrawtransaction all 3 types of tokens and addresses should be successful''' self.log.info("Testing createrawtransaction") #pubkeyhash and script hash for colored addresses new_address = self.nodes[0].getnewaddress() pubkeyhash = hash160( hex_str_to_bytes( self.nodes[0].getaddressinfo(new_address)["pubkey"])) scripthash = hash160( CScript( [OP_DUP, OP_HASH160, pubkeyhash, OP_EQUALVERIFY, OP_CHECKSIG])) cp2pkh_address1 = byte_to_base58(pubkeyhash, hex_str_to_bytes(self.colorids[1]), 112) cp2sh_address1 = byte_to_base58(scripthash, hex_str_to_bytes(self.colorids[1]), 197) cp2pkh_address2 = byte_to_base58(pubkeyhash, hex_str_to_bytes(self.colorids[2]), 112) cp2pkh_address3 = byte_to_base58(pubkeyhash, hex_str_to_bytes(self.colorids[3]), 112) cp2sh_address4 = byte_to_base58(scripthash, hex_str_to_bytes(self.colorids[4]), 197) cp2sh_address5 = byte_to_base58(scripthash, hex_str_to_bytes(self.colorids[5]), 197) # PART 1: using cp2pkh address # # create transaction 1 with colorid1 if self.options.usecli: rawtx = self.nodes[0].createrawtransaction( "[{\"txid\": \"%s\", \"vout\": %d }]" % (utxos[5]['txid'], utxos[5]['vout']), "[{\"%s\": 10}, {\"%s\" : 39}, { \"%s\" : 100}]" % (self.nodes[1].getnewaddress(), self.nodes[0].getnewaddress(), cp2pkh_address1)) raw_tx_in_block = self.nodes[0].signrawtransactionwithwallet( "%s" % rawtx, [], "ALL", self.options.scheme)['hex'] self.nodes[0].sendrawtransaction("%s" % raw_tx_in_block, True) else: raw_tx_in_block = self.nodes[0].signrawtransactionwithwallet( self.nodes[0].createrawtransaction( inputs=[{ 'txid': utxos[5]['txid'], 'vout': utxos[5]['vout'] }], outputs=[{ self.nodes[1].getnewaddress(): 10 }, { self.nodes[0].getnewaddress(): 39 }, { cp2pkh_address1: 100 }], ), [], "ALL", self.options.scheme)['hex'] self.nodes[0].sendrawtransaction(hexstring=raw_tx_in_block, allowhighfees=True) # create transaction 2 with colorid2 if self.options.usecli: rawtx = self.nodes[0].createrawtransaction( "[{\"txid\": \"%s\", \"vout\": %d }]" % (utxos[1]['txid'], utxos[1]['vout']), "[{\"%s\": 10}, {\"%s\" : 39}, { \"%s\" : 100}]" % (self.nodes[1].getnewaddress(), self.nodes[0].getnewaddress(), cp2pkh_address2)) raw_tx_in_block = self.nodes[0].signrawtransactionwithwallet( "%s" % rawtx, [], "ALL", self.options.scheme)['hex'] self.nodes[0].sendrawtransaction("%s" % raw_tx_in_block, True) else: raw_tx_in_block = self.nodes[0].signrawtransactionwithwallet( self.nodes[0].createrawtransaction( inputs=[{ 'txid': utxos[1]['txid'], 'vout': utxos[1]['vout'] }], outputs=[{ self.nodes[1].getnewaddress(): 10 }, { self.nodes[0].getnewaddress(): 39 }, { cp2pkh_address2: 100 }], ), [], "ALL", self.options.scheme)['hex'] self.nodes[0].sendrawtransaction(hexstring=raw_tx_in_block, allowhighfees=True) # create transaction 3 with colorid3 if self.options.usecli: rawtx = self.nodes[0].createrawtransaction( "[{\"txid\": \"%s\", \"vout\": %d }]" % (utxos[2]['txid'], utxos[2]['vout']), "[{\"%s\": 10}, {\"%s\" : 39}, { \"%s\" : 1}]" % (self.nodes[1].getnewaddress(), self.nodes[0].getnewaddress(), cp2pkh_address3)) raw_tx_in_block = self.nodes[0].signrawtransactionwithwallet( "%s" % rawtx, [], "ALL", self.options.scheme)['hex'] self.nodes[0].sendrawtransaction("%s" % raw_tx_in_block, True) else: raw_tx_in_block = self.nodes[0].signrawtransactionwithwallet( self.nodes[0].createrawtransaction( inputs=[{ 'txid': utxos[2]['txid'], 'vout': utxos[2]['vout'] }], outputs=[{ self.nodes[1].getnewaddress(): 10 }, { self.nodes[0].getnewaddress(): 39 }, { cp2pkh_address3: 1 }], ), [], "ALL", self.options.scheme)['hex'] self.nodes[0].sendrawtransaction(hexstring=raw_tx_in_block, allowhighfees=True) self.sync_all([self.nodes[0:3]]) self.nodes[2].generate(1, self.signblockprivkey_wif) self.test_nodeBalances() # PART 2: using cp2sh address # # create transaction 1 with colorid1 if self.options.usecli: rawtx = self.nodes[0].createrawtransaction( "[{\"txid\": \"%s\", \"vout\": %d }]" % (utxos[0]['txid'], utxos[0]['vout']), "[{\"%s\": 10}, {\"%s\" : 39}, { \"%s\" : 100}]" % (self.nodes[1].getnewaddress(), self.nodes[0].getnewaddress(), cp2sh_address1)) raw_tx_in_block = self.nodes[0].signrawtransactionwithwallet( "%s" % rawtx, [], "ALL", self.options.scheme)['hex'] self.nodes[0].sendrawtransaction("%s" % raw_tx_in_block, True) else: raw_tx_in_block = self.nodes[0].signrawtransactionwithwallet( self.nodes[0].createrawtransaction( inputs=[{ 'txid': utxos[0]['txid'], 'vout': utxos[0]['vout'] }], outputs=[{ self.nodes[1].getnewaddress(): 10 }, { self.nodes[0].getnewaddress(): 39 }, { cp2sh_address1: 100 }], ), [], "ALL", self.options.scheme)['hex'] self.nodes[0].sendrawtransaction(hexstring=raw_tx_in_block, allowhighfees=True) # create transaction 2 with colorid4 if self.options.usecli: rawtx = self.nodes[0].createrawtransaction( "[{\"txid\": \"%s\", \"vout\": %d }]" % (utxos[3]['txid'], utxos[3]['vout']), "[{\"%s\": 10}, {\"%s\" : 39}, { \"%s\" : 100}]" % (self.nodes[1].getnewaddress(), self.nodes[0].getnewaddress(), cp2sh_address4)) raw_tx_in_block = self.nodes[0].signrawtransactionwithwallet( "%s" % rawtx, [], "ALL", self.options.scheme)['hex'] self.nodes[0].sendrawtransaction("%s" % raw_tx_in_block, True) else: raw_tx_in_block = self.nodes[0].signrawtransactionwithwallet( self.nodes[0].createrawtransaction( inputs=[{ 'txid': utxos[3]['txid'], 'vout': utxos[3]['vout'] }], outputs=[{ self.nodes[1].getnewaddress(): 10 }, { self.nodes[0].getnewaddress(): 39 }, { cp2sh_address4: 100 }], ), [], "ALL", self.options.scheme)['hex'] self.nodes[0].sendrawtransaction(hexstring=raw_tx_in_block, allowhighfees=True) # create transaction 3 with colorid5 if self.options.usecli: rawtx = self.nodes[0].createrawtransaction( "[{\"txid\": \"%s\", \"vout\": %d }]" % (utxos[4]['txid'], utxos[4]['vout']), "[{\"%s\": 10}, {\"%s\" : 39}, { \"%s\" : 1}]" % (self.nodes[1].getnewaddress(), self.nodes[0].getnewaddress(), cp2sh_address5)) raw_tx_in_block = self.nodes[0].signrawtransactionwithwallet( "%s" % rawtx, [], "ALL", self.options.scheme)['hex'] self.nodes[0].sendrawtransaction("%s" % raw_tx_in_block, True) else: raw_tx_in_block = self.nodes[0].signrawtransactionwithwallet( self.nodes[0].createrawtransaction( inputs=[{ 'txid': utxos[4]['txid'], 'vout': utxos[4]['vout'] }], outputs=[{ self.nodes[1].getnewaddress(): 10 }, { self.nodes[0].getnewaddress(): 39 }, { cp2sh_address5: 1 }], ), [], "ALL", self.options.scheme)['hex'] self.nodes[0].sendrawtransaction(hexstring=raw_tx_in_block, allowhighfees=True) self.sync_all([self.nodes[0:3]]) self.nodes[2].generate(1, self.signblockprivkey_wif) self.test_nodeBalances()
def run_test(self): # Check that there's no UTXO on none of the nodes assert_equal(len(self.nodes[0].listunspent()), 0) assert_equal(len(self.nodes[1].listunspent()), 0) assert_equal(len(self.nodes[2].listunspent()), 0) self.log.info("Mining blocks...") self.nodes[0].generate(1, self.signblockprivkey_wif) walletinfo = self.nodes[0].getwalletinfo() assert_equal(len(walletinfo['balance']), 1) assert_equal(walletinfo['balance']['TPC'], 50) self.sync_all([self.nodes[0:3]]) self.nodes[2].generate(1, self.signblockprivkey_wif) self.sync_all([self.nodes[0:3]]) assert_equal(self.nodes[0].getbalance(), 50) assert_equal(self.nodes[1].getbalance(), 0) assert_equal(self.nodes[2].getbalance(), 50) # PART 1: using cp2pkh address # utxo = self.nodes[0].listunspent()[0] new_address = self.nodes[0].getnewaddress() pubkeyhash = hash160( hex_str_to_bytes( self.nodes[0].getaddressinfo(new_address)["pubkey"])) colorid1 = b'\xc1' + sha256(hex_str_to_bytes(utxo['scriptPubKey'])) cp2pkh_address = byte_to_base58(pubkeyhash, colorid1, 112) # create colored transaction 1 raw_tx_in_block = self.nodes[0].signrawtransactionwithwallet( self.nodes[0].createrawtransaction( inputs=[{ 'txid': utxo['txid'], 'vout': utxo['vout'] }], outputs=[{ self.nodes[1].getnewaddress(): 10 }, { self.nodes[0].getnewaddress(): 39 }, { cp2pkh_address: 100 }], ), [], "ALL", self.options.scheme)['hex'] txid_in_block = self.nodes[0].sendrawtransaction( hexstring=raw_tx_in_block, allowhighfees=True) self.sync_all([self.nodes[0:3]]) self.nodes[2].generate(1, self.signblockprivkey_wif) assert_equal(self.nodes[0].getbalance(), 39) assert_equal(self.nodes[1].getbalance(), 10) assert_equal(self.nodes[2].getbalance(), 101) walletinfo = self.nodes[0].getwalletinfo() assert_equal(len(walletinfo['balance']), 2) assert_equal(walletinfo['balance']['TPC'], 39) assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid1)], 100) walletinfo = self.nodes[1].getwalletinfo() assert_equal(len(walletinfo['balance']), 2) assert_equal(walletinfo['balance']['TPC'], 10) assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid1)], 0) walletinfo = self.nodes[2].getwalletinfo() assert_equal(len(walletinfo['balance']), 1) assert_equal(walletinfo['balance']['TPC'], 101) colorFromNode = self.nodes[0].getcolor(1, utxo['scriptPubKey']) assert_equal(hex_str_to_bytes(colorFromNode), colorid1) colorFromNode = self.nodes[0].getcolor(2, txid_in_block, 1) utxo_ser = sha256( reverse_bytes(hex_str_to_bytes(txid_in_block)) + (1).to_bytes(4, byteorder='little')) coloridexpected = 'c2' + encode(utxo_ser, 'hex_codec').decode('ascii') assert_equal(colorFromNode, coloridexpected) # PART 2: using cp2sh address utxo = self.nodes[0].listunspent()[0] pubkeyhash = hash160( hex_str_to_bytes(self.nodes[1].getaddressinfo( self.nodes[1].getnewaddress())["pubkey"])) scripthash = hash160( CScript( [OP_DUP, OP_HASH160, pubkeyhash, OP_EQUALVERIFY, OP_CHECKSIG])) colorid2 = b'\xc1' + sha256(hex_str_to_bytes(utxo['scriptPubKey'])) cp2sh_address = byte_to_base58(scripthash, colorid2, 197) # create colored transaction 2 raw_tx_in_block = self.nodes[0].signrawtransactionwithwallet( self.nodes[0].createrawtransaction( inputs=[{ 'txid': utxo['txid'], 'vout': utxo['vout'] }], outputs=[{ self.nodes[1].getnewaddress(): 10 }, { self.nodes[0].getnewaddress(): 28 }, { cp2sh_address: 100 }], ), [], "ALL", self.options.scheme)['hex'] txid_in_block = self.nodes[0].sendrawtransaction( hexstring=raw_tx_in_block, allowhighfees=True) self.sync_all([self.nodes[0:3]]) self.nodes[2].generate(1, self.signblockprivkey_wif) walletinfo = self.nodes[0].getwalletinfo() assert_equal(len(walletinfo['balance']), 3) assert_equal(walletinfo['balance']['TPC'], 28) assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid1)], 100) assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid2)], 0) walletinfo = self.nodes[1].getwalletinfo() assert_equal(len(walletinfo['balance']), 3) assert_equal(walletinfo['balance']['TPC'], 20) assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid1)], 0) assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid2)], 100) walletinfo = self.nodes[2].getwalletinfo() assert_equal(len(walletinfo['balance']), 1) assert_equal(walletinfo['balance']['TPC'], 152) colorFromNode = self.nodes[0].getcolor(1, utxo['scriptPubKey']) assert_equal(hex_str_to_bytes(colorFromNode), colorid2) colorFromNode = self.nodes[0].getcolor(2, txid_in_block, 1) utxo_ser = sha256( reverse_bytes(hex_str_to_bytes(txid_in_block)) + (1).to_bytes(4, byteorder='little')) coloridexpected = 'c2' + encode(utxo_ser, 'hex_codec').decode('ascii') assert_equal(colorFromNode, coloridexpected) # send colored coins (colorid1) from node0 to node1 using sendtoaddress: new_address = self.nodes[1].getnewaddress() pubkeyhash = hash160( hex_str_to_bytes( self.nodes[1].getaddressinfo(new_address)["pubkey"])) cp2pkh_address = byte_to_base58(pubkeyhash, colorid1, 112) self.log.debug("Testing sendtoaddress") txid = self.nodes[0].sendtoaddress(cp2pkh_address, 10) self.sync_all([self.nodes[0:3]]) assert_array_result(self.nodes[0].listtransactions(), {"txid": txid}, { "category": "send", "token": bytes_to_hex_str(colorid1), "amount": -10, "confirmations": 0 }) assert_array_result(self.nodes[1].listtransactions(), {"txid": txid}, { "category": "receive", "token": bytes_to_hex_str(colorid1), "amount": 10, "confirmations": 0 }) #mine a block, confirmations should change: self.nodes[2].generate(1, self.signblockprivkey_wif) self.sync_all([self.nodes[0:3]]) assert_array_result(self.nodes[0].listtransactions(), {"txid": txid}, { "category": "send", "token": bytes_to_hex_str(colorid1), "amount": -10, "confirmations": 1 }) assert_array_result(self.nodes[1].listtransactions(), {"txid": txid}, { "category": "receive", "token": bytes_to_hex_str(colorid1), "amount": 10, "confirmations": 1 }) walletinfo = self.nodes[0].getwalletinfo() assert_equal(len(walletinfo['balance']), 3) assert_equal(str(walletinfo['balance']['TPC']), '27.99990480') assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid1)], 90) assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid2)], 0) walletinfo = self.nodes[1].getwalletinfo() assert_equal(len(walletinfo['balance']), 3) assert_equal(walletinfo['balance']['TPC'], 20) assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid1)], 10) assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid2)], 100) walletinfo = self.nodes[2].getwalletinfo() assert_equal(len(walletinfo['balance']), 1) assert_equal(str(walletinfo['balance']['TPC']), '202.00009520') # send colored coins (colorid2) from node1 to node0 using transfertoken: new_address = self.nodes[0].getnewaddress() pubkeyhash = hash160( hex_str_to_bytes( self.nodes[0].getaddressinfo(new_address)["pubkey"])) cp2pkh_address = byte_to_base58(pubkeyhash, colorid2, 112) self.log.debug("Testing transfertoken") txid_transfer = self.nodes[1].transfertoken(cp2pkh_address, 10) self.sync_all([self.nodes[0:3]]) assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_transfer}, { "category": "send", "token": bytes_to_hex_str(colorid2), "amount": -10, "confirmations": 0 }) assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_transfer}, { "category": "receive", "token": bytes_to_hex_str(colorid2), "amount": 10, "confirmations": 0 }) #mine a block, confirmations should change: self.nodes[2].generate(1, self.signblockprivkey_wif) self.sync_all([self.nodes[0:3]]) assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_transfer}, { "category": "send", "token": bytes_to_hex_str(colorid2), "amount": -10, "confirmations": 1 }) assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_transfer}, { "category": "receive", "token": bytes_to_hex_str(colorid2), "amount": 10, "confirmations": 1 }) walletinfo = self.nodes[0].getwalletinfo() assert_equal(len(walletinfo['balance']), 3) assert_equal(str(walletinfo['balance']['TPC']), '27.99990480') assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid1)], 90) assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid2)], 10) walletinfo = self.nodes[1].getwalletinfo() assert_equal(len(walletinfo['balance']), 3) assert_equal(str(walletinfo['balance']['TPC']), '19.99992080') assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid1)], 10) assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid2)], 90) walletinfo = self.nodes[2].getwalletinfo() assert_equal(len(walletinfo['balance']), 1) assert_equal(str(walletinfo['balance']['TPC']), '252.00017440') self.log.debug("Testing getcolor") node2_utxos = self.nodes[2].listunspent() colorFromNode = self.nodes[2].getcolor(2, node2_utxos[0]['txid'], node2_utxos[0]['vout']) utxo_ser = sha256( reverse_bytes(hex_str_to_bytes(node2_utxos[0]['txid'])) + (node2_utxos[0]['vout']).to_bytes(4, byteorder='little')) colorid3 = 'c2' + encode(utxo_ser, 'hex_codec').decode('ascii') assert_equal(colorFromNode, colorid3) colorFromNode = self.nodes[2].getcolor(3, node2_utxos[1]['txid'], node2_utxos[1]['vout']) utxo_ser = sha256( reverse_bytes(hex_str_to_bytes(node2_utxos[1]['txid'])) + (node2_utxos[0]['vout']).to_bytes(4, byteorder='little')) colorid4 = 'c3' + encode(utxo_ser, 'hex_codec').decode('ascii') assert_equal(colorFromNode, colorid4) self.log.debug("Testing issuetoken") res = self.nodes[2].issuetoken(2, 100, node2_utxos[0]['txid'], node2_utxos[0]['vout']) txid_issue = res['txid'] assert_equal(res['color'], colorid3) assert_array_result(self.nodes[2].listtransactions(), {"txid": txid_issue}, { "category": "receive", "token": colorid3, "amount": 100, "confirmations": 0 }) #mine a block, confirmations should change: self.nodes[2].generate(1, self.signblockprivkey_wif) self.sync_all([self.nodes[0:3]]) assert_array_result(self.nodes[2].listtransactions(), {"txid": txid_issue}, { "category": "receive", "token": colorid3, "amount": 100, "confirmations": 1 }) walletinfo = self.nodes[0].getwalletinfo() assert_equal(len(walletinfo['balance']), 3) assert_equal(str(walletinfo['balance']['TPC']), '27.99990480') assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid1)], 90) assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid2)], 10) walletinfo = self.nodes[1].getwalletinfo() assert_equal(len(walletinfo['balance']), 3) assert_equal(str(walletinfo['balance']['TPC']), '19.99992080') assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid1)], 10) assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid2)], 90) walletinfo = self.nodes[2].getwalletinfo() assert_equal(len(walletinfo['balance']), 2) assert_equal(str(walletinfo['balance']['TPC']), '302.00017440') assert_equal(walletinfo['balance'][colorid3], 100) self.log.debug("Testing burntoken") txid_burn = self.nodes[1].burntoken(bytes_to_hex_str(colorid2), 20) self.nodes[2].generate(1, self.signblockprivkey_wif) self.sync_all([self.nodes[0:3]]) walletinfo = self.nodes[0].getwalletinfo() assert_equal(len(walletinfo['balance']), 3) assert_equal(str(walletinfo['balance']['TPC']), '27.99990480') assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid1)], 90) assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid2)], 10) walletinfo = self.nodes[1].getwalletinfo() assert_equal(len(walletinfo['balance']), 3) assert_equal(str(walletinfo['balance']['TPC']), '19.99983940') assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid1)], 10) assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid2)], 70) walletinfo = self.nodes[2].getwalletinfo() assert_equal(len(walletinfo['balance']), 2) assert_equal(str(walletinfo['balance']['TPC']), '352.00017440') assert_equal(walletinfo['balance'][colorid3], 100) txid_burn = self.nodes[0].burntoken(bytes_to_hex_str(colorid1), 90) self.nodes[2].generate(1, self.signblockprivkey_wif) self.sync_all([self.nodes[0:3]]) walletinfo = self.nodes[0].getwalletinfo() assert_equal(len(walletinfo['balance']), 3) assert_equal(str(walletinfo['balance']['TPC']), '27.99983720') assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid1)], 0) assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid2)], 10) walletinfo = self.nodes[1].getwalletinfo() assert_equal(len(walletinfo['balance']), 3) assert_equal(str(walletinfo['balance']['TPC']), '19.99983940') assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid1)], 10) assert_equal(walletinfo['balance'][bytes_to_hex_str(colorid2)], 70) walletinfo = self.nodes[2].getwalletinfo() assert_equal(len(walletinfo['balance']), 2) assert_equal(str(walletinfo['balance']['TPC']), '402.00025580') assert_equal(walletinfo['balance'][colorid3], 100)