timezone |
---|
UTC+8 |
请在上边的 timezone 添加你的当地时区(UTC),这会有助于你的打卡状态的自动化更新,如果没有添加,默认为北京时间 UTC+8 时区
- 自我介绍
Dex 对这个世界保持好奇心->想深入了解以太坊
- 你认为你会完成本次残酷学习吗?
会的
- 你的联系方式(推荐 Telegram)
- Telegram:t.me/dexhunt3r
- Twitter/X:x.com/dexhunt3r
- farcaster: warpcaster.com/dexhunter.eth
先把所有资源看了一下,比如
今天好像已经是week4了,所以需要把之前的内容过一下
- week1
- 大概介绍了下protocol, 历史和哲学
- 以太坊协议设计
- 技术黄皮书
- 实现
- 测试
- 合作
- week2
- week1的链接其实直接先到week3的,不确定为啥,week3对应的是lecture2 consensus,具体看这里
- 执行层
- 区块
- 状态机
- jrpc信息传递
- week3
- 共识层就是PoS,具体看Casper的论文
今天看了week4的内容,主要是关于测试和安全
Running tests using path: /data/tests
Running 1 test case...
Retesteth config path: /var/www/.retesteth
WARNING: Retesteth configs version is different (running: '0.3.2-legacy' vs config '0.3.2-cancun')!
WARNING: Update configs to the latest by deleting the folder `/var/www/.retesteth`!
Active client configurations: 't8ntool '
Checking test filler hashes for GeneralStateTests/stExample
Filter: 'accessListExample Shanghai'
Check `/data/tests/GeneralStateTests/stExample/accessListExample.json` hash
SrcFile `/data/tests/src/GeneralStateTestsFiller/stExample/accessListExampleFiller.yml`
Read json structure accessListExampleFiller.yml
Read json structure finish
Running tests for config 'Ethereum GO on StateTool' 2
Test Case "stExample": (1 of 1)
100%
Instantiated: "evm version 1.15.6-unstable-4cdd7c86-20250310"
Running accessListExample: (6995263567478450108)
Read json structure accessListExample.json
Read json finish
WARNING: Specified filter did not run a single transaction! (GeneralStateTests/stExample/accessListExample, fork: Shanghai, TrInfo: d: -1, g: -1, v: -1)
�*** No errors detected
�*** Total Tests Run: 1
--------
*** TOTAL WARNINGS DETECTED: 3 warnings during all test execution!
--------
info: Retesteth configs version is different (running: '0.3.2-legacy' vs config '0.3.2-cancun')!
info: Update configs to the latest by deleting the folder `/var/www/.retesteth`!
info: Specified filter did not run a single transaction! (GeneralStateTests/stExample/accessListExample, fork: Shanghai, TrInfo: d: -1, g: -1, v: -1) (GeneralStateTests/stExample/accessListExample, fork: Shanghai, TrInfo: d: -1, g: -1, v: -1)
不知道为什么昨天的commit被overwritten了,然后根据读历史的启发今天开始带着问题来学习。 -> 今天想知道的问题是,为什么以太坊主链到2025年了还是这么贵和慢 why is ehtereum mainnet still costly and slow in 2025?
slowness:
blocks produced every 12 seconds and each block containing about 185 transactions on average.
costliness:
The costliness arises from gas fees, which users pay for computational resources. During high demand, these fees spike due to limited block space, and the market-driven gas price mechanism means users must bid higher to get transactions processed quickly. Even with changes like the London hard fork in 2021 introducing a base fee, network congestion still drives up costs.
根据 EIP-1559
Transaction/Gas fee = Gas used × (Base fee + Priority fee)
可能是要等pectra和sharding才能让主链交易变得更快或便宜
References:
继续啃PoS
--> 发现一个简单的python实现 simple casper
不过好像没有测试finality和一些攻击的场景,感觉可以改写试试
原本的casper代码 https://github.com/ethereum/casper 新的代码 https://github.com/ethereum/consensus-specs
validator的条件
- 32 ETH
消减条约 slashing rules
- A validator must not publish two distinct votes for the same target height
- A validator must not vote within the span of its other votes.
参考两本书
以及开始看以太坊源码
关注一下mev
- 看到了siyuan大佬的post
- mev book
- mev book on github
- also take a look at flash bot's mev letters
了解了一些holesky的事情背景 grok summary
总结下 以太坊合约是一个有确定性但实际上无限的状态机(unbounded state machine),主要有两个功能
- 全局可访问的状态 singleton state (distributed single-state)
- 可以改变这个状态的虚拟机
World State 世界状态是 地址 到 账户 的映射,这部分的信息用 Merkle Patricia Trees 存储在数据库后端
我觉得这篇关于以太坊的技术实现文章写的非常通俗易懂,如果有不懂的内容可以参考
看精通以太坊第二章1
1 wei = 1e-18 ether or 1 ether = 1e18 wei
wallet (personal opinion)
metamask-> DO NOT USE (as for March 2025) unless you are lazy -> rabby wallet (the safe one)
don't lose your priv key -> use a cold wallet if possible
- main net
- test net
- ropsten
- kovan
- rinkeby
- localhost/custom rpc
TODO: will read more tomorrow about smart contract and world computer concept
精通以太坊第三章1
几个客户端的实现
- Parity, written in Rust4
- Geth, written in Go
- cpp-ethereum, written in C++
- pyethereum, written in Python
- Mantis, written in Scala
- Harmony, written in Java
第四章,关于密码学,内容比较多,分几天来看完1
椭圆曲线密码学2
- OpenSSL
- Bitcoin's libsecp256k1 -> secp256k1 elliptic curve
- Hash Function
- two types of accounts
- externally owned accounts (EOAs) <- private key + address + signature
- contracts <- smart contract code (executed by EVM)
Based on chapter 5
Ethereum wallets serve as the primary user interface to Ethereum, with two main aspects:
- For users: Applications that manage keys, track balances, and create/sign transactions
- For developers: Systems for key management and storage
Despite the name, wallets don't actually contain ether or tokens – these assets exist on the blockchain. Wallets hold the keys that provide control over these assets.
Wallet Technology Types:
- Each key is independently generated from a different random number
- Also known as "Just a Bunch of Keys" (JBOK) wallets
- More difficult to back up and manage
- Example: Keystore files (JSON-encoded, encrypted by passphrase)
- All keys derived from a single master key (seed)
- A single backup at creation secures all funds
- Seed can be encoded as mnemonic code words for easier backup
- Based on BIP-32 standard
- Keys derived in a tree structure (parent keys → child keys → grandchild keys)
- Provides organizational structure and improved security
Modern wallets typically implement several industry standards:
- Creates a human-readable backup (12-24 words)
- Random entropy → checksum → encode as words → derive seed
- Optional passphrase adds security (but increases risk of fund loss if forgotten)
- Creates tree-like structure of keys
- Extended keys (xprv, xpub) can derive child keys
- Hardened derivation prevents chain code compromise
- Defines purpose and path for HD wallets
- Standard path: m/purpose'/coin_type'/account'/change/address_index
- For Ethereum: m/44'/60'/0'/0/x (where x is the address index)
- Extended Keys: Parent keys that can derive child keys (with chain code)
- Hardened Derivation: Breaks parent-child relationship to improve security
- HD Wallet Path: Naming convention for identifying keys in the tree (e.g., m/44'/60'/0'/0/2)
- Mnemonic Words vs. Brainwallets: Mnemonics are generated randomly by the wallet, not chosen by the user
For implementing Ethereum wallets, build an HD wallet with a seed encoded as mnemonic code, following BIP-32, BIP-39, BIP-43, and BIP-44 standards for maximum security, flexibility, and compatibility.
- Always back up your seed phrase (mnemonic words) in a secure, physical location
- Never store your seed phrase digitally
- Consider using hardware wallets for large amounts of funds
- If using a passphrase with your mnemonic, ensure it can be recovered by trusted parties if needed
Transactions are signed messages originated by externally owned accounts (EOAs), transmitted through the Ethereum network, and recorded on the blockchain. They are the only mechanism that can:
- Trigger state changes in Ethereum
- Cause smart contracts to execute
A transaction contains the following data:
- Nonce: A sequence number issued by the originator to prevent message replay
- Gas price: Amount of ether (in wei) the originator is willing to pay per unit of gas
- Gas limit: Maximum amount of gas the originator is willing to buy
- Recipient: Destination Ethereum address
- Value: Amount of ether (in wei) to send
- Data: Variable-length binary data payload
- v, r, s: Components of the ECDSA digital signature
All transactions are serialized using Recursive Length Prefix (RLP) encoding.
The nonce is critical for two reasons:
- Transaction ordering: Ensures transactions from the same account are processed in the order they were created
- Replay protection: Makes each transaction unique, preventing duplicated payments
Nonces are tracked sequentially for each account. The nonce for a new transaction must be exactly one higher than the previous transaction's nonce.
Tracking Nonces:
- Use
web3.eth.getTransactionCount(address)
to find the current nonce - For multiple rapid transactions, maintain your own nonce counter
- Parity offers
parity_nextNonce
for more reliable nonce tracking
Nonce Gaps and Concurrency Issues:
- Missing nonces will cause subsequent transactions to be held in the mempool
- Duplicate nonces will cause one transaction to be accepted and one rejected
- Concurrency can cause problems when multiple systems generate transactions from the same account
Gas is Ethereum's mechanism for:
- Measuring computational resource usage
- Preventing DoS attacks
- Allocating resources in a fair manner
Two important components:
- Gas price: How much ether per unit of gas (set by the transaction creator)
- Gas limit: Maximum gas units the transaction can consume
Simple ether transfers between EOAs always cost exactly 21,000 gas. Contract interactions vary in cost depending on complexity.
The recipient is specified in the to
field:
- Can be an EOA or contract address
- No validation is performed on this field
- Sending to an invalid address effectively "burns" the ether
Transactions can contain:
- Value only: A payment
- Data only: A contract invocation
- Both: A payment and contract invocation
- Neither: Technically valid but not useful
For contract interactions, the data field typically contains:
- Function selector: First 4 bytes of the Keccak-256 hash of the function signature
- Function arguments: Encoded according to ABI specification
Special Transaction: Contract Creation
Contracts are created by sending transactions to the special "zero address" (0x0):
- The
to
field is set to 0x0 - The contract bytecode is included in the data field
- Optional ether can be included in the
value
field to fund the new contract
Digital Signatures
Transactions are signed using the Elliptic Curve Digital Signature Algorithm (ECDSA). Signatures serve three purposes:
- Authorization: Proves the owner of the private key authorized the transaction
- Non-repudiation: The proof of authorization is undeniable
- Integrity: The transaction data cannot be modified after signing
The signature includes three values:
- r, s: The ECDSA signature components
- v: Recovery identifier that helps derive the public key from the signature
ECDSA Mathematics
The ECDSA signature creation process:
- Generate an ephemeral (temporary) private key
- Derive the corresponding ephemeral public key
- The r value is the x coordinate of the ephemeral public key
- The s value is calculated using the private key, transaction hash, and ephemeral key
note: Signature verification can recover the public key without knowing the private key.
Transaction Signing in Practice
To sign a transaction:
- Create a transaction data structure with all fields
- RLP-encode the transaction data
- Calculate the Keccak-256 hash of the serialized message
- Sign the hash with the private key using ECDSA
- Append the signature values to the transaction
Offline Signing
For security, transaction signing can be separated from transaction transmission:
- Create unsigned transaction on an online system
- Transfer to an offline system for signing
- Transfer the signed transaction back to an online system for broadcasting
note: This process, called "offline signing," helps protect private keys by keeping them off internet-connected computers.
Transaction Propagation
Transactions propagate through the Ethereum network via a flood routing protocol:
- The node with the signed transaction validates it
- It then transmits the transaction to all its neighbors
- Each neighbor validates and retransmits to their neighbors
- Within seconds, the transaction reaches all nodes in the network
Recording on the Blockchain
Valid transactions are eventually:
- Selected by miners for inclusion in a block
- Recorded permanently on the blockchain
- Execute their effect on the Ethereum state
Multiple-Signature (Multisig) Transactions
While Ethereum's basic transactions don't directly support multiple signatures, smart contracts can implement multisig functionality:
- Funds are sent to a contract that enforces signature requirements
- Multisig contracts can have arbitrary signing conditions
- The contract only releases funds when conditions are satisfied
EIP-155: Transaction Replay Protection
EIP-155 prevents transaction replay attacks between different Ethereum networks by:
- Including a chain identifier in the transaction data
- Modifying the signing algorithm to encode the chain ID in the v value
- Making it impossible to replay a transaction meant for one network on another
Based on Chapter 7
What Is a Smart Contract?
Smart contracts in Ethereum are immutable computer programs that run deterministically in the Ethereum Virtual Machine. Despite the name, they aren't "smart" in the AI sense, nor are they legal contracts. They're simply programs deployed on the blockchain that execute exactly as programmed without possibility of downtime, censorship, or third-party interference.
Life Cycle of a Smart Contract
Smart contracts are written in high-level languages (most commonly Solidity), compiled to EVM bytecode, and deployed through special creation transactions. Each contract has a unique Ethereum address but no associated private key. Contracts only execute when called by a transaction, either directly from an EOA or indirectly via another contract. They remain dormant until triggered, and execution is atomic—either fully successful or completely reverted.
Ethereum High-Level Languages
While EVM bytecode is the ultimate language of execution, developers typically write smart contracts in higher-level languages. Solidity is the most widely used, but others include LLL, Serpent, Vyper, and Bamboo. These languages vary in their approach, with some being more declarative (functional) and others more imperative (procedural).
Building Smart Contracts with Solidity
Solidity is an object-oriented language with syntax similar to JavaScript or C++. It includes features specific to blockchain development, such as address types, gas optimization patterns, and built-in functions for Ethereum operations. The chapter walked through building a simple "Faucet" contract that can receive and dispense ether.
The Ethereum Contract ABI
The Application Binary Interface (ABI) defines how to encode function calls and data for the EVM. It allows applications to interact with contracts by specifying the format of functions, arguments, and return values. The ABI is typically output as a JSON structure during compilation.
The chapter covered many Solidity programming features:
- Data types: Booleans, integers, addresses, arrays, mappings, structs, etc.
- Variables and functions: Global variables like
msg.sender
,block.number
, and built-in functions - Contract definition: How to define contracts, interfaces, and libraries
- Function modifiers: For adding preconditions to functions
- Inheritance: How contracts can inherit from other contracts
- Error handling: Using assert, require, and revert
- Events: For logging information and providing return values to the front end
- Contract interaction: How to call other contracts using various methods
Gas Considerations
Gas is a critical constraint in smart contract development. The chapter discussed strategies for minimizing gas consumption, such as avoiding dynamically sized arrays and unnecessary external calls. It also showed how to estimate the gas cost of contract functions.
Smart contract development with Solidity requires understanding not just the language, but also the execution environment, security considerations, and economic implications of your code. This chapter provided the foundation for building effective and efficient smart contracts on Ethereum.
Based onchapter 8
Vyper is an experimental, contract-oriented programming language for the Ethereum Virtual Machine (EVM) It emphasizes readability and security. It aims to make it easier for developers to write intelligible and secure code, reducing the likelihood of vulnerabilities in smart contracts.
Vulnerabilities in Smart Contracts
A study of nearly one million Ethereum smart contracts identified three categories of vulnerabilities:
- Suicidal Contracts: Can be killed by arbitrary addresses
- Greedy Contracts: Can reach a state where they cannot release Ether
- Prodigal Contracts: Can be made to release Ether to arbitrary addresses
Vyper addresses these issues by enforcing a design that discourages writing misleading or insecure code.
- Key Differences from Solidity:
- No Modifiers
- No Class Inheritance
- No Inline Assembly
- No Function Overloading
- Strict Variable Typecasting
- No Infinite Loops
- Explicit Preconditions and Postconditions
- Decorators
@public # Function is accessible externally
@private # Function can only be called within the contract
@constant # Function does not modify state
@payable # Function can receive Ether
Variables and functions must be declared before use:
# Variable declaration
counter: int128
@public
def increment():
self.counter += 1
- Built-in Overflow Protection
- Implements
SafeMath
-like checks automatically - Uses clamps to enforce value ranges
- Prevents execution of overflowing operations
- Data Operations
Global State:
- State variables stored in Ethereum's global state trie
- Contracts can only modify their own storage
Events (Logs):
# Declaration
Transfer: event({from: indexed(address), to: indexed(address), value: uint256})
# Emitting
log Transfer(msg.sender, to_address, amount)
- Compilation Tools
-
Online Tools:
-
Command Line:
vyper /path/to/contract.vy # Compile to bytecode vyper -f json /path/to/contract.vy # Generate ABI in JSON format
Based onchapter 9
- Reentrancy Attacks
Exploiting the ability to repeatedly call a function before previous executions are completed, leading to inconsistent states and potential fund siphoning.
// Vulnerable code example
function withdraw() public {
uint amount = balances[msg.sender];
// Send funds before updating state
(bool success, ) = msg.sender.call{value: amount}("");
// State update happens after external call
balances[msg.sender] = 0;
}
- Integer Overflows and Underflows
Errors occurring when calculations exceed the maximum or minimum capacity of a data type, causing unexpected behavior.
// Vulnerable code example
function transfer(address _to, uint256 _value) public {
// No check if balance >= _value
balances[msg.sender] -= _value;
balances[_to] += _value;
}
- Denial of Service (DoS)
Malicious actions that prevent contract functions from executing properly, often by consuming excessive gas or manipulating contract state.
- Access Control Issues
Incorrect implementation of authorization checks, allowing unauthorized entities to perform privileged actions.
- Timestamp Dependence
Relying on block timestamps for critical contract logic, which can be manipulated by miners within a certain range.
- Unhandled Exceptions
Failing to manage errors or exceptions, which can disrupt contract execution flow and security.
- Code Review and Auditing: Regularly auditing code to detect and fix vulnerabilities before deployment.
- Use Established Libraries: Leveraging well-tested and community-reviewed libraries and frameworks (e.g., OpenZeppelin contracts).
- Thorough Testing: Implementing comprehensive test suites, including unit tests, integration tests, and property-based tests.
- Avoiding Complex Logic: Keeping contracts simple and modular to reduce the attack surface and make auditing easier.
- Fail-Safe Mechanisms: Designing contracts to be secure by default, with appropriate fallback functions and error handling.
- Static Analysis Tools: Utilizing tools like Mythril, Slither, and Oyente to automatically detect vulnerabilities.
- Formal Verification: Applying mathematical methods to prove the correctness of contract algorithms against a formal specification.
- Bug Bounty Programs: Encouraging external security researchers to find and report vulnerabilities through incentivized programs.
- The DAO Attack (2016): An infamous reentrancy attack that led to the theft of around 3.6 million Ether, highlighting the importance of secure coding practices.
- Parity Wallet Bugs (2017): A series of vulnerabilities in a popular wallet that resulted in significant funds being inaccessible or stolen.
- Compliance: Understanding and adhering to legal regulations regarding smart contracts and digital transactions in applicable jurisdictions.
- Transparency and Disclosure: Maintaining openness about contract functionality and potential risks to users and stakeholders.
- Advanced Security Protocols: Development of new protocols and standards aimed at enhancing security.
- Layer 2 Solutions: Implementing off-chain solutions to reduce the burden on the main blockchain and improve security.
- Education and Community Efforts: Growing emphasis on educating developers and fostering a community dedicated to best practices in security.
- OpenZeppelin Security Blog: https://blog.openzeppelin.com/
- Ethereum Smart Contract Best Practices: https://consensys.github.io/smart-contract-best-practices/
- Trail of Bits Security Blog: https://blog.trailofbits.com/
- Currency: Function as a private form of money
- Asset: Represent ownership of tangible/intangible assets
- Equity: Represent shares in organizations
- Resource: Represent shared computing/storage resources
- Access: Grant rights to digital/physical properties
- Voting: Enable voting rights in organizations
- Identity: Represent digital or legal identity
- Attestation: Verify certifications or facts
- Collectibles: Represent unique digital or physical items
- Utility: Access to specific services
- Fungible Tokens: Interchangeable units (like currency)
- Non-fungible Tokens: Unique items (like deeds or collectibles)
- Intrinsic: Assets native to the blockchain
- Extrinsic: External assets represented on blockchain
- Counterparty risk for external asset-backed tokens
- Implementation security considerations
- Gas costs in ether for token transactions
-
ERC20
- Most common standard
- Used for fungible tokens
- Basic transfer and approval functions
-
ERC223
- Proposed improvement
- Prevents accidental token loss
- Enhanced safety features
-
ERC777
- Advanced token standard
- Additional features and hooks
- Backward compatible with ERC20
-
ERC721
- Standard for non-fungible tokens
- Unique asset representation
- Used for deeds and collectibles
- Use established standards for interoperability
- Leverage battle-tested implementations
- Consider security implications of extensions
- Burning
Oracles can provide various types of data, including:
- Random Numbers: For fair selection in games and lotteries.
- Financial Data: Exchange rates, stock prices, benchmark interest rates.
- Weather Data: For insurance contracts and predictions.
- Sporting Events: For prediction markets.
- IoT Data: For supply chain tracking.
There are three main oracle design patterns:
-
Immediate-Read Oracles Provide data needed for immediate decisions. Data is stored in the oracle's smart contract storage and can be accessed directly by other contracts.
-
Publish-Subscribe Oracles Oracles update data regularly, and interested parties can subscribe to receive updates or monitor changes.
-
Request-Response Oracles DApps request specific data, and the oracle retrieves and returns the data asynchronously.
Ensuring the integrity and authenticity of the data provided by oracles is crucial. Two common approaches are:
-
Authenticity Proofs: Cryptographic guarantees that data has not been tampered with, such as TLSNotary proofs.
-
Trusted Execution Environments (TEEs): Hardware-based secure enclaves (e.g., Intel SGX) that securely process and attest to data integrity.
Computation oracles perform off-chain computations and return results to smart contracts. This is useful for resource-intensive calculations that are impractical to perform on-chain due to gas limits.
Examples include:
- Oraclize Offers computation services using AWS virtual machines and Docker containers.
- TrueBit Provides scalable and verifiable off-chain computations via a network of incentivized solvers and verifiers.
Decentralized oracles aim to eliminate single points of failure by using networks of data providers and on-chain aggregation methods.
Examples include:
- ChainLink Uses reputation, order-matching, and aggregation contracts to source data from multiple oracles.
- SchellingCoin Protocol Relies on multiple participants reporting values and using the median as the correct answer, incentivizing honest reporting.
Smart contracts in Solidity can interact with oracles through defined interfaces.
Examples include:
An example contract that uses Oraclize to fetch and update the ETH/USD price from an external API every 10 minutes.
contract EthUsdPriceTicker is usingOraclize {
uint public ethUsd;
event newOraclizeQuery(string description);
event newCallbackResult(string result);
function EthUsdPriceTicker() payable {
oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
queryTicker();
}
function __callback(bytes32 _queryId, string _result, bytes _proof) public {
if (msg.sender != oraclize_cbAddress()) throw;
newCallbackResult(_result);
ethUsd = parseInt(_result, 2);
queryTicker();
}
function queryTicker() external payable {
if (oraclize_getPrice("URL") > this.balance) {
newOraclizeQuery("Oraclize query was NOT sent, please add some ETH to cover for the query fee");
} else {
newOraclizeQuery("Oraclize query was sent, standing by for the answer...");
oraclize_query(60 * 10, "URL", "json(https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD).USD");
}
}
}
An example of a contract interacting with Thomson Reuters' BlockOne IQ oracle service to request market data.
contract OracleB1IQClient {
Oracle private oracle;
event LogError(bytes32 description);
function OracleB1IQClient(address addr) external payable {
oracle = Oracle(addr);
getIntraday("IBM", now);
}
function getIntraday(bytes32 ric, uint256 timestamp) public {
uint256 id = oracle.initRequest(0, this.handleSuccess, this.handleFailure);
oracle.addArgumentToRequestString(id, "symbol", ric);
oracle.addArgumentToRequestUint(id, "timestamp", timestamp);
oracle.executeRequest(id);
}
function handleSuccess(uint256 id) public {
assert(msg.sender == address(oracle));
bytes32 ric = oracle.getResponseString(id, "symbol");
uint256 open = oracle.getResponseUint(id, "open");
uint256 high = oracle.getResponseUint(id, "high");
uint256 low = oracle.getResponseUint(id, "low");
uint256 close = oracle.getResponseUint(id, "close");
uint256 bid = oracle.getResponseUint(id, "bid");
uint256 ask = oracle.getResponseUint(id, "ask");
uint256 timestamp = oracle.getResponseUint(id, "timestamp");
oracle.deleteResponse(id);
// Do something with the price data
}
function handleFailure(uint256 id) public {
assert(msg.sender == address(oracle));
bytes32 error = oracle.getResponseError(id);
oracle.deleteResponse(id);
emit LogError(error);
}
}
A DApp is an application that operates without central control, leveraging decentralized technologies to eliminate single points of failure or authority.
The key aspects that can be decentralized in an application include:
- Backend Software (Smart Contracts): Logic and state managed on blockchain.
- Frontend Software: Interfaces running locally or served via decentralized storage.
- Data Storage: Utilizing decentralized filesystems like IPFS or Swarm.
- Message Communications: Employing protocols like Whisper for P2P messaging.
- Name Resolution: Using systems like the Ethereum Name Service (ENS).
- Resiliency: No downtime due to decentralized operation.
- Transparency: Open-source code and on-chain transactions enhance trust.
- Censorship Resistance: Users interact directly without centralized interference.
Smart contracts on Ethereum act as the backend, executing business logic and maintaining state. These contracts are immutable and operate transparently on the blockchain. Key considerations when developing smart contracts include:
- Immutability: Contracts cannot be altered once deployed.
- Gas Costs: Computational operations incur costs, so efficiency is essential.
The frontend can be built using standard web technologies (HTML, CSS, JavaScript) and interacts with the blockchain via libraries like web3.js. Users can access DApps through web browsers equipped with extensions like MetaMask.
Due to the high cost of on-chain storage, DApps use decentralized storage solutions for large data:
- IPFS (InterPlanetary File System): A P2P hypermedia protocol for storing and sharing content-addressed files.
- Swarm: An Ethereum-native decentralized storage and content distribution service.
Protocols like Whisper enable P2P messaging without centralized servers, allowing for features like encrypted chat rooms within DApps.
The Ethereum Name Service (ENS) provides a decentralized domain name system,
allowing human-readable names (e.g., mydapp.eth
) to reference smart contracts, wallets, or Swarm/IPFS content hashes.
The Ethereum Virtual Machine (EVM) is the runtime environment for smart contracts in Ethereum.
- Computation Engine: Similar to virtual machines like the JVM or interpreters for languages like Java, the EVM executes compiled bytecode from high-level languages such as Solidity.
- Quasi–Turing-Complete: The EVM is limited by gas, ensuring that all executions halt and preventing infinite loops, thus addressing the halting problem.
- Stack-Based Architecture:
- Word Size: 256 bits, facilitating cryptographic operations.
- Components:
- Program Code ROM: Immutable code loaded for execution.
- Memory: Volatile and initialized to zero.
- Storage: Persistent data unique to each contract.
The EVM differs from traditional virtual machines:
- No Scheduling: Execution order is determined externally by the Ethereum clients processing transactions and blocks.
- No System Interface or Hardware: The EVM operates in a virtual environment without direct access to hardware or operating system interfaces.
- Global Single-Threaded Computer: Ethereum functions as a single-threaded world computer, where the EVM ensures deterministic execution of smart contracts.
The EVM supports a rich set of opcodes divided into categories:
- Arithmetic Operations:
ADD
,MUL
,SUB
,DIV
,MOD
, etc. - Stack Operations:
PUSH
,POP
,DUP
,SWAP
, etc. - Control Flow Operations:
JUMP
,JUMPI
,STOP
,RETURN
, etc. - Logical Operations:
AND
,OR
,XOR
,NOT
,LT
,GT
, etc. - Environmental Operations: Accessing information like
CALLER
,CALLVALUE
,GASPRICE
, etc. - Block Operations: Accessing block metadata such as
BLOCKHASH
,TIMESTAMP
,NUMBER
, etc. - System Operations:
CREATE
,CALL
,SELFDESTRUCT
, etc.
- World State: A mapping of addresses to account states.
- Accounts:
- Externally Owned Accounts (EOAs): Controlled by private keys, with no associated code.
- Contract Accounts: Contain code (smart contracts) and storage.
- State Transitions:
- Triggered by transactions and smart contract executions.
- The EVM processes state changes in a sandboxed environment, which is only committed to the world state upon successful execution.
- Solidity Compiler (
solc
): Used to compile high-level Solidity code into EVM bytecode. - Generating Opcodes and Bytecode:
solc --opcodes Contract.sol # Get opcode representation solc --bin Contract.sol # Get bytecode binary
- Analysis:
- Understanding opcodes helps in optimizing and debugging smart contracts.
- Example contracts can be compiled and their opcodes examined for educational purposes.
- Deployment Bytecode: Includes both the contract's runtime bytecode and initialization code.
- Runtime Bytecode: The code that is executed when the contract is called after deployment.
- Deployment Process:
- A special transaction with the
to
address set to zero deploys the contract. - The constructor and initialization code run, setting up the contract's storage and state.
- A special transaction with the
- Tools:
- Porosity: Open source decompiler
- Ethersplay: Binary Ninja plugin
- IDA-Evm: IDA plugin
- Understanding Dispatchers:
- Function selectors (first 4 bytes of the
keccak256
hash of the function signature) are used to route calls to the correct function.
- Function selectors (first 4 bytes of the
- Example Analysis:
- By disassembling a contract like
Faucet.sol
, one can see how the dispatcher handles function calls and fallback functions.
- By disassembling a contract like
- Halting Problem: The EVM avoids non-terminating execution by limiting computations with gas.
- Gas:
- Unit of Computational Work: Every opcode has an associated gas cost.
- Prevents Denial-of-Service Attacks: Attackers cannot exhaust network resources without incurring significant costs.
- Quasi–Turing-Complete: The EVM can execute any computation that completes within the gas limit.
- Gas Supply: Each transaction specifies a gas limit and gas price.
- Execution:
miner fee = gas cost * gas price remaining gas = gas limit - gas cost refunded ether = remaining gas * gas price
- Refunds:
- Unused gas is refunded to the sender.
- Gas Cost: Fixed amount of gas required for an operation (e.g.,
ADD
costs 3 gas). - Gas Price: Amount of ether the sender is willing to pay per unit of gas.
- Transaction Fee: Calculated as
gas used * gas price
.
- Definition: The maximum amount of gas allowed in a block, limiting the number of transactions.
- Adjustment:
- Miners can vote to adjust the block gas limit within certain constraints.
- Ensures network scalability and security.
Continue on EVM.
Because there is an analogy for evm, is that it's like JVM (java virtual machine) So I am digging up for jvm
Here's a comparison of the Java Virtual Machine (JVM) and the Ethereum Virtual Machine (EVM):
Similarities:
- Virtual Machine Abstraction: Both are
abstract machines
providing aruntime environment
. - Execution of Bytecode: Both execute
bytecode
, an intermediate representation of source code. - Memory Management (Conceptual): Both handle
memory management
, though the mechanisms differ. - Security Features: Both incorporate
security features
to isolate and control code execution. - Instruction Set: Both have a defined
instruction set
(opcodes
for EVM, bytecode instructions for JVM).
Differences:
-
Purpose and Environment:
- JVM:
General-purpose virtual machine
for applications, typically runs on a single machine. - EVM:
Decentralized virtual machine
forsmart contracts
on the Ethereum blockchain, runs on a network of nodes.
- JVM:
-
Architecture:
- JVM: Primarily a
register-based
virtual machine. - EVM: A
256-bit stack-based
virtual machine.
- JVM: Primarily a
-
Memory Management:
- JVM: Employs
automatic garbage collection (GC)
for heap memory. - EVM: Has
manual
andtransaction-scoped
memory, no automatic GC.
- JVM: Employs
-
State Management:
- JVM: Generally
stateless
between executions unless explicitly managed. - EVM: Maintains a
global, persistent state
called theWorld State
on the blockchain.
- JVM: Generally
-
Concurrency:
- JVM: Supports concurrency through
threads
. - EVM: Handles "concurrency" through the
sequential processing of transactions
within blocks.
- JVM: Supports concurrency through
-
Determinism:
- JVM: Generally deterministic for a single execution, but strict determinism across implementations isn't a core requirement.
- EVM: Is
strictly deterministic
to ensure consensus across the decentralized network.
-
Gas/Resource Model:
- JVM: Doesn't have a built-in cost model at the VM level.
- EVM: Has a
gas-based cost model
where eachopcode
has a gas cost.
-
Immutability:
- JVM: Code can be updated and redeployed.
- EVM: Smart contract code is generally
immutable
once deployed.
-
Underlying Technology:
- JVM: Typically runs on top of an
operating system
. - EVM: Runs as part of a
decentralized blockchain network
.
- JVM: Typically runs on top of an
-
Programming Languages:
- JVM: Primarily for
Java
, but supports other JVM-compatible languages. - EVM: Primarily for
Solidity
, but also supports other languages compiling to EVM bytecode.
- JVM: Primarily for
ethereum state
以太坊状态机
world state
mapping of eth address (160-bits) to accounts (balance + nonce + storage + program code)
smart contract security best practices
- minimalism/simplicity
- code reuse (use well defined lib)
- code quality
- readability/auditability (easy to audit, opensource)
- test coverage
Some more resources on security
- prepare for failure
- stay up to date
- keep it simple
- rolling out
- blockchain perperties
- simplicity vs. complexity
- external calls
- use caution when making external calls
- mark untrusted contracts
- avoid state changes after external calls
- don't use
transfer()
orsend()
- handle errors in external calls
- favor pull over push for external calls
- don't deletegatecall to unstrusted code
// bad
someAddress.send(55);
someAddress.call.value(55)(""); // this is doubly dangerous, as it will forward all remaining gas and doesn't check for result
someAddress.call.value(100)(bytes4(sha3("deposit()"))); // if deposit throws an exception, the raw call() will only return false and transaction will NOT be reverted
// good
(bool success, ) = someAddress.call.value(55)("");
if(!success) {
// handle failure code
}
ExternalContract(someAddress).deposit.value(100)();
Continue on the security practice
- Beware of coding an invariant that strictly checks the balance of a contract.
- for publishing data on-chain: use commitment schemes1 with separate phases: first commit using the hash of the values and in a later phase revealing the values.
- Do not make refund or claim processes dependent on a specific party performing a particular action with no other way of getting the funds out (1) provide a way of circumventing non-participating participants, perhaps through a time limit, and (2) consider adding economic incentive for participants to submit information in all of the situations in which they are supposed to do so.
- negation of signed integers2
Continue on security1
General philosophy: prepare for failure
- Upgradeability:
- Circuit Breakers: break if there a bug
- Speed Bumps: slow down actions, time to recover when maclious actions done
- Rate limiting
- Deployment
- Have a full test suite with 100% test coverage (or close to it)
- Deploy on your own testnet
- Deploy on the public testnet with substantial testing and bug bounties
- Exhaustive testing should allow various players to interact with the contract at volume
- Deploy on the mainnet in beta, with limits to the amount at risk
- Safe Haven (run bounty programs to find bugs)
assert()
,require()
,revert()
- Modifiers as Guards
- Integer Division
- Abstract vs Interfaces
- Fallback Functions
- Payability
- Visibility
- Locking Pragmas
- Event Monitoring
- Shadowing
- tx.origin
- Timestamp Dependence
- Complext Inheritrance
- Interface Types
- EXTCODESIZE Checks
TODO: Read specific cases and note down
- EIP20
- EIP721 (nft)
- be careful with
approve()
- details here -> To prevent, the best remediation is to remove the benefit of front-running in the application i.e. remove the importance of transaction ordering or time
- prevent transfer tokens to the same address of the smart contract -> Tokens might stuck at smart contract like in EOS case
- Specs, diagrams, state machines, models, and other documentation that helps auditors, reviewers, and the community understand what the system is intended to do.
- Many bugs can be found just from the specifications, and they are the least costly to fix.
- Rollout plans that include details listed here, and target dates.
- Where current code is deployed
- Compiler version, flags used, and steps for verifying the deployed bytecode matches the source code
- Compiler versions and flags that will be used for the different phases of rollout.
- Current status of deployed code (including outstanding issues, performance stats, etc.)
- Action plan in case a bug is discovered (e.g., emergency options, public notification process, etc.)
- Wind down process if something goes wrong (e.g., funders will get percentage of your balance before attack, from remaining funds)
- Responsible disclosure policy (e.g., where to report bugs found, the rules of any bug bounty program)
- Recourse in case of failure (e.g., insurance, penalty fund, no recourse)
- Key risks with contract e.g., You can lose all your money, hacker can vote for certain outcomes
- All known bugs/limitations
- Potential attacks and mitigants
- Potential conflicts of interest (e.g., will be using yourself, like Slock.it did with the DAO)
- Testing (including usage stats, discovered bugs, length of testing)
- People who have reviewed code (and their key feedback)
- Who to contact with issues
- Names of programmers and/or other important parties
- Chat room where questions can be asked
- Visualization
- Static and Dynamic Analysis
- Classification
- Testing
- Linters and Formatters
refer here for details
click here