Skip to content

Instantly share code, notes, and snippets.

@PatrickAlphaC
Last active February 26, 2021 17:12
Show Gist options
  • Save PatrickAlphaC/f490c0d51141dd0515244db40bbd0c17 to your computer and use it in GitHub Desktop.
Save PatrickAlphaC/f490c0d51141dd0515244db40bbd0c17 to your computer and use it in GitHub Desktop.
// First, a simple Bank contract
// Allows deposits, withdrawals, and balance checks
// simple_bank.sol (note .sol extension)
/* **** START EXAMPLE **** */
// Declare the source file compiler version
pragma solidity 0.6.6;
/* 'contract' has similarities to 'class' in other languages (class variables,
inheritance, etc.) */
contract SimpleBank { // CapWords
// Declare state variables outside function, persist through life of contract
// dictionary that maps addresses to balances
// always be careful about overflow attacks with numbers
mapping (address => uint) private balances;
// "private" means that other contracts can't directly query balances
// but data is still viewable to other parties on blockchain
address public owner;
// 'public' makes externally readable (not writeable) by users or contracts
// Events - publicize actions to external listeners
event LogDepositMade(address accountAddress, uint amount);
// Constructor, can receive one or many variables here; only one allowed
constructor() public {
// msg provides details about the message that's sent to the contract
// msg.sender is contract caller (address of contract creator)
owner = msg.sender;
}
/// @notice Deposit ether into bank
/// @return The balance of the user after the deposit is made
function deposit() public payable returns (uint) {
// Use 'require' to test user inputs, 'assert' for internal invariants
// Here we are making sure that there isn't an overflow issue
require((balances[msg.sender] + msg.value) >= balances[msg.sender]);
balances[msg.sender] += msg.value;
// no "this." or "self." required with state variable
// all values set to data type's initial value by default
emit LogDepositMade(msg.sender, msg.value); // fire event
return balances[msg.sender];
}
/// @notice Withdraw ether from bank
/// @dev This does not return any excess ether sent to it
/// @param withdrawAmount amount you want to withdraw
/// @return remainingBal
function withdraw(uint withdrawAmount) public returns (uint remainingBal) {
require(withdrawAmount <= balances[msg.sender]);
// Note the way we deduct the balance right away, before sending
// Every .transfer/.send from this contract can call an external function
// This may allow the caller to request an amount greater
// than their balance using a recursive call
// Aim to commit state before calling external functions, including .transfer/.send
balances[msg.sender] -= withdrawAmount;
// this automatically throws on a failure, which means the updated balance is reverted
msg.sender.transfer(withdrawAmount);
return balances[msg.sender];
}
/// @notice Get balance
/// @return The balance of the user
// 'view' (ex: constant) prevents function from editing state variables;
// allows function to run locally/off blockchain
function balance() view public returns (uint) {
return balances[msg.sender];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment