def generateInvalidUnlockTx(self, userAddress, contractAddress,
                                maliciousAddress):
        commit, witness, R, S = generate_submarine_commit._generateRS(
            normalize_address(rec_hex(userAddress)),
            normalize_address(rec_hex(contractAddress)), UNLOCK_AMOUNT, b'',
            OURGASPRICE, OURGASLIMIT)

        unlockFunctionSelector = b"\xec\x9b\x5b\x3a"
        submarineData = unlockFunctionSelector + commit

        # need the unsigned TX hash for ECRecover
        unlock_tx_unsigned_object = transactions.UnsignedTransaction(
            0,  # nonce;
            OURGASPRICE,  # gasprice
            OURGASLIMIT,  # startgas
            normalize_address(maliciousAddress),  # to addr
            UNLOCK_AMOUNT,  # value
            submarineData,  # data
        )
        unlock_tx_unsigned_hash = sha3(
            rlp.encode(unlock_tx_unsigned_object,
                       transactions.UnsignedTransaction))

        unlock_tx_object = transactions.Transaction(
            0,  # nonce;
            OURGASPRICE,  # gasprice
            OURGASLIMIT,  # startgas
            normalize_address(maliciousAddress),  # to addr
            UNLOCK_AMOUNT,  # value
            submarineData,  # data
            27,  # v
            R,  # r
            S  # s
        )

        try:
            pub = ecrecover_to_pub(unlock_tx_unsigned_hash, 27, R, S)
            if pub == b"\x00" * 64:
                log.info("Address no good, retrying")
                return self.generateInvalidUnlockTx(userAddress,
                                                    contractAddress,
                                                    maliciousAddress)
            else:
                commit_addr = sha3(pub)[-20:]
                log.info("Fake Unlock TX Dict: {}".format(
                    unlock_tx_unsigned_object.as_dict()))
                log.info("Fake Unlock TX Commit B: {}".format(commit_addr))
                return unlock_tx_object, unlock_tx_unsigned_object, commit_addr, commit, witness

        except (ValueError, InvalidTransaction) as e:
            if isinstance(e, ValueError) and "VRS" not in str(e):
                raise
            log.info("Address no good (%s), retrying" % e)
            return self.generateInvalidUnlockTx(userAddress, contractAddress,
                                                maliciousAddress)
Example #2
0
    def test_ExchangeWorkflowBuyTokensWithEth(self):
        ##
        ## STARTING STATE
        ##
        self.chain.mine(1)
        self.assertEqual(TOTAL_TOKEN_SUPPLY - TOKEN_AMOUNT_STARTING - BOB_STARTING_TOKEN_AMOUNT, self.token_contract.balanceOf(CONTRACT_OWNER_ADDRESS))
        self.assertEqual(TOKEN_AMOUNT_STARTING, self.token_contract.balanceOf(self.exchange_contract.address))
        self.assertEqual(ACCOUNT_STARTING_BALANCE - ETH_AMOUNT_STARTING, self.chain.head_state.get_balance(rec_hex(CONTRACT_OWNER_ADDRESS)))
        self.assertEqual(ACCOUNT_STARTING_BALANCE, self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS)))
        self.assertEqual(ETH_AMOUNT_STARTING, self.chain.head_state.get_balance(rec_hex(self.exchange_contract.address)))
        self.assertEqual(BOB_STARTING_TOKEN_AMOUNT, self.token_contract.balanceOf(BOB_ADDRESS))
        self.assertEqual(0, self.token_contract.balanceOf(ALICE_ADDRESS))
        self.assertEqual(ETH_AMOUNT_STARTING, self.exchange_contract.ethPool())
        self.assertEqual(TOKEN_AMOUNT_STARTING, self.exchange_contract.tokenPool())
        self.assertEqual(ETH_AMOUNT_STARTING * TOKEN_AMOUNT_STARTING, self.exchange_contract.invariant())
        currentInvariant = ETH_AMOUNT_STARTING * TOKEN_AMOUNT_STARTING
        self.assertEqual(COMMIT_PERIOD_LENGTH, self.exchange_contract.commitPeriodLength())

        ##
        ## ALICE BUYS TOKENS WITH ETH
        ##
        commitAddressAlice, commitAlice, witnessAlice, unlock_tx_hexAlice = generate_submarine_commit.generateCommitAddress(
             normalize_address(rec_hex(ALICE_ADDRESS)),
             normalize_address(rec_hex(self.exchange_contract.address)),
             ALICE_TRADE_AMOUNT, b'', OURGASPRICE, OURGASLIMIT)
        unlock_tx_infoAlice = rlp.decode(rec_bin(unlock_tx_hexAlice))
        unlock_tx_objectAlice = transactions.Transaction(
            int.from_bytes(unlock_tx_infoAlice[0], byteorder="big"),  # nonce;
            int.from_bytes(unlock_tx_infoAlice[1], byteorder="big"),  # gasprice
            int.from_bytes(unlock_tx_infoAlice[2], byteorder="big"),  # startgas
            unlock_tx_infoAlice[3],                                   # to addr
            int.from_bytes(unlock_tx_infoAlice[4], byteorder="big"),  # value
            unlock_tx_infoAlice[5],                                   # data
            int.from_bytes(unlock_tx_infoAlice[6], byteorder="big"),  # v
            int.from_bytes(unlock_tx_infoAlice[7], byteorder="big"),  # r
            int.from_bytes(unlock_tx_infoAlice[8], byteorder="big")   # s
        )

        commit_tx_objectAlice = transactions.Transaction(
            0, OURGASPRICE, BASIC_SEND_GAS_LIMIT, rec_bin(commitAddressAlice),
            (ALICE_TRADE_AMOUNT + extraTransactionFees),
            b'').sign(ALICE_PRIVATE_KEY)

        self.chain.direct_tx(commit_tx_objectAlice)
        commit_gasAlice = int(self.chain.head_state.gas_used)
        self.chain.mine(1)

        commit_block_numberAlice, commit_block_indexAlice = self.chain.chain.get_tx_position(
            commit_tx_objectAlice)
        self.assertEqual(ALICE_TRADE_AMOUNT + extraTransactionFees,
                         self.chain.head_state.get_balance(commitAddressAlice))
        self.assertEqual(
            ACCOUNT_STARTING_BALANCE - (ALICE_TRADE_AMOUNT + extraTransactionFees +
                                        BASIC_SEND_GAS_LIMIT * OURGASPRICE),
            self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS)))

        session_dataAlice = self.exchange_contract.getSubmarineState(rec_bin(commitAlice))
        self.assertListEqual(session_dataAlice,
                [SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL])

        finished_boolAlice = self.exchange_contract.revealedAndUnlocked(rec_bin(commitAlice))
        self.assertFalse(
            finished_boolAlice,
            "The contract should not be finished before it's even begun.")


        ##
        ## GENERATE AND BROADCAST REVEAL BID TXS
        ##
        self.chain.mine(COMMIT_PERIOD_LENGTH)

        proveth_commit_blockAlice = proveth_compatible_commit_block(
            self.chain.chain.get_block_by_number(commit_block_numberAlice),
            commit_tx_objectAlice,
        )
        commit_proof_blobAlice = proveth.generate_proof_blob(
            proveth_commit_blockAlice, commit_block_indexAlice)
        _unlockExtraData = b''  # In this example we dont have any extra embedded data as part of the unlock TX


        unlock_tx_unsigned_objectAlice = transactions.UnsignedTransaction(
            int.from_bytes(unlock_tx_infoAlice[0], byteorder="big"),  # nonce;
            int.from_bytes(unlock_tx_infoAlice[1], byteorder="big"),  # gasprice
            int.from_bytes(unlock_tx_infoAlice[2], byteorder="big"),  # startgas
            unlock_tx_infoAlice[3],  # to addr
            int.from_bytes(unlock_tx_infoAlice[4], byteorder="big"),  # value
            unlock_tx_infoAlice[5],  # data
        )
        unlock_tx_unsigned_rlpAlice = rlp.encode(unlock_tx_unsigned_objectAlice, transactions.UnsignedTransaction)


        self.chain.mine(5)
        self.exchange_contract.reveal(
            commit_block_numberAlice,   # uint32 _commitBlockNumber,
            _unlockExtraData,           # bytes _commitData,
            rec_bin(witnessAlice),      # bytes32 _witness,
            unlock_tx_unsigned_rlpAlice,  # bytes _rlpUnlockTxUnsigned,
            commit_proof_blobAlice,  # bytes _proofBlob
            sender=ALICE_PRIVATE_KEY,
            gasprice=OURGASPRICE)
        reveal_gasAlice = int(self.chain.head_state.gas_used)

        ##
        ## BROADCAST UNLOCK
        ##
        self.chain.mine(1)
        self.chain.direct_tx(unlock_tx_objectAlice)
        self.chain.mine(1)

        ##
        ## Call the actual ethToTokenSwap function
        ##
        self.exchange_contract.ethToTokenSwap(rec_bin(commitAlice), sender=ALICE_PRIVATE_KEY, gasprice=OURGASPRICE)
        swapcall_gasAlice = int(self.chain.head_state.gas_used)
        self.chain.mine(1)

        # unlock_block_numberAlice, unlock_block_indexAlice = self.chain.chain.get_tx_position(
        #         unlock_tx_objectAlice)
        # unlock_block_objectAlice = self.chain.chain.get_block_by_number(unlock_block_numberAlice)
        # print(unlock_block_objectAlice.as_dict())
        # print(unlock_block_objectAlice.as_dict()['transactions'][0].as_dict())
        # print(unlock_block_objectAlice.as_dict()['header'].as_dict())

        ##
        ## CHECK STATE AFTER TOKEN PURCHASE
        ##
        self.assertEqual(ETH_AMOUNT_STARTING+ALICE_TRADE_AMOUNT, self.exchange_contract.ethPool())
        self.assertEqual(ETH_AMOUNT_STARTING+ALICE_TRADE_AMOUNT, self.chain.head_state.get_balance(rec_hex(self.exchange_contract.address)))
        self.assertEqual(ACCOUNT_STARTING_BALANCE - ALICE_TRADE_AMOUNT - (OURGASPRICE*(commit_gasAlice + reveal_gasAlice + swapcall_gasAlice)) - extraTransactionFees, self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS)))
        tokens_out = int(TOKEN_AMOUNT_STARTING - (currentInvariant //(ETH_AMOUNT_STARTING + ALICE_TRADE_AMOUNT))) # // floor division
        self.assertEqual(tokens_out, self.token_contract.balanceOf(ALICE_ADDRESS))
        self.assertEqual(TOKEN_AMOUNT_STARTING - tokens_out, self.token_contract.balanceOf(self.exchange_contract.address))
        self.assertEqual(TOKEN_AMOUNT_STARTING - tokens_out, self.exchange_contract.tokenPool())
Example #3
0
    def test_auctionWorkflow(self):
        ##
        ## STARTING STATE
        ##

        starting_block_height = self.chain.head_state.block_number
        starting_owner_eth_holdings = self.chain.head_state.get_balance(rec_hex(CONTRACT_OWNER_ADDRESS))
        self.chain.mine(1)

        self.assertTrue(self.erc721_contract.isMinter(CONTRACT_OWNER_ADDRESS))
        self.chain.mine(1)
        self.assertEqual(1, self.erc721_contract.balanceOf(rec_hex(CONTRACT_OWNER_ADDRESS), sender=CONTRACT_OWNER_PRIVATE_KEY))
        self.assertEqual(rec_hex(CONTRACT_OWNER_ADDRESS), self.erc721_contract.ownerOf(TOKEN_ID, sender=CONTRACT_OWNER_PRIVATE_KEY))

        self.assertEqual(ACCOUNT_STARTING_BALANCE, self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS)))
        self.assertEqual(ACCOUNT_STARTING_BALANCE, self.chain.head_state.get_balance(rec_hex(BOB_ADDRESS)))
        self.assertEqual(ACCOUNT_STARTING_BALANCE, self.chain.head_state.get_balance(rec_hex(CHARLIE_ADDRESS)))
        self.assertTrue(self.auction_contract.address)
        self.assertEqual(27, self.auction_contract.vee())

        ##
        ## START THE AUCTION
        ## (By sending the token to the auction contract, triggering onERC721Received)
        startAuctionBlock = self.chain.head_state.block_number + 1
        endCommitPeriodBlock = self.chain.head_state.block_number + COMMIT_PERIOD_LENGTH
        onERC721RecievedDataField = encode_single_packed('(uint32,uint32)', [startAuctionBlock, endCommitPeriodBlock])
        self.erc721_contract.safeTransferFrom(CONTRACT_OWNER_ADDRESS, self.auction_contract.address, TOKEN_ID, onERC721RecievedDataField, sender=CONTRACT_OWNER_PRIVATE_KEY)
        self.assertEqual(rec_hex(self.auction_contract.address), self.erc721_contract.ownerOf(TOKEN_ID))
        self.assertEqual(rec_hex(CONTRACT_OWNER_ADDRESS), self.auction_contract.seller())
        self.assertEqual(startAuctionBlock, self.auction_contract.startBlock())
        self.assertEqual(endCommitPeriodBlock, self.auction_contract.endCommitBlock())
        self.assertEqual(endCommitPeriodBlock+REVEAL_PERIOD_LENGTH, self.auction_contract.endRevealBlock())
        self.assertEqual(TOKEN_ID, self.auction_contract.erc721TokenId())
        self.assertEqual(rec_hex(self.erc721_contract.address), self.auction_contract.erc721())

        #
        # GENERATE UNLOCK TXs
        #
        commitAddressAlice, commitAlice, witnessAlice, unlock_tx_hexAlice = generate_submarine_commit.generateCommitAddress(
             normalize_address(rec_hex(ALICE_ADDRESS)),
             normalize_address(rec_hex(self.auction_contract.address)),
             BID_AMOUNT_Alice, b'', OURGASPRICE, OURGASLIMIT)

        unlock_tx_infoAlice = rlp.decode(rec_bin(unlock_tx_hexAlice))
        unlock_tx_objectAlice = transactions.Transaction(
            int.from_bytes(unlock_tx_infoAlice[0], byteorder="big"),  # nonce;
            int.from_bytes(unlock_tx_infoAlice[1], byteorder="big"),  # gasprice
            int.from_bytes(unlock_tx_infoAlice[2], byteorder="big"),  # startgas
            unlock_tx_infoAlice[3],  # to addr
            int.from_bytes(unlock_tx_infoAlice[4], byteorder="big"),  # value
            unlock_tx_infoAlice[5],  # data
            int.from_bytes(unlock_tx_infoAlice[6], byteorder="big"),  # v
            int.from_bytes(unlock_tx_infoAlice[7], byteorder="big"),  # r
            int.from_bytes(unlock_tx_infoAlice[8], byteorder="big")  # s
        )
        commitAddressBob, commitBob, witnessBob, unlock_tx_hexBob = generate_submarine_commit.generateCommitAddress(
             normalize_address(rec_hex(BOB_ADDRESS)),
             normalize_address(rec_hex(self.auction_contract.address)),
             BID_AMOUNT_Bob, b'', OURGASPRICE, OURGASLIMIT)

        unlock_tx_infoBob = rlp.decode(rec_bin(unlock_tx_hexBob))
        unlock_tx_objectBob = transactions.Transaction(
            int.from_bytes(unlock_tx_infoBob[0], byteorder="big"),  # nonce;
            int.from_bytes(unlock_tx_infoBob[1], byteorder="big"),  # gasprice
            int.from_bytes(unlock_tx_infoBob[2], byteorder="big"),  # startgas
            unlock_tx_infoBob[3],  # to addr
            int.from_bytes(unlock_tx_infoBob[4], byteorder="big"),  # value
            unlock_tx_infoBob[5],  # data
            int.from_bytes(unlock_tx_infoBob[6], byteorder="big"),  # v
            int.from_bytes(unlock_tx_infoBob[7], byteorder="big"),  # r
            int.from_bytes(unlock_tx_infoBob[8], byteorder="big")  # s
        )
        commitAddressCharlie, commitCharlie, witnessCharlie, unlock_tx_hexCharlie = generate_submarine_commit.generateCommitAddress(
             normalize_address(rec_hex(CHARLIE_ADDRESS)),
             normalize_address(rec_hex(self.auction_contract.address)),
             BID_AMOUNT_Charlie, b'', OURGASPRICE, OURGASLIMIT)

        unlock_tx_infoCharlie = rlp.decode(rec_bin(unlock_tx_hexCharlie))
        unlock_tx_objectCharlie = transactions.Transaction(
            int.from_bytes(unlock_tx_infoCharlie[0], byteorder="big"),  # nonce;
            int.from_bytes(unlock_tx_infoCharlie[1], byteorder="big"),  # gasprice
            int.from_bytes(unlock_tx_infoCharlie[2], byteorder="big"),  # startgas
            unlock_tx_infoCharlie[3],  # to addr
            int.from_bytes(unlock_tx_infoCharlie[4], byteorder="big"),  # value
            unlock_tx_infoCharlie[5],  # data
            int.from_bytes(unlock_tx_infoCharlie[6], byteorder="big"),  # v
            int.from_bytes(unlock_tx_infoCharlie[7], byteorder="big"),  # r
            int.from_bytes(unlock_tx_infoCharlie[8], byteorder="big")  # s
        )

        #
        # GENERATE + BROADCAST COMMIT TXs
        #
        commit_tx_objectAlice = transactions.Transaction(
            0, OURGASPRICE, BASIC_SEND_GAS_LIMIT, rec_bin(commitAddressAlice),
            (BID_AMOUNT_Alice + extraTransactionFees),
            b'').sign(ALICE_PRIVATE_KEY)
        commit_gasAlice = int(self.chain.head_state.gas_used)

        self.chain.mine(1)
        self.chain.direct_tx(commit_tx_objectAlice)
        self.chain.mine(1)

        commit_tx_objectBob = transactions.Transaction(
            0, OURGASPRICE, BASIC_SEND_GAS_LIMIT, rec_bin(commitAddressBob),
            (BID_AMOUNT_Bob + extraTransactionFees),
            b'').sign(BOB_PRIVATE_KEY)
        commit_gasBob = int(self.chain.head_state.gas_used)

        self.chain.direct_tx(commit_tx_objectBob)
        self.chain.mine(1)

        commit_tx_objectCharlie = transactions.Transaction(
            0, OURGASPRICE, BASIC_SEND_GAS_LIMIT, rec_bin(commitAddressCharlie),
            (BID_AMOUNT_Charlie + extraTransactionFees),
            b'').sign(CHARLIE_PRIVATE_KEY)
        commit_gasCharlie = int(self.chain.head_state.gas_used)

        self.chain.direct_tx(commit_tx_objectCharlie)
        self.chain.mine(1)

        ##
        ## CHECK STATE AFTER COMMIT TX
        ##
        commit_block_numberAlice, commit_block_indexAlice = self.chain.chain.get_tx_position(
            commit_tx_objectAlice)
        self.assertEqual(BID_AMOUNT_Alice + extraTransactionFees,
                         self.chain.head_state.get_balance(commitAddressAlice))
        self.assertEqual(
            ACCOUNT_STARTING_BALANCE - (BID_AMOUNT_Alice + extraTransactionFees +
                                        BASIC_SEND_GAS_LIMIT * OURGASPRICE),
            self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS)))

        session_dataAlice = self.auction_contract.getSubmarineState(rec_bin(commitAlice))
        self.assertListEqual(session_dataAlice,
                [SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL])

        revealedAndUnlocked_boolAlice = self.auction_contract.revealedAndUnlocked(rec_bin(commitAlice))
        self.assertFalse(
            revealedAndUnlocked_boolAlice,
            "The contract should not be revealedAndUnlocked before it's even begun.")



        commit_block_numberBob, commit_block_indexBob = self.chain.chain.get_tx_position(
            commit_tx_objectBob)
        self.assertEqual(BID_AMOUNT_Bob + extraTransactionFees,
                         self.chain.head_state.get_balance(commitAddressBob))
        self.assertEqual(
            ACCOUNT_STARTING_BALANCE - (BID_AMOUNT_Bob + extraTransactionFees +
                                        BASIC_SEND_GAS_LIMIT * OURGASPRICE),
            self.chain.head_state.get_balance(rec_hex(BOB_ADDRESS)))

        session_dataBob = self.auction_contract.getSubmarineState(rec_bin(commitBob))
        self.assertListEqual(session_dataBob,
                [SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL])

        revealedAndUnlocked_boolBob = self.auction_contract.revealedAndUnlocked(rec_bin(commitBob))
        self.assertFalse(
            revealedAndUnlocked_boolBob,
            "The contract should not be revealedAndUnlocked before it's even begun.")

        commit_block_numberCharlie, commit_block_indexCharlie = self.chain.chain.get_tx_position(
            commit_tx_objectCharlie)
        self.assertEqual(BID_AMOUNT_Charlie + extraTransactionFees,
                         self.chain.head_state.get_balance(commitAddressCharlie))
        self.assertEqual(
            ACCOUNT_STARTING_BALANCE - (BID_AMOUNT_Charlie + extraTransactionFees +
                                        BASIC_SEND_GAS_LIMIT * OURGASPRICE),
            self.chain.head_state.get_balance(rec_hex(CHARLIE_ADDRESS)))

        session_dataCharlie = self.auction_contract.getSubmarineState(rec_bin(commitCharlie))
        self.assertListEqual(session_dataCharlie,
                [SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL])

        revealedAndUnlocked_boolCharlie = self.auction_contract.revealedAndUnlocked(rec_bin(commitCharlie))
        self.assertFalse(
            revealedAndUnlocked_boolCharlie,
            "The contract should not be revealedAndUnlocked before it's even begun.")

        ##
        ## GENERATE AND BROADCAST REVEAL BID TXS
        ##
        self.chain.mine(COMMIT_PERIOD_LENGTH + 1)

        commit_block_objectAlice = self.chain.chain.get_block_by_number(commit_block_numberAlice)
        proveth_expected_block_format_dictAlice = dict()
        proveth_expected_block_format_dictAlice['parentHash'] = commit_block_objectAlice['prevhash']
        proveth_expected_block_format_dictAlice['sha3Uncles'] = commit_block_objectAlice['uncles_hash']
        proveth_expected_block_format_dictAlice['miner'] = commit_block_objectAlice['coinbase']
        proveth_expected_block_format_dictAlice['stateRoot'] = commit_block_objectAlice['state_root']
        proveth_expected_block_format_dictAlice['transactionsRoot'] = commit_block_objectAlice['tx_list_root']
        proveth_expected_block_format_dictAlice['receiptsRoot'] = commit_block_objectAlice['receipts_root']
        proveth_expected_block_format_dictAlice['logsBloom'] = commit_block_objectAlice['bloom']
        proveth_expected_block_format_dictAlice['difficulty'] = commit_block_objectAlice['difficulty']
        proveth_expected_block_format_dictAlice['number'] = commit_block_objectAlice['number']
        proveth_expected_block_format_dictAlice['gasLimit'] = commit_block_objectAlice['gas_limit']
        proveth_expected_block_format_dictAlice['gasUsed'] = commit_block_objectAlice['gas_used']
        proveth_expected_block_format_dictAlice['timestamp'] = commit_block_objectAlice['timestamp']
        proveth_expected_block_format_dictAlice['extraData'] = commit_block_objectAlice['extra_data']
        proveth_expected_block_format_dictAlice['mixHash'] = commit_block_objectAlice['mixhash']
        proveth_expected_block_format_dictAlice['nonce'] = commit_block_objectAlice['nonce']
        proveth_expected_block_format_dictAlice['hash'] = commit_block_objectAlice.hash
        proveth_expected_block_format_dictAlice['uncles'] = []
        proveth_expected_block_format_dictAlice['transactions'] = ({
            "blockHash":          commit_block_objectAlice.hash,
            "blockNumber":        str(hex((commit_block_objectAlice['number']))),
            "from":               checksum_encode(ALICE_ADDRESS),
            "gas":                str(hex(commit_tx_objectAlice['startgas'])),
            "gasPrice":           str(hex(commit_tx_objectAlice['gasprice'])),
            "hash":               rec_hex(commit_tx_objectAlice['hash']),
            "input":              rec_hex(commit_tx_objectAlice['data']),
            "nonce":              str(hex(commit_tx_objectAlice['nonce'])),
            "to":                 checksum_encode(commit_tx_objectAlice['to']),
            "transactionIndex":   str(hex(0)),
            "value":              str(hex(commit_tx_objectAlice['value'])),
            "v":                  str(hex(commit_tx_objectAlice['v'])),
            "r":                  str(hex(commit_tx_objectAlice['r'])),
            "s":                  str(hex(commit_tx_objectAlice['s']))
        }, )

        commit_proof_blobAlice = proveth.generate_proof_blob(
            proveth_expected_block_format_dictAlice, commit_block_indexAlice)
        _unlockExtraData = b''  # In this example we dont have any extra embedded data as part of the unlock TX


        unlock_tx_unsigned_objectAlice = transactions.UnsignedTransaction(
            int.from_bytes(unlock_tx_infoAlice[0], byteorder="big"),  # nonce;
            int.from_bytes(unlock_tx_infoAlice[1], byteorder="big"),  # gasprice
            int.from_bytes(unlock_tx_infoAlice[2], byteorder="big"),  # startgas
            unlock_tx_infoAlice[3],  # to addr
            int.from_bytes(unlock_tx_infoAlice[4], byteorder="big"),  # value
            unlock_tx_infoAlice[5],  # data
        )
        unlock_tx_unsigned_rlpAlice = rlp.encode(unlock_tx_unsigned_objectAlice, transactions.UnsignedTransaction)


        self.auction_contract.reveal(
            commit_block_numberAlice,  # uint32 _commitBlockNumber,
            _unlockExtraData,  # bytes _commitData,
            rec_bin(witnessAlice),  # bytes32 _witness,
            unlock_tx_unsigned_rlpAlice,  # bytes _rlpUnlockTxUnsigned,
            commit_proof_blobAlice,  # bytes _proofBlob
            sender=ALICE_PRIVATE_KEY)
        reveal_gasAlice = int(self.chain.head_state.gas_used)

        self.chain.mine(1)

        commit_block_objectBob = self.chain.chain.get_block_by_number(commit_block_numberBob)
        proveth_expected_block_format_dictBob = dict()
        proveth_expected_block_format_dictBob['parentHash'] = commit_block_objectBob['prevhash']
        proveth_expected_block_format_dictBob['sha3Uncles'] = commit_block_objectBob['uncles_hash']
        proveth_expected_block_format_dictBob['miner'] = commit_block_objectBob['coinbase']
        proveth_expected_block_format_dictBob['stateRoot'] = commit_block_objectBob['state_root']
        proveth_expected_block_format_dictBob['transactionsRoot'] = commit_block_objectBob['tx_list_root']
        proveth_expected_block_format_dictBob['receiptsRoot'] = commit_block_objectBob['receipts_root']
        proveth_expected_block_format_dictBob['logsBloom'] = commit_block_objectBob['bloom']
        proveth_expected_block_format_dictBob['difficulty'] = commit_block_objectBob['difficulty']
        proveth_expected_block_format_dictBob['number'] = commit_block_objectBob['number']
        proveth_expected_block_format_dictBob['gasLimit'] = commit_block_objectBob['gas_limit']
        proveth_expected_block_format_dictBob['gasUsed'] = commit_block_objectBob['gas_used']
        proveth_expected_block_format_dictBob['timestamp'] = commit_block_objectBob['timestamp']
        proveth_expected_block_format_dictBob['extraData'] = commit_block_objectBob['extra_data']
        proveth_expected_block_format_dictBob['mixHash'] = commit_block_objectBob['mixhash']
        proveth_expected_block_format_dictBob['nonce'] = commit_block_objectBob['nonce']
        proveth_expected_block_format_dictBob['hash'] = commit_block_objectBob.hash
        proveth_expected_block_format_dictBob['uncles'] = []
        proveth_expected_block_format_dictBob['transactions'] = ({
            "blockHash":          commit_block_objectBob.hash,
            "blockNumber":        str(hex((commit_block_objectBob['number']))),
            "from":               checksum_encode(BOB_ADDRESS),
            "gas":                str(hex(commit_tx_objectBob['startgas'])),
            "gasPrice":           str(hex(commit_tx_objectBob['gasprice'])),
            "hash":               rec_hex(commit_tx_objectBob['hash']),
            "input":              rec_hex(commit_tx_objectBob['data']),
            "nonce":              str(hex(commit_tx_objectBob['nonce'])),
            "to":                 checksum_encode(commit_tx_objectBob['to']),
            "transactionIndex":   str(hex(0)),
            "value":              str(hex(commit_tx_objectBob['value'])),
            "v":                  str(hex(commit_tx_objectBob['v'])),
            "r":                  str(hex(commit_tx_objectBob['r'])),
            "s":                  str(hex(commit_tx_objectBob['s']))
        }, )

        commit_proof_blobBob = proveth.generate_proof_blob(
            proveth_expected_block_format_dictBob, commit_block_indexBob)
        _unlockExtraData = b''  # In this example we dont have any extra embedded data as part of the unlock TX


        unlock_tx_unsigned_objectBob = transactions.UnsignedTransaction(
            int.from_bytes(unlock_tx_infoBob[0], byteorder="big"),  # nonce;
            int.from_bytes(unlock_tx_infoBob[1], byteorder="big"),  # gasprice
            int.from_bytes(unlock_tx_infoBob[2], byteorder="big"),  # startgas
            unlock_tx_infoBob[3],  # to addr
            int.from_bytes(unlock_tx_infoBob[4], byteorder="big"),  # value
            unlock_tx_infoBob[5],  # data
        )
        unlock_tx_unsigned_rlpBob = rlp.encode(unlock_tx_unsigned_objectBob, transactions.UnsignedTransaction)


        self.auction_contract.reveal(
            commit_block_numberBob,  # uint32 _commitBlockNumber,
            _unlockExtraData,  # bytes _commitData,
            rec_bin(witnessBob),  # bytes32 _witness,
            unlock_tx_unsigned_rlpBob,  # bytes _rlpUnlockTxUnsigned,
            commit_proof_blobBob,  # bytes _proofBlob
            sender=BOB_PRIVATE_KEY)
        reveal_gasBob = int(self.chain.head_state.gas_used)

        self.chain.mine(1)

        commit_block_objectCharlie = self.chain.chain.get_block_by_number(commit_block_numberCharlie)
        proveth_expected_block_format_dictCharlie = dict()
        proveth_expected_block_format_dictCharlie['parentHash'] = commit_block_objectCharlie['prevhash']
        proveth_expected_block_format_dictCharlie['sha3Uncles'] = commit_block_objectCharlie['uncles_hash']
        proveth_expected_block_format_dictCharlie['miner'] = commit_block_objectCharlie['coinbase']
        proveth_expected_block_format_dictCharlie['stateRoot'] = commit_block_objectCharlie['state_root']
        proveth_expected_block_format_dictCharlie['transactionsRoot'] = commit_block_objectCharlie['tx_list_root']
        proveth_expected_block_format_dictCharlie['receiptsRoot'] = commit_block_objectCharlie['receipts_root']
        proveth_expected_block_format_dictCharlie['logsBloom'] = commit_block_objectCharlie['bloom']
        proveth_expected_block_format_dictCharlie['difficulty'] = commit_block_objectCharlie['difficulty']
        proveth_expected_block_format_dictCharlie['number'] = commit_block_objectCharlie['number']
        proveth_expected_block_format_dictCharlie['gasLimit'] = commit_block_objectCharlie['gas_limit']
        proveth_expected_block_format_dictCharlie['gasUsed'] = commit_block_objectCharlie['gas_used']
        proveth_expected_block_format_dictCharlie['timestamp'] = commit_block_objectCharlie['timestamp']
        proveth_expected_block_format_dictCharlie['extraData'] = commit_block_objectCharlie['extra_data']
        proveth_expected_block_format_dictCharlie['mixHash'] = commit_block_objectCharlie['mixhash']
        proveth_expected_block_format_dictCharlie['nonce'] = commit_block_objectCharlie['nonce']
        proveth_expected_block_format_dictCharlie['hash'] = commit_block_objectCharlie.hash
        proveth_expected_block_format_dictCharlie['uncles'] = []
        proveth_expected_block_format_dictCharlie['transactions'] = ({
            "blockHash":          commit_block_objectCharlie.hash,
            "blockNumber":        str(hex((commit_block_objectCharlie['number']))),
            "from":               checksum_encode(CHARLIE_ADDRESS),
            "gas":                str(hex(commit_tx_objectCharlie['startgas'])),
            "gasPrice":           str(hex(commit_tx_objectCharlie['gasprice'])),
            "hash":               rec_hex(commit_tx_objectCharlie['hash']),
            "input":              rec_hex(commit_tx_objectCharlie['data']),
            "nonce":              str(hex(commit_tx_objectCharlie['nonce'])),
            "to":                 checksum_encode(commit_tx_objectCharlie['to']),
            "transactionIndex":   str(hex(0)),
            "value":              str(hex(commit_tx_objectCharlie['value'])),
            "v":                  str(hex(commit_tx_objectCharlie['v'])),
            "r":                  str(hex(commit_tx_objectCharlie['r'])),
            "s":                  str(hex(commit_tx_objectCharlie['s']))
        }, )

        commit_proof_blobCharlie = proveth.generate_proof_blob(
            proveth_expected_block_format_dictCharlie, commit_block_indexCharlie)
        _unlockExtraData = b''  # In this example we dont have any extra embedded data as part of the unlock TX


        unlock_tx_unsigned_objectCharlie = transactions.UnsignedTransaction(
            int.from_bytes(unlock_tx_infoCharlie[0], byteorder="big"),  # nonce;
            int.from_bytes(unlock_tx_infoCharlie[1], byteorder="big"),  # gasprice
            int.from_bytes(unlock_tx_infoCharlie[2], byteorder="big"),  # startgas
            unlock_tx_infoCharlie[3],  # to addr
            int.from_bytes(unlock_tx_infoCharlie[4], byteorder="big"),  # value
            unlock_tx_infoCharlie[5],  # data
        )
        unlock_tx_unsigned_rlpCharlie = rlp.encode(unlock_tx_unsigned_objectCharlie, transactions.UnsignedTransaction)


        self.auction_contract.reveal(
            commit_block_numberCharlie,  # uint32 _commitBlockNumber,
            _unlockExtraData,  # bytes _commitData,
            rec_bin(witnessCharlie),  # bytes32 _witness,
            unlock_tx_unsigned_rlpCharlie,  # bytes _rlpUnlockTxUnsigned,
            commit_proof_blobCharlie,  # bytes _proofBlob
            sender=CHARLIE_PRIVATE_KEY)
        reveal_gasCharlie = int(self.chain.head_state.gas_used)

        self.chain.mine(1)

        ##
        ## CHECK THE STATE AFTER REVEAL
        ##
        bidRecordAlice = self.auction_contract.bidders(rec_bin(commitAlice))
        self.assertEqual(rec_hex(ALICE_ADDRESS), bidRecordAlice)
        session_dataAlice = self.auction_contract.getSubmarineState(rec_bin(commitAlice))
        self.assertListEqual(session_dataAlice, [BID_AMOUNT_Alice, SOLIDITY_NULL_INITIALVAL, commit_block_numberAlice, commit_block_indexAlice])
        revealedAndUnlocked_boolAlice = self.auction_contract.revealedAndUnlocked(rec_bin(commitAlice))
        self.assertFalse(revealedAndUnlocked_boolAlice)

        bidRecordBob = self.auction_contract.bidders(rec_bin(commitBob))
        self.assertEqual(rec_hex(BOB_ADDRESS), bidRecordBob)
        session_dataBob = self.auction_contract.getSubmarineState(rec_bin(commitBob))
        self.assertListEqual(session_dataBob, [BID_AMOUNT_Bob, SOLIDITY_NULL_INITIALVAL, commit_block_numberBob, commit_block_indexBob])
        revealedAndUnlocked_boolBob = self.auction_contract.revealedAndUnlocked(rec_bin(commitBob))
        self.assertFalse(revealedAndUnlocked_boolBob)

        bidRecordCharlie = self.auction_contract.bidders(rec_bin(commitCharlie))
        self.assertEqual(rec_hex(CHARLIE_ADDRESS), bidRecordCharlie)
        session_dataCharlie = self.auction_contract.getSubmarineState(rec_bin(commitCharlie))
        self.assertListEqual(session_dataCharlie, [BID_AMOUNT_Charlie, SOLIDITY_NULL_INITIALVAL, commit_block_numberCharlie, commit_block_indexCharlie])
        revealedAndUnlocked_boolCharlie = self.auction_contract.revealedAndUnlocked(rec_bin(commitCharlie))
        self.assertFalse(revealedAndUnlocked_boolCharlie)

        ##
        ## BROADCAST UNLOCK
        ##
        self.chain.mine(1)
        self.chain.direct_tx(unlock_tx_objectAlice)
        unlock_gasAlice = int(self.chain.head_state.gas_used)
        self.chain.mine(1)

        self.chain.mine(1)
        self.chain.direct_tx(unlock_tx_objectBob)
        unlock_gasBob = int(self.chain.head_state.gas_used)
        self.chain.mine(1)

        self.chain.mine(1)
        self.chain.direct_tx(unlock_tx_objectCharlie)
        unlock_gasCharlie = int(self.chain.head_state.gas_used)
        self.chain.mine(1)

        ##
        ## CHECK STATE AFTER UNLOCK
        ##

        # # stuff to help with debugging
        # # unlock_block_numberAlice, unlock_block_indexAlice = self.chain.chain.get_tx_position(
        # #         unlock_tx_objectAlice)
        # # unlock_block_objectAlice = self.chain.chain.get_block_by_number(unlock_block_numberAlice)
        # # print(unlock_block_objectAlice.as_dict())

        self.assertEqual(
            self.chain.head_state.get_balance(commitAddressAlice),
            (extraTransactionFees - unlock_gasAlice*OURGASPRICE),
            "Commit address should send along the money and have almost 0 money left."
        )

        self.assertEqual(
            self.chain.head_state.get_balance(commitAddressBob),
            (extraTransactionFees - unlock_gasBob*OURGASPRICE),
            "Commit address should send along the money and have almost 0 money left."
        )

        self.assertEqual(
            self.chain.head_state.get_balance(commitAddressCharlie),
            (extraTransactionFees - unlock_gasCharlie*OURGASPRICE),
            "Commit address should send along the money and have almost 0 money left."
        )

        self.assertEqual(
            self.chain.head_state.get_balance(self.auction_contract.address),
            (BID_AMOUNT_Alice + BID_AMOUNT_Bob + BID_AMOUNT_Charlie),
            "Contract address should have the sum of the bids balance."
        )


        session_dataAlice = self.auction_contract.getSubmarineState(rec_bin(commitAlice))
        self.assertListEqual(session_dataAlice, [BID_AMOUNT_Alice, BID_AMOUNT_Alice, commit_block_numberAlice, commit_block_indexAlice])
        revealedAndUnlocked_boolAlice = self.auction_contract.revealedAndUnlocked(rec_bin(commitAlice))
        self.assertTrue(revealedAndUnlocked_boolAlice)

        session_dataBob = self.auction_contract.getSubmarineState(rec_bin(commitBob))
        self.assertListEqual(session_dataBob, [BID_AMOUNT_Bob, BID_AMOUNT_Bob, commit_block_numberBob, commit_block_indexBob])
        revealedAndUnlocked_boolBob = self.auction_contract.revealedAndUnlocked(rec_bin(commitBob))
        self.assertTrue(revealedAndUnlocked_boolBob)

        session_dataCharlie = self.auction_contract.getSubmarineState(rec_bin(commitCharlie))
        self.assertListEqual(session_dataCharlie, [BID_AMOUNT_Charlie, BID_AMOUNT_Charlie, commit_block_numberCharlie, commit_block_indexCharlie])
        revealedAndUnlocked_boolCharlie = self.auction_contract.revealedAndUnlocked(rec_bin(commitCharlie))
        self.assertTrue(revealedAndUnlocked_boolCharlie)

        ##
        ## END AUCTION
        ##

        self.chain.mine(REVEAL_PERIOD_LENGTH)
        self.auction_contract.finalize(rec_bin(commitAlice), sender=ALICE_PRIVATE_KEY)
        self.auction_contract.finalize(rec_bin(commitBob), sender=BOB_PRIVATE_KEY)
        self.auction_contract.finalize(rec_bin(commitCharlie), sender=CHARLIE_PRIVATE_KEY)

        # ##
        # ## CHECK STATE NOW THAT AUCTION IS OVER

        self.assertEqual(commitCharlie, self.auction_contract.winningSubmarineId().hex())

        self.assertEqual(
            ACCOUNT_STARTING_BALANCE - (extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE),
            self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS)))

        self.assertEqual(
            ACCOUNT_STARTING_BALANCE - (extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE),
            self.chain.head_state.get_balance(rec_hex(BOB_ADDRESS)))

        self.assertEqual(
            ACCOUNT_STARTING_BALANCE - (BID_AMOUNT_Charlie + extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE),
            self.chain.head_state.get_balance(rec_hex(CHARLIE_ADDRESS)))

        self.assertEqual(starting_owner_eth_holdings + BID_AMOUNT_Charlie, self.chain.head_state.get_balance(rec_hex(CONTRACT_OWNER_ADDRESS)))
Example #4
0
    def test_spam_unlock_large_spam(self):
        ##
        ## STARTING STATE
        ##
        ALICE_ADDRESS = t.a1
        ALICE_PRIVATE_KEY = t.k1
        SPAM_PRIVATE_KEY_MALLORY = t.k7


        self.chain.mine(1)

        ##
        ## GENERATE UNLOCK TX
        ##
        addressB, commit, witness, unlock_tx_hex = generate_submarine_commit.generateCommitAddress(
            normalize_address(rec_hex(ALICE_ADDRESS)),
            normalize_address(rec_hex(self.verifier_contract.address)),
            UNLOCK_AMOUNT, b'', OURGASPRICE, OURGASLIMIT)

        unlock_tx_info = rlp.decode(rec_bin(unlock_tx_hex))

        unlock_tx_object = transactions.Transaction(
            int.from_bytes(unlock_tx_info[0], byteorder="big"),  # nonce;
            int.from_bytes(unlock_tx_info[1], byteorder="big"),  # gasprice
            int.from_bytes(unlock_tx_info[2], byteorder="big"),  # startgas
            unlock_tx_info[3],                                   # to addr
            int.from_bytes(unlock_tx_info[4], byteorder="big"),  # value
            unlock_tx_info[5],                                   # data
            int.from_bytes(unlock_tx_info[6], byteorder="big"),  # v
            int.from_bytes(unlock_tx_info[7], byteorder="big"),  # r
            int.from_bytes(unlock_tx_info[8], byteorder="big")   # s
        )
        unlock_tx_unsigned_object = transactions.UnsignedTransaction(
            int.from_bytes(unlock_tx_info[0], byteorder="big"),  # nonce;
            int.from_bytes(unlock_tx_info[1], byteorder="big"),  # gasprice
            int.from_bytes(unlock_tx_info[2], byteorder="big"),  # startgas
            unlock_tx_info[3],  # to addr
            int.from_bytes(unlock_tx_info[4], byteorder="big"),  # value
            unlock_tx_info[5],  # data
        )

        unlock_tx_unsigned_rlp = rlp.encode(unlock_tx_unsigned_object, transactions.UnsignedTransaction)



        ##
        ## SPAM THE UNLOCK FUNCTION
        ##
        SPAM_AMOUNT = UNLOCK_AMOUNT + 3235
        spam_tx_object = transactions.Transaction(
            0,
            OURGASPRICE,
            OURGASLIMIT,
            normalize_address(rec_hex(self.verifier_contract.address)),
            SPAM_AMOUNT,
            unlock_tx_object[5]).sign(SPAM_PRIVATE_KEY_MALLORY)

        self.chain.direct_tx(spam_tx_object)
        session_data = self.verifier_contract.getSubmarineState(rec_bin(commit))
        self.assertListEqual(session_data, [SOLIDITY_NULL_INITIALVAL, SPAM_AMOUNT, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL])
        self.chain.mine(1)

        ##
        ## GENERATE COMMIT
        ##
        commit_tx_object = transactions.Transaction(
            0, OURGASPRICE, BASIC_SEND_GAS_LIMIT, rec_bin(addressB),
            (UNLOCK_AMOUNT + extraTransactionFees),
            b'').sign(ALICE_PRIVATE_KEY)

        self.chain.direct_tx(commit_tx_object)

        self.chain.mine(4)

        session_data = self.verifier_contract.getSubmarineState(rec_bin(commit))
        self.assertListEqual(session_data, [SOLIDITY_NULL_INITIALVAL, SPAM_AMOUNT, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL])

        finished_bool = self.verifier_contract.revealedAndUnlocked(rec_bin(commit))
        self.assertFalse(
            finished_bool,
            "The contract should not be finished until after the reveal.")

        commit_block_number, commit_block_index = self.chain.chain.get_tx_position(commit_tx_object)

        ##
        ## BROADCAST UNLOCK (this should cause an exception since someone else donated money to your cause)
        ##
        with self.assertRaises(t.TransactionFailed):
            self.chain.direct_tx(unlock_tx_object)

        ##
        ## CHECK STATE AFTER UNLOCK
        ##
        session_data = self.verifier_contract.getSubmarineState(rec_bin(commit))
        self.assertListEqual(
            session_data, [SOLIDITY_NULL_INITIALVAL, SPAM_AMOUNT, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL],
            "State does not match expected value after unlock.")

        finished_bool = self.verifier_contract.revealedAndUnlocked(rec_bin(commit))
        self.assertFalse(finished_bool)

        ##
        ## GENERATE AND BROADCAST REVEAL TX
        ##
        assert (isinstance(witness, str))
        commit_block_object = self.chain.chain.get_block_by_number(
            commit_block_number)
        log.info("Block information: {}".format(
            str(commit_block_object.as_dict())))
        log.info("Block header: {}".format(
            str(commit_block_object.as_dict()['header'].as_dict())))
        log.info("Block transactions: {}".format(
            str(commit_block_object.as_dict()['transactions'][0].as_dict())))

        proveth_commit_block = proveth_compatible_commit_block(commit_block_object, commit_tx_object)
        commit_proof_blob = proveth.generate_proof_blob(
            proveth_commit_block, commit_block_index)
        log.info("Proof Blob generate by proveth.py: {}".format(
            rec_hex(commit_proof_blob)))

        # Solidity Event log listener
        def _event_listener(llog):
            log.info('Solidity Event listener log fire: {}'.format(str(llog)))
            log.info('Solidity Event listener log fire hex: {}'.format(
                str(rec_hex(llog['data']))))

        self.chain.head_state.log_listeners.append(_event_listener)
        _unlockExtraData = b''  # In this example we dont have any extra embedded data as part of the unlock TX

        self.chain.mine(20)
        self.verifier_contract.reveal(
            #print(
            commit_block_number,  # uint32 _commitBlockNumber,
            _unlockExtraData,  # bytes _commitData,
            rec_bin(witness),  # bytes32 _witness,
            unlock_tx_unsigned_rlp,  # bytes _rlpUnlockTxUnsigned,
            commit_proof_blob,  # bytes _proofBlob
            sender=ALICE_PRIVATE_KEY)

        log.info("Reveal TX Gas Used HeadState {}".format(
            self.chain.head_state.gas_used))
        reveal_gas = int(self.chain.head_state.gas_used)

        self.chain.mine(1)

        ##
        ## CHECK STATE AFTER REVEAL TX
        ##
        session_data = self.verifier_contract.getSubmarineState(rec_bin(commit))
        self.assertListEqual(
            session_data, [UNLOCK_AMOUNT, SPAM_AMOUNT, commit_block_number, commit_block_index],
            "After the Reveal, the state should report both revealed and unlocked."
        )
        finished_bool = self.verifier_contract.revealedAndUnlocked(rec_bin(commit))
        self.assertTrue(
            finished_bool,
            "The contract was unlocked first and then revealed, it should be finished"
        )
Example #5
0
    def test_workflow(self):
        ##
        ## STARTING STATE
        ##
        ALICE_ADDRESS = t.a1
        ALICE_PRIVATE_KEY = t.k1

        log.info("Contract Address: {}".format(
            rec_hex(self.verifier_contract.address)))
        log.info("State: Starting A1 has {} and has address {}".format(
            self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS)),
            rec_hex(ALICE_ADDRESS)))

        self.chain.mine(1)

        ##
        ## GENERATE UNLOCK AND BROADCAST TX, THEN BROADCAST JUST COMMIT TX
        ##
        addressB, commit, witness, unlock_tx_hex = generate_submarine_commit.generateCommitAddress(
            normalize_address(rec_hex(ALICE_ADDRESS)),
            normalize_address(rec_hex(self.verifier_contract.address)),
            UNLOCK_AMOUNT, b'', OURGASPRICE, OURGASLIMIT)
        log.info("Precomputed address of commit target: {}".format(addressB))

        assert (isinstance(witness, str))

        unlock_tx_info = rlp.decode(rec_bin(unlock_tx_hex))
        log.info("Unlock tx hex object: {}".format(rec_hex(unlock_tx_info)))

        unlock_tx_object = transactions.Transaction(
            int.from_bytes(unlock_tx_info[0], byteorder="big"),  # nonce;
            int.from_bytes(unlock_tx_info[1], byteorder="big"),  # gasprice
            int.from_bytes(unlock_tx_info[2], byteorder="big"),  # startgas
            unlock_tx_info[3],  # to addr
            int.from_bytes(unlock_tx_info[4], byteorder="big"),  # value
            unlock_tx_info[5],  # data
            int.from_bytes(unlock_tx_info[6], byteorder="big"),  # v
            int.from_bytes(unlock_tx_info[7], byteorder="big"),  # r
            int.from_bytes(unlock_tx_info[8], byteorder="big")  # s
        )
        log.info("Unlock tx hash: {}".format(rec_hex(unlock_tx_object.hash)))
        unlock_tx_unsigned_object = transactions.UnsignedTransaction(
            int.from_bytes(unlock_tx_info[0], byteorder="big"),  # nonce;
            int.from_bytes(unlock_tx_info[1], byteorder="big"),  # gasprice
            int.from_bytes(unlock_tx_info[2], byteorder="big"),  # startgas
            unlock_tx_info[3],  # to addr
            int.from_bytes(unlock_tx_info[4], byteorder="big"),  # value
            unlock_tx_info[5],  # data
        )

        unlock_tx_unsigned_rlp = rlp.encode(unlock_tx_unsigned_object, transactions.UnsignedTransaction)

        commit_tx_object = transactions.Transaction(
            0, OURGASPRICE, BASIC_SEND_GAS_LIMIT, rec_bin(addressB),
            (UNLOCK_AMOUNT + extraTransactionFees),
            b'').sign(ALICE_PRIVATE_KEY)
        log.info("Commit TX Object: {}".format(
            str(commit_tx_object.to_dict())))
        log.info("Commit TX gas used Intrinsic: {}".format(
            str(commit_tx_object.intrinsic_gas_used)))
        commit_gas = int(self.chain.head_state.gas_used)

        self.chain.direct_tx(commit_tx_object)
        log.info("Commit TX Gas Used HeadState {}".format(
            self.chain.head_state.gas_used))
        self.chain.mine(1)


        ##
        ## CHECK STATE AFTER COMMIT TX
        ##
        commit_block_number, commit_block_index = self.chain.chain.get_tx_position(
            commit_tx_object)
        log.info("Commit Tx block number {} and tx block index {}".format(
            commit_block_number, commit_block_index))
        log.info("State: After commit A1 has {} and has address {}".format(
            self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS)),
            rec_hex(ALICE_ADDRESS)))
        log.info("State: After commit B has {} and has address {}".format(
            self.chain.head_state.get_balance(addressB), addressB))
        self.assertEqual(UNLOCK_AMOUNT + extraTransactionFees,
                         self.chain.head_state.get_balance(addressB))
        self.assertEqual(
            ACCOUNT_STARTING_BALANCE - (UNLOCK_AMOUNT + extraTransactionFees +
                                        BASIC_SEND_GAS_LIMIT * OURGASPRICE),
            self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS)))

        session_data = self.verifier_contract.getSubmarineState(rec_bin(commit))
        self.assertListEqual(
            session_data, [SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL],
            "The contract should not know anything about the commit until after it's been revealed... "
        )

        finished_bool = self.verifier_contract.revealedAndUnlocked(rec_bin(commit))
        self.assertFalse(
            finished_bool,
            "The contract should not be finished before it's even begun.")

        ##
        ## GENERATE AND BROADCAST REVEAL TX
        ##
        commit_block_object = self.chain.chain.get_block_by_number(
            commit_block_number)
        log.info("Block information: {}".format(
            str(commit_block_object.as_dict())))
        log.info("Block header: {}".format(
            str(commit_block_object.as_dict()['header'].as_dict())))
        log.info("Block transactions: {}".format(
            str(commit_block_object.as_dict()['transactions'][0].as_dict())))

        proveth_commit_block = proveth_compatible_commit_block(commit_block_object, commit_tx_object)
        commit_proof_blob = proveth.generate_proof_blob(
            proveth_commit_block, commit_block_index)

        log.info("Proof Blob generate by proveth.py: {}".format(
            rec_hex(commit_proof_blob)))

        # Solidity Event log listener
        def _event_listener(llog):
            log.info('Solidity Event listener log fire: {}'.format(str(llog)))
            log.info('Solidity Event listener log fire hex: {}'.format(
                str(rec_hex(llog['data']))))

        self.chain.head_state.log_listeners.append(_event_listener)
        _unlockExtraData = b''  # In this example we dont have any extra embedded data as part of the unlock TX

        self.chain.mine(20)
        self.verifier_contract.reveal(
            #print(
            commit_block_number,  # uint32 _commitBlockNumber,
            _unlockExtraData,  # bytes _commitData,
            rec_bin(witness),  # bytes32 _witness,
            unlock_tx_unsigned_rlp,  # bytes _rlpUnlockTxUnsigned,
            commit_proof_blob,  # bytes _proofBlob
            sender=ALICE_PRIVATE_KEY)
        log.info("Reveal TX Gas Used HeadState {}".format(
            self.chain.head_state.gas_used))
        reveal_gas = int(self.chain.head_state.gas_used)

        self.chain.mine(1)

        ##
        ## CHECK STATE AFTER REVEAL TX
        ##
        session_data = self.verifier_contract.getSubmarineState(rec_bin(commit))
        self.assertListEqual(
            session_data, [UNLOCK_AMOUNT, SOLIDITY_NULL_INITIALVAL, commit_block_number, commit_block_index ],
            "After the Reveal, the state should report revealed but not unlocked."
        )
        finished_bool = self.verifier_contract.revealedAndUnlocked(rec_bin(commit))
        self.assertFalse(
            finished_bool,
            "The contract is only revealed, not unlocked and therefore finished."
        )

        ##
        ## BROADCAST UNLOCK
        ##
        self.chain.direct_tx(unlock_tx_object)
        log.info("Unlock TX Gas Used HeadState {}".format(
            self.chain.head_state.gas_used))
        unlock_gas = int(self.chain.head_state.gas_used)

        ##
        ## CHECK STATE AFTER UNLOCK
        ##
        log.info("State: After unlock B has {} and has address {}".format(
            self.chain.head_state.get_balance(addressB), addressB))

        self.assertLess(
            self.chain.head_state.get_balance(addressB),
            UNLOCK_AMOUNT + extraTransactionFees,
            "Address B should send along the money and have almost 0 money left."
        )
        self.assertEqual(
            999998562999979000000000,
            self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS)))

        session_data = self.verifier_contract.getSubmarineState(rec_bin(commit))
        self.assertListEqual(
            session_data, [UNLOCK_AMOUNT, UNLOCK_AMOUNT, commit_block_number, commit_block_index ],
            "State does not match expected value after unlock.")

        finished_bool = self.verifier_contract.revealedAndUnlocked(rec_bin(commit))
        self.assertTrue(finished_bool,
                        "After unlock, contract should be finished.")

        sumGas = commit_gas + reveal_gas + unlock_gas
        log.info("Final Gas Estimation {}".format(str(sumGas)))
    def test_auctionWorkflow(self):
        ##
        ## STARTING STATE
        ##
        starting_block_height = self.chain.head_state.block_number
        starting_owner_eth_holdings = self.chain.head_state.get_balance(
            rec_hex(CONTRACT_OWNER_ADDRESS))
        self.chain.mine(1)

        self.assertEqual(
            ACCOUNT_STARTING_BALANCE,
            self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS)))
        self.assertEqual(
            ACCOUNT_STARTING_BALANCE,
            self.chain.head_state.get_balance(rec_hex(BOB_ADDRESS)))
        self.assertEqual(
            ACCOUNT_STARTING_BALANCE,
            self.chain.head_state.get_balance(rec_hex(CHARLIE_ADDRESS)))
        self.assertEqual(27, self.verifier_contract.vee())
        self.assertEqual(COMMIT_PERIOD_LENGTH,
                         self.verifier_contract.commitPeriodLength())
        self.assertEqual(REVEAL_PERIOD_LENGTH,
                         self.verifier_contract.revealPeriodLength())
        self.assertEqual(
            starting_block_height + COMMIT_PERIOD_LENGTH +
            REVEAL_PERIOD_LENGTH, self.verifier_contract.auctionEndBlock())

        #
        # GENERATE UNLOCK TXs
        #
        commitAddressAlice, commitAlice, witnessAlice, unlock_tx_hexAlice = generate_submarine_commit.generateCommitAddress(
            normalize_address(rec_hex(ALICE_ADDRESS)),
            normalize_address(rec_hex(self.verifier_contract.address)),
            BID_AMOUNT_Alice, b'', OURGASPRICE, OURGASLIMIT)

        unlock_tx_infoAlice = rlp.decode(rec_bin(unlock_tx_hexAlice))
        unlock_tx_objectAlice = transactions.Transaction(
            int.from_bytes(unlock_tx_infoAlice[0], byteorder="big"),  # nonce;
            int.from_bytes(unlock_tx_infoAlice[1],
                           byteorder="big"),  # gasprice
            int.from_bytes(unlock_tx_infoAlice[2],
                           byteorder="big"),  # startgas
            unlock_tx_infoAlice[3],  # to addr
            int.from_bytes(unlock_tx_infoAlice[4], byteorder="big"),  # value
            unlock_tx_infoAlice[5],  # data
            int.from_bytes(unlock_tx_infoAlice[6], byteorder="big"),  # v
            int.from_bytes(unlock_tx_infoAlice[7], byteorder="big"),  # r
            int.from_bytes(unlock_tx_infoAlice[8], byteorder="big")  # s
        )
        commitAddressBob, commitBob, witnessBob, unlock_tx_hexBob = generate_submarine_commit.generateCommitAddress(
            normalize_address(rec_hex(BOB_ADDRESS)),
            normalize_address(rec_hex(self.verifier_contract.address)),
            BID_AMOUNT_Bob, b'', OURGASPRICE, OURGASLIMIT)

        unlock_tx_infoBob = rlp.decode(rec_bin(unlock_tx_hexBob))
        unlock_tx_objectBob = transactions.Transaction(
            int.from_bytes(unlock_tx_infoBob[0], byteorder="big"),  # nonce;
            int.from_bytes(unlock_tx_infoBob[1], byteorder="big"),  # gasprice
            int.from_bytes(unlock_tx_infoBob[2], byteorder="big"),  # startgas
            unlock_tx_infoBob[3],  # to addr
            int.from_bytes(unlock_tx_infoBob[4], byteorder="big"),  # value
            unlock_tx_infoBob[5],  # data
            int.from_bytes(unlock_tx_infoBob[6], byteorder="big"),  # v
            int.from_bytes(unlock_tx_infoBob[7], byteorder="big"),  # r
            int.from_bytes(unlock_tx_infoBob[8], byteorder="big")  # s
        )
        commitAddressCharlie, commitCharlie, witnessCharlie, unlock_tx_hexCharlie = generate_submarine_commit.generateCommitAddress(
            normalize_address(rec_hex(CHARLIE_ADDRESS)),
            normalize_address(rec_hex(self.verifier_contract.address)),
            BID_AMOUNT_Charlie, b'', OURGASPRICE, OURGASLIMIT)

        unlock_tx_infoCharlie = rlp.decode(rec_bin(unlock_tx_hexCharlie))
        unlock_tx_objectCharlie = transactions.Transaction(
            int.from_bytes(unlock_tx_infoCharlie[0],
                           byteorder="big"),  # nonce;
            int.from_bytes(unlock_tx_infoCharlie[1],
                           byteorder="big"),  # gasprice
            int.from_bytes(unlock_tx_infoCharlie[2],
                           byteorder="big"),  # startgas
            unlock_tx_infoCharlie[3],  # to addr
            int.from_bytes(unlock_tx_infoCharlie[4], byteorder="big"),  # value
            unlock_tx_infoCharlie[5],  # data
            int.from_bytes(unlock_tx_infoCharlie[6], byteorder="big"),  # v
            int.from_bytes(unlock_tx_infoCharlie[7], byteorder="big"),  # r
            int.from_bytes(unlock_tx_infoCharlie[8], byteorder="big")  # s
        )

        #
        # GENERATE + BROADCAST COMMIT TXs
        #
        commit_tx_objectAlice = transactions.Transaction(
            0, OURGASPRICE, BASIC_SEND_GAS_LIMIT, rec_bin(commitAddressAlice),
            (BID_AMOUNT_Alice + extraTransactionFees),
            b'').sign(ALICE_PRIVATE_KEY)
        commit_gasAlice = int(self.chain.head_state.gas_used)

        self.chain.direct_tx(commit_tx_objectAlice)
        self.chain.mine(1)

        commit_tx_objectBob = transactions.Transaction(
            0, OURGASPRICE, BASIC_SEND_GAS_LIMIT, rec_bin(commitAddressBob),
            (BID_AMOUNT_Bob + extraTransactionFees), b'').sign(BOB_PRIVATE_KEY)
        commit_gasBob = int(self.chain.head_state.gas_used)

        self.chain.direct_tx(commit_tx_objectBob)
        self.chain.mine(1)

        commit_tx_objectCharlie = transactions.Transaction(
            0, OURGASPRICE, BASIC_SEND_GAS_LIMIT,
            rec_bin(commitAddressCharlie),
            (BID_AMOUNT_Charlie + extraTransactionFees),
            b'').sign(CHARLIE_PRIVATE_KEY)
        commit_gasCharlie = int(self.chain.head_state.gas_used)

        self.chain.direct_tx(commit_tx_objectCharlie)
        self.chain.mine(1)

        ##
        ## CHECK STATE AFTER COMMIT TX
        ##
        commit_block_numberAlice, commit_block_indexAlice = self.chain.chain.get_tx_position(
            commit_tx_objectAlice)
        self.assertEqual(BID_AMOUNT_Alice + extraTransactionFees,
                         self.chain.head_state.get_balance(commitAddressAlice))
        self.assertEqual(
            ACCOUNT_STARTING_BALANCE -
            (BID_AMOUNT_Alice + extraTransactionFees +
             BASIC_SEND_GAS_LIMIT * OURGASPRICE),
            self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS)))

        session_dataAlice = self.verifier_contract.getCommitState(
            rec_bin(commitAlice))
        self.assertListEqual(session_dataAlice, [
            SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL,
            SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL
        ])

        finished_boolAlice = self.verifier_contract.finished(
            rec_bin(commitAlice))
        self.assertFalse(
            finished_boolAlice,
            "The contract should not be finished before it's even begun.")

        commit_block_numberBob, commit_block_indexBob = self.chain.chain.get_tx_position(
            commit_tx_objectBob)
        self.assertEqual(BID_AMOUNT_Bob + extraTransactionFees,
                         self.chain.head_state.get_balance(commitAddressBob))
        self.assertEqual(
            ACCOUNT_STARTING_BALANCE - (BID_AMOUNT_Bob + extraTransactionFees +
                                        BASIC_SEND_GAS_LIMIT * OURGASPRICE),
            self.chain.head_state.get_balance(rec_hex(BOB_ADDRESS)))

        session_dataBob = self.verifier_contract.getCommitState(
            rec_bin(commitBob))
        self.assertListEqual(session_dataBob, [
            SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL,
            SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL
        ])

        finished_boolBob = self.verifier_contract.finished(rec_bin(commitBob))
        self.assertFalse(
            finished_boolBob,
            "The contract should not be finished before it's even begun.")

        commit_block_numberCharlie, commit_block_indexCharlie = self.chain.chain.get_tx_position(
            commit_tx_objectCharlie)
        self.assertEqual(
            BID_AMOUNT_Charlie + extraTransactionFees,
            self.chain.head_state.get_balance(commitAddressCharlie))
        self.assertEqual(
            ACCOUNT_STARTING_BALANCE -
            (BID_AMOUNT_Charlie + extraTransactionFees +
             BASIC_SEND_GAS_LIMIT * OURGASPRICE),
            self.chain.head_state.get_balance(rec_hex(CHARLIE_ADDRESS)))

        session_dataCharlie = self.verifier_contract.getCommitState(
            rec_bin(commitCharlie))
        self.assertListEqual(session_dataCharlie, [
            SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL,
            SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL
        ])

        finished_boolCharlie = self.verifier_contract.finished(
            rec_bin(commitCharlie))
        self.assertFalse(
            finished_boolCharlie,
            "The contract should not be finished before it's even begun.")

        ##
        ## GENERATE AND BROADCAST REVEAL BID TXS
        ##
        self.chain.mine(COMMIT_PERIOD_LENGTH)

        commit_block_objectAlice = self.chain.chain.get_block_by_number(
            commit_block_numberAlice)
        proveth_expected_block_format_dictAlice = dict()
        proveth_expected_block_format_dictAlice[
            'parentHash'] = commit_block_objectAlice['prevhash']
        proveth_expected_block_format_dictAlice[
            'sha3Uncles'] = commit_block_objectAlice['uncles_hash']
        proveth_expected_block_format_dictAlice[
            'miner'] = commit_block_objectAlice['coinbase']
        proveth_expected_block_format_dictAlice[
            'stateRoot'] = commit_block_objectAlice['state_root']
        proveth_expected_block_format_dictAlice[
            'transactionsRoot'] = commit_block_objectAlice['tx_list_root']
        proveth_expected_block_format_dictAlice[
            'receiptsRoot'] = commit_block_objectAlice['receipts_root']
        proveth_expected_block_format_dictAlice[
            'logsBloom'] = commit_block_objectAlice['bloom']
        proveth_expected_block_format_dictAlice[
            'difficulty'] = commit_block_objectAlice['difficulty']
        proveth_expected_block_format_dictAlice[
            'number'] = commit_block_objectAlice['number']
        proveth_expected_block_format_dictAlice[
            'gasLimit'] = commit_block_objectAlice['gas_limit']
        proveth_expected_block_format_dictAlice[
            'gasUsed'] = commit_block_objectAlice['gas_used']
        proveth_expected_block_format_dictAlice[
            'timestamp'] = commit_block_objectAlice['timestamp']
        proveth_expected_block_format_dictAlice[
            'extraData'] = commit_block_objectAlice['extra_data']
        proveth_expected_block_format_dictAlice[
            'mixHash'] = commit_block_objectAlice['mixhash']
        proveth_expected_block_format_dictAlice[
            'nonce'] = commit_block_objectAlice['nonce']
        proveth_expected_block_format_dictAlice[
            'hash'] = commit_block_objectAlice.hash
        proveth_expected_block_format_dictAlice['uncles'] = []
        proveth_expected_block_format_dictAlice['transactions'] = ({
            "blockHash":
            commit_block_objectAlice.hash,
            "blockNumber":
            str(hex((commit_block_objectAlice['number']))),
            "from":
            checksum_encode(ALICE_ADDRESS),
            "gas":
            str(hex(commit_tx_objectAlice['startgas'])),
            "gasPrice":
            str(hex(commit_tx_objectAlice['gasprice'])),
            "hash":
            rec_hex(commit_tx_objectAlice['hash']),
            "input":
            rec_hex(commit_tx_objectAlice['data']),
            "nonce":
            str(hex(commit_tx_objectAlice['nonce'])),
            "to":
            checksum_encode(commit_tx_objectAlice['to']),
            "transactionIndex":
            str(hex(0)),
            "value":
            str(hex(commit_tx_objectAlice['value'])),
            "v":
            str(hex(commit_tx_objectAlice['v'])),
            "r":
            str(hex(commit_tx_objectAlice['r'])),
            "s":
            str(hex(commit_tx_objectAlice['s']))
        }, )

        commit_proof_blobAlice = proveth.generate_proof_blob(
            proveth_expected_block_format_dictAlice, commit_block_indexAlice)
        _unlockExtraData = b''  # In this example we dont have any extra embedded data as part of the unlock TX

        unlock_tx_unsigned_objectAlice = transactions.UnsignedTransaction(
            int.from_bytes(unlock_tx_infoAlice[0], byteorder="big"),  # nonce;
            int.from_bytes(unlock_tx_infoAlice[1],
                           byteorder="big"),  # gasprice
            int.from_bytes(unlock_tx_infoAlice[2],
                           byteorder="big"),  # startgas
            unlock_tx_infoAlice[3],  # to addr
            int.from_bytes(unlock_tx_infoAlice[4], byteorder="big"),  # value
            unlock_tx_infoAlice[5],  # data
        )
        unlock_tx_unsigned_rlpAlice = rlp.encode(
            unlock_tx_unsigned_objectAlice, transactions.UnsignedTransaction)

        self.verifier_contract.revealBid(
            commit_block_numberAlice,  # uint32 _commitBlockNumber,
            _unlockExtraData,  # bytes _commitData,
            rec_bin(witnessAlice),  # bytes32 _witness,
            unlock_tx_unsigned_rlpAlice,  # bytes _rlpUnlockTxUnsigned,
            commit_proof_blobAlice,  # bytes _proofBlob
            sender=ALICE_PRIVATE_KEY)
        reveal_gasAlice = int(self.chain.head_state.gas_used)

        self.chain.mine(1)

        commit_block_objectBob = self.chain.chain.get_block_by_number(
            commit_block_numberBob)
        proveth_expected_block_format_dictBob = dict()
        proveth_expected_block_format_dictBob[
            'parentHash'] = commit_block_objectBob['prevhash']
        proveth_expected_block_format_dictBob[
            'sha3Uncles'] = commit_block_objectBob['uncles_hash']
        proveth_expected_block_format_dictBob[
            'miner'] = commit_block_objectBob['coinbase']
        proveth_expected_block_format_dictBob[
            'stateRoot'] = commit_block_objectBob['state_root']
        proveth_expected_block_format_dictBob[
            'transactionsRoot'] = commit_block_objectBob['tx_list_root']
        proveth_expected_block_format_dictBob[
            'receiptsRoot'] = commit_block_objectBob['receipts_root']
        proveth_expected_block_format_dictBob[
            'logsBloom'] = commit_block_objectBob['bloom']
        proveth_expected_block_format_dictBob[
            'difficulty'] = commit_block_objectBob['difficulty']
        proveth_expected_block_format_dictBob[
            'number'] = commit_block_objectBob['number']
        proveth_expected_block_format_dictBob[
            'gasLimit'] = commit_block_objectBob['gas_limit']
        proveth_expected_block_format_dictBob[
            'gasUsed'] = commit_block_objectBob['gas_used']
        proveth_expected_block_format_dictBob[
            'timestamp'] = commit_block_objectBob['timestamp']
        proveth_expected_block_format_dictBob[
            'extraData'] = commit_block_objectBob['extra_data']
        proveth_expected_block_format_dictBob[
            'mixHash'] = commit_block_objectBob['mixhash']
        proveth_expected_block_format_dictBob[
            'nonce'] = commit_block_objectBob['nonce']
        proveth_expected_block_format_dictBob[
            'hash'] = commit_block_objectBob.hash
        proveth_expected_block_format_dictBob['uncles'] = []
        proveth_expected_block_format_dictBob['transactions'] = ({
            "blockHash":
            commit_block_objectBob.hash,
            "blockNumber":
            str(hex((commit_block_objectBob['number']))),
            "from":
            checksum_encode(BOB_ADDRESS),
            "gas":
            str(hex(commit_tx_objectBob['startgas'])),
            "gasPrice":
            str(hex(commit_tx_objectBob['gasprice'])),
            "hash":
            rec_hex(commit_tx_objectBob['hash']),
            "input":
            rec_hex(commit_tx_objectBob['data']),
            "nonce":
            str(hex(commit_tx_objectBob['nonce'])),
            "to":
            checksum_encode(commit_tx_objectBob['to']),
            "transactionIndex":
            str(hex(0)),
            "value":
            str(hex(commit_tx_objectBob['value'])),
            "v":
            str(hex(commit_tx_objectBob['v'])),
            "r":
            str(hex(commit_tx_objectBob['r'])),
            "s":
            str(hex(commit_tx_objectBob['s']))
        }, )

        commit_proof_blobBob = proveth.generate_proof_blob(
            proveth_expected_block_format_dictBob, commit_block_indexBob)
        _unlockExtraData = b''  # In this example we dont have any extra embedded data as part of the unlock TX

        unlock_tx_unsigned_objectBob = transactions.UnsignedTransaction(
            int.from_bytes(unlock_tx_infoBob[0], byteorder="big"),  # nonce;
            int.from_bytes(unlock_tx_infoBob[1], byteorder="big"),  # gasprice
            int.from_bytes(unlock_tx_infoBob[2], byteorder="big"),  # startgas
            unlock_tx_infoBob[3],  # to addr
            int.from_bytes(unlock_tx_infoBob[4], byteorder="big"),  # value
            unlock_tx_infoBob[5],  # data
        )
        unlock_tx_unsigned_rlpBob = rlp.encode(
            unlock_tx_unsigned_objectBob, transactions.UnsignedTransaction)

        self.verifier_contract.revealBid(
            commit_block_numberBob,  # uint32 _commitBlockNumber,
            _unlockExtraData,  # bytes _commitData,
            rec_bin(witnessBob),  # bytes32 _witness,
            unlock_tx_unsigned_rlpBob,  # bytes _rlpUnlockTxUnsigned,
            commit_proof_blobBob,  # bytes _proofBlob
            sender=BOB_PRIVATE_KEY)
        reveal_gasBob = int(self.chain.head_state.gas_used)

        self.chain.mine(1)

        commit_block_objectCharlie = self.chain.chain.get_block_by_number(
            commit_block_numberCharlie)
        proveth_expected_block_format_dictCharlie = dict()
        proveth_expected_block_format_dictCharlie[
            'parentHash'] = commit_block_objectCharlie['prevhash']
        proveth_expected_block_format_dictCharlie[
            'sha3Uncles'] = commit_block_objectCharlie['uncles_hash']
        proveth_expected_block_format_dictCharlie[
            'miner'] = commit_block_objectCharlie['coinbase']
        proveth_expected_block_format_dictCharlie[
            'stateRoot'] = commit_block_objectCharlie['state_root']
        proveth_expected_block_format_dictCharlie[
            'transactionsRoot'] = commit_block_objectCharlie['tx_list_root']
        proveth_expected_block_format_dictCharlie[
            'receiptsRoot'] = commit_block_objectCharlie['receipts_root']
        proveth_expected_block_format_dictCharlie[
            'logsBloom'] = commit_block_objectCharlie['bloom']
        proveth_expected_block_format_dictCharlie[
            'difficulty'] = commit_block_objectCharlie['difficulty']
        proveth_expected_block_format_dictCharlie[
            'number'] = commit_block_objectCharlie['number']
        proveth_expected_block_format_dictCharlie[
            'gasLimit'] = commit_block_objectCharlie['gas_limit']
        proveth_expected_block_format_dictCharlie[
            'gasUsed'] = commit_block_objectCharlie['gas_used']
        proveth_expected_block_format_dictCharlie[
            'timestamp'] = commit_block_objectCharlie['timestamp']
        proveth_expected_block_format_dictCharlie[
            'extraData'] = commit_block_objectCharlie['extra_data']
        proveth_expected_block_format_dictCharlie[
            'mixHash'] = commit_block_objectCharlie['mixhash']
        proveth_expected_block_format_dictCharlie[
            'nonce'] = commit_block_objectCharlie['nonce']
        proveth_expected_block_format_dictCharlie[
            'hash'] = commit_block_objectCharlie.hash
        proveth_expected_block_format_dictCharlie['uncles'] = []
        proveth_expected_block_format_dictCharlie['transactions'] = ({
            "blockHash":
            commit_block_objectCharlie.hash,
            "blockNumber":
            str(hex((commit_block_objectCharlie['number']))),
            "from":
            checksum_encode(CHARLIE_ADDRESS),
            "gas":
            str(hex(commit_tx_objectCharlie['startgas'])),
            "gasPrice":
            str(hex(commit_tx_objectCharlie['gasprice'])),
            "hash":
            rec_hex(commit_tx_objectCharlie['hash']),
            "input":
            rec_hex(commit_tx_objectCharlie['data']),
            "nonce":
            str(hex(commit_tx_objectCharlie['nonce'])),
            "to":
            checksum_encode(commit_tx_objectCharlie['to']),
            "transactionIndex":
            str(hex(0)),
            "value":
            str(hex(commit_tx_objectCharlie['value'])),
            "v":
            str(hex(commit_tx_objectCharlie['v'])),
            "r":
            str(hex(commit_tx_objectCharlie['r'])),
            "s":
            str(hex(commit_tx_objectCharlie['s']))
        }, )

        commit_proof_blobCharlie = proveth.generate_proof_blob(
            proveth_expected_block_format_dictCharlie,
            commit_block_indexCharlie)
        _unlockExtraData = b''  # In this example we dont have any extra embedded data as part of the unlock TX

        unlock_tx_unsigned_objectCharlie = transactions.UnsignedTransaction(
            int.from_bytes(unlock_tx_infoCharlie[0],
                           byteorder="big"),  # nonce;
            int.from_bytes(unlock_tx_infoCharlie[1],
                           byteorder="big"),  # gasprice
            int.from_bytes(unlock_tx_infoCharlie[2],
                           byteorder="big"),  # startgas
            unlock_tx_infoCharlie[3],  # to addr
            int.from_bytes(unlock_tx_infoCharlie[4], byteorder="big"),  # value
            unlock_tx_infoCharlie[5],  # data
        )
        unlock_tx_unsigned_rlpCharlie = rlp.encode(
            unlock_tx_unsigned_objectCharlie, transactions.UnsignedTransaction)

        self.verifier_contract.revealBid(
            commit_block_numberCharlie,  # uint32 _commitBlockNumber,
            _unlockExtraData,  # bytes _commitData,
            rec_bin(witnessCharlie),  # bytes32 _witness,
            unlock_tx_unsigned_rlpCharlie,  # bytes _rlpUnlockTxUnsigned,
            commit_proof_blobCharlie,  # bytes _proofBlob
            sender=CHARLIE_PRIVATE_KEY)
        reveal_gasCharlie = int(self.chain.head_state.gas_used)

        self.chain.mine(1)

        ##
        ## CHECK THE STATE AFTER REVEAL
        ##

        bidListLength = self.verifier_contract.getBidListLength()
        self.assertEqual(
            bidListLength, 3,
            "Number of bids should match the number of participants in the auction"
        )

        bidListItemAlice = self.verifier_contract.BidList(0)
        self.assertListEqual(
            ["0x" + ALICE_ADDRESS.hex(),
             bytearray.fromhex(commitAlice)], bidListItemAlice)
        session_dataAlice = self.verifier_contract.getCommitState(
            rec_bin(commitAlice))
        self.assertListEqual(session_dataAlice, [
            BID_AMOUNT_Alice, SOLIDITY_NULL_INITIALVAL,
            commit_block_numberAlice, commit_block_indexAlice
        ])
        finished_boolAlice = self.verifier_contract.finished(
            rec_bin(commitAlice))
        self.assertFalse(finished_boolAlice)

        bidListItemBob = self.verifier_contract.BidList(1)
        self.assertListEqual(
            ["0x" + BOB_ADDRESS.hex(),
             bytearray.fromhex(commitBob)], bidListItemBob)
        session_dataBob = self.verifier_contract.getCommitState(
            rec_bin(commitBob))
        self.assertListEqual(session_dataBob, [
            BID_AMOUNT_Bob, SOLIDITY_NULL_INITIALVAL, commit_block_numberBob,
            commit_block_indexBob
        ])
        finished_boolBob = self.verifier_contract.finished(rec_bin(commitBob))
        self.assertFalse(finished_boolBob)

        bidListItemCharlie = self.verifier_contract.BidList(2)
        self.assertListEqual(
            ["0x" + CHARLIE_ADDRESS.hex(),
             bytearray.fromhex(commitCharlie)], bidListItemCharlie)
        session_dataCharlie = self.verifier_contract.getCommitState(
            rec_bin(commitCharlie))
        self.assertListEqual(session_dataCharlie, [
            BID_AMOUNT_Charlie, SOLIDITY_NULL_INITIALVAL,
            commit_block_numberCharlie, commit_block_indexCharlie
        ])
        finished_boolCharlie = self.verifier_contract.finished(
            rec_bin(commitCharlie))
        self.assertFalse(finished_boolCharlie)

        ##
        ## BROADCAST UNLOCK
        ##
        self.chain.mine(1)
        self.chain.direct_tx(unlock_tx_objectAlice)
        unlock_gasAlice = int(self.chain.head_state.gas_used)
        self.chain.mine(1)

        self.chain.mine(1)
        self.chain.direct_tx(unlock_tx_objectBob)
        unlock_gasBob = int(self.chain.head_state.gas_used)
        self.chain.mine(1)

        self.chain.mine(1)
        self.chain.direct_tx(unlock_tx_objectCharlie)
        unlock_gasCharlie = int(self.chain.head_state.gas_used)
        self.chain.mine(1)

        ##
        ## CHECK STATE AFTER UNLOCK
        ##

        # stuff to help with debugging
        # unlock_block_numberAlice, unlock_block_indexAlice = self.chain.chain.get_tx_position(
        #         unlock_tx_objectAlice)
        # unlock_block_objectAlice = self.chain.chain.get_block_by_number(unlock_block_numberAlice)
        # print(unlock_block_objectAlice.as_dict())

        self.assertEqual(
            self.chain.head_state.get_balance(commitAddressAlice),
            (extraTransactionFees - unlock_gasAlice * OURGASPRICE),
            "Commit address should send along the money and have almost 0 money left."
        )

        self.assertEqual(
            self.chain.head_state.get_balance(commitAddressBob),
            (extraTransactionFees - unlock_gasBob * OURGASPRICE),
            "Commit address should send along the money and have almost 0 money left."
        )

        self.assertEqual(
            self.chain.head_state.get_balance(commitAddressCharlie),
            (extraTransactionFees - unlock_gasCharlie * OURGASPRICE),
            "Commit address should send along the money and have almost 0 money left."
        )

        self.assertEqual(
            self.chain.head_state.get_balance(self.verifier_contract.address),
            (BID_AMOUNT_Alice + BID_AMOUNT_Bob + BID_AMOUNT_Charlie),
            "Contract address should have the sum of the bids balance.")

        session_dataAlice = self.verifier_contract.getCommitState(
            rec_bin(commitAlice))
        self.assertListEqual(session_dataAlice, [
            BID_AMOUNT_Alice, BID_AMOUNT_Alice, commit_block_numberAlice,
            commit_block_indexAlice
        ])
        finished_boolAlice = self.verifier_contract.finished(
            rec_bin(commitAlice))
        self.assertTrue(finished_boolAlice)

        session_dataBob = self.verifier_contract.getCommitState(
            rec_bin(commitBob))
        self.assertListEqual(session_dataBob, [
            BID_AMOUNT_Bob, BID_AMOUNT_Bob, commit_block_numberBob,
            commit_block_indexBob
        ])
        finished_boolBob = self.verifier_contract.finished(rec_bin(commitBob))
        self.assertTrue(finished_boolBob)

        session_dataCharlie = self.verifier_contract.getCommitState(
            rec_bin(commitCharlie))
        self.assertListEqual(session_dataCharlie, [
            BID_AMOUNT_Charlie, BID_AMOUNT_Charlie, commit_block_numberCharlie,
            commit_block_indexCharlie
        ])
        finished_boolCharlie = self.verifier_contract.finished(
            rec_bin(commitCharlie))
        self.assertTrue(finished_boolCharlie)

        self.assertFalse(self.verifier_contract.auctionIsOver())

        ##
        ## END AUCTION
        ##

        self.chain.mine(REVEAL_PERIOD_LENGTH)
        self.verifier_contract.endauction(sender=RANDO_ADDRESS_PRIVATE_KEY)

        ##
        ## CHECK STATE NOW THAT AUCTION IS OVER

        self.assertTrue(self.verifier_contract.auctionIsOver())
        self.assertEqual(rec_hex(CHARLIE_ADDRESS),
                         self.verifier_contract.dogieOwner())

        self.assertEqual(
            ACCOUNT_STARTING_BALANCE -
            (extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE),
            self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS)))

        self.assertEqual(
            ACCOUNT_STARTING_BALANCE -
            (extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE),
            self.chain.head_state.get_balance(rec_hex(BOB_ADDRESS)))

        self.assertEqual(
            ACCOUNT_STARTING_BALANCE -
            (BID_AMOUNT_Charlie + extraTransactionFees +
             BASIC_SEND_GAS_LIMIT * OURGASPRICE),
            self.chain.head_state.get_balance(rec_hex(CHARLIE_ADDRESS)))

        self.assertEqual(
            starting_owner_eth_holdings + BID_AMOUNT_Charlie,
            self.chain.head_state.get_balance(rec_hex(CONTRACT_OWNER_ADDRESS)))