Example #1
0
def value_hash(val):
    if isinstance(val, int):
        return eth_utils.keccak(encode_single_packed('(uint256)', [val]))
        # return eth_utils.keccak(encode_single_packed(
        #     '(uint8,uint256)',
        #     [INT_TYPE_CODE, val]
        # ))
    if isinstance(val, Tuple):
        return eth_utils.keccak(
            encode_single_packed('(uint8' + ',bytes32' * len(val) + ')',
                                 [TUPLE_TYPE_CODE + len(val)] +
                                 [value_hash(v) for v in val.val]))
    if isinstance(val, AVMCodePoint):
        if hasattr(val.op, "op_code"):
            return eth_utils.keccak(
                encode_single_packed(
                    '(uint8,uint8,bytes32)',
                    [CODE_POINT_CODE, val.op.op_code, val.next_hash]))
        if isinstance(val.op, int):
            return eth_utils.keccak(
                encode_single_packed('(uint8,uint8,bytes32)',
                                     [CODE_POINT_CODE, val.op, val.next_hash]))
        if hasattr(val.op, "val"):
            return eth_utils.keccak(
                encode_single_packed('(uint8,uint8,bytes32,bytes32)', [
                    CODE_POINT_CODE, val.op.op.op_code,
                    value_hash(val.op.val), val.next_hash
                ]))
        raise Exception("Bad op type {}".format(val.op))

    raise Exception("Can't hash {}".format(val))
Example #2
0
    def application_specific_data(
        self
    ) -> bytes:  # TODO: Think a better name, perhaps something related to "message body" or something like that
        """
        In EIP191 version 0 signatures, data to be signed follows the following format:

            0x19 + 0x00 + validator_address + application_specific_data

        In the context of our MultiSig (which is the "validator"), the application specific data is the concatenation of:
          - Trustee address (actual sender of the TX)
          - Target address
          - Value included in the transaction (in wei)
          - Transaction data (e.g., an encoded call to a contract function)
          - MultiSig nonce
        """

        typed_elements = (
            ('address', self.trustee_address),  # Trustee address
            ('address', self.target_address),  # Target address
            ('uint256', self.value),  # Value of the transaction
            ('bytes', self.data),  # Transaction data
            ('uint256', self.nonce)  # MultiSig nonce
        )

        packed_elements = b''.join(
            [encode_single_packed(t, e) for t, e in typed_elements])
        return packed_elements
Example #3
0
 def test_defunct_hash_message(self):
     safe_tx_hash = HexBytes('0x4c9577d1b1b8dec52329a983ae26238b65f74b7dd9fb28d74ad9548e92aaf196')
     ethereum_signed_message = '\x19Ethereum Signed Message:\n32'
     encoded_message = encode_single_packed('(string,bytes32)',
                                            (ethereum_signed_message, HexBytes(safe_tx_hash)))
     encoded_hash = Web3.keccak(encoded_message)
     self.assertEqual(encoded_hash, defunct_hash_message(primitive=safe_tx_hash))
def solidityKeccak(abi_types, values, validity_check=False):
    """
    Executes keccak256 exactly as Solidity does.
    Takes list of abi_types as inputs -- `[uint24, int8[], bool]`
    and list of corresponding values  -- `[20, [-1, 5, 0], True]`

    Adapted from web3.py
    """
    if len(abi_types) != len(values):
        raise ValueError(
            "Length mismatch between provided abi types and values.  Got "
            "{0} types and {1} values.".format(len(abi_types), len(values))
        )
    if validity_check:
        for t, v in zip(abi_types, values):
            if not is_encodable(t, v):
                print(f'Value {v} is not encodable for ABI type {t}')
                return False
    hex_string = eth_utils.add_0x_prefix(''.join(
        encode_single_packed(abi_type, value).hex()
        for abi_type, value
        in zip(abi_types, values)
    ))
    # hex_string = encode_abi_packed(abi_types, values).hex()
    return eth_utils.keccak(hexstr=hex_string)
Example #5
0
def value_hash(val):
    if isinstance(val, int):
        return eth_utils.keccak(encode_single_packed("(uint256)", [val]))
        # return eth_utils.keccak(encode_single_packed(
        #     '(uint8,uint256)',
        #     [INT_TYPE_CODE, val]
        # ))
    if isinstance(val, Tuple):

        size = val.get_size()

        first_hash = eth_utils.keccak(
            encode_single_packed(
                "(uint8" + ",bytes32" * len(val) + ")",
                [len(val)] + [value_hash(v) for v in val.val],
            ))

        return eth_utils.keccak(
            encode_single_packed("(uint8,bytes32,uint256)",
                                 [TUPLE_TYPE_CODE] + [first_hash] + [size]))
    if isinstance(val, AVMCodePoint):
        if hasattr(val.op, "op_code"):
            return eth_utils.keccak(
                encode_single_packed(
                    "(uint8,uint8,bytes32)",
                    [CODE_POINT_CODE, val.op.op_code, val.next_hash],
                ))
        if isinstance(val.op, int):
            return eth_utils.keccak(
                encode_single_packed("(uint8,uint8,bytes32)",
                                     [CODE_POINT_CODE, val.op, val.next_hash]))
        if hasattr(val.op, "val"):
            return eth_utils.keccak(
                encode_single_packed(
                    "(uint8,uint8,bytes32,bytes32)",
                    [
                        CODE_POINT_CODE,
                        val.op.op.op_code,
                        value_hash(val.op.val),
                        val.next_hash,
                    ],
                ))
        raise Exception("Bad op type {}".format(val.op))

    raise Exception("Can't hash {}".format(val))
def test_encode_single(typ, python_value, _, packed_encoding):
    actual = encode_single_packed(typ, python_value)
    assert actual == packed_encoding
Example #7
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 #8
0
 def ethhash2(self):
     op1 = self.stack.pop()
     op2 = self.stack.pop()
     res = keccak(encode_single_packed("(uint256,uint256)", [op1, op2]))
     self.stack.push(big_endian_to_int(res))