# Table of contents- ## [Crypto Casino](#challenge-name-crypto-casino) ---
# Notes
### For some of the challenges, a rinkeby testnet wallet account is required. Make sure to get one before doing.
### I'm using Ubuntu 20.04 as my environment.
---
# Challenge name: Crypto Casino![Question Screenshot](../images/cryptocasino.png)
## Information
Contract address: ```0x186d5d064545f6211dD1B5286aB2Bc755dfF2F59```
> contract.sol```pragma solidity ^0.6.0;
contract casino {
    bytes32 private seed;    mapping(address => uint) public consecutiveWins;
    constructor () public{        seed = keccak256("satoshi nakmoto");    }
    function bet(uint guess) public{        uint num = uint(keccak256(abi.encodePacked(seed, block.number))) ^ 0x539;        if (guess == num) {            consecutiveWins[msg.sender] = consecutiveWins[msg.sender] + 1;        }else {            consecutiveWins[msg.sender] = 0;        }    }
    function done() public view returns (uint16[] memory) {        if (consecutiveWins[msg.sender] > 1) {            return [];        }    }
}```- ```seed``` is known, which is ```keccak256("satoshi nakmoto")```- i need to ```bet()``` for 2 times in a row successfully - i need to replicate ```abi.encodePacked(seed,block.number)``` in python- ```block.number``` is the length of the chain of rinkeby at the moment ```bet()``` was called
## My solution
For ```seed```, we can get it on ```brownie console``` by running ```web3.keccak(text="satoshi nakmoto")``````>>> web3.keccak(text="satoshi nakmoto")HexBytes('0xb37c910f4e0df0efafb35a55489604369808b6de642ff1dbab5062680afaddcd')```
For the value of ```abi.encodePacked(seed,block.number)```, i reversed it by trial and error in my local blockchain network
This following is the result of ```abi.encodePacked(seed,block.number)``` where block.number is 1 and 15.seed|block.number|abi.encodePacked-|-|-"b37c910f4e0df0efafb35a55489604369808b6de642ff1dbab5062680afaddcd"|1|"b37c910f4e0df0efafb35a55489604369808b6de642ff1dbab5062680afaddcd0000000000000000000000000000000000000000000000000000000000000001""b37c910f4e0df0efafb35a55489604369808b6de642ff1dbab5062680afaddcd"|15|"b37c910f4e0df0efafb35a55489604369808b6de642ff1dbab5062680afaddcd000000000000000000000000000000000000000000000000000000000000000f"
Now ```abi.encodePacked(seed,block.number)``` was reversed, time to make some bet.
1. In a directory, run ```brownie init crypto_casino_ctf``` > crypto_casino_ctf/contracts/contract.sol
```pragma solidity ^0.6.0;
contract casino {
    bytes32 private seed;    mapping(address => uint) public consecutiveWins;
    constructor () public{        seed = keccak256("satoshi nakmoto");    }
    function bet(uint guess) public{        uint num = uint(keccak256(abi.encodePacked(seed, block.number))) ^ 0x539;        if (guess == num) {            consecutiveWins[msg.sender] = consecutiveWins[msg.sender] + 1;        }else {            consecutiveWins[msg.sender] = 0;        }    }
    function done() public view returns (string memory) {        if (consecutiveWins[msg.sender] > 1) {            return "you broke the casino";  // <- replace with some string to let it compile successfully        }    }
}```
> crypto_casino_ctf/scripts/test.py
```from brownie import *
def main():    network.disconnect()    network.connect("rinkeby")
    network.gas_limit(50000) # set how much i am willing to pay
    accounts.add(YOUR_OWN_RINKEBY_NETWORK_WALLET_PRIVATE_KEY)
    d = Contract.from_abi(        address="0x186d5d064545f6211dD1B5286aB2Bc755dfF2F59",        abi=casino.abi,        name="target"    )
    # just in case i didn't guess it in the first 2 round    for k in range(3):        for i in range(2):            current_block_height = "%064x" % (chain.height+1)            seed = "b37c910f4e0df0efafb35a55489604369808b6de642ff1dbab5062680afaddcd" + current_block_height
            print("Doing block height (hex):",current_block_height)            print("Doing block height (dec): %064d"%(chain.height+1))
            ''' Replica of abi.encodePacked(seed,block.number) '''            _bytes = bytes.fromhex(seed)            _encodePacked = int.from_bytes(_bytes, byteorder="big")            _hexBytes = web3.keccak(_encodePacked)
            guess = int(_hexBytes.hex(), 16) ^ 0x539
            print(d.bet(guess, {"from": accounts[0].address}))        print("result", d.done({"from": accounts[0].address}))
```2. ```$ brownie run scripts/test.py```
```Brownie v1.13.0 - Python development framework for Ethereum
CryptoCasinoCtfProject is the active project.
Launching 'ganache-cli --port 8545 --gasLimit 12000000 --accounts 10 --hardfork istanbul --mnemonic brownie'...
Running 'scripts/test.py::main'...Terminating local RPC client...Transaction sent: 0x9fb6e2c090be7520b86a5b53a4bc21a2a500f69a0b17305650b041ff9dbd5293  Gas price: 1.0 gwei   Gas limit: 50000   Nonce: 36  target.bet confirmed - Block: 7991824   Gas used: 13928 (27.86%)
<Transaction '0x9fb6e2c090be7520b86a5b53a4bc21a2a500f69a0b17305650b041ff9dbd5293'>Transaction sent: 0x59c75618de39bdbd7c4239542388c1a9bb4ebd848c1cbd2086c86b3cc89030e7  Gas price: 1.0 gwei   Gas limit: 50000   Nonce: 37  target.bet confirmed - Block: 7991825   Gas used: 43690 (87.38%)
<Transaction '0x59c75618de39bdbd7c4239542388c1a9bb4ebd848c1cbd2086c86b3cc89030e7'>result Transaction sent: 0xb5ebc12b5fcc080c39874b8e43beb420cc8fc093528ec36a891df53d2ff7ad5d  Gas price: 1.0 gwei   Gas limit: 50000   Nonce: 38  target.bet confirmed - Block: 7991826   Gas used: 28690 (57.38%)
<Transaction '0xb5ebc12b5fcc080c39874b8e43beb420cc8fc093528ec36a891df53d2ff7ad5d'>Transaction sent: 0x4e171e5e5b97a86dca008923fb2d97f5ffbf39ace8fda27862926f2930133809  Gas price: 1.0 gwei   Gas limit: 50000   Nonce: 39  target.bet confirmed - Block: 7991827   Gas used: 28690 (57.38%)
<Transaction '0x4e171e5e5b97a86dca008923fb2d97f5ffbf39ace8fda27862926f2930133809'>  File "brownie/_cli/run.py", line 49, in main    return_value = run(args["<filename>"], method_name=args["<function>"] or "main")  File "brownie/project/scripts.py", line 66, in run    return getattr(module, method_name)(*args, **kwargs)  File "./scripts/test.py", line 47, in main    print("result", d.done({"from": accounts[0].address}))  File "brownie/network/contract.py", line 1696, in __call__    return self.call(*args, block_identifier=block_identifier)  File "brownie/network/contract.py", line 1509, in call    return self.decode_output(data)  File "brownie/network/contract.py", line 1595, in decode_output    result = eth_abi.decode_abi(types_list, HexBytes(hexstr))  File "eth_abi/codec.py", line 181, in decode_abi    return decoder(stream)  File "eth_abi/decoding.py", line 127, in __call__    return self.decode(stream)  File "eth_utils/functional.py", line 45, in inner    return callback(fn(*args, **kwargs))  File "eth_abi/decoding.py", line 173, in decode    yield decoder(stream)  File "eth_abi/decoding.py", line 127, in __call__    return self.decode(stream)  File "eth_abi/decoding.py", line 145, in decode    value = self.tail_decoder(stream)  File "eth_abi/decoding.py", line 127, in __call__    return self.decode(stream)  File "eth_abi/decoding.py", line 198, in decode    raw_data = self.read_data_from_stream(stream)  File "eth_abi/decoding.py", line 519, in read_data_from_stream    raise InsufficientDataBytes(InsufficientDataBytes: Tried to read 28991922601197568 bytes.  Only got 954 bytes```3. The error occurs when i have successfully bet'd for 2 in a row. (not quite sure how to overcome the InsufficientDataBytes error)4. So to retrieve the flag, i need to do the same error handling as what i did on [Crackme](#crackme)5. ```$ brownie console --network rinkeby``` ```Brownie v1.13.0 - Python development framework for Ethereum
CryptoCasinoCtfProject is the active project.Brownie environment is ready.>>> accounts.add(YOUR_OWN_RINKEBY_NETWORK_WALLET_PRIVATE_KEY)<LocalAccount '0x808DB180e48b9aC1878f81927345c4159b3Eb848'>>>> d = web3.eth.contract(... address="0x186d5d064545f6211dD1B5286aB2Bc755dfF2F59",... abi=casino.abi... )>>> d.functions.done().call({"from":accounts[0].address})  File "<console>", line 1, in <module>  File "web3/contract.py", line 954, in call    return call_contract_function(  File "web3/contract.py", line 1529, in call_contract_function    raise BadFunctionCallOutput(msg) from eBadFunctionCallOutput: Could not decode contract function call done return data b'\x00\x00\x00......\x00\x00\x00}' for output_types ['string']>>> return_data = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00N\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x007\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00N\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00">>> for a in return_data:...     if(a != '\x00'):...         print(a,end='')...flag{D3CN7R@l1Z3D_C@51N0S_5uck531>>>```
## Flag: flag{D3CN7R@l1Z3D_C@51N0S_5uck531}
---