Links
- eth converter (opens in a new tab)
- solidity by example (opens in a new tab)
- send/transferhttps://solidity-by-example.org/sending-ether/ (opens in a new tab)
variables & states
-
states:
public, internal, private
-
string public
message; -
uint256 internal
internalVar; -
uint8 private
privateVar; -
bytes
memory dataFromUser -
address
funder -
funders = new address[](0);
| creates new funder array with 0 obj -
immutable decimal
-
constant MY_HASH
functions
solidity kb (opens in a new tab)
-
external, public, internal, private
-
function fund() public payable
- allows user to pay -
function convertEthToUsd(uint256 ethAmount) internal returns (uint256)
- access within contract or derived -
function doesntAllowOtherContracts() private returns (uint256)
- access within contract only` -
modifier onlyOwner
-
constructor
-
fallback() external payable
-
receive() external payable
Notes
public
,internal
,private
int
can be negative.uint256
,uint8
can't
simple contract
Notes
- modify state of blockchain with
public
e.g.function store(uint256 _favoriteNumber) public
else useprivate
orinternal
- read only state of blockchain with
view
orpure
e.g.function retreive() public view returns(uint256)
- define data locations with
calldata
&memory
(in memory whilst function is running) andstorage
for permamnent storage. storage
won't work as a function param- support for maps with
string => uint256
e.g.mapping(address => uint256) public addressToAmountFunded;
maps an address to a number - working with imported contracts requires
contract address
+contract ABI
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
contract SimpleStorage {
uint256 public favoriteNumber;
People public person = People({
favoriteNumber: 2,
name: "Sam"
});
struct People {
uint256 favoriteNumber;
string name;
}
mapping(string => uint256) public nameToFavoriteNumber;
People[] public people;
function store(uint256 _favoriteNumber) public {
favoriteNumber = _favoriteNumber;
retreive();
}
function retreive() public view returns(uint256){
return favoriteNumber;
}
function addPerson(string calldata _name, uint256 _favoriteNumber) public {
People memory newPerson = People(_favoriteNumber, _name );
people.push(newPerson);
nameToFavoriteNumber[_name] = _favoriteNumber;
}
}
Import + Inheritance
Notes
- contract is like an object, create it with a constructor
Obj currentObj = new Obj()
- child inherits parent contract with
is
- parent function needs to be
public virtual
- to override, child function needs
override
- imports contain
.sol
e.g.import "./Contract.sol"
contract SimpleStorage {
function store(uint256 _favoriteNumber) public virtual{
favoriteNumber = _favoriteNumber;
retrieve();
}
}
//import "./SimpleStorage.sol";
contract ExtraStorage is SimpleStorage {
function store(uint256 _favoriteNumber) public override {
favoriteNumber = _favoriteNumber +5;
}
}
import "./SimpleStorage.sol";
contract StorageFactory {
//deploy an array of SimpleStorage
SimpleStorage[] public sArr;
function deployArrayOfSimpleStorages(){
SimpleStorage s = new SimpleStorage()
sArr.push(s)
}
function sfStore(uint256 _i, uint256 _num){
sArr[_i].store(_num);
}
}
DeFi
Notes
- always multiply before divide. e.g.
var1 * var2 / var3
=(var1 * var2) / var3
- spread unneeded params with commas e.g. if only price is needed, use
( , int256 price , , , )
- Eth in USD is eth price * 1e10 => use converter
msg.sender
msg.value
modifier
run before/after function depending on _ used.
modifier
function withdraw() public Owner{...}
// run withdraw before modifier
modifier checkOwner{
_;
require(msg.sender == owner);
}
// run withdraw after modifier
modifier checkOwner{
require(msg.sender == owner);
_;
}
transactions
- https://docs.soliditylang.org/en/v0.8.17/units-and-global-variables.html (opens in a new tab)
address(this)
is the contract address
Gas Optimization
using immutable and constant
// address public owner; changes into ==>
address public immutable i_owner;
// uint256 public MINIMUM_USD = 1 * 1e18; changes to =>
uint256 public constant MINIMUM_USD = 1 * 1e18;
using errors instead of logging to console
require changes to custom errors before:
require(msg.sender == owner, "sender isn't owner");
after:
// create error above contract declaration
error NotOwner();
contract MyContract {
modifier onlyOwner {
// require(msg.sender == i_owner, "sender isn't owner");
// _;
if(msg.sender != i_owner) {revert NotOwner();}
_;
}
}