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 |
-
Notifications
You must be signed in to change notification settings - Fork 0
Mapping Solidity <> Vyper
License
sambacha/solidity-vyper-atlas
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
About
Mapping Solidity <> Vyper
Topics
Resources
License
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published