Sublocku
In this challenge, we have to solve Sudoku challenge in the smart contract.
To make success the unlock function, we have to know the initialGrid (game) but it defined as a private variable.
pragma solidity ^0.8.26;
contract Sublocku {
    uint private size;
    uint256[][] private game;
    bool public isSolved = false;
    /*omit*/
    function unlock(uint256[][] memory solve) public {
        require(solve.length == size, "Solution grid size mismatch");
        for (uint i = 0; i < size; i++) {
            require(solve[i].length == size, "Solution grid row size mismatch");
        }
        for (uint i = 0; i < size; i++) {
            for (uint j = 0; j < size; j++) {
                if (game[i][j] != 0) {
                    require(game[i][j] == solve[i][j], "Cannot modify initial non-zero values");
                }
            }
        }
        require(checkRows(solve),    "Row validation failed");
        require(checkColumns(solve), "Column validation failed");
        require(checkSquares(solve), "Square validation failed");
        lastSolver = tx.origin;
    }
    
}
Don't worry, private variable in solidity is not private!!
At first, I wrote a solver to dump the solidity storage.
In Solidity, for dynamic two-dimensional arrays like a 9x9 array, the structure of storage is as follows:
At positions keccak(1) + 0 through keccak(1) + 8, the lengths of each array are stored.
The actual data is stored at positions keccak(keccak(1) + 0) + 0 through keccak(keccak(1) + 8) + 8.
# Dumping for the length of array.
keccak(1) = 0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6: 9 (hex: 0x0000000000000000000000000000000000000000000000000000000000000009)
keccak(1)+1 = 0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7: 9 (hex: 0x0000000000000000000000000000000000000000000000000000000000000009)
keccak(1)+2 = 0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf8: 9 (hex: 0x0000000000000000000000000000000000000000000000000000000000000009)
keccak(1)+3 = 0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf9: 9 (hex: 0x0000000000000000000000000000000000000000000000000000000000000009)
keccak(1)+4 = 0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfa: 9 (hex: 0x0000000000000000000000000000000000000000000000000000000000000009)
keccak(1)+5 = 0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfb: 9 (hex: 0x0000000000000000000000000000000000000000000000000000000000000009)
keccak(1)+6 = 0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfc: 9 (hex: 0x0000000000000000000000000000000000000000000000000000000000000009)
keccak(1)+7 = 0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfd: 9 (hex: 0x0000000000000000000000000000000000000000000000000000000000000009)
keccak(1)+8 = 0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfe: 9 (hex: 0x0000000000000000000000000000000000000000000000000000000000000009)
from web3 import Web3
CONTRACT_ADDRESS = "0x685215B6aD89715Ef72EfB820C13BFa8E024401a"
RPC_URL = "http://chall4.midnightflag.fr:13137/rpc"
PRIVATE_KEY = "cc67d5fe2dcfa52a37ec93922cdc411373c1b66bcdf349d9eb964887112160af"
MY_ADDRESS = "0xa4FddaE91497a02d80319ACC21A596e977e087F4"
CONTRACT_ADDRESS = "0x685215B6aD89715Ef72EfB820C13BFa8E024401a"
RPC_URL = "http://chall2.midnightflag.fr:10641/rpc"
CHAIN_ID = 1337
w3 = Web3(Web3.HTTPProvider(RPC_URL))
if not w3.is_connected():
    raise Exception("Failed to connect to RPC")
def get_storage_at_index(index, hex_output=False):
    value = w3.eth.get_storage_at(CONTRACT_ADDRESS, index)
    if hex_output:
        return "0x" + value.hex()
    else:
        if value == b'\x00' * 32:
            return 0
        return int.from_bytes(value, byteorder='big')
def calculate_keccak(value):
    slot_hex = hex(value)[2:].zfill(64)
    keccak_slot = w3.keccak(hexstr=slot_hex)
    return int.from_bytes(keccak_slot, byteorder='big')
def dump_multi_stage_keccak():
    keccak_1 = calculate_keccak(1)
    print(f"keccak(1) = {hex(keccak_1)}")
    
    for i in range(1,9):
        row_index = keccak_1 + i
        row_keccak = calculate_keccak(row_index)
        print(f"\n--- Row {i}: keccak(keccak(1) + {i}) = {hex(row_keccak)} ---")
        
        row_values = []
        for j in range(1,9):
            cell_slot = row_keccak + j
            try:
                value = get_storage_at_index(cell_slot)
                hex_value = get_storage_at_index(cell_slot, True)
                row_values.append(value)
                print(f"Cell [{i}][{j}] @ {hex(cell_slot)}: {value} (hex: {hex_value})")
            except Exception as e:
                print(f"Cell [{i}][{j}] @ {hex(cell_slot)} Error: {e}")
                row_values.append("ERR")
        
        print(f"Row {i} Value: {row_values}")
dump_multi_stage_keccak()
Strangely, when I tried to dump positions 0-8, an error occurred.
[3, 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR']
[9, 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR']
[5, 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR']
[4, 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR']
[6, 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR']
[8, 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR']
[7, 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR']
[1, 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR']
[2, 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR', 'ERR']
However, when I tried to dump positions 1-8, I was able to successfully retrieve the values.
keccak(1) = 0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6
--- Row 1: keccak(keccak(1) + 1) = 0xea7809e925a8989e20c901c4c1da82f0ba29b26797760d445a0ce4cf3c6fbd31 ---
Cell [1][1] @ 0xea7809e925a8989e20c901c4c1da82f0ba29b26797760d445a0ce4cf3c6fbd32: 2 (hex: 0x0000000000000000000000000000000000000000000000000000000000000002)
Cell [1][2] @ 0xea7809e925a8989e20c901c4c1da82f0ba29b26797760d445a0ce4cf3c6fbd33: 6 (hex: 0x0000000000000000000000000000000000000000000000000000000000000006)
Cell [1][3] @ 0xea7809e925a8989e20c901c4c1da82f0ba29b26797760d445a0ce4cf3c6fbd34: 3 (hex: 0x0000000000000000000000000000000000000000000000000000000000000003)
Cell [1][4] @ 0xea7809e925a8989e20c901c4c1da82f0ba29b26797760d445a0ce4cf3c6fbd35: 1 (hex: 0x0000000000000000000000000000000000000000000000000000000000000001)
Cell [1][5] @ 0xea7809e925a8989e20c901c4c1da82f0ba29b26797760d445a0ce4cf3c6fbd36: 8 (hex: 0x0000000000000000000000000000000000000000000000000000000000000008)
Cell [1][6] @ 0xea7809e925a8989e20c901c4c1da82f0ba29b26797760d445a0ce4cf3c6fbd37: 7 (hex: 0x0000000000000000000000000000000000000000000000000000000000000007)
Cell [1][7] @ 0xea7809e925a8989e20c901c4c1da82f0ba29b26797760d445a0ce4cf3c6fbd38: 5 (hex: 0x0000000000000000000000000000000000000000000000000000000000000005)
Cell [1][8] @ 0xea7809e925a8989e20c901c4c1da82f0ba29b26797760d445a0ce4cf3c6fbd39: 4 (hex: 0x0000000000000000000000000000000000000000000000000000000000000004)
Row 1 Value: [2, 6, 3, 1, 8, 7, 5, 4]
--- Row 2: keccak(keccak(1) + 2) = 0xb32787652f8eacc66cda8b4b73a1b9c31381474fe9e723b0ba866bfbd5dde02b ---
Cell [2][1] @ 0xb32787652f8eacc66cda8b4b73a1b9c31381474fe9e723b0ba866bfbd5dde02c: 4 (hex: 0x0000000000000000000000000000000000000000000000000000000000000004)
Cell [2][2] @ 0xb32787652f8eacc66cda8b4b73a1b9c31381474fe9e723b0ba866bfbd5dde02d: 8 (hex: 0x0000000000000000000000000000000000000000000000000000000000000008)
Cell [2][3] @ 0xb32787652f8eacc66cda8b4b73a1b9c31381474fe9e723b0ba866bfbd5dde02e: 7 (hex: 0x0000000000000000000000000000000000000000000000000000000000000007)
Cell [2][4] @ 0xb32787652f8eacc66cda8b4b73a1b9c31381474fe9e723b0ba866bfbd5dde02f: 2 (hex: 0x0000000000000000000000000000000000000000000000000000000000000002)
Cell [2][5] @ 0xb32787652f8eacc66cda8b4b73a1b9c31381474fe9e723b0ba866bfbd5dde030: 6 (hex: 0x0000000000000000000000000000000000000000000000000000000000000006)
Cell [2][6] @ 0xb32787652f8eacc66cda8b4b73a1b9c31381474fe9e723b0ba866bfbd5dde031: 3 (hex: 0x0000000000000000000000000000000000000000000000000000000000000003)
Cell [2][7] @ 0xb32787652f8eacc66cda8b4b73a1b9c31381474fe9e723b0ba866bfbd5dde032: 1 (hex: 0x0000000000000000000000000000000000000000000000000000000000000001)
Cell [2][8] @ 0xb32787652f8eacc66cda8b4b73a1b9c31381474fe9e723b0ba866bfbd5dde033: 9 (hex: 0x0000000000000000000000000000000000000000000000000000000000000009)
Row 2 Value: [4, 8, 7, 2, 6, 3, 1, 9]
--- Row 3: keccak(keccak(1) + 3) = 0xeec2ab63f4cd97b3799d9fb76fab247ec6b49ef064d9b5e6c242d49631a19ee9 ---
Cell [3][1] @ 0xeec2ab63f4cd97b3799d9fb76fab247ec6b49ef064d9b5e6c242d49631a19eea: 3 (hex: 0x0000000000000000000000000000000000000000000000000000000000000003)
Cell [3][2] @ 0xeec2ab63f4cd97b3799d9fb76fab247ec6b49ef064d9b5e6c242d49631a19eeb: 1 (hex: 0x0000000000000000000000000000000000000000000000000000000000000001)
Cell [3][3] @ 0xeec2ab63f4cd97b3799d9fb76fab247ec6b49ef064d9b5e6c242d49631a19eec: 8 (hex: 0x0000000000000000000000000000000000000000000000000000000000000008)
Cell [3][4] @ 0xeec2ab63f4cd97b3799d9fb76fab247ec6b49ef064d9b5e6c242d49631a19eed: 0 (hex: 0x0000000000000000000000000000000000000000000000000000000000000000)
Cell [3][5] @ 0xeec2ab63f4cd97b3799d9fb76fab247ec6b49ef064d9b5e6c242d49631a19eee: 7 (hex: 0x0000000000000000000000000000000000000000000000000000000000000007)
Cell [3][6] @ 0xeec2ab63f4cd97b3799d9fb76fab247ec6b49ef064d9b5e6c242d49631a19eef: 9 (hex: 0x0000000000000000000000000000000000000000000000000000000000000009)
Cell [3][7] @ 0xeec2ab63f4cd97b3799d9fb76fab247ec6b49ef064d9b5e6c242d49631a19ef0: 2 (hex: 0x0000000000000000000000000000000000000000000000000000000000000002)
Cell [3][8] @ 0xeec2ab63f4cd97b3799d9fb76fab247ec6b49ef064d9b5e6c242d49631a19ef1: 6 (hex: 0x0000000000000000000000000000000000000000000000000000000000000006)
Row 3 Value: [3, 1, 8, 0, 7, 9, 2, 6]
--- Row 4: keccak(keccak(1) + 4) = 0x83fae7d88d3202765861d3bf8af4fff3ab5293dab6070c6fa8f55d3c5e93a72c ---
Cell [4][1] @ 0x83fae7d88d3202765861d3bf8af4fff3ab5293dab6070c6fa8f55d3c5e93a72d: 9 (hex: 0x0000000000000000000000000000000000000000000000000000000000000009)
Cell [4][2] @ 0x83fae7d88d3202765861d3bf8af4fff3ab5293dab6070c6fa8f55d3c5e93a72e: 2 (hex: 0x0000000000000000000000000000000000000000000000000000000000000002)
Cell [4][3] @ 0x83fae7d88d3202765861d3bf8af4fff3ab5293dab6070c6fa8f55d3c5e93a72f: 1 (hex: 0x0000000000000000000000000000000000000000000000000000000000000001)
Cell [4][4] @ 0x83fae7d88d3202765861d3bf8af4fff3ab5293dab6070c6fa8f55d3c5e93a730: 3 (hex: 0x0000000000000000000000000000000000000000000000000000000000000003)
Cell [4][5] @ 0x83fae7d88d3202765861d3bf8af4fff3ab5293dab6070c6fa8f55d3c5e93a731: 4 (hex: 0x0000000000000000000000000000000000000000000000000000000000000004)
Cell [4][6] @ 0x83fae7d88d3202765861d3bf8af4fff3ab5293dab6070c6fa8f55d3c5e93a732: 8 (hex: 0x0000000000000000000000000000000000000000000000000000000000000008)
Cell [4][7] @ 0x83fae7d88d3202765861d3bf8af4fff3ab5293dab6070c6fa8f55d3c5e93a733: 7 (hex: 0x0000000000000000000000000000000000000000000000000000000000000007)
Cell [4][8] @ 0x83fae7d88d3202765861d3bf8af4fff3ab5293dab6070c6fa8f55d3c5e93a734: 5 (hex: 0x0000000000000000000000000000000000000000000000000000000000000005)
Row 4 Value: [9, 2, 1, 3, 4, 8, 7, 5]
--- Row 5: keccak(keccak(1) + 5) = 0xdc87d541e7563f7326faaad804b757103e4778479268dcf2932ef7d4addff3d5 ---
Cell [5][1] @ 0xdc87d541e7563f7326faaad804b757103e4778479268dcf2932ef7d4addff3d6: 7 (hex: 0x0000000000000000000000000000000000000000000000000000000000000007)
Cell [5][2] @ 0xdc87d541e7563f7326faaad804b757103e4778479268dcf2932ef7d4addff3d7: 5 (hex: 0x0000000000000000000000000000000000000000000000000000000000000005)
Cell [5][3] @ 0xdc87d541e7563f7326faaad804b757103e4778479268dcf2932ef7d4addff3d8: 9 (hex: 0x0000000000000000000000000000000000000000000000000000000000000009)
Cell [5][4] @ 0xdc87d541e7563f7326faaad804b757103e4778479268dcf2932ef7d4addff3d9: 6 (hex: 0x0000000000000000000000000000000000000000000000000000000000000006)
Cell [5][5] @ 0xdc87d541e7563f7326faaad804b757103e4778479268dcf2932ef7d4addff3da: 2 (hex: 0x0000000000000000000000000000000000000000000000000000000000000002)
Cell [5][6] @ 0xdc87d541e7563f7326faaad804b757103e4778479268dcf2932ef7d4addff3db: 4 (hex: 0x0000000000000000000000000000000000000000000000000000000000000004)
Cell [5][7] @ 0xdc87d541e7563f7326faaad804b757103e4778479268dcf2932ef7d4addff3dc: 3 (hex: 0x0000000000000000000000000000000000000000000000000000000000000003)
Cell [5][8] @ 0xdc87d541e7563f7326faaad804b757103e4778479268dcf2932ef7d4addff3dd: 1 (hex: 0x0000000000000000000000000000000000000000000000000000000000000001)
Row 5 Value: [7, 5, 9, 6, 2, 4, 3, 1]
--- Row 6: keccak(keccak(1) + 6) = 0xc0f1c97443847c789de7dfa956a43904c2a85104210919072378506a188b54eb ---
Cell [6][1] @ 0xc0f1c97443847c789de7dfa956a43904c2a85104210919072378506a188b54ec: 8 (hex: 0x0000000000000000000000000000000000000000000000000000000000000008)
Cell [6][2] @ 0xc0f1c97443847c789de7dfa956a43904c2a85104210919072378506a188b54ed: 9 (hex: 0x0000000000000000000000000000000000000000000000000000000000000009)
Cell [6][3] @ 0xc0f1c97443847c789de7dfa956a43904c2a85104210919072378506a188b54ee: 5 (hex: 0x0000000000000000000000000000000000000000000000000000000000000005)
Cell [6][4] @ 0xc0f1c97443847c789de7dfa956a43904c2a85104210919072378506a188b54ef: 4 (hex: 0x0000000000000000000000000000000000000000000000000000000000000004)
Cell [6][5] @ 0xc0f1c97443847c789de7dfa956a43904c2a85104210919072378506a188b54f0: 1 (hex: 0x0000000000000000000000000000000000000000000000000000000000000001)
Cell [6][6] @ 0xc0f1c97443847c789de7dfa956a43904c2a85104210919072378506a188b54f1: 2 (hex: 0x0000000000000000000000000000000000000000000000000000000000000002)
Cell [6][7] @ 0xc0f1c97443847c789de7dfa956a43904c2a85104210919072378506a188b54f2: 6 (hex: 0x0000000000000000000000000000000000000000000000000000000000000006)
Cell [6][8] @ 0xc0f1c97443847c789de7dfa956a43904c2a85104210919072378506a188b54f3: 3 (hex: 0x0000000000000000000000000000000000000000000000000000000000000003)
Row 6 Value: [8, 9, 5, 4, 1, 2, 6, 3]
--- Row 7: keccak(keccak(1) + 7) = 0x2f8b94bb7e8ba66c1abce78afab7a81ac78bb35dfd3b389165639d4dd75f9311 ---
Cell [7][1] @ 0x2f8b94bb7e8ba66c1abce78afab7a81ac78bb35dfd3b389165639d4dd75f9312: 0 (hex: 0x0000000000000000000000000000000000000000000000000000000000000000)
Cell [7][2] @ 0x2f8b94bb7e8ba66c1abce78afab7a81ac78bb35dfd3b389165639d4dd75f9313: 4 (hex: 0x0000000000000000000000000000000000000000000000000000000000000004)
Cell [7][3] @ 0x2f8b94bb7e8ba66c1abce78afab7a81ac78bb35dfd3b389165639d4dd75f9314: 2 (hex: 0x0000000000000000000000000000000000000000000000000000000000000002)
Cell [7][4] @ 0x2f8b94bb7e8ba66c1abce78afab7a81ac78bb35dfd3b389165639d4dd75f9315: 8 (hex: 0x0000000000000000000000000000000000000000000000000000000000000008)
Cell [7][5] @ 0x2f8b94bb7e8ba66c1abce78afab7a81ac78bb35dfd3b389165639d4dd75f9316: 0 (hex: 0x0000000000000000000000000000000000000000000000000000000000000000)
Cell [7][6] @ 0x2f8b94bb7e8ba66c1abce78afab7a81ac78bb35dfd3b389165639d4dd75f9317: 5 (hex: 0x0000000000000000000000000000000000000000000000000000000000000005)
Cell [7][7] @ 0x2f8b94bb7e8ba66c1abce78afab7a81ac78bb35dfd3b389165639d4dd75f9318: 9 (hex: 0x0000000000000000000000000000000000000000000000000000000000000009)
Cell [7][8] @ 0x2f8b94bb7e8ba66c1abce78afab7a81ac78bb35dfd3b389165639d4dd75f9319: 7 (hex: 0x0000000000000000000000000000000000000000000000000000000000000007)
Row 7 Value: [0, 4, 2, 8, 0, 5, 9, 7]
--- Row 8: keccak(keccak(1) + 8) = 0x1d0f346cde24a229e6350c15ac916ce091950e58cf25a3bb52ace5f29c4e6e9 ---
Cell [8][1] @ 0x1d0f346cde24a229e6350c15ac916ce091950e58cf25a3bb52ace5f29c4e6ea: 5 (hex: 0x0000000000000000000000000000000000000000000000000000000000000005)
Cell [8][2] @ 0x1d0f346cde24a229e6350c15ac916ce091950e58cf25a3bb52ace5f29c4e6eb: 3 (hex: 0x0000000000000000000000000000000000000000000000000000000000000003)
Cell [8][3] @ 0x1d0f346cde24a229e6350c15ac916ce091950e58cf25a3bb52ace5f29c4e6ec: 6 (hex: 0x0000000000000000000000000000000000000000000000000000000000000006)
Cell [8][4] @ 0x1d0f346cde24a229e6350c15ac916ce091950e58cf25a3bb52ace5f29c4e6ed: 7 (hex: 0x0000000000000000000000000000000000000000000000000000000000000007)
Cell [8][5] @ 0x1d0f346cde24a229e6350c15ac916ce091950e58cf25a3bb52ace5f29c4e6ee: 9 (hex: 0x0000000000000000000000000000000000000000000000000000000000000009)
Cell [8][6] @ 0x1d0f346cde24a229e6350c15ac916ce091950e58cf25a3bb52ace5f29c4e6ef: 1 (hex: 0x0000000000000000000000000000000000000000000000000000000000000001)
Cell [8][7] @ 0x1d0f346cde24a229e6350c15ac916ce091950e58cf25a3bb52ace5f29c4e6f0: 4 (hex: 0x0000000000000000000000000000000000000000000000000000000000000004)
Cell [8][8] @ 0x1d0f346cde24a229e6350c15ac916ce091950e58cf25a3bb52ace5f29c4e6f1: 8 (hex: 0x0000000000000000000000000000000000000000000000000000000000000008)
Row 8 Value: [5, 3, 6, 7, 9, 1, 4, 8]
Solving Sudoku manually and submit the solution, I successfully gain the flag.
from web3 import Web3
PRIVATE_KEY = "365d49e876d1889bd07bfb8c59f59ef03cd5da14172805aa8b8b32b292014e94"
MY_ADDRESS = "0xe519A406d5559A33eA5eBe529b755C8630d2FA89"
CONTRACT_ADDRESS = "0x685215B6aD89715Ef72EfB820C13BFa8E024401a"
RPC_URL = "http://chall4.midnightflag.fr:12458/rpc"
CHAIN_ID = 1337
w3 = Web3(Web3.HTTPProvider(RPC_URL))
if not w3.is_connected():
    raise Exception("Failed to connect to RPC")
account = w3.eth.account.from_key(PRIVATE_KEY)
w3.eth.default_account = account.address
ABI = [
    {
        "inputs": [
            {
                "internalType": "uint256[][]",
                "name": "solve",
                "type": "uint256[][]"
            }
        ],
        "name": "unlock",
        "outputs": [],
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "inputs": [],
        "name": "lastSolver",
        "outputs": [
            {
                "internalType": "address",
                "name": "",
                "type": "address"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    },
    {
        "inputs": [],
        "name": "owner",
        "outputs": [
            {
                "internalType": "address",
                "name": "",
                "type": "address"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    }
]
contract = w3.eth.contract(address=CONTRACT_ADDRESS, abi=ABI)
def submit_solution2(solution):
    try:
        transaction = contract.functions.unlock(solution).build_transaction({
            'chainId': CHAIN_ID,
            'gas': 3000000,
            'gasPrice': w3.to_wei('50', 'gwei'),
            'nonce': w3.eth.get_transaction_count(account.address),
        })
        
        signed_txn = w3.eth.account.sign_transaction(transaction, private_key=PRIVATE_KEY)
        
        raw_tx = signed_txn.raw_transaction
        tx_hash = w3.eth.send_raw_transaction(raw_tx)
        print(f"Transaction Hash: {tx_hash.hex()}")
        
        receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
        
        if receipt['status'] == 1:
            print("Transaction successful")
            
            last_solver = contract.functions.lastSolver().call()
            print(f"Last Solver: {last_solver}")
            if last_solver.lower() == MY_ADDRESS.lower():
                print("Success: I am the last solver!")
            else:
                print("Failed: I am not the last solver.")
            
            return True
        else:
            print("Transaction failed")
            return False
            
    except Exception as e:
        print(f"Error: {e}")
        return False
def main():
    try:
        owner = contract.functions.owner().call()
        print(f"Contract owner: {owner}")
    except Exception as e:
        print(f"Error: {e}")
    
    solution = [
        [3,1, 7, 4, 9, 5, 6, 8, 2],
        [9,2, 6, 3, 1, 8, 7, 5, 4],
        [5,4, 8, 7, 2, 6, 3, 1, 9],
        [4,3, 1, 8, 5, 7, 9, 2, 6],
        [6,9, 2, 1, 3, 4, 8, 7, 5],
        [8,7, 5, 9, 6, 2, 4, 3, 1],
        [7,8, 9, 5, 4, 1, 2, 6, 3],
        [1,6, 4, 2, 8, 3, 5, 9, 7],
        [2,5, 3, 6, 7, 9, 1, 4, 8],
    ]
    
    submit_solution2(solution)
if __name__ == "__main__":
    main()