diff --git a/docs/book/src/basics/blockchain_types.md b/docs/book/src/basics/blockchain_types.md index 61003bc7e9a..86b0ff799b3 100644 --- a/docs/book/src/basics/blockchain_types.md +++ b/docs/book/src/basics/blockchain_types.md @@ -6,7 +6,10 @@ These are provided via the standard library ([`lib-std`](https://github.com/Fuel ## `Address` Type + + The `Address` type is a type-safe wrapper around the primitive `b256` type. Unlike the EVM, an address **never** refers to a deployed smart contract (see the `ContractId` type below). An `Address` can be either the hash of a public key (effectively an [externally owned account](https://ethereum.org/en/whitepaper/#ethereum-accounts) if you're coming from the EVM) or the hash of a [predicate](../sway-program-types/predicates.md). Addresses own UTXOs. + An `Address` is implemented as follows. @@ -26,7 +29,10 @@ let forty_two: b256 = my_address.into(); ## `ContractId` Type + + The `ContractId` type is a type-safe wrapper around the primitive `b256` type. A contract's ID is a unique, deterministic identifier analogous to a contract's address in the EVM. Contracts cannot own UTXOs but can own assets. + A `ContractId` is implemented as follows. @@ -46,7 +52,10 @@ let forty_two: b256 = my_contract_id.into(); ## `Identity` Type + + The `Identity` type is an enum that allows for the handling of both `Address` and `ContractId` types. This is useful in cases where either type is accepted, e.g. receiving funds from an identified sender, but not caring if the sender is an address or a contract. + An `Identity` is implemented as follows. @@ -69,8 +78,10 @@ A `match` statement can be used to return to an `Address` or `ContractId` as wel ```sway {{#include ../../../../examples/identity/src/main.sw:different_executions}} ``` - + + A common use case for `Identity` is for access control. The use of `Identity` uniquely allows both `ContractId` and `Address` to have access control inclusively. + ```sway {{#include ../../../../examples/identity/src/main.sw:access_control_with_identity}} diff --git a/docs/book/src/basics/built_in_types.md b/docs/book/src/basics/built_in_types.md index 99ef6bc6140..545ee343b7b 100644 --- a/docs/book/src/basics/built_in_types.md +++ b/docs/book/src/basics/built_in_types.md @@ -2,10 +2,15 @@ Every value in Sway is of a certain type. Although deep down, all values are just ones and zeroes in the underlying virtual machine, Sway needs to know what those ones and zeroes actually mean. This is accomplished with _types_. + + Sway is a statically typed language. At compile time, the types of every value must be known. This does not mean you need to specify every single type: usually, the type can be reasonably inferred by the compiler. + ## Primitive Types + + Sway has the following primitive types: 1. `u8` (8-bit unsigned integer) @@ -17,6 +22,7 @@ Sway has the following primitive types: 1. `b256` (256 bits (32 bytes), i.e. a hash) All other types in Sway are built up of these primitive types, or references to these primitive types. You may notice that there are no signed integers—this is by design. In the blockchain domain that Sway occupies, floating-point values and negative numbers have smaller utility, so their implementation has been left up to libraries for specific use cases. + ## Numeric Types @@ -33,11 +39,19 @@ Numbers can be declared with binary syntax, hexadecimal syntax, base-10 syntax, 0xfff_aaa // underscore delineated hexadecimal ``` + + The default numeric type is `u64`. The FuelVM's word size is 64 bits, and the cases where using a smaller numeric type saves space are minimal. + ## Boolean Type -The boolean type (`bool`) has two potential values: `true` or `false`. Boolean values are typically used for conditional logic or validation, for example in `if` expressions. Booleans can be negated, or flipped, with the unary negation operator `!`. For example: + + +The boolean type (`bool`) has two potential values: `true` or `false`. Boolean values are typically used for conditional logic or validation, for example in `if` expressions. Booleans can be negated, or flipped, with the unary negation operator `!`. + + +For example: ```sway fn returns_false() -> bool { @@ -48,7 +62,12 @@ fn returns_false() -> bool { ## String Type -In Sway, static-length strings are a primitive type. This means that when you declare a string, its size is a part of its type. This is necessary for the compiler to know how much memory to give for the storage of that data. The size of the string is denoted with square brackets. Let's take a look: + + +In Sway, static-length strings are a primitive type. This means that when you declare a string, its size is a part of its type. This is necessary for the compiler to know how much memory to give for the storage of that data. The size of the string is denoted with square brackets. + + +Let's take a look: ```sway let my_string: str[4] = "fuel"; @@ -62,7 +81,12 @@ _Compound types_ are types that group multiple values into one type. In Sway, we ## Tuple Types -A tuple is a general-purpose static-length aggregation of types. In more plain terms, a tuple is a single type that consists of an aggregate of zero or more types. The internal types that make up a tuple, and the tuple's arity, define the tuple's type. Let's take a look at some examples. + + +A tuple is a general-purpose static-length aggregation of types. In more plain terms, a tuple is a single type that consists of an aggregate of zero or more types. The internal types that make up a tuple, and the tuple's arity, define the tuple's type. + + +Let's take a look at some examples. ```sway let x: (u64, u64) = (0, 0); @@ -75,7 +99,12 @@ let x: (u64, bool) = (42, true); assert(x.1); ``` -In this example, we have created a new tuple type, `(u64, bool)`, which is a composite of a `u64` and a `bool`. To access a value within a tuple, we use _tuple indexing_: `x.1` stands for the first (zero-indexed, so the `bool`) value of the tuple. Likewise, `x.0` would be the zeroth, `u64` value of the tuple. Tuple values can also be accessed via destructuring: +In this example, we have created a new tuple type, `(u64, bool)`, which is a composite of a `u64` and a `bool`. + + + +To access a value within a tuple, we use _tuple indexing_: `x.1` stands for the first (zero-indexed, so the `bool`) value of the tuple. Likewise, `x.0` would be the zeroth, `u64` value of the tuple. Tuple values can also be accessed via destructuring. + ```sway struct Foo {} @@ -94,7 +123,10 @@ let w: (u64) = (42,); // type error ## Arrays + + An array is similar to a tuple, but an array's values must all be of the same type. Arrays can hold arbitrary types including non-primitive types. + An array is written as a comma-separated list inside square brackets: @@ -102,9 +134,12 @@ An array is written as a comma-separated list inside square brackets: let x = [1, 2, 3, 4, 5]; ``` + + Arrays are allocated on the stack since their size is known. An array's size is _always_ static, i.e. it cannot change. An array of five elements cannot become an array of six elements. Arrays can be iterated over, unlike tuples. An array's type is written as the type the array contains followed by the number of elements, semicolon-separated and within square brackets, e.g. `[u64; 5]`. To access an element in an array, use the _array indexing syntax_, i.e. square brackets. + Array elements can also be mutated if the underlying array is declared as mutable: diff --git a/docs/book/src/basics/comments_and_logging.md b/docs/book/src/basics/comments_and_logging.md index 8f1e62a12a0..e59d44d61b1 100644 --- a/docs/book/src/basics/comments_and_logging.md +++ b/docs/book/src/basics/comments_and_logging.md @@ -2,7 +2,10 @@ ## Comments + + Comments in Sway start with two slashes and continue until the end of the line. For comments that extend beyond a single line, you'll need to include `//` on each line. + ```sway // hello world @@ -35,7 +38,10 @@ fn main() { ## Logging + + The `logging` library provides a generic `log` function that can be imported using `use std::logging::log` and used to log variables of any type. Each call to `log` appends a `receipt` to the list of receipts. There are two types of receipts that a `log` can generate: `Log` and `LogData`. + ```sway fn log_values(){ @@ -50,7 +56,12 @@ fn log_values(){ ### `Log` Receipt -The `Log` receipt is generated for _non-reference_ types, namely `bool`, `u8`, `u16`, `u32`, and `u64`. For example, logging an integer variable `x` that holds the value `42` using `log(x)` may generate the following receipt: + + +The `Log` receipt is generated for _non-reference_ types, namely `bool`, `u8`, `u16`, `u32`, and `u64`. + + +For example, logging an integer variable `x` that holds the value `42` using `log(x)` may generate the following receipt: ```console "Log": { @@ -68,7 +79,12 @@ Note that `ra` will include the value being logged. The additional registers `rc ### `LogData` Receipt -`LogData` is generated for _reference_ types which include all types except for the _non_reference_ types mentioned above. For example, logging a `b256` variable `b` that holds the value `0x1111111111111111111111111111111111111111111111111111111111111111` using `log(b)` may generate the following receipt: + + +`LogData` is generated for _reference_ types which include all types except for _non_reference_ types. + + +For example, logging a `b256` variable `b` that holds the value `0x1111111111111111111111111111111111111111111111111111111111111111` using `log(b)` may generate the following receipt: ```console "LogData": { diff --git a/docs/book/src/basics/commonly_used_library_types.md b/docs/book/src/basics/commonly_used_library_types.md index f84405543f7..4969614c055 100644 --- a/docs/book/src/basics/commonly_used_library_types.md +++ b/docs/book/src/basics/commonly_used_library_types.md @@ -4,13 +4,21 @@ The Sway Standard Library is the foundation of portable Sway software, a set of ## `Result` + + Type `Result` is the type used for returning and propagating errors. It is an `enum` with two variants: `Ok(T)`, representing success and containing a value, and `Err(E)`, representing error and containing an error value. The `T` and `E` in this definition are type parameters, allowing `Result` to be generic and to be used with any types. + ```sway {{#include ../../../../sway-lib-std/src/result.sw:docs_result}} ``` -Functions return `Result` whenever errors are expected and recoverable. Take the following example: + + +Functions return `Result` whenever errors are expected and recoverable. + + +Take the following example: ```sway {{#include ../../../../examples/result/src/main.sw}} @@ -18,18 +26,24 @@ Functions return `Result` whenever errors are expected and recoverable. Take the ## `Option` + + Type `Option` represents an optional value: every `Option` is either `Some` and contains a value, or `None`, and does not. `Option` types are very common in Sway code, as they have a number of uses: - Initial values where `None` can be used as an initializer. - Return value for otherwise reporting simple errors, where `None` is returned on error. The implementation of `Option` matches on the variant: if it's `Ok` it returns the inner value, if it's `None`, it [reverts](https://github.com/FuelLabs/fuel-specs/blob/master/src/vm/instruction_set.md#rvrt-revert). + ```sway {{#include ../../../../sway-lib-std/src/option.sw:docs_option}} ``` + + `Option` is commonly paired with pattern matching to query the presence of a value and take action, allowing developers to choose how to handle the `None` case. + Below is an example that uses pattern matching to handle invalid divisions by 0 by returning an `Option`: diff --git a/docs/book/src/basics/constants.md b/docs/book/src/basics/constants.md index bdef610bbf7..84622f13f0f 100644 --- a/docs/book/src/basics/constants.md +++ b/docs/book/src/basics/constants.md @@ -1,10 +1,13 @@ # Constants + + Constants are similar to variables; however, there are a few differences: - Constants are always evaluated at compile-time - Constants can be declared both inside of a [function](../index.md) and at global / `impl` scope. - The `mut` keyword cannot be used with constants. + ```sway const ID: u32 = 0; @@ -12,12 +15,15 @@ const ID: u32 = 0; ## Associated Constants + + Associated constants are constants associated with a type and can be declared in an `impl` block or in a `trait` definition. Associated constants declared inside a `trait` definition may omit their initializers to indicate that each implementation of the trait must specify those initializers. The identifier is the name of the constant used in the path. The type is the type that the definition has to implement. + You can _define_ an associated const directly in the interface surface of a trait: @@ -73,7 +79,10 @@ fn main() -> u64 { ## Configurable Constants + + Configurable constants are special constants that behave like regular constants in the sense that they cannot change during program execution, but they can be configured _after_ the Sway program has been built. The Rust and TS SDKs allow updating the values of these constants by injecting new values for them directly in the bytecode without having to build the program again. These are useful for contract factories and behave somewhat similarly to `immutable` variables from languages like Solidity. + Configurable constants are declared inside a `configurable` block and require a type ascription and an initializer as follows: diff --git a/docs/book/src/basics/control_flow.md b/docs/book/src/basics/control_flow.md index 9d75c4dc56e..291f4d045d6 100644 --- a/docs/book/src/basics/control_flow.md +++ b/docs/book/src/basics/control_flow.md @@ -2,7 +2,10 @@ ## `if` expressions + + Sway supports _if_, _else_, and _else if_ expressions that allow you to branch your code depending on conditions. + For example: @@ -32,7 +35,10 @@ Note that all branches of the `if` expression must return a value of the same ty ### `match` expressions + + Sway supports advanced pattern matching through exhaustive `match` expressions. Unlike an `if` statement, a `match` expression asserts **at compile** time that all possible patterns have been matched. If you don't handle all the patterns, you will get compiler error indicating that your `match` expression is non-exhaustive. + The basic syntax of a `match` statement is as follows: diff --git a/docs/book/src/basics/functions.md b/docs/book/src/basics/functions.md index b197fa5a0ff..01eaae763df 100644 --- a/docs/book/src/basics/functions.md +++ b/docs/book/src/basics/functions.md @@ -21,7 +21,12 @@ fn main() { ## Mutable Parameters -We can make a function parameter mutable by adding `ref mut` before the parameter name. This allows mutating the argument passed into the function when the function is called. For example: + + +We can make a function parameter mutable by adding `ref mut` before the parameter name. This allows mutating the argument passed into the function when the function is called. + + +For example: ```sway {{#include ../../../../examples/ref_mut_params/src/main.sw:increment}} diff --git a/docs/book/src/basics/index.md b/docs/book/src/basics/index.md index e5e2af79148..d42267159bd 100644 --- a/docs/book/src/basics/index.md +++ b/docs/book/src/basics/index.md @@ -2,13 +2,15 @@ Sway is a programming language designed for the FuelVM. It is a statically typed, compiled language with type inference and traits. Sway aims to make smart contract development safer and more performant through the use of strong static analysis and compiler feedback. -Sway basics. +Get started with the basics of Sway: - [Variables](./variables.md) - [Built-in Types](./built_in_types.md) +- [Commonly Used Library Types](./commonly_used_library_types.md) - [Blockchain Types](./blockchain_types.md) - [Functions](./functions.md) - [Structs, Tuples, and Enums](./structs_tuples_and_enums.md) - [Methods and Associated Functions](./methods_and_associated_functions.md) -- [Control Flow](./control_flow.mdz) +- [Constants](./constants.md) - [Comments and Logging](./comments_and_logging.md) +- [Control Flow](./control_flow.mdz) diff --git a/docs/book/src/basics/methods_and_associated_functions.md b/docs/book/src/basics/methods_and_associated_functions.md index 9a898c44c40..f21ed9a7b49 100644 --- a/docs/book/src/basics/methods_and_associated_functions.md +++ b/docs/book/src/basics/methods_and_associated_functions.md @@ -1,18 +1,29 @@ # Methods and Associated Functions + + Methods are similar to functions in that we declare them with the `fn` keyword and they have parameters and return a value. However, unlike functions, _Methods_ are defined within the context of a struct (or enum), and either refers to that type or mutates it. The first parameter of a method is always `self`, which represents the instance of the struct the method is being called on. _Associated functions_ are very similar to _methods_, in that they are also defined in the context of a struct or enum, but they do not actually use any of the data in the struct and as a result do not take _self_ as a parameter. Associated functions could be standalone functions, but they are included in a specific type for organizational or semantic reasons. To declare methods and associated functions for a struct or enum, use an _impl block_. Here, `impl` stands for implementation. + ```sway {{#include ../../../../examples/methods_and_associated_functions/src/main.sw}} ``` + + To call a method, simply use dot syntax: `foo.iz_baz_true()`. + -Similarly to [free functions](functions.md), methods and associated functions may accept `ref mut` parameters. For example: + + +Similarly to [free functions](functions.md), methods and associated functions may accept `ref mut` parameters. + + +For example: ```sway {{#include ../../../../examples/ref_mut_params/src/main.sw:move_right}} diff --git a/docs/book/src/basics/structs_tuples_and_enums.md b/docs/book/src/basics/structs_tuples_and_enums.md index 22a571e4985..d28973dbd5b 100644 --- a/docs/book/src/basics/structs_tuples_and_enums.md +++ b/docs/book/src/basics/structs_tuples_and_enums.md @@ -2,7 +2,10 @@ ## Structs + + Structs in Sway are a named grouping of types. You may also be familiar with structs via another name: _product types_. Sway does not make any significantly unique usages of structs; they are similar to most other languages which have structs. If you're coming from an object-oriented background, a struct is like the data attributes of an object. + Firstly, we declare a struct named `Foo` with two fields. The first field is named `bar` and it accepts values of type `u64`, the second field is named `baz` and it accepts `bool` values. @@ -10,6 +13,8 @@ Firstly, we declare a struct named `Foo` with two fields. The first field is nam {{#include ../../../../examples/structs/src/data_structures.sw}} ``` + + In order to instantiate the struct we use _struct instantiation syntax_, which is very similar to the declaration syntax except with expressions in place of types. There are three ways to instantiate the struct. @@ -17,6 +22,7 @@ There are three ways to instantiate the struct. - Hardcoding values for the fields - Passing in variables with names different than the struct fields - Using a shorthand notation via variables that are the same as the field names + ```sway {{#include ../../../../examples/structs/src/main.sw}} @@ -37,9 +43,12 @@ Structs have zero memory overhead. What that means is that in memory, each struc ## Tuples + + Tuples are a [basic static-length type](./built_in_types.md#tuple-types) which contain multiple different types within themselves. The type of a tuple is defined by the types of the values within it, and a tuple can contain basic types as well as structs and enums. You can access values directly by using the `.` syntax. Moreover, multiple variables can be extracted from a tuple using the destructuring syntax. + ```sway {{#include ../../../../examples/tuples/src/main.sw}} @@ -47,7 +56,10 @@ You can access values directly by using the `.` syntax. Moreover, multiple varia ## Enums + + _Enumerations_, or _enums_, are also known as _sum types_. An enum is a type that could be one of several variants. To declare an enum, you enumerate all potential variants. + Here, we have defined five potential colors. Each enum variant is just the color name. As there is no extra data associated with each variant, we say that each variant is of type `()`, or unit. diff --git a/docs/book/src/basics/variables.md b/docs/book/src/basics/variables.md index 99e86a2ccbf..6b37a8d8e9c 100644 --- a/docs/book/src/basics/variables.md +++ b/docs/book/src/basics/variables.md @@ -1,6 +1,11 @@ # Variables -Variables in Sway are _immutable by default_. This means that, by default, once a variable is declared, its value cannot change. This is one of the ways how Sway encourages safe programming, and many modern languages have this same default. Let's take a look at variables in detail. + + +Variables in Sway are _immutable by default_. This means that, by default, once a variable is declared, its value cannot change. This is one of the ways how Sway encourages safe programming, and many modern languages have this same default. + + +Let's take a look at variables in detail. ## Declaring a Variable @@ -29,7 +34,12 @@ Now, `foo` is mutable, and the reassignment to the number `6` is valid. That is, ## Type Annotations -A variable declaration can contain a _type annotation_. A type annotation serves the purpose of declaring the type, in addition to the value, of a variable. Let's take a look: + + +A variable declaration can contain a _type annotation_. A type annotation serves the purpose of declaring the type, in addition to the value, of a variable. + + +Let's take a look: ```sway let foo: u32 = 5; @@ -42,4 +52,7 @@ let bar: str[4] = "sway"; let baz: bool = true; ``` + + If the value declared cannot be assigned to the declared type, there will be an error generated by the compiler. + diff --git a/docs/book/src/blockchain-development/access_control.md b/docs/book/src/blockchain-development/access_control.md index 0a38bff0fae..10afdd954d8 100644 --- a/docs/book/src/blockchain-development/access_control.md +++ b/docs/book/src/blockchain-development/access_control.md @@ -1,20 +1,29 @@ # Access Control + + Smart contracts require the ability to restrict access to and identify certain users or contracts. Unlike account-based blockchains, transactions in UTXO-based blockchains (i.e. Fuel) do not necessarily have a unique transaction sender. Additional logic is needed to handle this difference, and is provided by the standard library. + ## `msg_sender` + + To deliver an experience akin to the EVM's access control, the `std` library provides a `msg_sender` function, which identifies a unique caller based upon the call and/or transaction input data. + ```sway {{#include ../../../../examples/msg_sender/src/main.sw}} ``` + + The `msg_sender` function works as follows: - If the caller is a contract, then `Ok(Sender)` is returned with the `ContractId` sender variant. - If the caller is external (i.e. from a script), then all coin input owners in the transaction are checked. If all owners are the same, then `Ok(Sender)` is returned with the `Address` sender variant. - If the caller is external and coin input owners are different, then the caller cannot be determined and a `Err(AuthError)` is returned. + ## Contract Ownership diff --git a/docs/book/src/blockchain-development/native_assets.md b/docs/book/src/blockchain-development/native_assets.md index a68fad0d0a2..7d8c8deab3a 100644 --- a/docs/book/src/blockchain-development/native_assets.md +++ b/docs/book/src/blockchain-development/native_assets.md @@ -1,5 +1,7 @@ # Native Support for Multiple Asset Types + + The FuelVM has built-in support for working with multiple assets. What does this mean in practice? @@ -7,6 +9,7 @@ What does this mean in practice? As in the EVM, sending ETH to an address or contract is an operation built into the FuelVM, meaning it doesn't rely on the existence of some token smart contract to update balances to track ownership. However, unlike the EVM, the process for sending _any_ native asset is the same. This means that while you would still need a smart contract to handle the minting and burning of fungible tokens, the sending and receiving of these tokens can be done independently of the token contract. + ## Liquidity Pool Example diff --git a/docs/book/src/blockchain-development/purity.md b/docs/book/src/blockchain-development/purity.md index cd9bd563d7f..b6ba55a54a8 100644 --- a/docs/book/src/blockchain-development/purity.md +++ b/docs/book/src/blockchain-development/purity.md @@ -1,8 +1,11 @@ # Purity + + A function is _pure_ if it does not access any [persistent storage](./storage.md). Conversely, the function is _impure_ if it does access any storage. Naturally, as storage is only available in smart contracts, impure functions cannot be used in predicates, scripts, or libraries. A pure function cannot call an impure function. In Sway, functions are pure by default but can be opted into impurity via the `storage` function attribute. The `storage` attribute may take `read` and/or `write` arguments indicating which type of access the function requires. + ```sway #[storage(read)] @@ -18,8 +21,16 @@ fn increment_amount(increment: u64) -> u64 { > **Note**: the `#[storage(write)]` attribute also permits a function to read from storage. This is due to the fact that partially writing a storage slot requires first reading the slot. + + Impure functions which call other impure functions must have at least the same storage privileges or a superset of those for the function called. For example, to call a function with write access a caller must also have write access, or both read and write access. To call a function with read and write access the caller must also have both privileges. + The `storage` attribute may also be applied to [methods and associated functions](../basics/methods_and_associated_functions.md), [trait](../advanced/traits.md) and [ABI](../sway-program-types/smart_contracts.md#the-abi-declaration) declarations. -A pure function gives you some guarantees: you will not incur excessive storage gas costs, the compiler can apply additional optimizations, and they are generally easy to reason about and audit. [A similar concept exists in Solidity](https://docs.soliditylang.org/en/v0.8.10/contracts.html#pure-functions). Note that Solidity refers to contract storage as _contract state_, and in the Sway/Fuel ecosystem, these two terms are largely interchangeable. + + +A pure function gives you some guarantees: you will not incur excessive storage gas costs, the compiler can apply additional optimizations, and they are generally easy to reason about and audit. + + +[A similar concept exists in Solidity](https://docs.soliditylang.org/en/v0.8.10/contracts.html#pure-functions). Note that Solidity refers to contract storage as _contract state_, and in the Sway/Fuel ecosystem, these two terms are largely interchangeable. diff --git a/docs/book/src/blockchain-development/storage.md b/docs/book/src/blockchain-development/storage.md index 9f4e160004c..23bf0b2f529 100644 --- a/docs/book/src/blockchain-development/storage.md +++ b/docs/book/src/blockchain-development/storage.md @@ -1,10 +1,13 @@ # Storage + + When developing a [smart contract](../sway-program-types/smart_contracts.md), you will typically need some sort of persistent storage. In this case, persistent storage, often just called _storage_ in this context, is a place where you can store values that are persisted inside the contract itself. This is in contrast to a regular value in _memory_, which disappears after the contract exits. Put in conventional programming terms, contract storage is like saving data to a hard drive. That data is saved even after the program which saved it exits. That data is persistent. Using memory is like declaring a variable in a program: it exists for the duration of the program and is non-persistent. Some basic use cases of storage include declaring an owner address for a contract and saving balances in a wallet. + ## Storage Accesses Via the `storage` Keyword diff --git a/docs/book/src/common-collections/storage_map.md b/docs/book/src/common-collections/storage_map.md index 5ccd0fa87b3..3a20f029735 100644 --- a/docs/book/src/common-collections/storage_map.md +++ b/docs/book/src/common-collections/storage_map.md @@ -1,12 +1,17 @@ # Storage Maps -Another important common collection is the storage map. The type `StorageMap` from the standard library stores a mapping of keys of type `K` to values of type `V` using a hashing function, which determines how it places these keys and values into _storage slots_. This is similar to [Rust's `HashMap`](https://doc.rust-lang.org/std/collections/struct.HashMap.html) but with a few differences. +Another important common collection is the storage map. + + + +The type `StorageMap` from the standard library stores a mapping of keys of type `K` to values of type `V` using a hashing function, which determines how it places these keys and values into _storage slots_. This is similar to [Rust's `HashMap`](https://doc.rust-lang.org/std/collections/struct.HashMap.html) but with a few differences. Storage maps are useful when you want to look up data not by using an index, as you can with vectors, but by using a key that can be of any type. For example, when building a ledger-based sub-currency smart contract, you could keep track of the balance of each wallet in a storage map in which each key is a wallet’s `Address` and the values are each wallet’s balance. Given an `Address`, you can retrieve its balance. Similarly to `StorageVec`, `StorageMap` can only be used in a contract because only contracts are allowed to access persistent storage. `StorageMap` is included in the [standard library prelude](../introduction/standard_library.md#standard-library-prelude) which means that there is no need to import it manually. + ## Creating a New Storage Map @@ -16,13 +21,21 @@ To create a new empty storage map, we have to declare the map in a `storage` blo {{#include ../../../../examples/storage_map/src/main.sw:storage_map_decl}} ``` + + Just like any other storage variable, two things are required when declaring a `StorageMap`: a type annotation and an initializer. The initializer is just an empty struct of type `StorageMap` because `StorageMap` itself is an empty struct! Everything that is interesting about `StorageMap` is implemented in its methods. Storage maps, just like `Vec` and `StorageVec`, are implemented using generics which means that the `StorageMap` type provided by the standard library can map keys of any type `K` to values of any type `V`. In the example above, we’ve told the Sway compiler that the `StorageMap` in `map` will map keys of type `Address` to values of type `u64`. + ## Updating a Storage Map -To insert key-value pairs into a storage map, we can use the `insert` method, as shown below: + + +To insert key-value pairs into a storage map, we can use the `insert` method. + + +For example: ```sway {{#include ../../../../examples/storage_map/src/main.sw:storage_map_insert}} @@ -39,7 +52,12 @@ Note two details here. First, in order to use `insert`, we need to first access ## Accessing Values in a Storage Map -We can get a value out of the storage map by providing its `key` to the `get` method, as shown below: + + +We can get a value out of the storage map by providing its `key` to the `get` method. + + +For example: ```sway {{#include ../../../../examples/storage_map/src/main.sw:storage_map_get}} diff --git a/docs/book/src/introduction/forc_project.md b/docs/book/src/introduction/forc_project.md index 4bea8277225..b2746ec716d 100644 --- a/docs/book/src/introduction/forc_project.md +++ b/docs/book/src/introduction/forc_project.md @@ -8,6 +8,8 @@ forc new my-fuel-project Here is the project that Forc has initialized: + + ```console $ cd my-fuel-project $ tree . @@ -15,8 +17,12 @@ $ tree . └── src    └── main.sw ``` + + + `Forc.toml` is the _manifest file_ (similar to `Cargo.toml` for Cargo or `package.json` for Node), and defines project metadata such as the project name and dependencies. + For additional information on dependency management, see: [here](../forc/dependencies.md). diff --git a/docs/book/src/introduction/standard_library.md b/docs/book/src/introduction/standard_library.md index 888f9578d8b..81a46e3d0d7 100644 --- a/docs/book/src/introduction/standard_library.md +++ b/docs/book/src/introduction/standard_library.md @@ -1,8 +1,11 @@ # Standard Library + + Similar to Rust, Sway comes with its own standard library. The Sway Standard Library is the foundation of portable Sway software, a set of minimal shared abstractions for the broader Sway ecosystem. It offers core types, like `Result` and `Option`, library-defined operations on language primitives, native asset management, blockchain contextual operations, access control, storage management, and support for types from other VMs, among many other things. + The entire Sway standard library is a Forc project called `std`, and is available directly here: (navigate to the appropriate tagged release if the latest `master` is not compatible). For the latest `std` documentation see: . @@ -20,6 +23,8 @@ This imports the `StorageVec` type into the current namespace. ## Standard Library Prelude + + Sway comes with a variety of things in its standard library. However, if you had to manually import every single thing that you used, it would be very verbose. But importing a lot of things that a program never uses isn't good either. A balance needs to be struck. The prelude is the list of things that Sway automatically imports into every Sway program. It's kept as small as possible, and is focused on things which are used in almost every single Sway program. @@ -40,3 +45,4 @@ The current version of the prelude lives in [`std::prelude`](https://github.com/ - [`std::revert::revert`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/revert.sw), a function that reverts the VM. - [`std::logging::log`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/logging.sw), a function that logs arbitrary stack types. - [`std::auth::msg_sender`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/auth.sw), a function that gets the `Identity` from which a call was made. + diff --git a/docs/book/src/reference/solidity_differences.md b/docs/book/src/reference/solidity_differences.md index d6b01c6d8f3..cd224339636 100644 --- a/docs/book/src/reference/solidity_differences.md +++ b/docs/book/src/reference/solidity_differences.md @@ -20,7 +20,10 @@ Panics in the FuelVM (called "reverts" in Solidity and the EVM) are global, i.e. ## Default Safe Math + + Math in the FuelVM is by default safe (i.e. any overflow or exception is a panic). Safety checks are performed natively in the VM implementation, rather than at the bytecode level like [Solidity's default safe math](https://docs.soliditylang.org/en/latest/080-breaking-changes.html#silent-changes-of-the-semantics). + ## No* Code Size Limit diff --git a/docs/book/src/reference/style_guide.md b/docs/book/src/reference/style_guide.md index 801d3547f6b..db9375b5469 100644 --- a/docs/book/src/reference/style_guide.md +++ b/docs/book/src/reference/style_guide.md @@ -2,4 +2,7 @@ ## Capitalization + + In Sway, structs, traits, and enums are `CapitalCase`. Modules, variables, and functions are `snake_case`, constants are `SCREAMING_SNAKE_CASE`. The compiler will warn you if your capitalization is ever unidiomatic. + diff --git a/docs/book/src/sway-program-types/index.md b/docs/book/src/sway-program-types/index.md index 5155303f9aa..18c97dae3a3 100644 --- a/docs/book/src/sway-program-types/index.md +++ b/docs/book/src/sway-program-types/index.md @@ -1,8 +1,11 @@ # Sway Program Types + + A Sway program itself has a type: it is either a _contract_, a _predicate_, a _script_, or a _library_. The first three of these things are all deployable to the blockchain. A _library_ is simply a project designed for code reuse and is never directly deployed to the chain. Every Sway file _must_ begin with a declaration of what type of program it is. A project can have many libraries within it, but only one contract, script, or predicate. Scripts and predicates require `main` functions to serve as entry points, while contracts instead publish an ABI. This chapter will go into detail about all of these various types of programs and what purposes they serve. + Contracts are used primarily for protocols or systems that operate within a fixed set of rules. A good example would be a staking contract or a decentralized exchange. diff --git a/docs/book/src/sway-program-types/libraries.md b/docs/book/src/sway-program-types/libraries.md index 74459ca0282..4c122c0a5f9 100644 --- a/docs/book/src/sway-program-types/libraries.md +++ b/docs/book/src/sway-program-types/libraries.md @@ -1,10 +1,18 @@ # Libraries -Libraries in Sway are files used to define new common behavior. The most prominent example of this is the [Sway Standard Library](../introduction/standard_library.html) that is made implicitly available to all Forc projects created using `forc new`. + + +Libraries in Sway are files used to define new common behavior. + + +The most prominent example of this is the [Sway Standard Library](../introduction/standard_library.html) that is made implicitly available to all Forc projects created using `forc new`. ## Writing Libraries + + Libraries are defined using the `library` keyword at the beginning of a file, followed by a name so that they can be imported. + ```sway library; @@ -65,8 +73,11 @@ which denotes the authors, an entry file, the name by which it can be imported, For large libraries, it is recommended to have a `lib.sw` entry point re-export all other sub-libraries. + + The `mod` keyword registers a submodule, making its items (such as functions and structs) accessible from the parent library. If used at the top level it will refer to a file in the `src` folder and in other cases in a folder named after the library in which it is defined. + For example, the `lib.sw` of the standard library looks like: diff --git a/docs/book/src/sway-program-types/smart_contracts.md b/docs/book/src/sway-program-types/smart_contracts.md index 5655763848b..be29d76e41b 100644 --- a/docs/book/src/sway-program-types/smart_contracts.md +++ b/docs/book/src/sway-program-types/smart_contracts.md @@ -1,10 +1,22 @@ # What is a Smart Contract? -A smart contract is no different than a script or predicate in that it is a piece of bytecode that is deployed to the blockchain via a [transaction](https://fuellabs.github.io/fuel-specs/master/protocol/tx_format). The main features of a smart contract that differentiate it from scripts or predicates are that it is _callable_ and _stateful_. Put another way, a smart contract is analogous to a deployed API with some database state. The interface of a smart contract, also just called a contract, must be defined strictly with an [ABI declaration](#the-abi-declaration). See [this contract](../examples/subcurrency.md) for an example. + + +A smart contract is no different than a script or predicate in that it is a piece of bytecode that is deployed to the blockchain via a [transaction](https://fuellabs.github.io/fuel-specs/master/protocol/tx_format). The main features of a smart contract that differentiate it from scripts or predicates are that it is _callable_ and _stateful_. Put another way, a smart contract is analogous to a deployed API with some database state. + + +The interface of a smart contract, also just called a contract, must be defined strictly with an [ABI declaration](#the-abi-declaration). See [this contract](../examples/subcurrency.md) for an example. ## Syntax of a Smart Contract -As with any Sway program, the program starts with a declaration of what [program type](./index.md) it is. A contract must also either define or import an [ABI declaration](#the-abi-declaration) and implement it. It is considered good practice to define your ABI in a separate library and import it into your contract. This allows callers of your contract to simply import the ABI directly and use it in their scripts to call your contract. Let's take a look at an ABI declaration in a library: +As with any Sway program, the program starts with a declaration of what [program type](./index.md) it is. A contract must also either define or import an [ABI declaration](#the-abi-declaration) and implement it. + + + +It is considered good practice to define your ABI in a separate library and import it into your contract. This allows callers of your contract to simply import the ABI directly and use it in their scripts to call your contract. + + +Let's take a look at an ABI declaration in a library: ```sway {{#include ../../../../examples/wallet_abi/src/main.sw:abi_library}} diff --git a/docs/book/src/testing/unit-testing.md b/docs/book/src/testing/unit-testing.md index b2616c427bd..ecbe7ed02ba 100644 --- a/docs/book/src/testing/unit-testing.md +++ b/docs/book/src/testing/unit-testing.md @@ -1,8 +1,13 @@ # Unit Testing + + Forc provides built-in support for building and executing tests for a package. -Tests are written as free functions with the `#[test]` attribute. For example: +Tests are written as free functions with the `#[test]` attribute. + + +For example: ```sway #[test] @@ -42,7 +47,12 @@ the options available for `forc test`. ## Testing Failure -Forc supports testing failing cases for test functions declared with `#[test(should_revert)]`. For example: + + +Forc supports testing failing cases for test functions declared with `#[test(should_revert)]`. + + +For example: ```sway #[test(should_revert)] @@ -93,7 +103,10 @@ fn test_fail() { } ``` + + > **Note:** When running `forc test`, your contract will be built twice: first *without* unit tests in order to determine the contract's ID, then a second time *with* unit tests with the `CONTRACT_ID` provided to their namespace. This `CONTRACT_ID` can be used with the `abi` cast to enable contract calls within unit tests. + Unit tests can call methods of external contracts if those contracts are added as contract dependencies, i.e. in the the [`contract-dependencies`](../forc/manifest_reference.md#the-contract-dependencies-section) section of the manifest file. An example of such calls is shown below: @@ -109,7 +122,10 @@ Example `Forc.toml` for contract above: ## Running Tests in Parallel or Serially + + By default, all unit tests in your project are run in parallel. Note that this does not lead to any data races in storage because each unit test has its own storage space that is not shared by any other unit test. + By default, `forc test` will use all the available threads in your system. To request that a specific number of threads be used, the flag `--test-threads ` can be provided to `forc test`.