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 sendtx(client, blknum1, txindex1, oindex1, blknum2, txindex2, oindex2, cur12, amount1, newowner1, amount2, newowner2, key1, key2): if cur12 == "0x0": cur12 = NULL_ADDRESS if newowner1 == "0x0": newowner1 = NULL_ADDRESS if newowner2 == "0x0": newowner2 = NULL_ADDRESS # Form a transaction tx = Transaction(blknum1, txindex1, oindex1, blknum2, txindex2, oindex2, utils.normalize_address(cur12), utils.normalize_address(newowner1), amount1, utils.normalize_address(newowner2), amount2) # Sign it if key1: tx.sign1(utils.normalize_key(key1)) if key2: tx.sign2(utils.normalize_key(key2)) client_call(client.apply_transaction, [tx], "Sent transaction")
def create_utxo(self, to_contractaddress, provide_amount): utxos = self.get_utxos() for blknum, txindex, oindex, contractaddress, amount, tokenid in utxos: if contractaddress.lower() == to_contractaddress[2:].lower(): if amount == provide_amount: return blknum, txindex, oindex, contractaddress, amount, tokenid for blknum, txindex, oindex, contractaddress, amount, tokenid in utxos: if contractaddress.lower() == to_contractaddress[2:].lower(): if amount > provide_amount: tx = Transaction(blknum, txindex, oindex, 0, 0, 0, utils.normalize_address(self.address), utils.normalize_address(contractaddress), provide_amount, 0, utils.normalize_address(self.address), utils.normalize_address(contractaddress), amount - provide_amount, 0) tx.sign1( utils.normalize_key(plasma_config["AUTHORITY_KEY"])) tx.sign2( utils.normalize_key(plasma_config["AUTHORITY_KEY"])) self.child_chain.apply_transaction( rlp.encode(tx, Transaction).hex()) break else: raise ValueError("no available utxo") utxos = self.get_utxos() for blknum, txindex, oindex, contractaddress, amount, tokenid in utxos: if contractaddress.lower() == to_contractaddress[2:].lower(): if amount == provide_amount: return blknum, txindex, oindex, contractaddress, amount, tokenid raise Exception("Something went wrong")
def test_apply_transaction_with_same_uid_tx_already_in_block_should_fail( self, child_chain): # create a another (invalid) transaction with same uid in block 2 # this transaction would be used as the prev_tx of second same uid tx DUMMY_TX_OWNER = b'\x8cT\xa4\xa0\x17\x9f$\x80\x1fI\xf92-\xab<\x87\xeb\x19L\x9b' tx = Transaction(prev_block=0, uid=1, amount=10, new_owner=DUMMY_TX_OWNER) child_chain.db.save_block(Block([tx]), 2) child_chain.current_block_number = 3 child_chain.db.increment_current_block_num() # first apply a tx with the uid DUMMY_TX_KEY = b'8b76243a95f959bf101248474e6bdacdedc8ad995d287c24616a41bd51642965' tx = Transaction(prev_block=1, uid=1, amount=10, new_owner=self.DUMMY_TX_NEW_OWNER) tx.sign(eth_utils.normalize_key(DUMMY_TX_KEY)) child_chain.apply_transaction(rlp.encode(tx).hex()) # apply another tx with the same uid should fail tx = Transaction(prev_block=2, uid=1, amount=10, new_owner=self.DUMMY_TX_NEW_OWNER) tx.sign(eth_utils.normalize_key(DUMMY_TX_KEY)) with pytest.raises(TxWithSameUidAlreadyExists): child_chain.apply_transaction(rlp.encode(tx).hex())
def sendtx(client, blknum1, txindex1, oindex1, blknum2, txindex2, oindex2, newowner1, contractaddress1, amount1, tokenid1, newowner2, contractaddress2, amount2, tokenid2, key1, key2): if newowner1 == "0x0": newowner1 = NULL_ADDRESS if newowner2 == "0x0": newowner2 = NULL_ADDRESS if contractaddress1 == "0x0": contractaddress1 = NULL_ADDRESS if contractaddress2 == "0x0": contractaddress2 = NULL_ADDRESS if key2 is None: key2 = key1 # Form a transaction tx = Transaction(blknum1, txindex1, oindex1, blknum2, txindex2, oindex2, utils.normalize_address(newowner1), utils.normalize_address(contractaddress1), amount1, tokenid1, utils.normalize_address(newowner2), utils.normalize_address(contractaddress2), amount2, tokenid2) # Sign it tx.sign1(utils.normalize_key(key1)) tx.sign2(utils.normalize_key(key2)) client.apply_transaction(tx) print("Sent transaction")
def set_dict(self, **num): print("set test") print("Data type of argument:", type(num)) for key, value in num.items(): print("{} is {}".format(key, value)) #self.root_chain.deposit(transact={'from': owner, 'value': amount}) mapping = {} mapping.update(num) for key, value in mapping.items(): print("{} is {}".format(key, value)) #convert dict to binary string bin_mapping = pickle.dumps(mapping) blknum = self.chain.next_deposit_block new_block = Block(None, blknum, NULL_SIGNATURE) new_block.add_mapping(mapping) self.chain.add_block(new_block) print("Number {} {}".format(new_block.number, self.chain.next_deposit_block)) tx = Transaction( blknum, 0, 0, 0, 0, 0, utils.normalize_address(0x0), utils.normalize_address( '0xfd02EcEE62797e75D86BCff1642EB0844afB28c7'), 1, utils.normalize_address(NULL_ADDRESS), 1, NULL_SIGNATURE, NULL_SIGNATURE, 0, bin_mapping) key1 = '3bb369fecdc16b93b99514d8ed9c2e87c5824cf4a6a98d2e8e91b7dd0c063304' print("Data type of key1:", type(key1)) tx.sign1(utils.normalize_key(key1)) self.current_block.add_transaction(tx) print("Added {}".format(self.current_block.transaction_set[0])) print("Added {}".format(self.current_block.transaction_set[0].mapping)) self.chain.set_dict(**num)
def makeorder(client, address, currency, amount, tokenprice, key): utxos = client_call(client.get_utxos, [address, currency]) amount = int(amount * 1e18) # Find a utxos with enough tokens for utxo in utxos: if utxo[3] >= amount: # generate the transaction object change_amount = utxo[3] - amount if change_amount: tx = Transaction(Transaction.TxnType.make_order, utxo[0], utxo[1], utxo[2], 0, 0, 0, Transaction.UTXOType.make_order, utils.normalize_address(address), amount, tokenprice, utils.normalize_address(currency), Transaction.UTXOType.transfer, utils.normalize_address(address), change_amount, 0, utils.normalize_address(currency), 0, NULL_ADDRESS, 0, 0, NULL_ADDRESS, 0, NULL_ADDRESS, 0, 0, NULL_ADDRESS) else: tx = Transaction(Transaction.TxnType.make_order, utxo[0], utxo[1], utxo[2], 0, 0, 0, Transaction.UTXOType.make_order, utils.normalize_address(address), amount, tokenprice, utils.normalize_address(currency), 0, NULL_ADDRESS, 0, 0, NULL_ADDRESS, 0, NULL_ADDRESS, 0, 0, NULL_ADDRESS, 0, NULL_ADDRESS, 0, 0, NULL_ADDRESS) tx.sign1(utils.normalize_key(key)) client_call(client.apply_transaction, [tx], "Sent transaction") break
def sign_data(data, key): data_hash = eth.sha3(data) key_bytes = eth.normalize_key(key) sig = eth.ecsign(data_hash, key_bytes) logging.debug('Signature created: {0}'.format(sig)) return sig
def sign(self, unsigned_tx, privtKey): before_hash = utils.sha3(binascii.unhexlify(unsigned_tx.encode())) v, r, s = ecsign(before_hash, normalize_key(privtKey)) signature = binascii.hexlify( int_to_big_endian(r) + int_to_big_endian(s) + bytes(chr(v).encode())).decode() return signature
def test_apply_transaction_with_invalid_sig(self, child_chain): DUMMY_INVALID_TX_KEY = b'7a76243a95f959bf101248474e6bdacdedc8ad995d287c24616a41bd51642965' tx = Transaction(prev_block=1, uid=1, amount=10, new_owner=self.DUMMY_TX_NEW_OWNER) tx.sign(eth_utils.normalize_key(DUMMY_INVALID_TX_KEY)) with pytest.raises(InvalidTxSignatureException): child_chain.apply_transaction(rlp.encode(tx).hex())
def _submitblock(client, key, block): # Sign the block block.make_mutable() normalized_key = utils.normalize_key(key) block.sign(normalized_key) client.submit_block(block) print("Submitted current block")
def withdraw(self): blknum, txindex, oindex = int(self.inp[1]), int(self.inp[2]), int( self.inp[3]) txPos = [blknum, txindex, oindex] key1 = utils.normalize_key(self.inp[4]) key2 = utils.normalize_key(self.inp[5]) if len(self.inp) == 6 else b'' block = self.client.get_block(blknum) block = rlp.decode(utils.decode_hex(block), Block) tx = block.transaction_set[txindex] block.merkilize_transaction_set proof = block.merkle.create_membership_proof(tx.merkle_hash) confirmSig1 = confirm_tx(tx, block.merkle.root, key1) confirmSig2 = b'' if key2: confirmSig2 = confirm_tx(tx, block.merkle.root, key2) sigs = tx.sig1 + tx.sig2 + confirmSig1 + confirmSig2 self.client.withdraw(txPos, tx, proof, sigs) print("Successfully submitted a withdrawal")
def test_apply_transaction_with_mismatch_amount(self, child_chain): DUMMY_TX_KEY = b'8b76243a95f959bf101248474e6bdacdedc8ad995d287c24616a41bd51642965' # token with uid 1 doesn't have 20 tx = Transaction(prev_block=1, uid=1, amount=20, new_owner=self.DUMMY_TX_NEW_OWNER) tx.sign(eth_utils.normalize_key(DUMMY_TX_KEY)) with pytest.raises(TxAmountMismatchException): child_chain.apply_transaction(rlp.encode(tx).hex())
def test_apply_transaction_with_previous_tx_not_exist(self, child_chain): DUMMY_TX_KEY = b'8b76243a95f959bf101248474e6bdacdedc8ad995d287c24616a41bd51642965' # token with uid 3 doesn't exist tx = Transaction(prev_block=1, uid=3, amount=10, new_owner=self.DUMMY_TX_NEW_OWNER) tx.sign(eth_utils.normalize_key(DUMMY_TX_KEY)) with pytest.raises(PreviousTxNotFoundException): child_chain.apply_transaction(rlp.encode(tx).hex())
def userA_tries_to_double_spend_some_eth_to_userC(context, amount): invalid_tx = Transaction(DEPOSIT_TX_BLOCK, uid, 1, utils.normalize_address(userC)) invalid_tx.sign(utils.normalize_key(userA_key)) invalid_tx_merkle = SparseMerkleTree(257, {uid: invalid_tx.merkle_hash}) root_chain = container.get_root_chain() root_chain.functions.submitBlock(invalid_tx_merkle.root, TRANSFER_TX_2_BLOCK).transact({ 'from': operator })
def submit_block(self): if len(self.inp) != 2: raise ("Wrong number of inputs to submit block") key = utils.normalize_key(self.inp[1]) block = self.client.get_current_block() block = rlp.decode(utils.decode_hex(block), Block) block.make_mutable() block.sign(key) self.client.submit_block(block) print("Successfully submitted a block!")
def sign_args(self,typeList, valueList, privtKey): ''' :param typeList: ['bytes32', 'bytes32', 'uint256', 'uint256'] :param valueList: ["0x3ae88fe370c39384fc16da2c9e768cf5d2495b48", "0x9da26fc2e1d6ad9fdd46138906b0104ae68a65d8", 1, 1] :param privtKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" :return: ''' data_hash = self.solidity_hash(typeList, valueList) v, r, s = ecsign(data_hash, normalize_key(privtKey)) signature = self.int_to_big_endian(r) + self.int_to_big_endian(s) + bytes(chr(v - 27).encode()) return signature.hex()
def submitblock(client, key): # Get the current block, already decoded by client block = client_call(client.get_current_block) # Sign the block block.make_mutable() normalized_key = utils.normalize_key(key) block.sign(normalized_key) client_call(client.submit_block, [block], "Submitted current block")
def test_apply_transaction_with_double_spending(self, child_chain): DUMMY_TX_KEY = b'8b76243a95f959bf101248474e6bdacdedc8ad995d287c24616a41bd51642965' tx = Transaction(prev_block=1, uid=1, amount=10, new_owner=self.DUMMY_TX_NEW_OWNER) tx.sign(eth_utils.normalize_key(DUMMY_TX_KEY)) child_chain.apply_transaction(rlp.encode(tx).hex()) # try to spend a spent transaction with pytest.raises(TxAlreadySpentException): child_chain.apply_transaction(rlp.encode(tx).hex())
def deposit(self): if len(self.inp) != 3: raise Exception("Wrong number of inputs for deposit") amount1 = int(self.inp[1]) key = utils.normalize_key(self.inp[2]) newOwner1 = utils.privtoaddr(key) newOwner2, amount2 = utils.normalize_address(b'\x00' * 20), 0 tx = Transaction(0, 0, 0, 0, 0, 0, newOwner1, amount1, newOwner2, amount2, 0) self.client.deposit(tx, key) print("Succesfully deposited %s to %s" % (amount1, newOwner1))
def withdraw(client, blknum, txindex, oindex, key1, key2): # Get the transaction's block, already decoded by client block = client.get_block(blknum) # Create a Merkle proof tx = block.transaction_set[txindex] block.merklize_transaction_set() 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 submitblock(client, key): # Get the current block and decode it encoded_block = client.get_current_block() block = rlp.decode(utils.decode_hex(encoded_block), Block) # Sign the block block.make_mutable() normalized_key = utils.normalize_key(key) block.sign(normalized_key) client.submit_block(block) print("Submitted current block")
def test_apply_transaction(self, child_chain): DUMMY_TX_KEY = b'8b76243a95f959bf101248474e6bdacdedc8ad995d287c24616a41bd51642965' tx = Transaction(prev_block=1, uid=1, amount=10, new_owner=self.DUMMY_TX_NEW_OWNER) tx.sign(eth_utils.normalize_key(DUMMY_TX_KEY)) child_chain.apply_transaction(rlp.encode(tx).hex()) prev_tx = child_chain.blocks[1].transaction_set[0] assert child_chain.current_block.transaction_set[0] == tx assert prev_tx.new_owner == tx.sender assert prev_tx.amount == tx.amount assert prev_tx.spent is True
def sign_args(self, typeList, valueList, privtKey): ''' :param typeList: ['bytes32', 'bytes32', 'uint256', 'uint256'] :param valueList: ["0x3ae88fe370c39384fc16da2c9e768cf5d2495b48", "0x9da26fc2e1d6ad9fdd46138906b0104ae68a65d8", 1, 1] :param privtKey: "095e53c9c20e23fd01eaad953c01da9e9d3ed9bebcfed8e5b2c2fce94037d963" :return: ''' data_hash = Web3.soliditySha3(typeList, valueList) v, r, s = ecsign(data_hash, normalize_key(privtKey)) signature = binascii.hexlify(int_to_big_endian(r) + int_to_big_endian(s) + bytes(chr(v - 27).encode())) return signature
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 transferToken(prev_block, uid, amount, new_owner, owner_key): # client = Client(container.get_root_chain(), container.get_child_chain_client(), owner_key) # client.send_transaction(prev_block, uid, amount, new_owner) new_owner = utils.normalize_address(new_owner) tx = Transaction(prev_block, uid, amount, new_owner) owner_key = utils.normalize_key(owner_key) tx.sign(owner_key) # self.child_chain.send_transaction(rlp.encode(tx, Transaction).hex()) encoded_txn = rlp.encode(tx, Transaction).hex() payload = {'tx': encoded_txn} response = requests.post("http://localhost:8546/send_tx", data=payload) print(response.status_code) if response.status_code == 200: print(response.content)
def __init__(self, public_address, private_key, root_chain_provider=None, child_chain_provider=None, ): if root_chain_provider is None: self.web3 = Web3(Web3.HTTPProvider("http://localhost:8545")) else: self.web3 = Web3(Web3.HTTPProvider(root_chain_provider)) if child_chain_provider is None: self.child_chain = "http://localhost:8546" else: self.child_chain = child_chain_provider if self.web3.isChecksumAddress(public_address): self.address = public_address else: self.address = self.web3.toChecksumAddress(public_address) self.key = utils.normalize_key(private_key) self.contract = None
def send_tx(self): if len(self.inp) != 14 and len(self.inp) != 13: raise Exception( "Wrong number of inputs for sending a transaction!") blknum1, tx_pos1, utxo_pos1 = int(self.inp[1]), int(self.inp[2]), int( self.inp[3]) blknum2, tx_pos2, utxo_pos2 = int(self.inp[4]), int(self.inp[5]), int( self.inp[6]) newowner1 = utils.normalize_address(self.inp[7]) amount1 = int(self.inp[8]) newowner2 = utils.normalize_address(self.inp[9]) amount2 = int(self.inp[10]) fee = int(self.inp[11]) key1 = utils.normalize_key(self.inp[12]) key2 = utils.normalize_key(self.inp[13]) if len( self.inp) == 14 else b'' tx = Transaction(blknum1, tx_pos1, utxo_pos1, blknum2, tx_pos2, utxo_pos2, newowner1, amount1, newowner2, amount2, fee) tx.sign1(key1) if key2: tx.sign2(key2) self.client.apply_transaction(tx) print("Succesfully added transaction!")
def submitblock(client, key): print("submitblock called at %s" % str(datetime.datetime.now())) # Get the current block, already decoded by client block = client_call(client.get_current_block) print("current block has %d txns" % len(block.transaction_set)) # If there are no transactions in the current block, then don't submit it if len(block.transaction_set) == 0: return # Sign the block block.make_mutable() normalized_key = utils.normalize_key(key) block.sign(normalized_key) client_call(client.submit_block, [block], "Submitted current block")
def create_partially_signed_transaction(self, from_contractaddress, to_contractaddress, amount): exchange_rate = self.get_exchange_rate(from_contractaddress, to_contractaddress, amount) if exchange_rate is None: return None provide_amount = amount * exchange_rate blknum1, txindex1, oindex1, contractaddress2, amount2, tokenid2 = self.create_utxo( to_contractaddress, provide_amount) ps_tx = Transaction( blknum1, txindex1, oindex1, 0, 0, 0, utils.normalize_address(self.address), b'\x00' * 20 if from_contractaddress == "0x0" else from_contractaddress, amount, 0, b'\x00' * 20, contractaddress2, amount2, tokenid2) ps_tx.sign1(utils.normalize_key(plasma_config["AUTHORITY_KEY"])) return ps_tx.to_json()
def sign(self, key, network_id=None): """Sign this transaction with a private key. A potentially already existing signature would be overridden. """ if network_id is None: rawhash = utils.sha3(rlp.encode(self, UnsignedTransaction)) else: assert 1 <= network_id < 2**63 - 18 rlpdata = rlp.encode(rlp.infer_sedes(self).serialize(self)[ :-3] + [network_id, b'', b'']) rawhash = utils.sha3(rlpdata) key = normalize_key(key) self.v, self.r, self.s = ecsign(rawhash, key) if network_id is not None: self.v += 8 + network_id * 2 self._sender = utils.privtoaddr(key) return self
def createOrder(orderHash, key=tester.k0): key = normalize_key(key) v, r, s = ecsign(sha3("\x19Ethereum Signed Message:\n32" + orderHash), key) return v, zpad(bytearray_to_bytestr(int_to_32bytearray(r)), 32), zpad(bytearray_to_bytestr(int_to_32bytearray(s)), 32)