If you have worked with Ethereum then you must have written smart contracts, and thus most probably used the keyword private
. It seems like it does its work well. Right? Well, actually not when it comes to keep secrets on ethereum.
Anyone in this world with a blockchain explorer can see your so called private variables.
Sounds ridiculous, but yes its true. Let’s see how to hack a contract.
Hacking Smart contracts
Let’s take a vulnerable contract.
It’s basically a game: an odd-even multiplayer game contract, which chooses the winner based on the numbers guessed. Each player chooses a number and if the sum is even then the first player wins, otherwise the second player wins.
The game contract stores the bets of two players in players
mapping. Since this variable is declared as private, the second player cannot read the data. Each player has to transfer 1 Ether to the contract in order to play. This condition is checked using require
. Once the second player places his bet, the winner is selected based on the odd-even logic and gets the whole bet amount of both players.
Let’s place our bet(execute play(100)
). As the number we bet is private so no one can see it. It’s like a secret…
But wait. Let’s see what actually happened when we executed this transaction.
State changes in Ethereum are usually done through a transaction. If the receiving account is a contract in a transaction, the EVM runs the contract’s code either to completion or until the execution runs out of gas.
Details, such as which method to call and input parameters are specified in the data field of each transaction. For example, for modifying a private state variable in the contract, you need to pass the “private” value to the setter method through a transaction. Considering the fact that every transaction data is visible to all the nodes, you could easily read private variables if you know the transaction.
Let’s look into the odd-event contract that we discussed above and see how you can decode the transaction data.
For every method call, the transaction data will have 2 fields:
In our smart contract, call to the method will have the following transaction data. Let’s try to decode this.
0x6587f6ec0000000000000000000000000000000000000000000000000000000000000064
First 4 bytes of the transaction data always points to the method signature. It is calculated by taking the first 4 bytes of keccak
hash of the method signature. In our example, it is bytes4(keccak256('play(uint)'))
which is 0x6587f6ec
.
The following characters point to the parameter of the specified method. Each parameter is represented by the hex value of the input padded to 32 bytes. If 100 is the input parameter to play
method, then the transaction data for that parameter is:
0x0000000000000000000000000000000000000000000000000000000000000064
BUSTED!
Well, now any one with a block explorer and a bit of knowledge can place his 2nd bet accordingly and rip you off.
This can get more complex if there are more parameters and they are dynamic. You can get more details about argument encoding from the official solidity documentation.
The question now comes is that is there any way to avoid this kind of hack? Well there are some solutions to this:
privateFor
variable which will only allow the recipients to see the data parameter; while others will receive a blank data parameter. (I have left a lot of details here on how the it works. You can find them here).Thanks for reading;)
Hold down the clap button if you liked the content! It helps me gain exposure .
Want to learn more? Checkout my previous articles.
5 resources to get started with ethereum_Ultimate guide for understanding & starting with ethereum._hackernoon.com
ContractPedia: An Encyclopedia of 40 Smart Contract Platforms_A Complete List of all Smart Contract supportive Platforms The blockchain is changing the world as we know it today. It…_hackernoon.com
ConsensusPedia: An Encyclopedia of 30 Consensus Algorithms_A complete list of all consensus algorithms._hackernoon.com
Difference between SideChains and State Channels_A complete comparison of the two scaling methods._hackernoon.com
EOS 101: Getting started with EOS, Part 1_The only blockchain which has blocktime of less than a second: 0.5 sec!_hackernoon.com
Clap 50 times and follow me on Twitter: @vasa_develop