历史是前进的, 从第一个创世区块的产生和以太坊协议的部署开始, 人类社会就迈出了走向未来社会变革的伟大的一步.
CT degens: CT stands for Crypto Twitter, degens refer to a link-minded group who buys crypto asset not because they believe in it, but because they believe someone else would buy it from them.
GM: good morning
GN: good night
GMI / WAGMI: we all gonna make it
NGMI: not gonna make it
Ape: taking a large position in relative to one's portfolio size (related to BAYC?)
Probably Nothing: "Probably Something"
Mint: interact with contract to get something
IYKYK: If You Know, You Know
Few: few understands
Normies: people who don't touch cryptos
Shill: Shilling is when someone is actively promoting a certain behaviour with a hidden motive.
LFG: Let's fucking go. [Rocket] [Rocket] [Rocket]
FOMO: fear of missing out
Cope: opposite of FOMO
Central Bank Digital Currency (CBDC): CBDC Tracker
centralized power can control deflation, inflation easily
prevent collapse of national currency
Decentralized Digital Identifications (DDID): by zero-knowledge proof
provide legal recognition for DAO
and some regulation impacts
Get Anonymous Crypto:
[ENS] Domain: a domain service for wallet address
Pay Per Share (PPS): accept share and aggregate using pool's risk by estimate average, without fee.
PPS+: PPS with fee.
Pay Per Last and Share (PPLNS): online averaging, sharing both fee and block.
Stale Share: either result send to centralized pool is correct but someone is ahead of you
LHR Hack:
How to Increase Mining Hash Rate. Unlocking LHR Graphics Cards with Gminer and its related Reddit
Operating System and Driver Version impact Hashrate: choose 470.74
with HiveOS
Operating System: HiveOS
Here is a Good Intro Video by 3B1B.
区块链是由比特币创造的, 所以我们先说比特币. 比特币是一种分布式账本. 我们先用一个例子来说明.
假如有这样一个城市, 城市的人民为了节省制造货币的材料而不使用货币, 取而代之的是, 城市中所有的人会把自己和所有其他人的收入和支出记在一个小本本上, 这样一来每人都知道其他人的余额, 以方便日后一对一的交易. 于是, 每个人在买东西的时候都会大叫一声: 嘿, 我要给张三 10 块钱, 这是第 204 笔交易. [前面 203 笔交易的总结文本], [加上这笔交易后的总结文本]
. 注意, 嘿, 我要给张三 10 块钱
是数字签名过的信息: 大家都能读取消息的内容并且可以验证这条消息是谁发出的. 其中两个总结文本是所有人钱包余额的总结文本, 这两条文本确保了每个消息只能记录一次. 由以下公式得出. 大多数人纷纷拿起笔抄了下来.
\text{总结文本}_{t+1} = 总结(\text{总结文本}_{t} + \text{新交易})
接下来我们看看任何一方如果不诚实会发生什么:
如果 [前面 203 笔交易的总结文本]
是错误的, 那么听到第 204 笔交易的人们可以查阅自己的账本上写着的 [前面 203 笔交易的总结文本]
看看两份总结是否对的上. 如果对不上, 怕是自己漏听了前面的交易. 这样就不会把这笔对不上的交易记下来. 如果发现交易有错, 即可继续交头接耳直到收到正确的信息后记录在案, 否则拒绝信息.
如果买方故意把喊得声音太小(或许有人离得太远或者耳背), 导致只有镇子上 49% 的人听到了第 204 笔交易. 这不可能发生, 因为大家都想知道真实的交易, 所以会交头接耳共享信息.
Here is a deeper dive into mechanics of P2P Network implementation
nonce: Cryptography order of transection, increase by exactly 1 for each transection. If it is the same as historic transection, they are seen as the same transection. Having nonce can invalidate historical un-mined transection and replace it with higher gas fee for quicker mining.
Wallets: a pair of private key and address (without public key). Usually you can find address by using only private key. This process is polynomial time but reverse process is NP-hard.
Paper Wallet: Paper Wallet is private and public key you can write down on paper.
Public Key: the address to give to people asking for money
Private Key: keep it secret
MetaMask: Open source Ethereum wallet, probably the only wallet on browser.
挖矿: 一种争夺记账权并且通过共识系统获得奖励的方式. 全网总算力越大, 单个服务器收益越小
爆块奖励:
大约每 10 分钟一个区块, 大约每 4 年减半
2009: 一个区块 50 BTC
2012: 25
2016: 12.5
2020: 6.25
2024: 3.125
目前比特币总市值小于黄金(12万亿), 当比特币总市值等于黄金时: 57万美元一枚
手续费奖励 (gas fee): 大约每笔交易 0.0005
因为区块大小有限, 算出 SHA256
后不能把所有听到的交易打包
所以服务器挑选手续费最高的交易打包
Gas: calculated by instruction in code, has a limit since smart contract is Turing-Complete
Gas Price: determined by supply and demand by miner and protocol signer
Gas Limit: [21000 ~ ?]
PoW: proof of work (显卡计算 difficult computing problem 挖矿) PoC: proof of capacity (硬盘挖矿) PoS: proof of stack (伪随机挖矿, 且概率正比与已有的 coin)
Transection Speed: It feels to me like we can greatly reduce transection speed if we reduce network latency. This way, we can shorten the block length and decrease PoW to the point that it becomes proof of network latency.
ETC: Ethereum classic, the one originally created by Vitalik Buterin, but hard-forked due to people stole a lot of Ethereum and Vitalik suggest a hardfork, making old Ethereum ETC
and new Ethereum (where the hack never happened) ETH
.
ETH symbol: \Xi
EIP 1559:
current model: user bid on gas fee
new model:
Time line
Nov.1, 2008: Bitcoin Paper
Jan.9, 2009: first BTC block
2013: ETC
Sep. 2014: 60s/block, 5ETC
Oct. 2014: 12s/block, 5ETC
2015: Frontier update
2016: Homestead update
2017: Metropolis (Byzantine) update, 3ETC
2019: Metropolis (Constantinople) update, 2ETC
2020-2021: Serenity Update
2022: currently in progress switching to make ETH
a shard of ETH2
ETH2 (Serenity): beacon and shards chain
Beacon Chain:
validator: Either attesters or proposer, the miner GPU. An address (validator client) can obtain a validators for staking every 32 ETH
shards: 64 Shards chains are running in parallel of Beacon Chain. They are packed into Beacon Chain.
time
Comments
ETH will become one of ETH2 shard
ETH2 shard does not support transection nor contract, they will be tasks for layer2
DAO: 是一个分布式的盈利组织
由 smart contract 来给员工付费
由 tokenometry 来评估员工的工作效果
组织所有人以投票的方式决定 DAO 的行动方式
DAO 的未来是去中心化的分配, 而不是去完全中心化的决策
半去中心化决策: 项目发起人直接招人去干, 后以投票来分配
ICP DAO:
DAO 员想干什么直接投票就是
月底汇报工作贡献, 自拟定 token 工资. 由系统伪随机匹配相近拟定工资的人投票, 是否批准 token 工资
好处
目前的困难
线上很难对接线下 physical interaction
tokenometry 非常难设计的公平
每次投票都需要消耗 gas fee
KYC: Know your customer (调查用户身份)
DAOMaker: DAO Maker creates growth technologies and funding frameworks for startups, while simultaneously reducing risks for investors.
PeopleDAO: buy constitution
激励机制:
stake 越早, 不拿出, 获得的越多
...
In the eyes of banks and regulations, these terms are used
Exchange Traded Product (ETP): Shares in which its value depend on performance of a project
Exchange Traded Funds (ETF): Someone spread money into shares of multiple different project and combine them to minimize risk and sell a portion to you.
Comments: right now asset management products are trying to get approvals to provide cryptocruency into their system so that everybody can "own" (not really) and invest in cryptocruency.
There is a small difference between the word "coin" and "token". See Regulations and Distinguish Between Coin and Token.
Coin: For main-chain, can be used as gas fee. Mainly for value.
Token: Representation, can have utility purpose such as voting and stock. Can exist on multiple blockchain.
Regulation: there is a lot of paperwork to do for release either coin or token
Security Asset Rating List by Regulation: Crypto Rating Council
Token Properties
Locked (Staked): boolean, whether it is used for exchange of other tokens
Burned: boolean, whether it gives to address 0x00
and no longer exists, causing deflation.
Supply: how many tokens exist in world at max
DOGE
: high market cap, low valueYFI
: low market cap, high value (easier to double value?? Why?)MarketCap: multiply number of tokens in circulation (mined, not locked) by current price
Allocation:
Vesting: a process of gradually pre-allocate overtime to prevent selling right after obtain and increase confidence
Inflation: printing more token (APY 5\% ~ 50\%) as incentive, common in PoS tokens, liquidity providers and yield farmers. Will cause total value drop on token. No effect on short term.
Deflation: increase value overtime. No effect on short term. (BTC
is deflationary by accidental lost wallet; ETC
burns token, deflation more than inflation.)
Wrapped Token:
wETH
: Wrapped ether for coding convenience since ETH
itself is not compliant with ERC20
.
wBTC
: wrap BTC
to fit ERC20
. A good video here.
Oracle Machine: get off-chain information including deterministic random number
Chainlink: A decentralized oracle networks (DONs) that use smart contract to query data from multiple centralized source and provide a interface for other contracts.
DOS: A Decentralized Layer-2 Oracle Service supporting multiple heterogeneous blockchains. Use off-chain P2P to ensure decentralization.
DAI
: a stable currency manipulated by MakerDAO, unlike USDT
whose controlled by a company.
xDAI
: side chain (of DAI
?) created by freezing coins with lower transection feeUSDT
: non-algorithmic stable coin (centralized, like USDC
, PACKS
), backed by company called "Tether", on multiple chains. The company promise to exchange 1 USD
to 1 USDT
back and forth.
算法稳定币: 创造需求并通过市场信任而无背书的与法币挂钩的货币. 详见 这篇文章分析
Ren: Enable you to switch asset on different main chain, pay both ETH
miner and BTC
miner with insane gas fee and will probably fail because you don't own any ETH
to pay the miners.
UNI
(Uniswap): a liquidity pool-based currency (on Ethereum) that is used to exchange between currency (ETH
and any ERC20
currency) (source)
Liquidity Pool (Automatic Market Maker): Imagine a pool of tokens filled with DAI
(stable currency) and ETH
. Those tokens are thrown into the pool by Liquidity Providers for exchange of some kinds of Liquidity Token (like UNI
Uniswap)
Liquidity Provider: Set initial relative price between DAI
and ETH
, will promise to supply equal value of both currency.
Automatic Market Maker (Pricing Algorithm): different protocol currency use different algorithm:
UNI
(uniswap): say we have x
many tokens of DAI
and y
many tokens of ETH
, we make sure x \cdot y = k where k is a constant. This is because the ratio of token in the pool dictates the price. When someone buy ETH
in DAI / ETH
pool, this will result in increase of price of ETH
and decrease of price of DAI
. Therefore a larger pool will make the two currency relatively stable (large pool create less slippage).CRV
(curve): use a different protocol that lowers the fee and slippageBAL
(balancer): can have multiple different currency in the same poolSUSHI
(sushi swap): a currency created through vampire attack as a liquidity pool. SUSHI
liquidity provider gets only 0.25\% transaction fee. // QUESTION: is sushi different for each pool or not?xSUSHI
: SUSHI
holder stack SUSHI
to SushiBar
for xSUSHI
and can be redeemed. 0.05\% transaction fee goes to xSUSHI
holder. xSUSHI
token has voting rights. xSUSHI
is also in xSUSHI/ETH
pool.SUSHI
as result of SUSHI DAO
. SUSHI DAO
select newly established token to put on menu
and reward new token holder with SUSHI
. This way, ONSEN
provides liquidity to newly established token and benifit SUSHI
ecosystem since more people might want to invest in new tokens than old ones. // QUESTION: what exactly is the benifit hereSUSHI
are claimable from liquidity farming, \frac{2}{3} are claimable on weekly basis after 6 months.Compound
: A lending, borrowing contract, currency that implements variable supply / borrow APY (annual percentage yield) depending on borrowing supply and demand. Source
Lender: Lender drop TOKEN
as collateral into Money Market for cTOKEN
, where TOKEN
become avaliable for borrowers. Lender also get awarded by cTOKEN
as borrower borrow, and cTOKEN
can be redeemed. How much cTOKEN
does lender get per TOKEN
? That depends on exchange rate (starts with 0.02 and strictly increasing with supply APY). Let e be exchange rate, then #cTOKEN = \frac{#TOKEN}{e}. Lender's cTOKEN
can be traded while borrower's collateral cTOKEN
cannot. Borrower get interests that is proportional the the change in exchange rate between two time frame.
Borrower: Lock certain amount of cTOKEN
(whose value must sometimes be greater than borrow amount) to borrow TOKEN
. cTOKEN
will be liquidated if borrower failed to return money in infinite time (this would likely happen if the value of cTOKEN
drops after borrowing)
collateral factor: how much percent value of a token (ETH
or DIE
, they have collateral factor of 75\%) can be used to borrow other token. At maximum, you can borrow maximum x value of TOKEN
where x is the value of collateral (cTOKEN
) borrower supplies times TOKEN
's collateral factor.
How do contract determine cTOKEN
value: take current price from server highly liquidates exchanges.
AAVE
: Like Compound aTOKEN
, but in top of variable supply / borrow APY, also offer stable borrow APY (fixed in short term, variable in long term) and flash loan (borrow for a time of 1 ETH
transaction).
Lender: aTOKEN
's value is 1:1 ratio to TOKEN
. Interest distributed by increase the value of aTOKEN
.
How do contract determine aTOKEN
value: rely on centralized organization CHAINLINK and fall back to take current price from server highly liquidates exchanges.
Flash Loans: borrow money in one automic transaction (AAVE and dy/dx protocol)
transection: Like SQL database, you can code up a transection that takes multiple steps. If the transection fails, everything will roll back (but you still need to pay gas feed)
fee split: 0.09\% total for AAVE for depositors (70\%), AVAE API facilitator (6\%), burned in AAVE token (24\%)
risk: gas fee, network speed (front-running), price slippage (depends on size of liquidity pool), price change within a short amount of time.
arbitrage: When CRV
offer 1 DAI = 1 USDC while UNI
offer 0.99 DAI = 1 USDC borrow DAI
at AAVE, swap DAI
for USDC
on UNI
, swap USDC
for DAI
on CRV
, replay DAI
at AAVE
BZXHack: Flash loan were used to manipulate UNI
oracle. Therefore using UNI
as price oracle is risky
Ordered Book Based: loopring, idex
Derivative: contracts that depends on other (future) variables. syntheticx (provide on-chain exposure to different currency)
SNX
) that generate synthetic assets on ETH
. VideoSNX
token into debt poolSNX
which is very high, which is 700\%)Margin Trading: using borrowed fund to increase position (dy/dx, fulcrum)
Insurance: guarantee or compensation, protection of smart contract failure and deposit. (nexus mutual, opyn)
Risk of DeFi:
Yield Farming: make max profit out of compound, uniswap, curve, synthetics, balancer
by move funds around (crop rotation). They can profited by fees and extra incentive mechanics of a currency.
lending, borrowing
liquidity pool
staking tokens
Cross-Chain Transfer:
Multichain: formally known as AnySwap
Opensea: biggest and centralized NFT trading platform with instane fee OpenDao: DAO created for NFT community, may be protest against Opensea.
Minecraft Voxel home plot:
Axie: 卡牌对战游戏, 需要购买 3 只 AXIE
启动资金.
PVE: 每日任务, 农夫玩家
PVP: 排名赛获得 AXS
(限量发行 2 亿 7 千万), 有投票权, 可育种
每日任务: 获取 SLP
(150), 无发行上限, 可育种
缓和通货膨胀: 货币供给和回收机制
Chain: Ronin Ethereum Sidechain
Here is a good article about GameFi in 2022
BlokTopia: Metaverse for news exchange and publication
DarkForest: hidden information game, with its zkSNARKs
to make a game interesting, it should be either NP-hard (so that computer are as bad as human) or hidden information game
otherwise, there exists tricks to let the computer do all of the work
note that computer can also approximate NP-hard problems better than human using DeepLearning
the value comes from PoW of brain power!
DarkForest is probably the only game I aspire in the blockchain world. For game developers, Here are articles on how to make on-chain game competitive.
Stepn: Stepn run to earn. Gamify running.
Nouns: Nouns, mint one avatar every day, bid for on-chain identity.
Wolf Game: Wolf // TODO
Kantan Game: Kantanainu, play-2-earn battle PC game
The Crypt Game: Crypt, Loot-based Dungeon Raiding for Forbidden NFT Relics. Twitter
Topology.gg: Topology, developing on-chain physics on StarkNet chain. Twitter
Special Gaming Mechanisms:
governance and developed by players
slow transection speed encourage strategic games
universal identity can be used to go accross games
computational power encourage hard games
bots-vs-human: id-verification
client agnostic: but ui is important
Resources Website:
Some Free 3D Models & Textures:
http://www.davidoreilly.com/library
https://www.turbosquid.com/
https://free3d.com/3d-models/fbx
https://3dwarehouse.sketchup.com/search/?searchTab=model
https://sketchfab.com/
https://opengameart.org/
https://www.mixamo.com/#/
https://texturehaven.com/textures/
Free Skyboxes:
Dark Forest
Running on xDAI
You can get a little bit xDAI
on xDAI Faucet
Mining map on CPU
local storage / index db on browser (map size about 30MB)
How to Play:
Planet Types:
big planet are in deep space
shallow space have higher defense
some planet have special property
Planet Utility:
battery: small planets serve battery for other planet
S-curve: energy 50% is most efficient
npm install --global yarn
npm install -g @darkforest_eth/gamelogic
npm install -g @projectsophon/df-plugin-dev-server
以我的观点, Metaverse 可以是一个游戏平台, 一个社交平台, 一个购物平台, 但绝对不是一个生活平台, 而且 VR 不是必须 (除非它是一个增强版本的 AR 世界).
如何高效的购物: 你传送到一个虚拟购物商城, 加速逛商店, 一家商店就停留 3~4 秒
如何高效社交: 去虚拟酒吧, 匹配人, 单间或大厅讲堂
如何高效游戏: 参见 roblox
New Launchpad on The BLOK on BlockTopia:
Sipher: game with good vision and roadmap
Sunflower Farmers: Plant, Craft, Chop, Mine, Fight, Earn. Sunflower Farmers, Open source, no pre-sale and no premine.
// TODO
ENS: Decentralized naming for wallets and websites, selling .eth
domain owned by Ethiopia. They have their token named ENS
for its DAO.
Public Good on blockchain: Issue with funding public good, and half-solution with DAO
// TODO
Quadratic Funding: a proposed smart way to distribute funding money by quadratic formula that says your voice is square root of your money. Video
Opensource Project Funding:
uniswap grants
ohm grants
arweave grants
Metafora // TODO: ...
Side Chain: independent chain, but will update once awhile on Ethereum main chain
Usually: proof of stake, delegated proof of stake
Ethereum Compatible: they support EVM and DApp, but code need to deployed separately on side chain
Security: depend solely on nodes on side chain
Plasma Network: kinda like beacon, shard to the extreme? // TODO
Rollups: based on EVM start contract, batched transection - ZkRollups: transections are by default guilty unless proved innocent - OptimisticRollups: assume correct unless (fraud) proved guilty, has a dispute period
Loopring: lower gas fee layer 2 solution
Polygon (MATIC
): side chain PoS solution with plasma network
burning MATIC
gas
Bridge: PoS bridge, Plasma Bridge
working on: Polygon-Hermez Merge, zkRollup (live), OptimisticRollup
Optimism: main-net with optimistic roll up
Arbitrum: optimistic roll up
Layer-2 Solutions:
Channels: only submit transection result to base chain
Plasma: allow copies of main chain
Side chain: xDAI
Rollups: combine sidechain transection as proof and submit to main chain as one transection
Diem
: Diem (formerly known as Libra) is a permissioned (regulated) blockchain-based payment system proposed by the Meta (formally Facebook). It is regulated with Libra Association (later renamed to Diem Association) founded in Geneva, Switzerland. The currency and network do not yet exist. The launch was originally planned to be in 2020,[3][4] but only rudimentary experimental code has been released.
Worldcoin
(ERC20): use iris tracing (scanning eyes) to give people basic income. Personal info will be collected and the idea of basic income may be a flaw. See Youtube
MetaHero: bring on the next 10 million new users to cryptocurrency
Good tech to research:// TODO
zkSync: zkSync solves Ethereum scalability with zero security compromises
Starkware: STARK Proof Pioneers Bringing scalability, security and privacy to a blockchain near you
Bittensor: decentralized machine learning
Web3: Web3 increase data accessability from individual companies to everyone while stress data ownership to individuals.
Subgraph: an oracle of blockchain historical data provider
Basically a utility chain that governs which blockchain data should be collected, and distributed
How to learn?
CryptoZombies: https://github.com/loomnetwork/cryptozombies-lesson-code
Chainlink Starter Kits:
From BuildSpace
Intro to web3 -- build a web3 version of Twitter: https://buildspace.so/solidity
Mint your own, custom NFT collection: Note: This is one is perfect if you’re confident in your web dev skills. https://buildspace.so/build-nfts
Ship an epic Web3 app on Solana with React/ Rust: https://buildspace.so/learn-solana
Build your own DAO with just Javascript: https://buildspace.so/daos
Build a turn-based, NFT browser game on Ethereum: https://buildspace.so/nft-game
Build an NFT collection Solana with just Javascript: https://buildspace.so/solana-nfts
// You can take the projects in any order you want, can even sign-up for all 3. But, if you're not super confident in picking up new tech -- we'd recommend taking the "Intro to Web3" project first. If you're pretty confident in your ability to pick up new tech, the NFT or game project would be good!
// Each project will probably take you like 5-10 hours. Depends on your skill level.
// Learn JS: https://scrimba.com/learn/learnjavascript, Learn React: https://scrimba.com/learn/learnreact
Hackathon:
Jobs:
Example Project: BBoxDAO by @daoleno#1135
EVM: Ethereum Virtual Machine
Chainlist: networks that support EVM
Smart Contract: contract (with an address) on blockchain coded by Solidity (Programming Language). Since it stores in specific chain, there exists no cross-chain contract.
ERC20
: A interface protocol for creating new currency on ETH using smart contract. There is a unintended behavior in which implementations of ERC20 only accept a certain currency to exchange for the implementation. If wrong currency is used, those tokens in wrong currency will be lost.
ERC223
: The above problem is fixed in this new protocol. (source: ERC20 tokens - Simply Explained
ERC1155
: Mix of ERC20
and ERC223
by creating metadata field. You can create it in one contract and transfer once. Here is a good video explaning the concept.
Good Stuff to Read:
ERC1155: Read docs on Open Zeppelin
Frontend Libraries: web3.js
, ethers.js
connect MetaMask
Backend Libraries: Hardhat and Truffle Suite (for localhost contract testing with MetaMask), Ganache (for simulating blockchain locally), Openzeppelin (for template), Waffle (automatic unit test)
Offchain Storage: IPFS
(decentralized file sharing), OrbitDB
and ThreadDB
(database built on top of IPFS
)
FileCoin
Arweave
: See Near's Documentation
Decentralized Internet Provider: Helium
WebIDE: Remix IDE
Mirror: write articles on chain
connect to wallet and got an Mirror address
chains: storage on AR
address and linked to ETH
address
WRITE
: new user gets 0.01 WRITE
you get airdrop by publishing good articles
$WRITE RACE: https://mirror.xyz/race
RSS3:
Fantom: deployment DApp
Tutorials Series: // TODO: clean up
npm
stands for node package manager. However, npm
has multiple versions, so it is suggested to install nvm
to comtrol the versions of npm
and node
. To install nvm
:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
nvm install
If nvm
not found, you should add path to ~/.bashrc
. Sometimes reopening terminal does not work, this typically happen when you are using ~/.zshrc
instead of ~/.bashrc
(strangely bash
does not run ~/.bashrc
too). In this case, you need to run the following command or add the following command to your ~/.zshrc
:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completio
After installed, you should be able to use node --version
to find out your current version of npm
. Other often used commands of nvm
are:
nvm current
: show you whether it is using system-wide npm
or npm
that is installed through npm
.
nvm use v16
: switch to npm
with version 16
.
nvm install 16
: install version 16
of npm
When you first install, it will make your first installation default version:
Now using node v16.17.0 (npm v8.15.0)
Creating default alias: default -> 16 (-> v16.17.0)
Note that nvm
don't switch version for every opening of terminals. To set default behavior: do nvm alias default 16.14.0
To check system-wide installation: npm list -g --depth=0
. The place where the install package is is npm bin -g
.
If you encountered errors about nvm is not compatible with the npm config "prefix":
npm config delete prefix
npm config set prefix $NVM_DIR/versions/node/v[YOUR_VERSION]
If you installed package using nvm
provided npm
, you should see those package in /home/koke_cacao/.nvm/versions/node/v16.14.0
where ${NVM_DIR} = /home/koke_cacao/.nvm
. If you don't see them, and find out that you nvm use 16
and it installed to /home/koke_cacao/.nvm/versions/node/v17.5.0
instead, then it is your .npmrc
made this behavior. You can solve this simply by removing .npmrc
. This behavior is documented here
We install yarn globally npm install --global yarn
.
Sometimes, when you do yarn global add [package]
, you cannot find the package you installed. You need to add yarn's package directory to path. Normally, you can do PATH=/home/$USER/.yarn/bin:$PATH
Now, npm
is not a good package manager, to migrate from npm
to yarn
, simply run yarn
in project directory. See migration guide for detail.
So there are 2 versions of yarn
, use classic version for now. Don't use yarn2
or yarn3
.
We have node
, nvm
, npm
, yarn
, corepack
node
is the package we want
npm
and yarn
manages node
-related packages
nvm
manages node
version
Normally, you do not need standalone version of solidity. Your Truffle
or Hardhat
(and even VSCode
) will provide solidity versions for you.
Just install hardhat or truffle. Those libraries will automatically detect the version of solidity you need and install them when you try to compile.
You can download solidity
VSCode
plugin at configure it to use remote
. Note that this VSCode
's solidity
is a online version of solidity.
If you insist, to globally install solidity compiler, you do: npm install -g solc
.
Now you have solc
package, try soljs --help
.
npm install -g truffle
: install truffle test suit
npm install -g ganache
: install ganache for EVM server (recommanded, its the same as ganache-cli on Linux. Set port to HTTP://127.0.0.1:8545
when using graphical interface)
npm install -g ganache-cli
: install ganache command line interface for EVM server
truffle create test Egg
: create sample tests for Egg
contract
truffle console --network development
: running truffle server for debug (good with ganache). You can get accounts with let accounts = await web3.eth.getAccounts()
.
truffle develop
: spawn a EVM at port 9545
When testing, run ganache-cli
or ganache
to start the EVM server. And then deploy contract using truffle migrate
(you can use --reset
to run all your migrations from the beginning) and test contract using truffle test
. Note that truffle also comes with a solidity
version.
If you are on linux, use ganache
server if you wish to use command line. Use .AppImage
version if you need graphical interface.
Setup Project:
yarn init -y
yarn add hardhat
yarn hardhat
(This will install additional packages: @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers
)
Then, you can use these commands:
yarn hardhat accounts
yarn hardhat compile
yarn hardhat clean
yarn hardhat test
yarn hardhat node
node scripts/sample-script.js
yarn hardhat help
yarn hardhat run scripts/deploy.js --network localhost
All the settings are in hardhat.config.js
. Here is a Good Hardhat Workflow Tutorial
Node.js is a Javascript engine. It is not a framework.
run npm install express
in project directory will install express framework
node_module
will be created in project directory when run above command (or install any module for the first time)
all packages should be installed locally unless it provides an executable command that you run from the shell (CLI), and it's reused across projects
There are a few important package for web server:
yarn add express
: express minimalist framework (here is a good Express Tutorial)yarn global add nodemon
: automatic refresh webpage upon changeComplete Architecture and Testing Environment
npm init -y
: run in the project directory to init package.json
file for node project after doing touch index.js
{
"name": "cryptoeggs_frontend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Just replace every npm
with yarn
and install
with add
.
PM2 runs our node.js
application as a background process in production environment.
To install PM2: yarn global add pm2
(yarn install -g pm2
is depricated)
To run PM2 server: pm2 start app.js
Show all apps running: pm2 status
Rstart apps: pm2 restart app.js
Stop apps: pm2 stop app.js
Show logs: pm2 logs
Flush logs: pm2 flush
Setup automatic launch when server starts: pm2 startup ubuntu
When automatically setup init script, pm2
may tell you do to the following command.
sudo env PATH=$PATH:/home/ubuntu/.nvm/versions/node/v16.17.0/bin /home/ubuntu/.config/yarn/global/node_modules/pm2/bin/pm2 startup ubuntu -u www-data --hp /home/ubuntu
The -u
flag is to specify which user you want to execute pm2
as and the --hp
flag is to specify home directory. env PATH=$PATH:/home/ubuntu/.nvm/versions/node/v16.17.0/bin /home/ubuntu/.config/yarn/global/
is just run pm2
command with some environment variables. After you run the command, it will create /etc/systemd/system/pm2-ubuntu.service
for you.
Here is a full tutorial on how to depoy npm
apps.
If you try to install dependency for front end, you are in trouble because browser parser don't understand import
or require
. You need to use some sort of Module Bundlers for frontend development. Here is a good overview on what is module bundler
There are choices:
Webpack is a pipeline to transcribe any code and pack them, with many customization
rollup
snowpack
Vite: fast bundler with convinient defaults, good for small project. Here is a Good Tutorial
Browserify: loads frontend require
dependency to create bundle.js
. It also support addons to support import
and make the code minified.
Videos To Learn
ether
: 1 ETH
wei
: there are 10^{18} wei
in one ether
event: A ethereum logging system, for front end to listen (instead of constantly refresh). Data in logging can't be access by contracts, but are emitted by contracts. I guess servers don't need to store them if they don't want. For detailed explanation: Events and Deployment
indexed
: indexed parameters are more searchable, since non-indexed parameters are abi
-encoded (cost less gas), you have to know the abi
to decode them.
In Etherscan, you see:
abi
or not)events are good if you have some data you want to be historically recorded on the blockchain so you can read it from your app's front-end, but not within contract
Stackoverflow answers why events
are cheap: EVM nodes are not required to keep logs forever and can garbage collect old logs to save space. Dapps listening for these logs cannot rely on them being persisted forever (e.g. really old events), but can probably listen to new events as a means of updating on changes.
Here is a good article about EVM logging system.
Official Doc says that logs "stay there as long as a block is accessible (forever as of now, but this might change with Serenity)" but nodes can delete them.
```solidity zombiefactory.sol pragma solidity 0.4.19; // engine version, don't use [^] since it may create bug
// with "@chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol"; you can import code from Github import "./ownable.sol";
contract ZombieFactory is Ownable{ event NewZombie(uint zombieId, string name, uint dna);
// 通常情况下我们不会考虑使用 uint 变种, 因为无论如何定义 uint 的大小
// Solidity 为它保留 256 位的存储空间. 例如, 使用 uint8 而不是 uint (uint256) 不会为你节省任何 gas.
// 除非把 uint 绑定到 struct 里面
uint dnaDigits = 16; // globals
uint dnaModulus = 10 ** dnaDigits;
struct Zombie {
string name;
uint dna;
}
// dynamic array
// public will automatically create a public getter function
Zombie[] public zombies; // read only
// mapping to user data
mapping (uint => address) public zombieToOwner;
mapping (address => uint) ownerZombieCount;
// private means no user can call this function, for contract internal use, not even child contract
// internal 和 private 类似, 不过, 如果某个合约继承自其父合约, 这个合约即可以访问父合约中定义的 "内部" 函数.
// external 与 public 类似, 只不过这些函数只能在合约之外调用 - 它们不能被合约内的其他函数调用.
// private < internal < public < external
function _createZombie(string _name, uint _dna) internal {
// in some cases, [push] will not increase array length
uint id = zombies.push(Zombie(_name, _dna)) - 1;
// add to mapping
// msg.sender here is internal function, address of contract signer
zombieToOwner[id] = msg.sender;
ownerZombieCount[msg.sender]++;
// broadcast
NewZombie(id, _name, _dna);
}
// view: can access contract data, cannot write. Does not cost gas (when called externally, or internally with no non-view parents) because it only queries 1 node instead of all.
// pure: cannot read, cannot write
// keccak256: a function that generates 256位的16进制数字. Unsafe for blockchain.
function _generateRandomDna(string _str) private view returns (uint) {
uint rand = uint(keccak256(_str));
return rand % dnaModulus;
}
// require: will refund gas fee to caller
// assert: will not refund, something horrible goes wrong (like overflow when using SafeMath library)
function createRandomZombie(string _name) public {
require(ownerZombieCount[msg.sender] == 0);
uint randDna = _generateRandomDna(_name);
_createZombie(_name, randDna);
}
}
```solidity zombiefeeding.sol
pragma solidity ^0.4.19;
import "./zombiefactory.sol";
// interface: just a code template for the interpreter. No real connection.
contract KittyInterface {
function getKitty(uint256 _id) external view returns (
bool isGestating,
bool isReady,
uint256 cooldownIndex,
uint256 nextActionAt,
uint256 siringWithId,
uint256 birthTime,
uint256 matronId,
uint256 sireId,
uint256 generation,
uint256 genes
);
}
// inheritage: literally adding code from ZombieFactory to ZombieFeeding
contract ZombieFeeding is ZombieFactory {
// Below implementation would not resist new contract version of Kitty
// address ckAddress = 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d;
// referencing a contract instance by its address (remember, there is only one instance for every contract)
//KittyInterface kittyContract = KittyInterface(ckAddress);
KittyInterface kittyContract;
// use [onlyOwner] decorator, see [ownable.sol]
function setKittyContractAddress(address _address) external onlyOwner {
kittyContract = KittyInterface(_address);
}
function feedAndMultiply(uint _zombieId, uint _targetDna, string _species) public {
require(msg.sender == zombieToOwner[_zombieId]);
Zombie storage myZombie = zombies[_zombieId];
_targetDna = _targetDna % dnaModulus;
uint newDna = (myZombie.dna + _targetDna) / 2;
// Note: solidity does not support string comparison
// to compare content of string, use `require(keccak256(_name) == keccak256("Vitalik"));`
if (keccak256(_species) == keccak256("kitty")) {
newDna = newDna - newDna % 100 + 99;
}
_createZombie("NoName", newDna);
}
function feedOnKitty(uint _zombieId, uint _kittyId) public {
uint kittyDna;
(,,,,,,,,,kittyDna) = kittyContract.getKitty(_kittyId);
feedAndMultiply(_zombieId, kittyDna, "kitty");
}
}
```solidity ownable.sol contract Ownable { address public owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
// constructor, only execute once when contract first created
function Ownable() public {
owner = msg.sender;
}
// create a new decorator to use to decorate other functions
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0));
OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
The machine run one instance of the program, therefore globals are used as storage. When creating local variable from globals, you either specify `memory` to receive a copy of specify `storage` to receive the actual instance. `storage` is a magnitude more expensive than `memory` since `storage` need to be synced with all nodes (regardless of `view`?).
Different Places to Store: [Youtube](https://www.youtube.com/watch?v=wOCIhzAuhgs)
- storage: when changed, will change block data
- memory: when changed, will not change block data, big struct
- stack: stack, small storage like integers
- calldata: data passed to contract during transmission
Payable: a function can be marked as `payable` to accept money. This can be achieved in `web3.js` with `OnlineStore.buySomething().send(from: web3.eth.defaultAccount, value: web3.utils.toWei(0.001))`. And in the backend `require(msg.value == 0.001 ether);`. The contract has an account (contract address) which stores those money to maintain balance. In a function to buy stuff from the seller, buyer will execute the code `seller.transfer(msg.value)`
To get money as a owner from the locked value in contract: Note that the value of `ETH` will change and therefore it is a good idea to allow the owner of the contract to change certain price.
```solidity
contract GetPaid is Ownable {
function withdraw() external onlyOwner {
address payable _owner = address(uint160(owner()));
_owner.transfer(address(this).balance);
}
}
Unsafe Random Number: this will result miner to selectively include transection until random number gives desired outcome
// Generate a random number between 1 and 100:
uint randNonce = 0;
uint random = uint(keccak256(abi.encodePacked(now, msg.sender, randNonce))) % 100;
randNonce++;
uint random2 = uint(keccak256(abi.encodePacked(now, msg.sender, randNonce))) % 100;
Safely Generate Random Number: read StackOverflow. One idea is to use off-chain oracle.
ERC721 Token: a collection of non-identical tokens
contract ERC721 {
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
function balanceOf(address _owner) external view returns (uint256); // how many distinct tokens owner has
function ownerOf(uint256 _tokenId) external view returns (address); // who own this token
function transferFrom(address _from, address _to, uint256 _tokenId) external payable; // either called by [_from] or approved address; emit Transfer
function approve(address _approved, uint256 _tokenId) external payable; // caller approve [_approved] to take [_tokenId] from caller; emit Approval
}
Library: in a contract, call using SafeMath for uint256;
will add extra functions to native datatype.
natspec: commenting style
/// @title A contract for basic math operations
/// @author H4XF13LD MORRIS 💯💯😎💯💯
/// @notice explains to a user what the contract / function does. For now, this contract just adds a multiply function
contract Math {
/// @notice Multiplies 2 numbers together
/// @param x the first uint.
/// @param y the second uint.
/// @return z the product of (x * y)
/// @dev for explaining extra details to developers. This function does not currently check for overflows
function multiply(uint x, uint y) returns (uint z) {
// This is just a normal comment, and won't get picked up by natspec
z = x * y;
}
}
To PERMANENTLY remove contract code: doc
function kill() public onlyOwner {
selfdestruct(owner()); // remaining ether goes to owner
}
[selfdestruct] is the only way for code at a certain address to be removed from the blockchain. This makes it a pretty important feature! Even if a contract’s code does not contain a call to [selfdestruct], it can still perform that operation using [delegatecall] or [callcode].
Here is a good API tutorial.
There are two libraries to use for front end:
web3.js
ethers.js
: Tutorial, Cheat Sheet
Front-end:
Provider: a node on blockchain. To specify provider using infura: var web3 = new Web3(new Web3.providers.WebsocketProvider("wss://mainnet.infura.io/ws"));
Contract Address: generated after deployment
Application Binary Interface (ABI): contracts' interface in JSON
format, given by the Solidity compiler. To instantiate contract: var myContract = new web3js.eth.Contract(myABI, myContractAddress);
call
: for view
or pure
function, execute myContract.methods.myMethod(123).call().then(function(result){// do something});
to run myMethod
with 123
arg.
send
: execute myContract.methods.myMethod(123).send()
to run myMethod
with 123
arg.
window.addEventListener('load', function() {
// Checking if Web3 has been injected by the browser (Mist/MetaMask)
if (typeof web3 !== 'undefined') {
// Use Mist/MetaMask's provider
web3js = new Web3(web3.currentProvider);
} else {
// Handle the case where the user doesn't have web3. Probably show them a message telling them to install Metamask in order to use our app.
}
// Now you can start your app & access web3js freely:
startApp()
})
Note: Metamask uses Infura's servers under the hood as a web3 provider, just like we did above — but it also gives the user the option to choose their own web3 provider. So by using Metamask's web3 provider, you're giving the user a choice, and it's one less thing you have to worry about in your app.
To "listen" to change account event:
var userAccount;
var accountInterval = setInterval(function() {
if (web3.eth.accounts[0] !== userAccount) { // Check if account has changed
userAccount = web3.eth.accounts[0];
updateInterface(); // Call some function to update the UI with the new account
}
}, 100);
To send:
function createRandomZombie(name) {
$("#txStatus").text("Creating new zombie on the blockchain. This may take a while...");
return cryptoZombies.methods.createRandomZombie(name)
// [gas], [gasPrice] are optional, if blank, MetaMask will let the user choose these values.
// [value] is only for [payable] functions
// or use `web3js.utils.toWei("1");`
.send({ from: userAccount, gas: 300000, gasPrice: 140, value: web3js.utils.toWei("0.001", "ether") })
.on("receipt", function(receipt) {
$("#txStatus").text("Successfully created " + name + "!");
}).on("error", function(error) { $("#txStatus").text(error); });
}
To subscribe an event of the contract:
cryptoZombies.events.NewZombie()
.on("data", function(event) {
let zombie = event.returnValues;
console.log("A new zombie was born!", zombie.zombieId, zombie.name, zombie.dna);
}).on("error", console.error);
To get past event:
cryptoZombies.getPastEvents("NewZombie", { fromBlock: 0, toBlock: "latest" })
.then(function(events) {
// `events` is an array of `event` objects that we can iterate, like we did above
// This code will get us a list of every zombie that was ever created
});
Project structure:
├── build
├── contracts
├── Migrations.json
├── CryptoZombies.json
├── erc721.json
├── ownable.json
├── safemath.json
├── zombieattack.json
├── zombiefactory.json
├── zombiefeeding.json
├── zombiehelper.json
├── zombieownership.json
├── contracts
├── Migrations.sol
├── CryptoZombies.sol
├── erc721.sol
├── ownable.sol
├── safemath.sol
├── zombieattack.sol
├── zombiefactory.sol
├── zombiefeeding.sol
├── zombiehelper.sol
├── zombieownership.sol
├── migrations
└── test
. package-lock.json
. truffle-config.js
. truffle.js
Tools:
Ganache: sets up a local Ethereum network, it creates 10 test accounts and gives them 100 Ethers
Chai
Sample Test Code
const CryptoZombies = artifacts.require("CryptoZombies"); // contract name
const zombieNames = ["Zombie 1", "Zombie 2"];
contract("CryptoZombies", (accounts) => {
let [alice, bob] = accounts; // Ganache function
let contractInstance;
beforeEach(async () => { // hook that execute in front of every [it]
contractInstance = await CryptoZombies.new();
});
it("should be able to create a new zombie", async () => {
const result = await contractInstance.createRandomZombie(zombieNames[0], {from: alice}); // [from] is contract sender
// These log are automatically created by Truffle as fake events
// [result.tx]: the transaction hash
// [result.receipt]: an object containing the transaction receipt. If [result.receipt.status] is equal to true it means that the transaction was successful. Otherwise, it means that the transaction failed.
assert.equal(result.receipt.status, true); // we can also use [deepEqual()]
assert.equal(result.logs[0].args.name,zombieNames[0]);
});
it("should not allow two zombies", async () => {
await contractInstance.createRandomZombie(zombieNames[0], {from: alice});
await utils.shouldThrow(contractInstance.createRandomZombie(zombieNames[1], {from: alice}));
});
// [context] is to group tests together
context("with the two-step transfer scenario", async () => {
it("should approve and then transfer a zombie when the approved address calls transferFrom", async () => {
const result = await contractInstance.createRandomZombie(zombieNames[0], {from: alice});
const zombieId = result.logs[0].args.zombieId.toNumber();
await contractInstance.approve(bob, zombieId, {from: alice});
await contractInstance.transferFrom(alice, bob, zombieId, {from: bob});
const newOwner = await contractInstance.ownerOf(zombieId);
assert.equal(newOwner,bob);
})
// will not run [xit]
xit("should approve and then transfer a zombie when the owner calls transferFrom", async () => {
})
});
afterEach(async () => {
await contractInstance.kill();
});
})
To use time-travel:
evm_increaseTime
: increases the time for the next block. Note since all transections are assumed to be execute in one block, evm_mine
is needed to reflect time change.
evm_mine
: mines a new block
it looks like in newer version we can mine a block at exact time
here is a blog about managing time in complex test
javascript tests/helper/utils.js
async function shouldThrow(promise) {
try {
await promise;
assert(true);
}
catch (err) {
return;
}
assert(false, "The contract did not throw.");
}
module.exports = {
shouldThrow,
};
Some Bad Hardhat Tutorial:
Because we uploaded only machine readable bytecode to blockchain, in order to make people trust our code (Json) and use our code (ContractABI)
Verifying Contract Using Blockscout: Here
Contract Name: the name of your contract in code
ABI-Encoded Constructor Arguments: What is it?
Standard Input JSON: it is basically sourcecode in one line
Verifying Contract Using Hardhat and Etherscan: Here
Choosing a stack: StackShare
Tutorials on using tools
And there is a very good Tutorial on Etherscan
DeFi Info
Testnet Explorer:
Sokol(SPOA) Testnet: The Sokol Testnet provides an application testing environment for developers planning to use the Ethereum POA Core network.
Blockchain Explorer:
EtherScan: Best tool for Ethereum
Bridge
Opensource Explorer: BlockScout
Token Sniffer: TokenSniffer
Contract Apprival Checker: check wallet approved which contract for how much money
General Explorer:
Gas Fee Explorer:
Trading Bot: Pionex
Swaps Pool:
Token allocation checker:
ETH Merge Simulation: Ultrasound
NFT Platform
L2-Projects: L2Beats - Ethereum L2 systems
Security:
HoneySwapDetector: HoneySwapDetector
Videos:
Timeline: Web3IsGreat
Charts of Blockchain Ecosystem: CryptoDiffer (They maybe outdated)
Rapid News Feed: Telegram
Airdrop Opportunity
Website:
Short-term Problem
GPU overpriced
Environmental Unfriendly
Opensea brings money, but also uneducated investors (most investors will not even look at the tech before putting in their money)
miner extractable value: miner can include, exclude, or re-order transactions within the blocks they produce to arbitrage
how to know the creator, not the copyright owner, is actually selling
Long-term Problem
Reading Lists
Making Sense of Rollups, Part One: Optimistic vs. Zero Knowledge // TODO
Credible Neutrality As A Guiding Principle by Vitalik Buterin// TODO
Everything You Know about the Scalability Trilemma is Probably Wrong// TODO
Future Applications:
distributed AI as contract proof
distributed computing: putting service program permanently on blockchain so that people can sell service that can be permanently purchased and used, every time it gets used, gas fee and fee for original creator is (optionally) generated. The issue with current blockchain is that only data ownership has value. Develop specific algorithm is not profitable. Service is profitable (like selling computing power for specific algorithm)
NFT derivatives: AAA games
opensource DAO-based search engine for searching blockchain articles
on-chain deep learning: web3 increase data avaliability, which improves deep learning
quantum resistent crypto currency
web3的知乎提问平台
web3的搜索引擎
GameFi has to finish and validate a transection faster than human reasoning speed to achieve its full potentiality
Chainlink can be implemented as a on-chain server. Instead of querying and aggregate real-time info, it can just cache info every 1s and collect "gas" from callers, and spend gas ever 1s instead of multiple time per second. And code that automatically fire given some event.
Table of Content