Skip to content

sambacha/solidity-vyper-atlas

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Feature Solidity Vyper
Version $ solc --versionVersion: 0.6.12 $ vyper --version0.2.3
General notes on syntax Solidity loosely borrows its syntax from Javascript and C Vyper syntax is valid Python 3 syntax (but the opposite is not true)
Block delimiters { } : # Vyper uses Python's off-side rule
Statement separator ; \n' and :
End of line comment // comment # comment
Multiple line comment /* multiple linecomment */ # Multiple line# comment
Constant uint constant TOTAL_SUPPLY = 10000000; TOTAL_SUPPLY: constant(uint256) = 10000000
Assignment v = 1; v = 1
Parallel assignment (x, y) = (0, 1); Tuple to tuple assignment not supported
Swap (x, y) = (y, x);
Compound assignment -=, *=, /=, %=, |=, &=, ^= -=, *=, /=, %=, |=, &=, ^=
Increment and decrement i++, ++i, i--, --i i += 1, i -= 1
Null null doesn't exist in Solidity but any unitialized variables take a default value represented by 0 in memory null doesn't exist in Vyper but any unitialized variables take a default value represented by 0 in memory
Set variable to default value delete v // doesn't work with mappings v = empty(uint256)
Null test v == 0 v == 0
Conditional expression x > 0 ? x : -x Conditional expression not supported
Contract lifecycle
Feature Solidity Vyper
Contract creation Contract c = new Contract(args);
Contract creation with funding Contract c = new Contract{value: amount}(args);
Salted contract creation (CREATE2) Contract c = new Contract{salt: salt}(args);
Create forwarder contract contract: address = create_forwarder_to(other_contract, value)
Selfdestruct (Avoid) selfdestruct(refundAddr) selfdestruct(refund_addr)
Interfaces
Feature Solidity Vyper
Interfaces interface HelloWorld { function hello() external pure; function world(int) external pure;} interface HelloWorld: def hello(): nonpayable def world(uint256): nonpayable
Interface type interface HelloWorldWithEvent { event Event(); function hello() external pure; function world(int) external pure;}contract Test { bytes4 public hello_world_with_event = type(HelloWorldWithEvent).interfaceId;}
Operators
Feature Solidity Vyper
True and false true false True False
Falsehoods FALSE FALSE
Logical operators && || ! and or not
Relational operators #ERROR! #ERROR!
Min and max max(x, y)
Arithmetic operators #ERROR! #ERROR!
Integer division / /
Bit operators << >> & | ^ ~ << >> & | ^ ~
Binary & hex literals uint x = 0x52string memory s = hex"52" a: address= 0x14d465376c051Cbcd80Aa2d35Fd5df9910f80543b: Bytes[32]= b'\x01\x02\x03\x04\x05\x06... (32 bytes)d: Bytes[1] = 0b00010001
Data structures
Feature Solidity Vyper
String type string String[N] # N is a fixed number
Bytes type bytes // dynamicbytes1, bytes2, ..., bytes32 // packedbytes[N] // N is a fixed number, unpacked Bytes[N] # N is a fixed number
String literal "don't \"no\""'don"t \'no\''� "don't \"no\""'don"t \'no\''
String length bytes(s).length len(s)
String literal escapes \ (escapes an actual newline)\\ (backslash)\' (single quote)\" (double quote)\b (backspace)\f (form feed)\n (newline)\r (carriage return)\t (tab)\v (vertical tab)\xNN (hex escape)\uNNNN (unicode escape) \ (escapes an actual newline)\\ (backslash)\' (single quote)\" (double quote)\a (bell)\b (backspace)\f (form feed)\n (newline)\r (carriage return)\t (tab)\v (vertical tab)\ooo (octal escape)\xNN (hex escape)\uNNNN (unicode escape)\uNNNNNNNN (unicode escape)
Are strings mutable? Yes Yes
Slice abi.decode(_payload[:4], (bytes4))// array slices only implemented for calldata arrays slice(x, _start, _len)
String comparison keccak256(abi.encodePacked(s1)) == keccak256(abi.encodePacked(s2)) keccak256(s1) == keccak256(s2)
String concatenation abi.encodePacked(s1, s2) concat(s1, s2)
Array literal [1, 2, 3] [1, 2, 3]
Length a.length len(a)
Empty test a.length == 0
Lookup a[0] a[0]
Update a[0] = 1; a[0] = 1
Out of bounds access Failing assertion Failing assertion
Add new element a.push(3); # Dynamic arrays
Remove element a.pop(); # Dynamic arrays
Struct struct Pair { uint x; uint y;} // Creating a structPair memory pair = Pair(2, 3); // Instantiating a struct variablerequire(pair.y > pair.x); // Accessing elements struct Pair: x: uint256 y: uint256 # Creating a structpair: Pair = Pair({x: 2, y: 3}) # Instantiating a struct variableassert pair.y > pair.x # Accessing elements
Mapping size Impossible to know Impossible to know
Lookup m[2] m[2]
Update m[2] = 1; m[2] = 1
Missing key behaviour A mapping has no concept of set keys, a mapping always refers to a hashed value that is the same for a given mapping and key A mapping has no concept of set keys, a mapping always refers to a hashed value that is the same for a given mapping and key
Delete key m[2] = 0; m[2] = empty(uint256)
Immutable variables uint immutable x; // have to be assigned in the constructor
Functions
Feature Solidity Vyper
Define function function add2(uint x, uint y) public pure returns (uint) { return x + y;} @externaldef add2(x: uint256, y: uint256) -> uint256: return x + y
Function argument storage location function first(uint[] calldata x) public pure returns (uint) { // this function doesn't copy x to memory return x[0];}function first(uint[] memory x) public pure returns (uint) { // this function first copies x to memory return x[0];}
Invoke function add2(x, y) add2(x, y)
External function calls c.f{gas: 1000, value: 4 ether}() c.f()raw_call(address, data, outsize, gas, value, is_delegate_call)
Control flow
Feature Solidity Vyper
If statement if (a > 2) { ...else if (a == 0) { ...} else { ...} if a > 2: ...elif a == 0: ...else: ...
For loop for (uint i = 0; i < 3; i++) { ...} for i in range(3): ...
While loop while (a > 0) { ...}
Do-While loop do { ...} while (a > 0);
Return value return x + y; return x + y
Break break; break
Continue continue; continue
Assert assert(x > y); assert x > y
Require require(x > y);
Revert require(false, "revert reason") raise "revert reason"
Exception handling interface DataFeed { function getData(address token) external returns (uint value); }contract FeedConsumer { DataFeed feed; uint errorCount; function rate(address token) public returns (uint value, bool success) { // Permanently disable the mechanism if there are // more than 10 errors. require(errorCount < 10); try feed.getData(token) returns (uint v) { return (v, true); } catch Error(string memory /*reason*/) { // This is executed in case // revert was called inside getData // and a reason string was provided. errorCount++; return (0, false); } catch (bytes memory /*lowLevelData*/) { // This is executed in case revert() was used // or there was a failing assertion, division // by zero, etc. inside getData. errorCount++; return (0, false); } }}
Misc
Feature Solidity Vyper
Comments NatSpec conventions for functions:/// @author Mary A. Botanist/// @notice Calculate tree age in years, rounded up, for live trees/// @dev The Alexandr N. Tetearing algorithm could increase precision/// @param rings The number of rings from dendrochronological sample/// @return age in years, rounded up for partial yearsEvents:/// The address `participant` just registered for the gathering.event Registered(address participant);Special inheritance syntax for contracts:/// @inheritdoc OtherContract def foo(): """ @author Mary A. Botanist @notice Calculate tree age in years, rounded up, for live trees @dev The Alexandr N. Tetearing algorithm could increase precision @param rings The number of rings from dendrochronological sample @return age in years, rounded up for partial years """ ...
Payment with error on failure (Avoid for Solidity) address.transfer() send(address, value)
Payment with false on failure (Avoid for Solidity) address.send()
Payment with gas forwarding (WARNING) address.call.value().gas()() raw_call(address, data, outsize, gas, value, is_delegate_call)
Event logging event Deposit( address indexed _from, bytes32 indexed _id, uint _value);emit Deposit(msg.sender, _id, msg.value); event Deposit: _from: indexed(address) _id: indexed(bytes32) _value: uint256log Deposit(msg.sender, _id, msg.value)
Units, global constants and type ranges 1 ether1 finney1 szabo1 wei1 gwei1 seconds1 minutes1 hours1 days1 weeks1 years // deprecatedtype(uint).mintype(uint).maxtype(int8).mintype(int8).max... ZERO_ADDRESSas_wei_value(1, "finney")as_wei_value(1, "szabo")as_wei_value(1, "wei")as_wei_value(1, "babbage")as_wei_value(1, "shannon")EMPTY_BYTES32MAX_INT128MIN_INT128MAX_DECIMALMIN_DECIMALMAX_UINT256ZERO_WEI
Block and transaction properties blockhash(blockNumber)block.coinbaseblock.difficultyblock.gaslimitblock.numberblock.timestampnow // alias for block.timestampgasleft()msg.datamsg.gasmsg.sendermsg.sigmsg.valuetx.gaspricetx.origin blockhash(blockNumber)block.coinbaseblock.difficultyblock.numberblock.prevhash # Same as blockhash(block.number - 1)block.timestampmsg.gasmsg.sendermsg.valuetx.origin