v0.2.0-alpha "Borax"
Pre-releaseRelease Notes
📄 Draft Spec
ℹ️ Getting Started
Fe is moving fast. Read up on all the latest improvements.
WARNING: All current Fe releases are alpha releases and only meant to share the development progress with developers and enthusiasts. It is NOT yet ready for production usage.
0.2.0-alpha "Borax" (2021-02-27)
Features
-
Add support for string literals.
Example:
def get_ticker_symbol() -> string3: return "ETH"
String literals are stored in and loaded from the compiled bytecode. (#186)
-
The CLI now compiles every contract in a module, not just the first one. (#197)
Sample compiler output with all targets enabled:
output |-- Bar | |-- Bar.bin | |-- Bar_abi.json | `-- Bar_ir.yul |-- Foo | |-- Foo.bin | |-- Foo_abi.json | `-- Foo_ir.yul |-- module.ast `-- module.tokens
-
Add support for string type casts (#201)
Example:
val: string100 = string100("foo")
-
Add basic support for structs. (#203)
Example:
struct House: price: u256 size: u256 vacant: bool contract City: pub def get_price() -> u256: building: House = House(300, 500, true) assert building.size == 500 assert building.price == 300 assert building.vacant return building.price
-
Added support for external contract calls. Contract definitions now
add a type to the module scope, which may be used to create contract
values with the contract's public functions as callable attributes. (#204)Example:
contract Foo: pub def build_array(a: u256, b: u256) -> u256[3]: my_array: u256[3] my_array[0] = a my_array[1] = a * b my_array[2] = b return my_array contract FooProxy: pub def call_build_array( foo_address: address, a: u256, b: u256, ) -> u256[3]: foo: Foo = Foo(foo_address) return foo.build_array(a, b)
-
Add support for
block
,msg
,chain
, andtx
properties: (#208)block.coinbase: address block.difficulty: u256 block.number: u256 block.timestamp: u256 chain.id: u256 msg.value: u256 tx.gas_price: u256 tx.origin: address
(Note that
msg.sender: address
was added previously.)Example:
def post_fork() -> bool: return block.number > 2675000
-
The CLI now panics if an error is encountered during Yul compilation. (#218)
-
Support for contract creations.
Example of
create2
, which takes avalue
and addresssalt
as parameters.contract Foo: pub def get_my_num() -> u256: return 42 contract FooFactory: pub def create2_foo() -> address: # value and salt foo: Foo = Foo.create2(0, 52) return address(foo)
Example of
create
, which just takes avalue
parameter.contract Foo: pub def get_my_num() -> u256: return 42 contract FooFactory: pub def create_foo() -> address: # value and salt foo: Foo = Foo.create(0) return address(foo)
Note: We do not yet support init parameters. (#239)
-
Support updating individual struct fields in storage. (#246)
Example:
pub def update_house_price(price: u256): self.my_house.price = price
-
Implement global
keccak256
method. The method expects one parameter ofbytes[n]
and returns the hash as anu256
. In a future versionkeccak256
will most likely
be moved behind an import so that it has to be imported (e.g.from std.crypto import keccak256
). (#255)Example:
pub def hash_single_byte(val: bytes[1]) -> u256: return keccak256(val)
-
Require structs to be initialized using keyword arguments.
Example:
struct House: vacant: bool price: u256
Previously,
House
could be instantiated asHouse(true, 1000000)
.
With this change it is required to be instantiated likeHouse(vacant=true, price=1000000)
This ensures property assignment is less prone to get mixed up. It also makes struct
initialization visually stand out more from function calls. (#260) -
Implement support for boolean
not
operator. (#264)Example:
if not covid_test.is_positive(person): allow_boarding(person)
-
Do over/underflow checks for additions (SafeMath).
With this change all additions (e.g
x + y
) for signed and unsigned
integers check for over- and underflows and revert if necessary. (#265) -
Added a builtin function
abi_encode()
that can be used to encode stucts. The return type is a
fixed-size array of bytes that is equal in size to the encoding. The type system does not support
dynamically-sized arrays yet, which is why we used fixed. (#266)Example:
struct House: price: u256 size: u256 rooms: u8 vacant: bool contract Foo: pub def hashed_house() -> u256: house: House = House( price=300, size=500, rooms=u8(20), vacant=true ) return keccak256(house.abi_encode())
-
Perform over/underflow checks for subtractions (SafeMath). (#267)
With this change all subtractions (e.g
x - y
) for signed and unsigned
integers check for over- and underflows and revert if necessary. -
Support for the boolean operations
and
andor
. (#270)Examples:
contract Foo: pub def bar(x: bool, y: bool) -> bool: return x and y
contract Foo: pub def bar(x: bool, y: bool) -> bool: return x or y
Support for
self.address
.This expression returns the address of the current contract.
Example:
contract Foo: pub def bar() -> address: return self.address
Bugfixes
-
Perform type checking when calling event constructors
Previously, the following would not raise an error even though it should:
contract Foo: event MyEvent: val_1: string100 val_2: u8 pub def foo(): emit MyEvent("foo", 1000)
Wit this change, the code fails with a type error as expected. (#202)
-
Fix bug where compilation of contracts without public functions would result in illegal YUL. (#219)
E.g without this change, the following doesn't compile to proper YUL
contract Empty: lonely: u256
-
Ensure numeric literals can't exceed 256 bit range. Previously, this would result in a
non user friendly error at the YUL compilation stage. With this change it is caught
at the analyzer stage and presented to the user as a regular error. (#225) -
Fix crash when return is used without value.
These two methods should both be treated as returning
()
pub def explicit_return(): return pub def implicit(): pass
Without this change, the
explicit_return
crashes the compiler. (#261)