def withdraw(client, blknum, txindex, oindex, key1, key2): # Get the transaction's block, already decoded by client block = client_call(client.get_block, [blknum]) # loop through for idx, val in enumerate(block.transaction_set): print("index is %d and value is %s" % (idx, val.files)) # Create a Merkle proof tx = block.transaction_set[txindex] proof = block.merkle.create_membership_proof(tx.merkle_hash) # Create the confirmation signatures confirmSig1, confirmSig2 = b'', b'' if key1: confirmSig1 = confirm_tx(tx, block.merkle.root, utils.normalize_key(key1)) if key2: confirmSig2 = confirm_tx(tx, block.merkle.root, utils.normalize_key(key2)) sigs = tx.sig1 + tx.sig2 + confirmSig1 + confirmSig2 client.withdraw(blknum, txindex, oindex, tx, proof, sigs) print("Submitted withdrawal")
def test_challenge_exit(t, u, root_chain, assert_tx_failed): owner, value_1, key = t.a1, 100, t.k1 tx1 = Transaction(0, 0, 0, 0, 0, 0, NULL_ADDRESS, owner, value_1, NULL_ADDRESS, 0) deposit_tx_hash = get_deposit_hash(owner, NULL_ADDRESS, value_1) utxo_pos1 = encode_utxo_id(root_chain.getDepositBlock(), 0, 0) root_chain.deposit(value=value_1, sender=key) utxo_pos2 = encode_utxo_id(root_chain.getDepositBlock(), 0, 0) root_chain.deposit(value=value_1, sender=key) merkle = FixedMerkle(16, [deposit_tx_hash], True) proof = merkle.create_membership_proof(deposit_tx_hash) confirmSig1 = confirm_tx(tx1, root_chain.getPlasmaBlock(utxo_pos1)[0], key) sigs = tx1.sig1 + tx1.sig2 + confirmSig1 root_chain.startDepositExit(utxo_pos1, NULL_ADDRESS, tx1.amount1, sender=key) tx3 = Transaction(utxo_pos2, 0, 0, 0, 0, 0, NULL_ADDRESS, owner, value_1, NULL_ADDRESS, 0) tx3.sign1(key) tx_bytes3 = rlp.encode(tx3, UnsignedTransaction) merkle = FixedMerkle(16, [tx3.merkle_hash], True) proof = merkle.create_membership_proof(tx3.merkle_hash) child_blknum = root_chain.currentChildBlock() root_chain.submitBlock(merkle.root) confirmSig = confirm_tx(tx3, root_chain.getPlasmaBlock(child_blknum)[0], key) sigs = tx3.sig1 + tx3.sig2 utxo_pos3 = encode_utxo_id(child_blknum, 0, 0) tx4 = Transaction(utxo_pos1, 0, 0, 0, 0, 0, NULL_ADDRESS, owner, value_1, NULL_ADDRESS, 0) tx4.sign1(key) tx_bytes4 = rlp.encode(tx4, UnsignedTransaction) merkle = FixedMerkle(16, [tx4.merkle_hash], True) proof = merkle.create_membership_proof(tx4.merkle_hash) child_blknum = root_chain.currentChildBlock() root_chain.submitBlock(merkle.root) confirmSig = confirm_tx(tx4, root_chain.getPlasmaBlock(child_blknum)[0], key) sigs = tx4.sig1 + tx4.sig2 utxo_pos4 = encode_utxo_id(child_blknum, 0, 0) oindex1 = 0 assert root_chain.exits(utxo_pos1) == [ '0x' + owner.hex(), NULL_ADDRESS_HEX, 100 ] # Fails if transaction after exit doesn't reference the utxo being exited assert_tx_failed(lambda: root_chain.challengeExit( utxo_pos3, oindex1, tx_bytes3, proof, sigs, confirmSig)) # Fails if transaction proof is incorrect assert_tx_failed(lambda: root_chain.challengeExit( utxo_pos4, oindex1, tx_bytes4, proof[::-1], sigs, confirmSig)) # Fails if transaction confirmation is incorrect assert_tx_failed(lambda: root_chain.challengeExit( utxo_pos4, oindex1, tx_bytes4, proof, sigs, confirmSig[::-1])) root_chain.challengeExit(utxo_pos4, oindex1, tx_bytes4, proof, sigs, confirmSig) assert root_chain.exits(utxo_pos1) == [ NULL_ADDRESS_HEX, NULL_ADDRESS_HEX, value_1 ]
def confirm(self, tx_id, signatory1, signatory2=None): tx = self.child_chain.get_transaction(tx_id) (blknum, _, _) = decode_utxo_id(tx_id) block_root = self.child_chain.get_block(blknum).root confirm_sigs = b'' for signatory in [x for x in [signatory1, signatory2] if x is not None]: confirm_sigs += confirm_tx(tx, block_root, signatory['key']) self.confirmations[tx_id] = confirm_sigs
def confirm_sig(client, blknum, key): utxo_id = blknum * 1000000000 + 10000 * 0 + 0 block = client_call(client.get_block, [blknum]) root = block.root print("block root:", root) tx = client_call(client.get_transaction, [utxo_id]) _key = utils.normalize_key(key) confirmSig = confirm_tx(tx, root, _key) print("confirm sig:", utils.encode_hex(confirmSig))
def confirm(self, tx_id, signatory1, signatory2=None): transaction = self.transactions[tx_id] tx = transaction['tx'] encoded_tx = rlp.encode(tx).hex() blknum, _ = self.child_chain.get_tx_pos(encoded_tx) block_root = self.child_chain.blocks[blknum].merkle.root confirm_sigs = b'' for signatory in [x for x in [signatory1, signatory2] if x is not None]: confirm_sigs += confirm_tx(tx, block_root, signatory['key']) self.transactions[tx_id]['confirm_sigs'] = confirm_sigs
def confirm_sig(client, blknum, key): block = client_call(client.get_block, [blknum]) tx = client_call(client.get_transaction, [blknum, 0]) _key = utils.normalize_key(key) confirmSig = confirm_tx(tx, block.root, _key) print("confirm sig:", utils.encode_hex(confirmSig))
def test_start_exit(t, root_chain, assert_tx_failed): week_and_a_half = 60 * 60 * 24 * 13 owner, value_1, key = t.a1, 100, t.k1 tx1 = Transaction(0, 0, 0, 0, 0, 0, NULL_ADDRESS, owner, value_1, NULL_ADDRESS, 0) deposit_tx_hash = get_deposit_hash(owner, NULL_ADDRESS, value_1) dep_blknum = root_chain.getDepositBlock() assert dep_blknum == 1 root_chain.deposit(value=value_1, sender=key) merkle = FixedMerkle(16, [deposit_tx_hash], True) proof = merkle.create_membership_proof(deposit_tx_hash) confirmSig1 = confirm_tx(tx1, root_chain.getPlasmaBlock(dep_blknum)[0], key) snapshot = t.chain.snapshot() sigs = tx1.sig1 + tx1.sig2 + confirmSig1 utxoId = encode_utxo_id(dep_blknum, 0, 0) # Deposit exit root_chain.startDepositExit(utxoId, NULL_ADDRESS, tx1.amount1, sender=key) t.chain.head_state.timestamp += week_and_a_half # Cannot exit twice off of the same utxo utxo_pos1 = encode_utxo_id(dep_blknum, 0, 0) assert_tx_failed(lambda: root_chain.startExit( utxo_pos1, deposit_tx_hash, proof, sigs, sender=key)) assert root_chain.getExit(utxo_pos1) == [ '0x' + owner.hex(), NULL_ADDRESS_HEX, 100 ] t.chain.revert(snapshot) tx2 = Transaction(dep_blknum, 0, 0, 0, 0, 0, NULL_ADDRESS, owner, value_1, NULL_ADDRESS, 0) tx2.sign1(key) tx_bytes2 = rlp.encode(tx2, UnsignedTransaction) merkle = FixedMerkle(16, [tx2.merkle_hash], True) proof = merkle.create_membership_proof(tx2.merkle_hash) child_blknum = root_chain.currentChildBlock() assert child_blknum == 1000 root_chain.submitBlock(merkle.root) confirmSig1 = confirm_tx(tx2, root_chain.getPlasmaBlock(child_blknum)[0], key) sigs = tx2.sig1 + tx2.sig2 + confirmSig1 snapshot = t.chain.snapshot() # # Single input exit utxo_pos2 = encode_utxo_id(child_blknum, 0, 0) root_chain.startExit(utxo_pos2, tx_bytes2, proof, sigs, sender=key) assert root_chain.getExit(utxo_pos2) == [ '0x' + owner.hex(), NULL_ADDRESS_HEX, 100 ] t.chain.revert(snapshot) dep2_blknum = root_chain.getDepositBlock() assert dep2_blknum == 1001 root_chain.deposit(value=value_1, sender=key) tx3 = Transaction(child_blknum, 0, 0, dep2_blknum, 0, 0, NULL_ADDRESS, owner, value_1, NULL_ADDRESS, 0, 0) tx3.sign1(key) tx3.sign2(key) tx_bytes3 = rlp.encode(tx3, UnsignedTransaction) merkle = FixedMerkle(16, [tx3.merkle_hash], True) proof = merkle.create_membership_proof(tx3.merkle_hash) child2_blknum = root_chain.currentChildBlock() assert child2_blknum == 2000 root_chain.submitBlock(merkle.root) confirmSig1 = confirm_tx(tx3, root_chain.getPlasmaBlock(child2_blknum)[0], key) confirmSig2 = confirm_tx(tx3, root_chain.getPlasmaBlock(child2_blknum)[0], key) sigs = tx3.sig1 + tx3.sig2 + confirmSig1 + confirmSig2 # Double input exit utxo_pos3 = encode_utxo_id(child2_blknum, 0, 0) root_chain.startExit(utxo_pos3, tx_bytes3, proof, sigs, sender=key) assert root_chain.getExit(utxo_pos3) == [ '0x' + owner.hex(), NULL_ADDRESS_HEX, 100 ]