Hello,
I'm practicing smart contracts with Ethernaut. I'm at the coinflip stage, and I'm making this thread to ask for help on solving it with JavaScript, aka not deploying a smart contract to interact with my instance. I created JavaScript code to call the flip function with the correct guess, but by the time it's mined it's a different block and the guess is meaningless (yes I called it blockieBlock lol):
blockieBlock = await web3.eth.getBlock(await web3.eth.getBlockNumber()-1);
if (Math.floor(parseInt(blockieBlock.hash.slice(2),16) / factor) == 0) {
contract.flip(false);
console.log("flipped 0 bc block # is " + blockieBlock.number);
} else {
contract.flip(1)
console.log("flipped 1 bc block # is " + blockieBlock.number);
}
I used .slice(2) to get rid of '0x' in the beginning of the hash string, and I've verified with many blocks that this gave the correct hash and rounds down to 0 or 1 for the guess. I did this strategy in multiple forms and I couldn't get console.log( ____) to even work, but it's fine because I switched strategies.
When I switched strategies, I began trying to submit a transaction to the contract with value: 0 and data: contract.flip( blahblahblah). Here it is:
web3.eth.sendTransaction({from: player, to: contract.address, value: 0, data: contract.flip(Math.floor(parseInt((await web3.eth.getBlock(await web3.eth.getBlockNumber()-1)).hash.slice(2),16) / factor))})
It seemed to work and I got to 4 coin flips correct, but it seems to get an incorrect guess at 3 or 4 coin flips because I can't get higher than 4. I wanted to analyze what's happening by making data a longer string (the web3.js documentation says it's a bytes string I believe), but I didn't know how to do that without interfering with the boolean input of the function argument. So I tried making data an array:
web3.eth.sendTransaction({from: player, to: contract.address, value: 0, data: [contract.flip(Math.floor(parseInt((await web3.eth.getBlock(await web3.eth.getBlockNumber()-1)).hash.slice(2),16) / factor)), "hello"]})
This didn't work, and the testnet etherscan still only has this as my input data:
Function: flip(bool _guess) ***
MethodID: 0x1d263f67
[0]: 0000000000000000000000000000000000000000000000000000000000000001
I'm assuming since the function flip only has 1 argument, it wouldn't accept an array like this. Is there not a way to add more data to the data parameter of sendTransaction() ? I want to confirm that it is not luck that I got 4 and 3 successful coin flips before going back to 0, and I want to see if when I guess incorrectly with this function, it's missing the getBlock by 1 block, or see if it's sometimes getting the block wrong by a few blocks. I kind of like Google Chrome's console where I'm running these JS scripts, and I believe it's only possible because metamask or the ethernaut contract created an instance (a web3 instance with web3.js?) on the console for me? I wanted to try to see if I can hack each contract in Ethernaut with just the console, so that's why I'm looking for a different solution, but I'm not sure if I can do it by just calling functions in the console, or if I need to create a contract with a script, and then call the functions of that contract with JavaScript. To deploy a contract, you put the smart contract literally as the data argument into a sendTransaction function, right? Does that mean that the data argument of a sendTransaction() function is interpreted in Solidity language/syntax, even though the sendTransaction function is in JavaScript and ran from a JavaScript console? Is there a way to send more data to each transaction to monitor and analyze what's happening with my script?
Sorry for so many questions, I'm still a relatively newbie coder/developer/whatever this is called, and I'm just thankful for Ethernaut as a tool, but I haven't deployed smart contracts and I wanted to try hacking from just a JavaScript console. (I did send a transaction from windows cmd.exe through an instance created by Alchemy, but I don't even have Truffle yet or know how to use it to deploy a contract, and I like the instance Google Chrome and Metamask created).
Thanks in advance!