CS代考 GF-256 operations

Ethereum & Solidity mechanics

Recap: Ethereum in one slide
● States S = a map from addresses to state

Copyright By PowCoder代写 加微信 powcoder

● Inputs I (transactions)
● Transition f:
○ validate signature
○ run to.code(from, data, value, startgas, gasprice)
● Start state: ∅
y affect the state of
value startgas gasprice
any address

Recap: The full* Ethereum blockchain structure
prev height nonce difficulty
state root
miner extra
transaction root receipt root

Recap: The full* Ethereum blockchain structure
prev height nonce difficulty
state root
miner extra
transaction root receipt root

Recap: The full* Ethereum blockchain structure
prev height nonce difficulty
state root
miner extra
transaction root receipt root
final state
log output

Ethereum addresses can be accounts or contracts
Note: no UTXOs in
H(pub_key)
H(creator, nonce)
Merkle storage root
ETH balance
#transaction sent
Volatile fields

Three* types of transaction in Ethereum

Three* types of transaction in Ethereum
transfer_val

Three* types of transaction in Ethereum
transfer_val
transfer_val

NameCoin in introduced three new opcodes NAME_NEW: H(r, “jbonneau”)
12 block delay (frontrunning)
NAME_FIRST_UPDATE: r, “jbonneau”, {“ip” : “68.178.254.235”}
NAME_UPDATE: “jbonneau”, {“ip6” : “2001:4860:0:1001::68”}

Ethereum Virtual Machine

EVM is stack-based, like BTC script Features
● 1024-depth stack
● 32-byte words
● Accelerated crypto
○ Big num multiply
○ GF-256 operations
CALLDATALOAD
CALLDATALOAD
CALLDATALOAD

EVM provides basic API for I/O
● tx info: sender, value, gas limit
● resource use: gas remaining, memory used
● block info: depth, timestamp, miner, hash
● send messages (call other contracts and/or send money)
● write to logs
● self destruct

Subtleties to contract calls
● Data: unlimited params/return values
○ Direct mapped to memory address + size
● Exceptions: out of gas, bad jump, etc.
○ No state changes persisted
○ Control returns to caller
● Call stack limit: 1024
○ Calls from 1024th frame will fail

EVM memory model offers a lot of space
Storage: {0,1}256→{0,1}256 map (persistent) Memory: {0,1}256→{0,1}256 map (volatile between tx)
● in other words, both can store 2264 bits!
● arranged in 256-bit words
● all memory is zero-initialized
Storage in Ethereum is very expensive. Limiting memory use is critical

Efficient map commitments

How can Ethereum commit to so much state? Recall: storage is a {0,1}256→{0,1}256 map Requirements:
● O(lg k) update cost
● O(lg k) proofs (even for zero values)
Key insight:
keys supported
keys with a non-zero value
commitment size
Optimize for efficient storage of zeroized values

Non-solution: use a binary tree, paths encode address 0

Requires O(2n) computation

Optimization #1: pre-compute all sizes of empty tree
Dynamic programming formula: 0
Empty[x] = H(Empty[x-1]||Empty[x-1])
This works!
Proofs are length O(lg n)

Optimization #2: shrink all single subtrees; store prefix
“01”, Alice
“diverge node”
0 “”, works!
Proofs are length O(lg k)
“”, ’s “ ATRICIA tree” has a few quirks
● Used in two main places
○ overall state
○ per-contract storage ● 16-ary
○ proofs ~4x longer ● paths can be < 256 bits ○ “1”, “01” are distinct ○ Really 2257-1 addresses Solidity should look familiar ● Syntax looks like C++, JavaScript etc. ● Contracts look like classes/objects ○ Can mark functions internal ● Static typing ○ Most types can be cast e.g. bool(x) Basic program structure Solidity should look familiar ● Imperative. Syntax looks like C++, JavaScript etc. ● Object-oriented. Contracts are like objects/classes ● Static typing. Most types can be cast Solidity programs let you define a contract contract HelloWorld { Storage: Member variables stored on the blockchain contract HelloWorld { int count; Everything in Solidity is initialized to zero function hello() public { Functions: enable interaction with outside world contract HelloWorld { int count; function hello() public returns int{ count += 1; return count; function megaHello() private { count += 10; Constructors: enable one-time setup contract HelloWorld { int count; constructor(int initialCount) public { count = initialCount; function hello() public { Set of public functions form a contract’s ABI contract myToken { function totalSupply(); Application Binary Interface function balanceOf(address tokenOwner); function allowance(address tokenOwner, address spender); function transfer(address to, uint tokens); function approve(address spender, uint tokens); function transferFrom(address from, address to, uint tokens); Data types in Solidity Basic types should look familiar (value types) true/false value int, int8, int16, ... int256 signed integers uint, uint8, uint16, ... uint256 unsigned integers byte, bytes2, bytes3, ... bytes32 fixed-size byte arrays What’s missing? ● Floating point ● Pointers address stores a contract or account address contract Squares { address a; function sendMoney(uint amount) private { a.transfer(amount); struct allows grouping related values contract Election { struct Voter { address key; bool hasVoted; uint precinctNumber; v.hasVoted = true; enum streamlines hard-coding values contract Casino { enum Suit {Hearts, Diamonds, Clubs, Spades} function deal() public { Suit leadSuit; leadSuit = Suit.Hearts; Dynamic arrays built-in contract Squares { function countSquares(uint n) public { uint[] memory s = new uint[](n); uint l = s.length; mapping relates keys to values contract Bank { mapping (address => uint) balances;
function deposit() public returns uint{
balances[msg.sender] += msg.value;
return balances[msg.sender];

Mapped values stored at storage address H(key)
mapping(string => uint) balances;
H(“balances”|”Bob”)
H(“balances”|”Joe”)
H(“balances”|”Alice”)
● balances[“Andrew”] = 0 if “Andrew” doesn’t exist
● to delete a key, set balances[“Andrew’] = 0
● cannot iterate over all items in a map
● cannot delete an entire map

Object-oriented features

Inheritance
abstract contract Animal {
contract Cat is Animal {
function talk() public override
function talk() purbeltiucrnosv(ebryrtiedse32 sound){
function talk() public virtual returns(bytes32);
contract Kitten is Cat {
return “meow”; returns(bytes32 sound){ return “mewwwwwww”;

Interfaces
interface Token {
function name() public view returns (string)
function totalSupply() public view returns (uint256)
function balanceOf(address _owner) public view returns (uint256
function transfer(address _to, uint256 _value) public returns (bool
Only virtual functions; multiple inheritance is allowed

Function modifiers affect visibility
who can access?
only this contract
this construct or derived contracts
only other contracts

Function modifiers affect capabilities
limitations
can’t write any persistent state
can’t read or write any state

Solidity conventions

Polite contracts call throw errors
uint8 numCandidates;
uint32 votingFee;
mapping(address => bool) hasVoted;
mapping(uint8 => uint32) numVotes;
/// Cast a vote for a designated candidate
function castVote(uint8 candidate) {
if (msg.value < votingFee) if (hasVoted[msg.sender]) hasVoted[msg.sender] = true; numVotes[candidate] += 1; Error ensures no effects persisted except gas consumption Several ways to throw an error bool shouldBeTrue; require(shouldBeTrue); assert(shouldBeTrue); if(!shouldBeTrue) { if(!shouldBeTrue) { //burn all remaining gas //burn all remaining gas (deprecated) Modifiers ease repetitive safety checks address public owner; uint public electionEnd; modifier onlyBy(address _account){ require(msg.sender == _account); modifier onlyAfter(uint _block) { require(block.blocknumber >= _block);
function endElection()
onlyBy(owner) onlyAfter(electionEnd){

Built-in support for calling other contracts
● a.transfer(x) sends x to address a
○ returns 0 if this fails due to call stack
● foo.call{value:3, gas:20764}( bytes4(sha3(“bar()”)));
○ also callcode, delegatecall
○ default is 0 value, all available gas
● new constructor deploys a new contract ○ Careful, it’s expensive!
Smart contracts code is fixed forever. Calls required to update functionality

Solidity gotchas
● Member variables public by default ○ getters automatically provided
● Functions must be marked payable to accept funds
● Member variables go to storage by default
○ Method variables go to memory
● Fallback function()
○ Called if no function specified (e.g. send)
○ Called if non-existent function called
● msg.sender vs. tx.origin
https://solidity.readthedocs.io/en/develop/solidity-in-depth.html

Solidity and EVM may outgrow Ethereum itself
– Enterprise Ethereum Alliance
-Goal: support EVM, Solidity and tools for private blockchains – maintain compatibility with Ethereum network

Don’t like Solidity? Write your own language! Untyped, looks like python Typed, looks like JS Typed, looks like Go
Vyper Solidity Bamboo Research here
Lower-Level Language
Ethereum VM Bytecode Stack Language
Looks like Forth. Defined in Yellowpaper

Gas and transaction limits

Ethereum is like Ryanair: pay to board, then keep paying

Gas in Ethereum is a necessary evil
● All miners must evaluate all transactions ○ limit computation cost
● All miners must store all state ○ limit storage use
● Short-cut the halting problem
○ Finite GAS_LIMIT ensures all programs halt
Bitcoin also employs a (crude) means to pay for resources consumed

Every operation has a fixed gas cost
Basic operations
ADD, MUL, PUSH, JUMP
Storage read
Storage write
Storage write (from zero)
Storage zeroize
Contract call
CALL, CODECALL, etc.
Transaction overhead
Contract creation
Contract destruction
SELFDESTRUCT

Gas metering is complex
1. Transactions specify START_GAS, GAS_PRICE
2. If START_GAS ⨉ GAS_PRICE > caller.balance, halt
3. Deduct START_GAS ⨉ GAS_PRICE from caller.balance
4. Set GAS = START_GAS
5. Run code, deducting from GAS
6. For negative values, add to GAS_REFUND
a. GAS only decreases
7. After termination, add GAS + GAS_REFUND to caller.balance

Every step taken by a contract costs gas Gas remaining
PUSH1 0x80
PUSH1 0x40
PUSH1 0x04
CALLDATASIZE
PUSH2 0x011c
PUSH4 0xffffffff

Every step taken by a contract costs gas Gas remaining
PUSH1 0x80
PUSH1 0x40
PUSH1 0x04
CALLDATASIZE
PUSH2 0x011c
PUSH4 0xffffffff

Every step taken by a contract costs gas Gas remaining
PUSH1 0x80
PUSH1 0x40
PUSH1 0x04
CALLDATASIZE
PUSH2 0x011c
PUSH4 0xffffffff

Every step taken by a contract costs gas Gas remaining
PUSH1 0x80
PUSH1 0x40
PUSH1 0x04
CALLDATASIZE
PUSH2 0x011c
PUSH4 0xffffffff

Every step taken by a contract costs gas Gas remaining
PUSH1 0x80
PUSH1 0x40
PUSH1 0x04
CALLDATASIZE
PUSH2 0x011c
PUSH4 0xffffffff

Every step taken by a contract costs gas
PUSH1 0x80
PUSH1 0x40
PUSH1 0x04
Gas remaining
CALLDATASIZE
Remaining gas is
refunded to the transaction creator
PUSH2 0x011c
PUSH4 0xffffffff

Gas must be paid upfront by transaction creator
Maximum amount of gas this transaction can consume
Amount (in wei) sender is willing to pay per unit of gas

The full gas picture
C.foo() alice.balance
PUSH1 0x80
PUSH1 0x40
PUSH1 0x00
I’d like to execute C.foo() with
PUSH1 0x40
START_GAS = 100000 at a
GAS_PRICE of 2

The full gas picture
C.foo() alice.balance
Gas remaining
Gas refund
PUSH1 0x80
PUSH1 0x40
PUSH1 0x00
PUSH1 0x40

The full gas picture
C.foo() alice.balance
Gas remaining
Gas refund
PUSH1 0x80
PUSH1 0x40
PUSH1 0x00
PUSH1 0x40

The full gas picture
C.foo() alice.balance
Gas remaining
Gas refund
PUSH1 0x80
PUSH1 0x40
PUSH1 0x00
PUSH1 0x40

The full gas picture
C.foo() alice.balance
Gas remaining
Gas refund
PUSH1 0x80
PUSH1 0x40
PUSH1 0x00
PUSH1 0x40

The full gas picture
C.foo() alice.balance
Gas remaining
Gas refund
PUSH1 0x80
PUSH1 0x40
Total refund:
PUSH1 0x00
(74988+15000) ⨉ 2 PUSH1 0x40

The full gas picture
C.foo() alice.balance
PUSH1 0x80
PUSH1 0x40
PUSH1 0x00
PUSH1 0x40

Out-of-gas exceptions are bad news
● State reverts to previous value
○ Except that START_GAS * GAS_PRICE is still deducted

Out-of-gas errors can cascade
90 function b(): y = C.c()
return “Hello”
function a():
return x + “ World!”
80 function c(): while (true) {
return “Bonjour”
Out of gas
Out of gas
Out of gas

Callers can choose to limit how much gas they send
function b(): 5 assert msg.gas >= 10 y = C.c.gas(5)()
assert(y == 0);
// out of gas
return “Hello”
function a(): 10 assert(msg.gas >= 100);
x = B.b.gas(10)()
return x + “ World!”
function c():
assert(msg.gas >= 5
while (true) {
return “Bonjour”
“Hello World!”
Out of gas

Contracts can query the amount of gas remaining
contract HelloWorld {
function bar(address a) public returns (int){
if (gasleft() > 50000)
f = new Foo();
Also available:
f = Foo(a); ● tx.gasprice
● block.gaslimit return f.baz();
● msg.gas, equivalent to gasleft() }

Gas today is about 55⨉10-9 ether = 0.000184 USD

Gas today is about 55⨉10-9 ether = 0.000185 USD
USD cost [April 2022]
Basic operations
ADD, MUL, PUSH, JUMP
Storage read
Storage write
Storage write (from zero)
Storage zeroize
Contract call
CALL, CODECALL, etc.
Transaction overhead
Contract creation
Contract destruction
SELFDESTRUCT

Economics of gas are similar to transaction fees
● Miners choose transactions based on GAS_PRICE
● In theory, they should not care which opcodes are used
○ In practice, some “overpriced” opcodes may be preferred
● Maximum gas limit per block
○ Miners can slowly raise it, each block votes

Miners may include the most profitable transactions
source: ethgasstation.info

Miners limited by a global limit on gas per block

Arbitrage possible with fluctuating gas prices
● Idea: bank gas when prices are low
○ Store junk in memory
○ Create junk contracts
● Free these resources when prices are high
○ Saves if gas costs increase by 33% or more

Summary: smart contracts must optimize gas usage ● Running time, memory consumption irrelevant
● Compilers should optimize for gas
● Programmers should optimize, too
○ Tip: avoid storage if at all possible!

Ethereum project

Ethereum blockchain is different than Bitcoins
Target time between blocks
14.5 seconds
10 minutes
Proof of work
Stale block rewards
Uncle rewards
Hard forks
regularly planned
explicit (committed in each block)

Ethereum is “run” by the Ethereum Foundation
Compatible “alt-clients” exist (e.g. Parity, Consensys)

Hard Forks are frequent in still lags behind Bitcoin

程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com