diff --git a/versioned_docs/version-1.0/anti-patterns.md b/versioned_docs/version-1.0/anti-patterns.md index 6acc46f..5fc832f 100644 --- a/versioned_docs/version-1.0/anti-patterns.md +++ b/versioned_docs/version-1.0/anti-patterns.md @@ -30,7 +30,8 @@ which provides the opportunity for bad actors to take advantage of. // They could deploy the contract with an Ethereum-style access control list functionality -access(all) fun transferNFT(id: UInt64, owner: auth(Storage) &Account) { +access(all) +fun transferNFT(id: UInt64, owner: auth(Storage) &Account) { assert(owner(id) == owner.address) transfer(id) @@ -42,7 +43,8 @@ access(all) fun transferNFT(id: UInt64, owner: auth(Storage) &Account) { // should not be accessible in this function // BAD -access(all) fun transferNFT(id: UInt64, owner: auth(Storage) &Account) { +access(all) +fun transferNFT(id: UInt64, owner: auth(Storage) &Account) { assert(owner(id) == owner.address) transfer(id) @@ -120,14 +122,20 @@ and then a new creation function can be potentially included within the admin re // Pseudo-code // BAD -access(all) contract Currency { - access(all) resource Admin { - access(all) fun mintTokens() +access(all) +contract Currency { + + access(all) + resource Admin { + + access(all) + fun mintTokens() } // Anyone in the network can call this function // And use the Admin resource to mint tokens - access(all) fun createAdmin(): @Admin { + access(all) + fun createAdmin(): @Admin { return <-create Admin() } } @@ -135,12 +143,18 @@ access(all) contract Currency { // This contract makes the admin creation private and in the initializer // so that only the one who controls the account can mint tokens // GOOD -access(all) contract Currency { - access(all) resource Admin { - access(all) fun mintTokens() +access(all) +contract Currency { + + access(all) + resource Admin { + + access(all) + fun mintTokens() // Only an admin can create new Admins - access(all) fun createAdmin(): @Admin { + access(all) + fun createAdmin(): @Admin { return <-create Admin() } } @@ -181,14 +195,18 @@ which increments the number that tracks the play IDs and emits an event: // Simplified Code // BAD // -access(all) contract TopShot { +access(all) +contract TopShot { // The Record that is used to track every unique play ID - access(all) var nextPlayID: UInt32 + access(all) + var nextPlayID: UInt32 - access(all) struct Play { + access(all) + struct Play { - access(all) let playID: UInt32 + access(all) + let playID: UInt32 init() { @@ -216,24 +234,30 @@ that creates the plays. // Update contract state in admin resource functions // GOOD // -access(all) contract TopShot { +access(all) +contract TopShot { // The Record that is used to track every unique play ID - access(all) var nextPlayID: UInt32 + access(all) + var nextPlayID: UInt32 - access(all) struct Play { + access(all) + struct Play { - access(all) let playID: UInt32 + access(all) + let playID: UInt32 init() { self.playID = TopShot.nextPlayID } } - access(all) resource Admin { + access(all) + resource Admin { // Protected within the private admin resource - access(all) fun createPlay() { + access(all) + fun createPlay() { // Create the new Play var newPlay = Play() diff --git a/versioned_docs/version-1.0/design-patterns.md b/versioned_docs/version-1.0/design-patterns.md index 186b5d2..2f98727 100644 --- a/versioned_docs/version-1.0/design-patterns.md +++ b/versioned_docs/version-1.0/design-patterns.md @@ -38,8 +38,11 @@ Example Snippet: ```cadence // BAD Practice: Do not hard code storage paths -access(all) contract NamedFields { - access(all) resource Test {} +access(all) +contract NamedFields { + + access(all) + resource Test {} init() { // BAD: Hard-coded storage path @@ -49,11 +52,15 @@ access(all) contract NamedFields { // GOOD practice: Instead, use a field // -access(all) contract NamedFields { - access(all) resource Test {} +access(all) +contract NamedFields { + + access(all) + resource Test {} // GOOD: field storage path - access(all) let TestStoragePath: StoragePath + access(all) + let TestStoragePath: StoragePath init() { // assign and access the field here and in transactions @@ -88,10 +95,12 @@ Example: ```cadence // BAD: Field is private, so it cannot be read by the public -access(self) let totalSupply: UFix64 +access(self) +let totalSupply: UFix64 // GOOD: Field is public, so it can be read and used by anyone -access(all) let totalSupply: UFix64 +access(all) +let totalSupply: UFix64 ``` ## Script-Accessible report @@ -117,9 +126,14 @@ See [Script-Accessible public field/function](#script-accessible-public-fieldfun ### Example ```cadence -access(all) contract AContract { - access(all) let BResourceStoragePath: StoragePath - access(all) let BResourcePublicPath: PublicPath +access(all) +contract AContract { + + access(all) + let BResourceStoragePath: StoragePath + + access(all) + let BResourcePublicPath: PublicPath init() { self.BResourceStoragePath = /storage/BResource @@ -127,15 +141,21 @@ access(all) contract AContract { } // Resource definition - access(all) resource BResource { - access(all) var c: UInt64 - access(all) var d: String + access(all) + resource BResource { + + access(all) + var c: UInt64 + + access(all) + var d: String // Generate a struct with the same fields // to return when a script wants to see the fields of the resource // without having to return the actual resource - access(all) fun generateReport(): BReportStruct { + access(all) + fun generateReport(): BReportStruct { return BReportStruct(c: self.c, d: self.d) } @@ -146,9 +166,14 @@ access(all) contract AContract { } // Define a struct with the same fields as the resource - access(all) struct BReportStruct { - access(all) var c: UInt64 - access(all) var d: String + access(all) + struct BReportStruct { + + access(all) + var c: UInt64 + + access(all) + var d: String init(c: UInt64, d: String) { self.c = c @@ -172,7 +197,8 @@ transaction { import AContract from 0xAContract // Return the struct with a script -access(all) fun main(account: Address): AContract.BReportStruct { +access(all) +fun main(account: Address): AContract.BReportStruct { // borrow the resource let b = getAccount(account).capabilities .borrow<&AContract.BResource>(AContract.BResourcePublicPath) @@ -225,12 +251,16 @@ All fields, functions, types, variables, etc., need to have names that clearly d ```cadence // BAD: Unclear naming // -access(all) contract Tax { +access(all) +contract Tax { + // Do not use abbreviations unless absolutely necessary - access(all) var pcnt: UFix64 + access(all) + var pcnt: UFix64 // Not clear what the function is calculating or what the parameter should be - access(all) fun calculate(num: UFix64): UFix64 { + access(all) + fun calculate(num: UFix64): UFix64 { // What total is this referring to? let total = num + (num * self.pcnt) @@ -240,13 +270,17 @@ access(all) contract Tax { // GOOD: Clear naming // -access(all) contract TaxUtilities { +access(all) +contract TaxUtilities { + // Clearly states what the field is for - access(all) var taxPercentage: UFix64 + access(all) + var taxPercentage: UFix64 // Clearly states that this function calculates the // total cost after tax - access(all) fun calculateTotalCostPlusTax(preTaxCost: UFix64): UFix64 { + access(all) + fun calculateTotalCostPlusTax(preTaxCost: UFix64): UFix64 { let postTaxCost = preTaxCost + (preTaxCost * self.taxPercentage) return postTaxCost @@ -281,7 +315,8 @@ This could be used when purchasing an NFT to verify that the NFT was deposited i transaction { - access(all) let buyerCollectionRef: &NonFungibleToken.Collection + access(all) + let buyerCollectionRef: &NonFungibleToken.Collection prepare(acct: auth(BorrowValue) &Account) { diff --git a/versioned_docs/version-1.0/language/access-control.md b/versioned_docs/version-1.0/language/access-control.md index 3228cb9..ecdb1b6 100644 --- a/versioned_docs/version-1.0/language/access-control.md +++ b/versioned_docs/version-1.0/language/access-control.md @@ -38,7 +38,8 @@ Fields can only be assigned to and mutated from within the same or inner scope. For example, to make a function publicly accessible (`access(all)` is explained below): ``` -access(all) fun test() {} +access(all) +fun test() {} ``` There are five levels of access control: @@ -112,54 +113,64 @@ from inside the contract they are declared in. ```cadence // Declare a private constant, inaccessible/invisible in outer scope. // -access(self) let a = 1 +access(self) +let a = 1 // Declare a public constant, accessible/visible in all scopes. // -access(all) let b = 2 +access(all) +let b = 2 ``` ```cadence // Declare a public struct, accessible/visible in all scopes. // -access(all) struct SomeStruct { +access(all) +struct SomeStruct { // Declare a private constant field which is only readable // in the current and inner scopes. // - access(self) let a: Int + access(self) + let a: Int // Declare a public constant field which is readable in all scopes. // - access(all) let b: Int + access(all) + let b: Int // Declare a private variable field which is only readable // and writable in the current and inner scopes. // - access(self) var c: Int + access(self) + var c: Int // Declare a public variable field which is not settable, // so it is only writable in the current and inner scopes, // and readable in all scopes. // - access(all) var d: Int + access(all) + var d: Int // Arrays and dictionaries declared without (set) cannot be // mutated in external scopes - access(all) let arr: [Int] + access(all) + let arr: [Int] // The initializer is omitted for brevity. // Declare a private function which is only callable // in the current and inner scopes. // - access(self) fun privateTest() { + access(self) + fun privateTest() { // ... } // Declare a public function which is callable in all scopes. // - access(all) fun publicTest() { + access(all) + fun publicTest() { // ... } @@ -333,6 +344,7 @@ entitlement OuterEntitlement entitlement InnerEntitlement resource InnerResource { + access(all) fun foo() { ... } @@ -420,6 +432,7 @@ entitlement mapping OuterToInnerMap { } resource InnerResource { + access(all) fun foo() { ... } diff --git a/versioned_docs/version-1.0/language/accounts/contracts.mdx b/versioned_docs/version-1.0/language/accounts/contracts.mdx index f7d5706..61fcef6 100644 --- a/versioned_docs/version-1.0/language/accounts/contracts.mdx +++ b/versioned_docs/version-1.0/language/accounts/contracts.mdx @@ -110,8 +110,12 @@ struct DeployedContract { /// For example, given a contract /// ``` /// contract Foo { - /// access(all) struct Bar {...} - /// access(all) resource Qux {...} + /// + /// access(all) + /// struct Bar {...} + /// + /// access(all) + /// resource Qux {...} /// } /// ``` /// then `.publicTypes()` will return an array equivalent to the expression `[Type(), Type()]` @@ -212,6 +216,7 @@ For example, assuming the following contract code should be deployed: ```cadence access(all) contract Test { + access(all) let message: String @@ -273,8 +278,11 @@ For example, assuming that a contract named `Test` is already deployed to the ac and it should be updated with the following contract code: ```cadence -access(all) contract Test { - access(all) let message: String +access(all) +contract Test { + + access(all) + let message: String init(message: String) { self.message = message diff --git a/versioned_docs/version-1.0/language/attachments.mdx b/versioned_docs/version-1.0/language/attachments.mdx index e4fde59..60f1288 100644 --- a/versioned_docs/version-1.0/language/attachments.mdx +++ b/versioned_docs/version-1.0/language/attachments.mdx @@ -14,7 +14,8 @@ Attachments are declared with the `attachment` keyword, which would be declared As such, the following would be examples of legal declarations of attachments: ```cadence -access(all) attachment Foo for MyStruct { +access(all) +attachment Foo for MyStruct { // ... } @@ -57,24 +58,32 @@ So, for an attachment declared `access(all) attachment Foo for Bar`, the `base` So, for example, this would be a valid declaration of an attachment: ``` -access(all) resource R { - access(all) let x: Int +access(all) +resource R { + + access(all) + let x: Int init (_ x: Int) { self.x = x } - access(all) fun foo() { ... } + access(all) + fun foo() { ... } } -access(all) attachment A for R { - access(all) let derivedX: Int +access(all) +attachment A for R { + + access(all) + let derivedX: Int init (_ scalar: Int) { self.derivedX = base.x * scalar } - access(all) fun foo() { + access(all) + fun foo() { base.foo() } } @@ -88,13 +97,24 @@ A developer cannot, therefore, access any `access(self)` fields on the `base` value, nor can they mutate any array or dictionary typed fields. ```cadence -access(all) resource interface SomeInterface { - access(all) let b: Bool - access(self) let i: Int - access(all) let a: [String] +access(all) +resource interface SomeInterface { + + access(all) + let b: Bool + + access(self) + let i: Int + + access(all) + let a: [String] } -access(all) attachment SomeAttachment for SomeContract.SomeStruct { - access(all) let i: Int +access(all) +attachment SomeAttachment for SomeContract.SomeStruct { + + access(all) + let i: Int + init(i: Int) { if base.b { self.i = base.i // cannot access `i` on the `base` value @@ -102,7 +122,9 @@ access(all) attachment SomeAttachment for SomeContract.SomeStruct { self.i = i } } - access(all) fun foo() { + + access(all) + fun foo() { base.a.append("hello") // cannot mutate `a` outside of the composite where it was defined } } @@ -114,13 +136,16 @@ the type of `base` would be `auth(E) &R`, and the type of `self` would be `auth( ```cadence resource R { - access(E) fun foo() { + access(E) + fun foo() { //... } } -access(all) attachment A for R { - access(E) fun bar() { +access(all) +attachment A for R { + access(E) + fun bar() { base.foo() // available because `E` is required above, and thus `base` is type `auth(E) &R`. } } @@ -130,15 +155,20 @@ while this would not: ```cadence resource R { - access(E) fun foo() { + access(E) + fun foo() { //... } } -access(all) attachment A for R { - access(self) fun bar() { +access(all) +attachment A for R { + + access(self) + fun bar() { base.foo() // unavailable because this function has `self` access, and thus `base` only is type `&R`. } + } ``` @@ -170,8 +200,11 @@ the `to` keyword, and an expression that evaluates to the base value for that at Any arguments required by the attachment's initializer are provided in its constructor call. ```cadence -access(all) resource R {} -access(all) attachment A for R { +access(all) +resource R {} + +access(all) +attachment A for R { init(x: Int) { //... } @@ -190,9 +223,14 @@ but it is important to note that the attachment being created will not be access ```cadence -access(all) resource interface I {} -access(all) resource R: I {} -access(all) attachment A for I {} +access(all) +resource interface I {} + +access(all) +resource R: I {} + +access(all) +attachment A for I {} // ... let r <- create R() // has type @R @@ -228,16 +266,20 @@ entitlement E entitlement F resource R { - access(E) fun foo() { + access(E) + fun foo() { // ... } - access(F) fun bar() { + + access(F) + fun bar() { // ... } } attachment A for R { - access(E | F) fun qux() { + access(E | F) + fun qux() { // ... } } diff --git a/versioned_docs/version-1.0/language/capabilities.md b/versioned_docs/version-1.0/language/capabilities.md index f001a3d..a9f2102 100644 --- a/versioned_docs/version-1.0/language/capabilities.md +++ b/versioned_docs/version-1.0/language/capabilities.md @@ -39,6 +39,7 @@ Capabilities are created and managed through [capability controllers](./accounts ```cadence access(all) struct Capability { + /// The address of the account which the capability targets. access(all) let address: Address diff --git a/versioned_docs/version-1.0/language/composite-types.mdx b/versioned_docs/version-1.0/language/composite-types.mdx index cf1cbdf..5a45a1c 100644 --- a/versioned_docs/version-1.0/language/composite-types.mdx +++ b/versioned_docs/version-1.0/language/composite-types.mdx @@ -57,11 +57,13 @@ and resources are declared using the `resource` keyword. The keyword is followed by the name. ```cadence -access(all) struct SomeStruct { +access(all) +struct SomeStruct { // ... } -access(all) resource SomeResource { +access(all) +resource SomeResource { // ... } ``` @@ -161,9 +163,14 @@ and the name of the field. // private so they cannot be accessed in outer scopes. // Access control will be explained in a later section. // -access(all) struct Token { - access(all) let id: Int - access(all) var balance: Int +access(all) +struct Token { + + access(all) + let id: Int + + access(all) + var balance: Int init(id: Int, balance: Int) { self.id = id @@ -175,19 +182,24 @@ access(all) struct Token { Note that it is invalid to provide the initial value for a field in the field declaration. ```cadence -access(all) struct StructureWithConstantField { +access(all) +struct StructureWithConstantField { // Invalid: It is invalid to provide an initial value in the field declaration. // The field must be initialized by setting the initial value in the initializer. // - access(all) let id: Int = 1 + access(all) + let id: Int = 1 } ``` The field access syntax must be used to access fields – fields are not available as variables. ```cadence -access(all) struct Token { - access(all) let id: Int +access(all) +struct Token { + + access(all) + let id: Int init(initialID: Int) { // Invalid: There is no variable with the name `id` available. @@ -201,8 +213,11 @@ access(all) struct Token { The initializer is **not** automatically derived from the fields, it must be explicitly declared. ```cadence -access(all) struct Token { - access(all) let id: Int +access(all) +struct Token { + + access(all) + let id: Int // Invalid: Missing initializer initializing field `id`. } @@ -235,9 +250,14 @@ In an initializer, writes to `self` are considered `view` (unlike within other c as the value being constructed here is by definition local to the context calling the initializer. ```cadence -access(all) struct Token { - access(all) let id: Int - access(all) var balance: Int +access(all) +struct Token { + + access(all) + let id: Int + + access(all) + var balance: Int view init(id: Int, balance: Int) { self.id = id @@ -256,9 +276,14 @@ that the function is called on. // Declare a structure named "Rectangle", which represents a rectangle // and has variable fields for the width and height. // -access(all) struct Rectangle { - access(all) var width: Int - access(all) var height: Int +access(all) +struct Rectangle { + + access(all) + var width: Int + + access(all) + var height: Int init(width: Int, height: Int) { self.width = width @@ -268,7 +293,8 @@ access(all) struct Rectangle { // Declare a function named "scale", which scales // the rectangle by the given factor. // - access(all) fun scale(factor: Int) { + access(all) + fun scale(factor: Int) { self.width = self.width * factor self.height = self.height * factor } @@ -336,8 +362,11 @@ Accessing a field or calling a function of a structure does not copy it. ```cadence // Declare a structure named `SomeStruct`, with a variable integer field. // -access(all) struct SomeStruct { - access(all) var value: Int +access(all) +struct SomeStruct { + + access(all) + var value: Int init(value: Int) { self.value = value @@ -386,18 +415,23 @@ of an optional composite type. ```cadence // Declare a struct with a field and method. -access(all) struct Value { - access(all) var number: Int +access(all) +struct Value { + + access(all) + var number: Int init() { self.number = 2 } - access(all) fun set(new: Int) { + access(all) + fun set(new: Int) { self.number = new } - access(all) fun setAndReturn(new: Int): Int { + access(all) + fun setAndReturn(new: Int): Int { self.number = new return new } @@ -449,18 +483,23 @@ of an optional composite type. ```cadence // Declare a struct with a field and method. -access(all) struct Value { - access(all) var number: Int +access(all) +struct Value { + + access(all) + var number: Int init() { self.number = 2 } - access(all) fun set(new: Int) { + access(all) + fun set(new: Int) { self.number = new } - access(all) fun setAndReturn(new: Int): Int { + access(all) + fun setAndReturn(new: Int): Int { self.number = new return new } diff --git a/versioned_docs/version-1.0/language/contract-updatability.md b/versioned_docs/version-1.0/language/contract-updatability.md index 21b293d..6f46ae2 100644 --- a/versioned_docs/version-1.0/language/contract-updatability.md +++ b/versioned_docs/version-1.0/language/contract-updatability.md @@ -74,16 +74,23 @@ A field may belong to a contract, struct, resource, or interface. ```cadence // Existing contract - access(all) contract Foo { - access(all) var a: String - access(all) var b: Int + access(all) + contract Foo { + + access(all) + var a: String + + access(all) + var b: Int } // Updated contract - access(all) contract Foo { - access(all) var a: String + access(all) + contract Foo { + access(all) + var a: String } ``` - It leaves data for the removed field unused at the storage, as it is no longer accessible. @@ -93,17 +100,27 @@ A field may belong to a contract, struct, resource, or interface. ```cadence // Existing contract - access(all) contract Foo { - access(all) var a: String - access(all) var b: Int + access(all) + contract Foo { + + access(all) + var a: String + + access(all) + var b: Int } // Updated contract - access(all) contract Foo { - access(all) var b: Int - access(all) var a: String + access(all) + contract Foo { + + access(all) + var b: Int + + access(all) + var a: String } ``` @@ -111,15 +128,19 @@ A field may belong to a contract, struct, resource, or interface. ```cadence // Existing contract - access(all) contract Foo { - access(all) var a: String + access(all) + contract Foo { + access(all) + var a: String } // Updated contract - access(all) contract Foo { - access(self) var a: String // access modifier changed to 'access(self)' + access(all) + contract Foo { + access(self) + var a: String // access modifier changed to 'access(self)' } ``` @@ -128,16 +149,23 @@ A field may belong to a contract, struct, resource, or interface. ```cadence // Existing contract - access(all) contract Foo { - access(all) var a: String + access(all) + contract Foo { + access(all) + var a: String } // Updated contract - access(all) contract Foo { - access(all) var a: String - access(all) var b: Int // Invalid new field + access(all) + contract Foo { + + access(all) + var a: String + + access(all) + var b: Int // Invalid new field } ``` - Initializer of a contract only run once, when the contract is deployed for the first time. It does not rerun @@ -150,15 +178,21 @@ A field may belong to a contract, struct, resource, or interface. ```cadence // Existing contract - access(all) contract Foo { - access(all) var a: String + access(all) + contract Foo { + + access(all) + var a: String } // Updated contract - access(all) contract Foo { - access(all) var a: Int // Invalid type change + access(all) + contract Foo { + + access(all) + var a: Int // Invalid type change } ``` - In an already stored contract, the field `a` would have a value of type `String`. @@ -180,13 +214,15 @@ A field may belong to a contract, struct, resource, or interface. ```cadence // Existing struct - access(all) struct Foo { + access(all) + struct Foo { } // Upated struct - access(all) struct Foo: T { + access(all) + struct Foo: T { } ``` - However, if adding a conformance also requires changing the existing structure (e.g: adding a new field that is @@ -203,26 +239,30 @@ A field may belong to a contract, struct, resource, or interface. ```cadence // Existing struct - access(all) struct Foo { + access(all) + struct Foo { } // Changed to a struct interface - access(all) struct interface Foo { // Invalid type declaration change + access(all) + struct interface Foo { // Invalid type declaration change } ``` - Removing an interface conformance of a struct/resource is not valid. ```cadence // Existing struct - access(all) struct Foo: T { + access(all) + struct Foo: T { } // Upated struct - access(all) struct Foo { + access(all) + struct Foo { } ``` @@ -253,17 +293,27 @@ Below sections describes the restrictions imposed on updating the members of a s ```cadence // Existing enum with `Int` raw type - access(all) enum Color: Int { - access(all) case RED - access(all) case BLUE + access(all) + enum Color: Int { + + access(all) + case RED + + access(all) + case BLUE } // Updated enum with `UInt8` raw type - access(all) enum Color: UInt8 { // Invalid change of raw type - access(all) case RED - access(all) case BLUE + access(all) + enum Color: UInt8 { // Invalid change of raw type + + access(all) + case RED + + access(all) + case BLUE } ``` - When the enum value is stored, the raw value associated with the enum-case gets stored. @@ -282,18 +332,30 @@ it originally was (type confusion). ```cadence // Existing enum - access(all) enum Color: Int { - access(all) case RED - access(all) case BLUE + access(all) + enum Color: Int { + + access(all) + case RED + + access(all) + case BLUE } // Updated enum - access(all) enum Color: Int { - access(all) case RED - access(all) case BLUE - access(all) case GREEN // valid new enum-case at the bottom + access(all) + enum Color: Int { + + access(all) + case RED + + access(all) + case BLUE + + access(all) + case GREEN // valid new enum-case at the bottom } ``` #### Invalid Changes @@ -301,35 +363,57 @@ it originally was (type confusion). ```cadence // Existing enum - access(all) enum Color: Int { - access(all) case RED - access(all) case BLUE + access(all) + enum Color: Int { + + access(all) + case RED + + access(all) + case BLUE } // Updated enum - access(all) enum Color: Int { - access(all) case RED - access(all) case GREEN // invalid new enum-case in the middle - access(all) case BLUE + access(all) + enum Color: Int { + + access(all) + case RED + + access(all) + case GREEN // invalid new enum-case in the middle + + access(all) + case BLUE } ``` - Changing the name of an enum-case is invalid. ```cadence // Existing enum - access(all) enum Color: Int { - access(all) case RED - access(all) case BLUE + access(all) + enum Color: Int { + + access(all) + case RED + + access(all) + case BLUE } // Updated enum - access(all) enum Color: Int { - access(all) case RED - access(all) case GREEN // invalid change of names + access(all) + enum Color: Int { + + access(all) + case RED + + access(all) + case GREEN // invalid change of names } ``` - Previously stored raw values for `Color.BLUE` now represents `Color.GREEN`. i.e: The stored values have changed @@ -342,16 +426,24 @@ it originally was (type confusion). ```cadence // Existing enum - access(all) enum Color: Int { - access(all) case RED - access(all) case BLUE + access(all) + enum Color: Int { + + access(all) + case RED + + access(all) + case BLUE } // Updated enum - access(all) enum Color: Int { - access(all) case RED + access(all) + enum Color: Int { + + access(all) + case RED // invalid removal of `case BLUE` } @@ -360,17 +452,27 @@ it originally was (type confusion). ```cadence // Existing enum - access(all) enum Color: Int { - access(all) case RED - access(all) case BLUE + access(all) + enum Color: Int { + + access(all) + case RED + + access(all) + case BLUE } // Updated enum - access(all) enum Color: UInt8 { - access(all) case BLUE // invalid change of order - access(all) case RED + access(all) + enum Color: UInt8 { + + access(all) + case BLUE // invalid change of order + + access(all) + case RED } ``` - Raw value of an enum is implicit, and corresponds to the defined order. diff --git a/versioned_docs/version-1.0/language/contracts.mdx b/versioned_docs/version-1.0/language/contracts.mdx index e747347..d794923 100644 --- a/versioned_docs/version-1.0/language/contracts.mdx +++ b/versioned_docs/version-1.0/language/contracts.mdx @@ -114,9 +114,14 @@ but they have to be in the contract and not another top-level definition. // if they were deployed to the account contract storage and // the deployment would be rejected. // -access(all) resource Vault {} -access(all) struct Hat {} -access(all) fun helloWorld(): String {} +access(all) +resource Vault {} + +access(all) +struct Hat {} + +access(all) +fun helloWorld(): String {} let num: Int ``` @@ -132,13 +137,17 @@ there is no way to create this resource, so it would not be usable. ```cadence // Valid -access(all) contract FungibleToken { +access(all) +contract FungibleToken { - access(all) resource interface Receiver { + access(all) + resource interface Receiver { - access(all) balance: Int + access(all) + balance: Int - access(all) fun deposit(from: @{Receiver}) { + access(all) + fun deposit(from: @{Receiver}) { pre { from.balance > 0: "Deposit balance needs to be positive!" @@ -150,10 +159,12 @@ access(all) contract FungibleToken { } } - access(all) resource Vault: Receiver { + access(all) + resource Vault: Receiver { // keeps track of the total balance of the accounts tokens - access(all) var balance: Int + access(all) + var balance: Int init(balance: Int) { self.balance = balance @@ -161,7 +172,8 @@ access(all) contract FungibleToken { // withdraw subtracts amount from the vaults balance and // returns a vault object with the subtracted balance - access(all) fun withdraw(amount: Int): @Vault { + access(all) + fun withdraw(amount: Int): @Vault { self.balance = self.balance - amount return <-create Vault(balance: amount) } @@ -169,7 +181,8 @@ access(all) contract FungibleToken { // deposit takes a vault object as a parameter and adds // its balance to the balance of the Account's vault, then // destroys the sent vault because its balance has been consumed - access(all) fun deposit(from: @{Receiver}) { + access(all) + fun deposit(from: @{Receiver}) { self.balance = self.balance + from.balance destroy from } @@ -232,19 +245,23 @@ They can refer to that nested interface by saying `{ContractInterfaceName}.{Nest // Declare a contract interface that declares an interface and a resource // that needs to implement that interface in the contract implementation. // -access(all) contract interface InterfaceExample { +access(all) +contract interface InterfaceExample { // Implementations do not need to declare this // They refer to it as InterfaceExample.NestedInterface // - access(all) resource interface NestedInterface {} + access(all) + resource interface NestedInterface {} // Implementations must declare this type // - access(all) resource Composite: NestedInterface {} + access(all) + resource Composite: NestedInterface {} } -access(all) contract ExampleContract: InterfaceExample { +access(all) +contract ExampleContract: InterfaceExample { // The contract doesn't need to redeclare the `NestedInterface` interface // because it is already declared in the contract interface @@ -252,7 +269,8 @@ access(all) contract ExampleContract: InterfaceExample { // The resource has to refer to the resource interface using the name // of the contract interface to access it // - access(all) resource Composite: InterfaceExample.NestedInterface { + access(all) + resource Composite: InterfaceExample.NestedInterface { } } ``` diff --git a/versioned_docs/version-1.0/language/core-events.md b/versioned_docs/version-1.0/language/core-events.md index 2caff35..9b0dfbc 100644 --- a/versioned_docs/version-1.0/language/core-events.md +++ b/versioned_docs/version-1.0/language/core-events.md @@ -15,7 +15,8 @@ Event that is emitted when a new account gets created. Event name: `flow.AccountCreated` ```cadence -access(all) event AccountCreated(address: Address) +access(all) +event AccountCreated(address: Address) ``` | Field | Type | Description | @@ -30,7 +31,8 @@ Event that is emitted when a key gets added to an account. Event name: `flow.AccountKeyAdded` ```cadence -access(all) event AccountKeyAdded( +access(all) +event AccountKeyAdded( address: Address, publicKey: PublicKey ) @@ -49,7 +51,8 @@ Event that is emitted when a key gets removed from an account. Event name: `flow.AccountKeyRemoved` ```cadence -access(all) event AccountKeyRemoved( +access(all) +event AccountKeyRemoved( address: Address, publicKey: PublicKey ) @@ -68,7 +71,8 @@ Event that is emitted when a contract gets deployed to an account. Event name: `flow.AccountContractAdded` ```cadence -access(all) event AccountContractAdded( +access(all) +event AccountContractAdded( address: Address, codeHash: [UInt8], contract: String @@ -88,7 +92,8 @@ Event that is emitted when a contract gets updated on an account. Event name: `flow.AccountContractUpdated` ```cadence -access(all) event AccountContractUpdated( +access(all) +event AccountContractUpdated( address: Address, codeHash: [UInt8], contract: String @@ -109,7 +114,8 @@ Event that is emitted when a contract gets removed from an account. Event name: `flow.AccountContractRemoved` ```cadence -access(all) event AccountContractRemoved( +access(all) +event AccountContractRemoved( address: Address, codeHash: [UInt8], contract: String @@ -129,7 +135,8 @@ Event that is emitted when a Capability is published from an account. Event name: `flow.InboxValuePublished` ```cadence -access(all) event InboxValuePublished(provider: Address, recipient: Address, name: String, type: Type) +access(all) +event InboxValuePublished(provider: Address, recipient: Address, name: String, type: Type) ``` | Field | Type | Description | @@ -150,7 +157,8 @@ Event that is emitted when a Capability is unpublished from an account. Event name: `flow.InboxValueUnpublished` ```cadence -access(all) event InboxValueUnpublished(provider: Address, name: String) +access(all) +event InboxValueUnpublished(provider: Address, name: String) ``` | Field | Type | Description | @@ -169,7 +177,8 @@ Event that is emitted when a Capability is claimed by an account. Event name: `flow.InboxValueClaimed` ```cadence -access(all) event InboxValueClaimed(provider: Address, recipient: Address, name: String) +access(all) +event InboxValueClaimed(provider: Address, recipient: Address, name: String) ``` | Field | Type | Description | diff --git a/versioned_docs/version-1.0/language/crypto.mdx b/versioned_docs/version-1.0/language/crypto.mdx index 336226a..511b4fd 100644 --- a/versioned_docs/version-1.0/language/crypto.mdx +++ b/versioned_docs/version-1.0/language/crypto.mdx @@ -9,18 +9,23 @@ The built-in [enumeration](./enumerations.md) `HashAlgorithm` provides the set of supported hashing algorithms. ```cadence -access(all) enum HashAlgorithm: UInt8 { +access(all) +enum HashAlgorithm: UInt8 { /// SHA2_256 is SHA-2 with a 256-bit digest (also referred to as SHA256). - access(all) case SHA2_256 = 1 + access(all) + case SHA2_256 = 1 /// SHA2_384 is SHA-2 with a 384-bit digest (also referred to as SHA384). - access(all) case SHA2_384 = 2 + access(all) + case SHA2_384 = 2 /// SHA3_256 is SHA-3 with a 256-bit digest. - access(all) case SHA3_256 = 3 + access(all) + case SHA3_256 = 3 /// SHA3_384 is SHA-3 with a 384-bit digest. - access(all) case SHA3_384 = 4 + access(all) + case SHA3_384 = 4 /// KMAC128_BLS_BLS12_381 is an instance of KECCAK Message Authentication Code (KMAC128) mac algorithm. /// Although this is a MAC algorithm, KMAC is included in this list as it can be used hash @@ -29,17 +34,21 @@ access(all) enum HashAlgorithm: UInt8 { /// It is a customized version of KMAC128 that is compatible with the hashing to curve /// used in BLS signatures. /// It is the same hasher used by signatures in the internal Flow protocol. - access(all) case KMAC128_BLS_BLS12_381 = 5 + access(all) + case KMAC128_BLS_BLS12_381 = 5 /// KECCAK_256 is the legacy Keccak algorithm with a 256-bits digest, as per the original submission to the NIST SHA3 competition. /// KECCAK_256 is different than SHA3 and is used by Ethereum. - access(all) case KECCAK_256 = 6 + access(all) + case KECCAK_256 = 6 /// Returns the hash of the given data - access(all) view fun hash(_ data: [UInt8]): [UInt8] + access(all) + view fun hash(_ data: [UInt8]): [UInt8] /// Returns the hash of the given data and tag - access(all) view fun hashWithTag(_ data: [UInt8], tag: string): [UInt8] + access(all) + view fun hashWithTag(_ data: [UInt8], tag: string): [UInt8] } ``` @@ -95,17 +104,21 @@ The built-in [enumeration](./enumerations.md) `SignatureAlgorithm` provides the set of supported signature algorithms. ```cadence -access(all) enum SignatureAlgorithm: UInt8 { +access(all) +enum SignatureAlgorithm: UInt8 { /// ECDSA_P256 is ECDSA on the NIST P-256 curve. - access(all) case ECDSA_P256 = 1 + access(all) + case ECDSA_P256 = 1 /// ECDSA_secp256k1 is ECDSA on the secp256k1 curve. - access(all) case ECDSA_secp256k1 = 2 + access(all) + case ECDSA_secp256k1 = 2 /// BLS_BLS12_381 is BLS signature scheme on the BLS12-381 curve. /// The scheme is set-up so that signatures are in G_1 (subgroup of the curve over the prime field) /// while public keys are in G_2 (subgroup of the curve over the prime field extension). - access(all) case BLS_BLS12_381 = 3 + access(all) + case BLS_BLS12_381 = 3 } ``` @@ -116,6 +129,7 @@ access(all) enum SignatureAlgorithm: UInt8 { ```cadence access(all) struct PublicKey { + access(all) let publicKey: [UInt8] @@ -338,7 +352,8 @@ For example, to verify two signatures with equal weights for some signed data: ```cadence import Crypto -access(all) fun test main() { +access(all) +fun test main() { let keyList = Crypto.KeyList() let publicKeyA = PublicKey( @@ -390,12 +405,23 @@ access(all) fun test main() { The API of the Crypto contract related to key lists is: ```cadence -access(all) struct KeyListEntry { - access(all) let keyIndex: Int - access(all) let publicKey: PublicKey - access(all) let hashAlgorithm: HashAlgorithm - access(all) let weight: UFix64 - access(all) let isRevoked: Bool +access(all) +struct KeyListEntry { + + access(all) + let keyIndex: Int + + access(all) + let publicKey: PublicKey + + access(all) + let hashAlgorithm: HashAlgorithm + + access(all) + let weight: UFix64 + + access(all) + let isRevoked: Bool init( keyIndex: Int, @@ -406,12 +432,14 @@ access(all) struct KeyListEntry { ) } -access(all) struct KeyList { +access(all) +struct KeyList { init() /// Adds a new key with the given weight - access(all) fun add( + access(all) + fun add( _ publicKey: PublicKey, hashAlgorithm: HashAlgorithm, weight: UFix64 @@ -419,22 +447,31 @@ access(all) struct KeyList { /// Returns the key at the given index, if it exists. /// Revoked keys are always returned, but they have `isRevoked` field set to true - access(all) fun get(keyIndex: Int): KeyListEntry? + access(all) + fun get(keyIndex: Int): KeyListEntry? /// Marks the key at the given index revoked, but does not delete it - access(all) fun revoke(keyIndex: Int) + access(all) + fun revoke(keyIndex: Int) /// Returns true if the given signatures are valid for the given signed data - access(all) fun verify( + access(all) + fun verify( signatureSet: [KeyListSignature], signedData: [UInt8] ): Bool } -access(all) struct KeyListSignature { - access(all) let keyIndex: Int - access(all) let signature: [UInt8] +access(all) +struct KeyListSignature { - access(all) init(keyIndex: Int, signature: [UInt8]) + access(all) + let keyIndex: Int + + access(all) + let signature: [UInt8] + + access(all) + init(keyIndex: Int, signature: [UInt8]) } ``` diff --git a/versioned_docs/version-1.0/language/enumerations.md b/versioned_docs/version-1.0/language/enumerations.md index 137094c..4fc1705 100644 --- a/versioned_docs/version-1.0/language/enumerations.md +++ b/versioned_docs/version-1.0/language/enumerations.md @@ -34,10 +34,17 @@ Enum cases can be compared using the equality operators `==` and `!=`. // Declare an enum named `Color` which has the raw value type `UInt8`, // and declare three enum cases: `red`, `green`, and `blue` // -access(all) enum Color: UInt8 { - access(all) case red - access(all) case green - access(all) case blue +access(all) +enum Color: UInt8 { + + access(all) + case red + + access(all) + case green + + access(all) + case blue } // Declare a variable which has the enum type `Color` and initialize // it to the enum case `blue` of the enum diff --git a/versioned_docs/version-1.0/language/environment-information.md b/versioned_docs/version-1.0/language/environment-information.md index 27131a8..2dea77f 100644 --- a/versioned_docs/version-1.0/language/environment-information.md +++ b/versioned_docs/version-1.0/language/environment-information.md @@ -34,26 +34,30 @@ To get information about a block, the functions `getCurrentBlock` and `getBlock` The `Block` type contains the identifier, height, and timestamp: ```cadence -access(all) struct Block { +access(all) +struct Block { /// The ID of the block. /// /// It is essentially the hash of the block. /// - access(all) let id: [UInt8; 32] + access(all) + let id: [UInt8; 32] /// The height of the block. /// /// If the blockchain is viewed as a tree with the genesis block at the root, // the height of a node is the number of edges between the node and the genesis block /// - access(all) let height: UInt64 + access(all) + let height: UInt64 /// The view of the block. /// /// It is a detail of the consensus algorithm. It is a monotonically increasing integer /// and counts rounds in the consensus algorithm. It is reset to zero at each spork. /// - access(all) let view: UInt64 + access(all) + let view: UInt64 /// The timestamp of the block. /// @@ -62,7 +66,8 @@ access(all) struct Block { /// NOTE: It is included by the proposer, there are no guarantees on how much the time stamp can deviate from the true time the block was published. /// Consider observing blocks’ status changes off-chain yourself to get a more reliable value. /// - access(all) let timestamp: UFix64 + access(all) + let timestamp: UFix64 } ``` diff --git a/versioned_docs/version-1.0/language/events.md b/versioned_docs/version-1.0/language/events.md index 40b50a5..02c90b2 100644 --- a/versioned_docs/version-1.0/language/events.md +++ b/versioned_docs/version-1.0/language/events.md @@ -28,7 +28,8 @@ Events cannot be declared globally or within resource or struct types. // event GlobalEvent(field: Int) -access(all) contract Events { +access(all) +contract Events { // Event with explicit argument labels // event BarEvent(labelA fieldA: Int, labelB fieldB: Int) @@ -46,7 +47,8 @@ access(all) contract Events { To emit an event from a program, use the `emit` statement: ```cadence -access(all) contract Events { +access(all) +contract Events { event FooEvent(x: Int, y: Int) // Event with argument labels diff --git a/versioned_docs/version-1.0/language/functions.mdx b/versioned_docs/version-1.0/language/functions.mdx index e951cfa..9643d02 100644 --- a/versioned_docs/version-1.0/language/functions.mdx +++ b/versioned_docs/version-1.0/language/functions.mdx @@ -599,7 +599,8 @@ or passed to functions as arguments. // Declare a function named `transform` which applies a function to each element // of an array of integers and returns a new array of the results. // -access(all) fun transform(function: fun(Int): Int, integers: [Int]): [Int] { +access(all) +fun transform(function: fun(Int): Int, integers: [Int]): [Int] { var newIntegers: [Int] = [] for integer in integers { newIntegers.append(function(integer)) @@ -607,7 +608,8 @@ access(all) fun transform(function: fun(Int): Int, integers: [Int]): [Int] { return newIntegers } -access(all) fun double(_ integer: Int): Int { +access(all) +fun double(_ integer: Int): Int { return integer * 2 } diff --git a/versioned_docs/version-1.0/language/glossary.mdx b/versioned_docs/version-1.0/language/glossary.mdx index 92b3eae..3c3ef8a 100644 --- a/versioned_docs/version-1.0/language/glossary.mdx +++ b/versioned_docs/version-1.0/language/glossary.mdx @@ -53,8 +53,11 @@ This emphasizes the whole type acts like a resource. ```cadence // Declare a resource named `SomeResource` -access(all) resource SomeResource { - access(all) var value: Int +access(all) +resource SomeResource { + + access(all) + var value: Int init(value: Int) { self.value = value @@ -65,7 +68,8 @@ access(all) resource SomeResource { let a: @SomeResource <- create SomeResource(value: 0) // also in functions declarations -access(all) fun use(resource: @SomeResource) { +access(all) +fun use(resource: @SomeResource) { destroy resource } ``` @@ -187,7 +191,8 @@ If the variable is `nil`, the move succeeds. If it is not nil, the program aborts. ```cadence -access(all) resource R {} +access(all) +resource R {} var a: @R? <- nil a <-! create R() diff --git a/versioned_docs/version-1.0/language/interfaces.mdx b/versioned_docs/version-1.0/language/interfaces.mdx index 5f76bbf..9306196 100644 --- a/versioned_docs/version-1.0/language/interfaces.mdx +++ b/versioned_docs/version-1.0/language/interfaces.mdx @@ -70,7 +70,8 @@ For now, the syntax `{I}` can be read as the type of any value that implements t // Declare a resource interface for a fungible token. // Only resources can implement this resource interface. // -access(all) resource interface FungibleToken { +access(all) +resource interface FungibleToken { // Require the implementing type to provide a field for the balance // that is readable in all scopes (`access(all)`). @@ -79,7 +80,8 @@ access(all) resource interface FungibleToken { // so the field may be implemented as either a variable // or as a constant field. // - access(all) balance: Int + access(all) + balance: Int // Require the implementing type to provide an initializer that // given the initial balance, must initialize the balance field. @@ -109,7 +111,8 @@ access(all) resource interface FungibleToken { // The type `{FungibleToken}` is the type of any resource // that implements the resource interface `FungibleToken`. // - access(all) fun withdraw(amount: Int): @{FungibleToken} { + access(all) + fun withdraw(amount: Int): @{FungibleToken} { pre { amount > 0: "the amount must be positive" @@ -135,7 +138,8 @@ access(all) resource interface FungibleToken { // The parameter type `{FungibleToken}` is the type of any resource // that implements the resource interface `FungibleToken`. // - access(all) fun deposit(_ token: @{FungibleToken}) { + access(all) + fun deposit(_ token: @{FungibleToken}) { post { self.balance == before(self.balance) + token.balance: "the amount must be added to the balance" @@ -182,7 +186,8 @@ in terms of name, parameter argument labels, parameter types, and the return typ // It has a variable field named `balance`, that can be written // by functions of the type, but outer scopes can only read it. // -access(all) resource ExampleToken: FungibleToken { +access(all) +resource ExampleToken: FungibleToken { // Implement the required field `balance` for the `FungibleToken` interface. // The interface does not specify if the field must be variable, constant, @@ -190,7 +195,8 @@ access(all) resource ExampleToken: FungibleToken { // but limit outer scopes to only read from the field, it is declared variable, // and only has public access (non-settable). // - access(all) var balance: Int + access(all) + var balance: Int // Implement the required initializer for the `FungibleToken` interface: // accept an initial balance and initialize the `balance` field. @@ -214,7 +220,8 @@ access(all) resource ExampleToken: FungibleToken { // NOTE: neither the precondition nor the postcondition declared // in the interface have to be repeated here in the implementation. // - access(all) fun withdraw(amount: Int): @ExampleToken { + access(all) + fun withdraw(amount: Int): @ExampleToken { self.balance = self.balance - amount return create ExampleToken(balance: amount) } @@ -235,7 +242,8 @@ access(all) resource ExampleToken: FungibleToken { // NOTE: neither the precondition nor the postcondition declared // in the interface have to be repeated here in the implementation. // - access(all) fun deposit(_ token: @{FungibleToken}) { + access(all) + fun deposit(_ token: @{FungibleToken}) { if let exampleToken <- token as? ExampleToken { self.balance = self.balance + exampleToken.balance destroy exampleToken @@ -290,19 +298,23 @@ and an implementation may provide a variable field which is public, (the `access(all)` modifier is used). ```cadence -access(all) struct interface AnInterface { +access(all) +struct interface AnInterface { // Require the implementing type to provide a contract-readable // field named `a` that has type `Int`. It may be a variable // or a constant field. // - access(contract) a: Int + access(contract) + a: Int } -access(all) struct AnImplementation: AnInterface { +access(all) +struct AnImplementation: AnInterface { // Declare a public variable field named `a` that has type `Int`. // This implementation satisfies the requirement for interface `AnInterface`: // - access(all) var a: Int + access(all) + var a: Int init(a: Int) { self.a = a @@ -325,18 +337,25 @@ when accessing a value of such a type. // Require implementing types to provide a field which returns the area, // and a function which scales the shape by a given factor. // -access(all) struct interface Shape { - access(all) fun getArea(): Int - access(all) fun scale(factor: Int) +access(all) +struct interface Shape { + + access(all) + fun getArea(): Int + + access(all) + fun scale(factor: Int) } // Declare a structure named `Square` the implements the `Shape` interface. // -access(all) struct Square: Shape { +access(all) +struct Square: Shape { // In addition to the required fields from the interface, // the type can also declare additional fields. // - access(all) var length: Int + access(all) + var length: Int // Provided the field `area` which is required to conform // to the interface `Shape`. @@ -344,36 +363,46 @@ access(all) struct Square: Shape { // Since `area` was not declared as a constant, variable, // field in the interface, it can be declared. // - access(all) fun getArea(): Int { + access(all) + fun getArea(): Int { return self.length * self.length } - access(all) init(length: Int) { + access(all) + init(length: Int) { self.length = length } // Provided the implementation of the function `scale` // which is required to conform to the interface `Shape`. // - access(all) fun scale(factor: Int) { + access(all) + fun scale(factor: Int) { self.length = self.length * factor } } // Declare a structure named `Rectangle` that also implements the `Shape` interface. // -access(all) struct Rectangle: Shape { - access(all) var width: Int - access(all) var height: Int +access(all) +struct Rectangle: Shape { + + access(all) + var width: Int + + access(all) + var height: Int // Provided the field `area which is required to conform // to the interface `Shape`. // - access(all) fun getArea(): Int { + access(all) + fun getArea(): Int { return self.width * self.height } - access(all) init(width: Int, height: Int) { + access(all) + init(width: Int, height: Int) { self.width = width self.height = height } @@ -381,7 +410,8 @@ access(all) struct Rectangle: Shape { // Provided the implementation of the function `scale` // which is required to conform to the interface `Shape`. // - access(all) fun scale(factor: Int) { + access(all) + fun scale(factor: Int) { self.width = self.width * factor self.height = self.height * factor } @@ -548,13 +578,17 @@ When an interface inherits from another, all the fields, functions, and types of available to the inheriting interface. ```cadence -access(all) resource interface Receiver { - access(all) fun deposit(_ something: @AnyResource) +access(all) +resource interface Receiver { + access(all) + fun deposit(_ something: @AnyResource) } // `Vault` interface inherits from `Receiver` interface. -access(all) resource interface Vault: Receiver { - access(all) fun withdraw(_ amount: Int): @Vault +access(all) +resource interface Vault: Receiver { + access(all) + fun withdraw(_ amount: Int): @Vault } ``` @@ -562,11 +596,15 @@ In the example above, `Vault` inherits `Receiver`. Anyone implementing the `Vaul implement the `Receiver` interface. ```cadence -access(all) resource MyVault: Vault { +access(all) +resource MyVault: Vault { + // Must implement all the methods coming from both `Vault` and `Receiver` interfaces. - access(all) fun deposit(_ something: @AnyResource) {} + access(all) + fun deposit(_ something: @AnyResource) {} - access(all) fun withdraw(_ amount: Int): @Vault {} + access(all) + fun withdraw(_ amount: Int): @Vault {} } ``` @@ -580,26 +618,34 @@ The following sections explain how these ambiguities are resolved for different If two fields with identical names have identical types, then it will be valid. ```cadence -access(all) resource interface Receiver { - access(all) var id: UInt64 +access(all) +resource interface Receiver { + access(all) + var id: UInt64 } -access(all) resource interface Vault: Receiver { +access(all) +resource interface Vault: Receiver { // `id` field has the same type as the `Receiver.id`. Hence this is valid. - access(all) var id: UInt64 + access(all) + var id: UInt64 } ``` Otherwise, interface conformance is not valid. ```cadence -access(all) resource interface Receiver { - access(all) var id: Int +access(all) +resource interface Receiver { + access(all) + var id: Int } -access(all) resource interface Vault: Receiver { +access(all) +resource interface Vault: Receiver { // `id` field has a different type than the `Receiver.id`. Hence this is invalid. - access(all) var id: UInt64 + access(all) + var id: UInt64 } ``` @@ -608,29 +654,37 @@ access(all) resource interface Vault: Receiver { If two functions with identical names also have identical signatures, that is valid. ```cadence -access(all) resource interface Receiver { - access(all) fun deposit(_ something: @AnyResource) +access(all) +resource interface Receiver { + access(all) + fun deposit(_ something: @AnyResource) } -access(all) resource interface Vault: Receiver { +access(all) +resource interface Vault: Receiver { // `deposit` function has the same signature as the `Receiver.deposit`. // Also none of them have any default implementations. // Hence this is valid. - access(all) fun deposit(_ something: @AnyResource) + access(all) + fun deposit(_ something: @AnyResource) } ``` If the signatures of the two functions are different, then the interface conformance is not valid. ```cadence -access(all) resource interface Receiver { - access(all) fun deposit(_ something: @AnyResource) +access(all) +resource interface Receiver { + access(all) + fun deposit(_ something: @AnyResource) } -access(all) resource interface Vault: Receiver { +access(all) +resource interface Vault: Receiver { // Error: `deposit` function has a different signature compared to the `Receiver.deposit`. // So these two cannot co-exist. - access(all) fun deposit() + access(all) + fun deposit() } ``` @@ -642,17 +696,21 @@ to determine the order of the execution of the conditions. Given the pre/post conditions are `view` only, the order of execution would not have an impact on the conditions. ```cadence -access(all) resource interface Receiver { - access(all) fun deposit(_ something: @AnyResource) { +access(all) +resource interface Receiver { + access(all) + fun deposit(_ something: @AnyResource) { pre{ self.balance > 100 } } } -access(all) resource interface Vault: Receiver { +access(all) +resource interface Vault: Receiver { // `deposit` function has the same signature as the `Receiver.deposit`. // Having pre/post condition is valid. // Both conditions would be executed, in a pre-determined order. - access(all) fun deposit(_ something: @AnyResource) { + access(all) + fun deposit(_ something: @AnyResource) { pre{ self.balance > 50 } } } @@ -663,13 +721,17 @@ access(all) resource interface Vault: Receiver { An interface can provide a default implementation to an inherited function. ```cadence -access(all) resource interface Receiver { - access(all) fun log(_ message: String) +access(all) +resource interface Receiver { + access(all) + fun log(_ message: String) } -access(all) resource interface Vault: Receiver { +access(all) +resource interface Vault: Receiver { // Valid: Provides the implementation for `Receiver.log` method. - access(all) fun log(_ message: String) { + access(all) + fun log(_ message: String) { log(message.append("from Vault")) } } @@ -678,15 +740,19 @@ access(all) resource interface Vault: Receiver { However, an interface cannot override an inherited default implementation of a function. ```cadence -access(all) resource interface Receiver { - access(all) fun log(_ message: String) { +access(all) +resource interface Receiver { + access(all) + fun log(_ message: String) { log(message.append("from Receiver")) } } -access(all) resource interface Vault: Receiver { +access(all) +resource interface Vault: Receiver { // Invalid: Cannot override the `Receiver.log` method. - access(all) fun log(_ message: String) { + access(all) + fun log(_ message: String) { log(message.append("from Vault")) } } @@ -695,39 +761,49 @@ access(all) resource interface Vault: Receiver { It is also invalid to have two or more inherited default implementations for an interface. ```cadence -access(all) resource interface Receiver { - access(all) fun log(_ message: String) { +access(all) +resource interface Receiver { + access(all) + fun log(_ message: String) { log(message.append("from Receiver")) } } -access(all) resource interface Provider { - access(all) fun log(_ message: String) { +access(all) +resource interface Provider { + access(all) + fun log(_ message: String) { log(message.append("from Provider")) } } // Invalid: Two default functions from two interfaces. -access(all) resource interface Vault: Receiver, Provider {} +access(all) +resource interface Vault: Receiver, Provider {} ``` Having said that, there can be situations where the same default function can be available via different inheritance paths. ```cadence -access(all) resource interface Logger { - access(all) fun log(_ message: String) { +access(all) +resource interface Logger { + access(all) + fun log(_ message: String) { log(message.append("from Logger")) } } -access(all) resource interface Receiver: Logger {} +access(all) +resource interface Receiver: Logger {} -access(all) resource interface Provider: Logger {} +access(all) +resource interface Provider: Logger {} // Valid: `Logger.log()` default function is visible to the `Vault` interface // via both `Receiver` and `Provider`. -access(all) resource interface Vault: Receiver, Provider {} +access(all) +resource interface Vault: Receiver, Provider {} ``` In the above example, `Logger.log()` default function is visible to the `Vault` interface via both `Receiver` and `Provider`. @@ -741,20 +817,25 @@ A more complex situation is where a default function is available via one inheri is available via another inheritance path. ```cadence -access(all) resource interface Receiver { - access(all) fun log(_ message: String) { +access(all) +resource interface Receiver { + access(all) + fun log(_ message: String) { log(message.append("from Receiver")) } } -access(all) resource interface Provider { - access(all) fun log(_ message: String) { +access(all) +resource interface Provider { + access(all) + fun log(_ message: String) { pre{ message != "" } } } // Valid: Both the default function and the condition would be available. -access(all) resource interface Vault: Receiver, Provider {} +access(all) +resource interface Vault: Receiver, Provider {} ``` In such situations, all rules applicable for default functions inheritance as well as condition inheritance @@ -768,16 +849,22 @@ Type and event definitions would also behave similarly to the default functions. Inherited interfaces can override type definitions and event definitions. ```cadence -access(all) contract interface Token { - access(all) struct Foo {} +access(all) +contract interface Token { + access(all) + struct Foo {} } -access(all) contract interface NonFungibleToken: Token { - access(all) struct Foo {} +access(all) +contract interface NonFungibleToken: Token { + access(all) + struct Foo {} } -access(all) contract MyToken: NonFungibleToken { - access(all) fun test() { +access(all) +contract MyToken: NonFungibleToken { + access(all) + fun test() { let foo: Foo // This will refer to the `NonFungibleToken.Foo` } } @@ -789,32 +876,42 @@ access it using the fully qualified name. e.g: `let foo: Token.Foo`. However, it is not allowed to have two or more inherited type/events definitions with identical names for an interface. ```cadence -access(all) contract interface Token { - access(all) struct Foo {} +access(all) +contract interface Token { + access(all) + struct Foo {} } -access(all) contract interface Collectible { - access(all) struct Foo {} +access(all) +contract interface Collectible { + access(all) + struct Foo {} } // Invalid: Two type definitions with the same name from two interfaces. -access(all) contract NonFungibleToken: Token, Collectible { +access(all) +contract NonFungibleToken: Token, Collectible { } ``` Similar to default functions, there can be situations where the same type/event definition can be available via different inheritance paths. ```cadence -access(all) contract interface Logger { - access(all) struct Foo {} +access(all) +contract interface Logger { + access(all) + struct Foo {} } -access(all) contract interface Token: Logger {} +access(all) +contract interface Token: Logger {} -access(all) contract interface Collectible: Logger {} +access(all) +contract interface Collectible: Logger {} // Valid: `Logger.Foo` struct is visible to the `NonFungibleToken` interface via both `Token` and `Collectible`. -access(all) contract interface NonFungibleToken: Token, Collectible {} +access(all) +contract interface NonFungibleToken: Token, Collectible {} ``` In the above example, `Logger.Foo` type definition is visible to the `NonFungibleToken` interface via both `Token` @@ -827,21 +924,27 @@ However, if at least one of the interfaces in the middle of the chain also overr then the code becomes invalid, as there are multiple implementations present now, which leads to ambiguity. ```cadence -access(all) contract interface Logger { - access(all) struct Foo {} +access(all) +contract interface Logger { + access(all) + struct Foo {} } -access(all) contract interface Token: Logger { - access(all) struct Foo {} +access(all) +contract interface Token: Logger { + access(all) + struct Foo {} } -access(all) contract interface Collectible: Logger {} +access(all) +contract interface Collectible: Logger {} // Invalid: The default implementation of the `Foo` struct by the `Logger` // interface is visible to the `NonFungibleToken` via the `Collectible` interface. // Another implementation of `Foo` struct is visible to the `NonFungibleToken` via the `Token` interface. // This creates ambiguity. -access(all) resource interface NonFungibleToken: Token, Provider {} +access(all) +resource interface NonFungibleToken: Token, Provider {} ``` @@ -865,31 +968,36 @@ This would convert to a Cadence implementation similar to: ```cadence struct interface A: B, C { - access(all) fun test() { + access(all) + fun test() { pre { print("A") } } } struct interface B: D, E { - access(all) fun test() { + access(all) + fun test() { pre { print("B") } } } struct interface C: E { - access(all) fun test() { + access(all) + fun test() { pre { print("C") } } } struct interface D { - access(all) fun test() { + access(all) + fun test() { pre { print("D") } } } struct interface E { - access(all) fun test() { + access(all) + fun test() { pre { print("E") } } } @@ -899,7 +1007,8 @@ Any concrete type implementing interface `A` would be equivalent to implementing ```cadence struct Foo: A { - access(all) fun test() { + access(all) + fun test() { pre { print("Foo") } } } @@ -910,7 +1019,8 @@ The linearized interface order would be: [A, B, D, E, C]. i.e: same as having: ```cadence struct Foo: A, B, D, C, E { - access(all) fun test() { + access(all) + fun test() { pre { print("Foo") } } } diff --git a/versioned_docs/version-1.0/language/intersection-types.md b/versioned_docs/version-1.0/language/intersection-types.md index 2137f25..8f0021a 100644 --- a/versioned_docs/version-1.0/language/intersection-types.md +++ b/versioned_docs/version-1.0/language/intersection-types.md @@ -20,20 +20,28 @@ if the function accidentally attempts to access other functionality, this is prevented by the static checker. ```cadence -access(all) struct interface HasID { - access(all) let id: String +access(all) +struct interface HasID { + access(all) + let id: String } -access(all) struct A: HasID { - access(all) let id: String +access(all) +struct A: HasID { + + access(all) + let id: String init(id: String) { self.id = id } } -access(all) struct B: HasID { - access(all) let id: String +access(all) +struct B: HasID { + + access(all) + let id: String init(id: String) { self.id = id @@ -52,7 +60,8 @@ let hasID2: {HasID} = B(id: "2") // The type `{HasID}` is a short-hand for `AnyStruct{HasID}`: // Some structure which only allows access to the functionality of interface `HasID`. // -access(all) fun getID(_ value: {HasID}): String { +access(all) +fun getID(_ value: {HasID}): String { return value.id } @@ -67,13 +76,20 @@ If more than two interfaces are present in an intersection type, any concrete value of that type must implement both of them: ```cadence -access(all) struct interface HasMetadata { - access(all) let metadata: AnyStruct +access(all) +struct interface HasMetadata { + access(all) + let metadata: AnyStruct } -access(all) struct C: HasID, HasMetadata { - access(all) let id: String - access(all) var metadata: AnyStruct +access(all) +struct C: HasID, HasMetadata { + + access(all) + let id: String + + access(all) + var metadata: AnyStruct init(id: String) { self.id = id diff --git a/versioned_docs/version-1.0/language/references.mdx b/versioned_docs/version-1.0/language/references.mdx index 6fd5344..4ee753f 100644 --- a/versioned_docs/version-1.0/language/references.mdx +++ b/versioned_docs/version-1.0/language/references.mdx @@ -73,13 +73,17 @@ resource interface HasCount { // Declare a resource named `Counter` that conforms to `HasCount` // resource Counter: HasCount { - access(all) var count: Int + + access(all) + var count: Int - access(all) init(count: Int) { + access(all) + init(count: Int) { self.count = count } - access(all) fun increment() { + access(all) + fun increment() { self.count = self.count + 1 } } @@ -149,7 +153,9 @@ entitlement Reset resource interface HasCount { count: Int - access(Reset) fun resetCount() + + access(Reset) + fun resetCount() } ``` @@ -244,7 +250,8 @@ entitlement mapping M { // omitted } resource interface I { - access(M) let foo: auth(M) &T + access(M) + let foo: auth(M) &T } ``` @@ -259,9 +266,11 @@ entitlement mapping M { // omitted } resource I { - access(self) let myField: T + access(self) + let myField: T - access(M) fun getMyField(): auth(M) &T { + access(M) + fun getMyField(): auth(M) &T { return &self.myField as auth(M) &T } } @@ -288,10 +297,12 @@ and the other (ownedNFTs) is dictionary-typed. resource Collection { // Primitive-typed field - access(all) var id: String + access(all) + var id: String // Dictionary typed field - access(all) var ownedNFTs: @{UInt64: NFT} + access(all) + var ownedNFTs: @{UInt64: NFT} } ``` @@ -344,7 +355,8 @@ In other words, the assignment operator for arrays/dictionaries would also have Think of assignment as a built-in function with `Mutate` or `(Insert, Remove)` entitlements. e.g: ```cadence -access(Mutate | (Insert, Remove)) set(keyOrIndex, value) { ... } +access(Mutate | (Insert, Remove)) +set(keyOrIndex, value) { ... } ``` Note that the syntax for having nested entitlements in access modifiers like `(Mutate | (Insert, Remove))` diff --git a/versioned_docs/version-1.0/language/resources.mdx b/versioned_docs/version-1.0/language/resources.mdx index c3909cb..45872eb 100644 --- a/versioned_docs/version-1.0/language/resources.mdx +++ b/versioned_docs/version-1.0/language/resources.mdx @@ -40,8 +40,11 @@ and when it is returned from a function. ```cadence // Declare a resource named `SomeResource`, with a variable integer field. // -access(all) resource SomeResource { - access(all) var value: Int +access(all) +resource SomeResource { + + access(all) + var value: Int init(value: Int) { self.value = value @@ -69,7 +72,8 @@ b.value // equals 0 // // The parameter has a resource type, so the type annotation must be prefixed with `@`. // -access(all) fun use(resource: @SomeResource) { +access(all) +fun use(resource: @SomeResource) { // ... } @@ -128,7 +132,8 @@ let someResource: @SomeResource <- create SomeResource(value: 5) // // The parameter has a resource type, so the type annotation must be prefixed with `@`. // -access(all) fun use(resource: @SomeResource) { +access(all) +fun use(resource: @SomeResource) { destroy resource } @@ -137,7 +142,8 @@ access(all) fun use(resource: @SomeResource) { // The return type is a resource type, so the type annotation must be prefixed with `@`. // The return statement must also use the `<-` operator to make it explicit the resource is moved. // -access(all) fun get(): @SomeResource { +access(all) +fun get(): @SomeResource { let newResource <- create SomeResource() return <-newResource } @@ -149,7 +155,8 @@ Resources **must** be used exactly once. // Declare a function which consumes a resource but does not use it. // This function is invalid, because it would cause a loss of the resource. // -access(all) fun forgetToUse(resource: @SomeResource) { +access(all) +fun forgetToUse(resource: @SomeResource) { // Invalid: The resource parameter `resource` is not used, but must be. } ``` @@ -177,7 +184,8 @@ res.value // This function is invalid, because it does not always use the resource parameter, // which would cause a loss of the resource. // -access(all) fun sometimesDestroy(resource: @SomeResource, destroyResource: Bool) { +access(all) +fun sometimesDestroy(resource: @SomeResource, destroyResource: Bool) { if destroyResource { destroy resource } @@ -192,7 +200,8 @@ access(all) fun sometimesDestroy(resource: @SomeResource, destroyResource: Bool) // This function is valid, as it always uses the resource parameter, // and does not cause a loss of the resource. // -access(all) fun alwaysUse(resource: @SomeResource, destroyResource: Bool) { +access(all) +fun alwaysUse(resource: @SomeResource, destroyResource: Bool) { if destroyResource { destroy resource } else { @@ -208,7 +217,8 @@ access(all) fun alwaysUse(resource: @SomeResource, destroyResource: Bool) { // This function is invalid, because it does not always use the resource parameter, // which would cause a loss of the resource. // -access(all) fun returnBeforeDestroy(move: Bool) { +access(all) +fun returnBeforeDestroy(move: Bool) { let res <- create SomeResource(value: 1) if move { use(resource: <-res) @@ -234,7 +244,8 @@ Instead, use a swap statement (`<->`) or shift statement (`<- target <-`) to replace the resource variable with another resource. ```cadence -access(all) resource R {} +access(all) +resource R {} var x <- create R() var y <- create R() @@ -291,7 +302,8 @@ all the nested resources are also destroyed. ```cadence // Declare a resource with resource fields // -access(all) resource Parent { +access(all) +resource Parent { var child1: @Child var child2: @Child init(child1: @Child, child2: @Child) { diff --git a/versioned_docs/version-1.0/language/run-time-types.md b/versioned_docs/version-1.0/language/run-time-types.md index 3f60316..4036628 100644 --- a/versioned_docs/version-1.0/language/run-time-types.md +++ b/versioned_docs/version-1.0/language/run-time-types.md @@ -180,21 +180,26 @@ something.isInstance(Type()) // is `false` For example, this allows implementing a marketplace sale resource: ```cadence -access(all) resource SimpleSale { +access(all) +resource SimpleSale { /// The resource for sale. /// Once the resource is sold, the field becomes `nil`. /// - access(all) var resourceForSale: @AnyResource? + access(all) + var resourceForSale: @AnyResource? /// The price that is wanted for the purchase of the resource. /// - access(all) let priceForResource: UFix64 + access(all) + let priceForResource: UFix64 /// The type of currency that is required for the purchase. /// - access(all) let requiredCurrency: Type - access(all) let paymentReceiver: Capability<&{FungibleToken.Receiver}> + access(all) + let requiredCurrency: Type + access(all) + let paymentReceiver: Capability<&{FungibleToken.Receiver}> /// `paymentReceiver` is the capability that will be borrowed /// once a valid purchase is made. @@ -218,7 +223,8 @@ access(all) resource SimpleSale { /// If the purchase succeeds, the resource for sale is returned. /// If the purchase fails, the program aborts. /// - access(all) fun buyObject(with funds: @FungibleToken.Vault): @AnyResource { + access(all) + fun buyObject(with funds: @FungibleToken.Vault): @AnyResource { pre { // Ensure the resource is still up for sale self.resourceForSale != nil: "The resource has already been sold" diff --git a/versioned_docs/version-1.0/solidity-to-cadence.md b/versioned_docs/version-1.0/solidity-to-cadence.md index 4502594..984237f 100644 --- a/versioned_docs/version-1.0/solidity-to-cadence.md +++ b/versioned_docs/version-1.0/solidity-to-cadence.md @@ -290,7 +290,8 @@ Scripts are read-only in nature, requiring only a `main` function declaration an import FungibleToken from "../../contracts/FungibleToken.cdc" import ExampleToken from "../../contracts/ExampleToken.cdc" -access(all) fun main(account: Address): UFix64 { +access(all) +fun main(account: Address): UFix64 { let acct = getAccount(account) let vaultRef = acct.capabilities .borrow<&ExampleToken.Vault>(ExampleToken.VaultPublicPath) diff --git a/versioned_docs/version-1.0/testing-framework.mdx b/versioned_docs/version-1.0/testing-framework.mdx index 8b3a66c..cdbd9f4 100644 --- a/versioned_docs/version-1.0/testing-framework.mdx +++ b/versioned_docs/version-1.0/testing-framework.mdx @@ -22,36 +22,44 @@ All the above four functions are optional. // A `setup` function that always runs before the rest of the test cases. // Can be used to initialize things that would be used across the test cases. // e.g: initialling a blockchain backend, initializing a contract, etc. -access(all) fun setup() { +access(all) +fun setup() { } // The `beforeEach` function runs before each test case. Can be used to perform // some state cleanup before each test case, among other things. -access(all) fun beforeEach() { +access(all) +fun beforeEach() { } // The `afterEach` function runs after each test case. Can be used to perform // some state cleanup after each test case, among other things. -access(all) fun afterEach() { +access(all) +fun afterEach() { } // Valid test functions start with the 'test' prefix. -access(all) fun testSomething() { +access(all) +fun testSomething() { } -access(all) fun testAnotherThing() { +access(all) +fun testAnotherThing() { } -access(all) fun testMoreThings() { +access(all) +fun testMoreThings() { } // Test functions cannot have any arguments or return values. -access(all) fun testInvalidSignature(message: String): Bool { +access(all) +fun testInvalidSignature(message: String): Bool { } // A `tearDown` function that always runs at the end of all test cases. // e.g: Can be used to stop the blockchain back-end used for tests, etc. or any cleanup. -access(all) fun tearDown() { +access(all) +fun tearDown() { } ``` ## Test Standard Library @@ -77,7 +85,8 @@ The message argument is optional. ```cadence import Test -access(all) fun testExample() { +access(all) +fun testExample() { Test.assert(2 == 2) Test.assert([1, 2, 3].length == 0, message: "Array length is not 0") } @@ -96,7 +105,8 @@ The message argument is optional. ```cadence import Test -access(all) fun testExample() { +access(all) +fun testExample() { let array = [1, 2, 3] if array.length != 0 { @@ -116,7 +126,8 @@ The `expect` function tests a value against a matcher (see [matchers](#matchers) ```cadence import Test -access(all) fun testExample() { +access(all) +fun testExample() { let array = [1, 2, 3] Test.expect(array.length, Test.equal(3)) @@ -135,15 +146,19 @@ reports a message which explains how the two values differ. ```cadence import Test -access(all) struct Foo { - access(all) let answer: Int +access(all) +struct Foo { + + access(all) + let answer: Int init(answer: Int) { self.answer = answer } } -access(all) fun testExample() { +access(all) +fun testExample() { Test.assertEqual("this string", "this string") Test.assertEqual(21, 21) Test.assertEqual(true, true) @@ -183,14 +198,17 @@ an error message that contains the given error message portion. ```cadence import Test -access(all) struct Foo { - access(self) let answer: UInt8 +access(all) +struct Foo { + access(self) + let answer: UInt8 init(answer: UInt8) { self.answer = answer } - access(all) fun correctAnswer(_ input: UInt8): Bool { + access(all) + fun correctAnswer(_ input: UInt8): Bool { if self.answer != input { panic("wrong answer!") } @@ -198,7 +216,8 @@ access(all) struct Foo { } } -access(all) fun testExample() { +access(all) +fun testExample() { let foo = Foo(answer: 42) Test.expectFailure(fun(): Void { @@ -212,18 +231,22 @@ access(all) fun testExample() { A matcher is an object that consists of a test function and associated utility functionality. ```cadence -access(all) struct Matcher { +access(all) +struct Matcher { - access(all) let test: fun(AnyStruct): Bool + access(all) + let test: fun(AnyStruct): Bool - access(all) init(test: fun(AnyStruct): Bool) { + access(all) + init(test: fun(AnyStruct): Bool) { self.test = test } /// Combine this matcher with the given matcher. /// Returns a new matcher that succeeds if this and the given matcher succeed. /// - access(all) fun and(_ other: Matcher): Matcher { + access(all) + fun and(_ other: Matcher): Matcher { return Matcher(test: fun (value: AnyStruct): Bool { return self.test(value) && other.test(value) }) @@ -232,7 +255,8 @@ access(all) struct Matcher { /// Combine this matcher with the given matcher. /// Returns a new matcher that succeeds if this or the given matcher succeeds. /// - access(all) fun or(_ other: Matcher): Matcher { + access(all) + fun or(_ other: Matcher): Matcher { return Matcher(test: fun (value: AnyStruct): Bool { return self.test(value) || other.test(value) }) @@ -261,7 +285,8 @@ For example, a matcher that checks whether a given integer value is negative can ```cadence import Test -access(all) fun testExample() { +access(all) +fun testExample() { let isNegative = Test.newMatcher(fun (_ value: Int): Bool { return value < 0 }) @@ -271,7 +296,8 @@ access(all) fun testExample() { Test.assert(isNegative.test(-15), message: "number is not negative") } -access(all) fun testCustomMatcherUntyped() { +access(all) +fun testCustomMatcherUntyped() { let matcher = Test.newMatcher(fun (_ value: AnyStruct): Bool { if !value.getType().isSubtype(of: Type()) { return false @@ -283,7 +309,8 @@ access(all) fun testCustomMatcherUntyped() { Test.expect(8, matcher) } -access(all) fun testCustomMatcherTyped() { +access(all) +fun testCustomMatcherTyped() { let matcher = Test.newMatcher(fun (_ value: Int): Bool { return value == 7 }) @@ -306,7 +333,8 @@ Accepts an `AnyStruct` value. ```cadence import Test -access(all) fun testExample() { +access(all) +fun testExample() { let array = [1, 2, 3] Test.expect([1, 2, 3], Test.equal(array)) @@ -325,7 +353,8 @@ greater than the given number. ```cadence import Test -access(all) fun testExample() { +access(all) +fun testExample() { let str = "Hello, there" Test.expect(str.length, Test.beGreaterThan(5)) @@ -344,7 +373,8 @@ less than the given number. ```cadence import Test -access(all) fun testExample() { +access(all) +fun testExample() { let str = "Hello, there" Test.expect(str.length, Test.beLessThan(15)) @@ -362,7 +392,8 @@ The `beNil` function returns a new matcher that checks if the given test value i ```cadence import Test -access(all) fun testExample() { +access(all) +fun testExample() { let message: String? = nil Test.expect(message, Test.beNil()) @@ -381,7 +412,8 @@ and the tested value contains no elements. ```cadence import Test -access(all) fun testExample() { +access(all) +fun testExample() { let array: [String] = [] Test.expect(array, Test.beEmpty()) @@ -404,7 +436,8 @@ and has the given number of elements. ```cadence import Test -access(all) fun testExample() { +access(all) +fun testExample() { let array: [String] = ["one", "two", "three"] Test.expect(array, Test.haveElementCount(3)) @@ -426,7 +459,8 @@ a value that is equal to the given value, or the tested value is a dictionary that contains an entry where the key is equal to the given value. ```cadence -access(all) fun testExample() { +access(all) +fun testExample() { let array: [String] = ["one", "two", "three"] Test.expect(array, Test.contain("one")) @@ -450,7 +484,8 @@ Returns false in any other case. ```cadence import Test -access(all) fun testExample() { +access(all) +fun testExample() { let blockchain = Test.newEmulatorBlockchain() let result = blockchain.executeScript( "access(all) fun main(): Int { return 2 + 3 }", @@ -475,7 +510,8 @@ Returns false in any other case. ```cadence import Test -access(all) fun testExample() { +access(all) +fun testExample() { let blockchain = Test.newEmulatorBlockchain() let account = blockchain.createAccount() @@ -513,7 +549,8 @@ The `not` function returns a new matcher that negates the test of the given matc ```cadence import Test -access(all) fun testExample() { +access(all) +fun testExample() { let isEven = Test.newMatcher(fun (_ value: Int): Bool { return value % 2 == 0 }) @@ -540,7 +577,8 @@ If this matcher succeeds, then the other matcher would not be tested. ```cadence import Test -access(all) fun testExample() { +access(all) +fun testExample() { let one = Test.equal(1) let two = Test.equal(2) @@ -562,7 +600,8 @@ Returns a new matcher that succeeds if this and the given matcher succeed. ```cadence import Test -access(all) fun testExample() { +access(all) +fun testExample() { let sevenOrMore = Test.newMatcher(fun (_ value: Int): Bool { return value >= 7 }) @@ -584,9 +623,11 @@ It imitates the behavior of a real network, for testing. ```cadence /// Blockchain emulates a real network. /// -access(all) struct Blockchain { +access(all) +struct Blockchain { - access(all) let backend: AnyStruct{BlockchainBackend} + access(all) + let backend: AnyStruct{BlockchainBackend} init(backend: AnyStruct{BlockchainBackend}) { self.backend = backend @@ -595,7 +636,8 @@ access(all) struct Blockchain { /// Executes a script and returns the script return value and the status. /// `returnValue` field of the result will be `nil` if the script failed. /// - access(all) fun executeScript(_ script: String, _ arguments: [AnyStruct]): ScriptResult { + access(all) + fun executeScript(_ script: String, _ arguments: [AnyStruct]): ScriptResult { return self.backend.executeScript(script, arguments) } @@ -603,33 +645,38 @@ access(all) struct Blockchain { /// The transaction is paid by the service account. /// The returned account can be used to sign and authorize transactions. /// - access(all) fun createAccount(): Account { + access(all) + fun createAccount(): Account { return self.backend.createAccount() } /// Add a transaction to the current block. /// - access(all) fun addTransaction(_ tx: Transaction) { + access(all) + fun addTransaction(_ tx: Transaction) { self.backend.addTransaction(tx) } /// Executes the next transaction in the block, if any. /// Returns the result of the transaction, or nil if no transaction was scheduled. /// - access(all) fun executeNextTransaction(): TransactionResult? { + access(all) + fun executeNextTransaction(): TransactionResult? { return self.backend.executeNextTransaction() } /// Commit the current block. /// Committing will fail if there are un-executed transactions in the block. /// - access(all) fun commitBlock() { + access(all) + fun commitBlock() { self.backend.commitBlock() } /// Executes a given transaction and commits the current block. /// - access(all) fun executeTransaction(_ tx: Transaction): TransactionResult { + access(all) + fun executeTransaction(_ tx: Transaction): TransactionResult { self.addTransaction(tx) let txResult = self.executeNextTransaction()! self.commitBlock() @@ -638,7 +685,8 @@ access(all) struct Blockchain { /// Executes a given set of transactions and commits the current block. /// - access(all) fun executeTransactions(_ transactions: [Transaction]): [TransactionResult] { + access(all) + fun executeTransactions(_ transactions: [Transaction]): [TransactionResult] { for tx in transactions { self.addTransaction(tx) } @@ -655,7 +703,8 @@ access(all) struct Blockchain { /// Deploys a given contract, and initializes it with the arguments. /// - access(all) fun deployContract( + access(all) + fun deployContract( name: String, code: String, account: Account, @@ -672,46 +721,53 @@ access(all) struct Blockchain { /// Set the configuration to be used by the blockchain. /// Overrides any existing configuration. /// - access(all) fun useConfiguration(_ configuration: Configuration) { + access(all) + fun useConfiguration(_ configuration: Configuration) { self.backend.useConfiguration(configuration) } /// Returns all the logs from the blockchain, up to the calling point. /// - access(all) fun logs(): [String] { + access(all) + fun logs(): [String] { return self.backend.logs() } /// Returns the service account of the blockchain. Can be used to sign /// transactions with this account. /// - access(all) fun serviceAccount(): Account { + access(all) + fun serviceAccount(): Account { return self.backend.serviceAccount() } /// Returns all events emitted from the blockchain. /// - access(all) fun events(): [AnyStruct] { + access(all) + fun events(): [AnyStruct] { return self.backend.events(nil) } /// Returns all events emitted from the blockchain, /// filtered by type. /// - access(all) fun eventsOfType(_ type: Type): [AnyStruct] { + access(all) + fun eventsOfType(_ type: Type): [AnyStruct] { return self.backend.events(type) } /// Resets the state of the blockchain to the given height. /// - access(all) fun reset(to height: UInt64) { + access(all) + fun reset(to height: UInt64) { self.backend.reset(to: height) } /// Moves the time of the blockchain by the given delta, /// which should be passed in the form of seconds. /// - access(all) fun moveTime(by delta: Fix64) { + access(all) + fun moveTime(by delta: Fix64) { self.backend.moveTime(by: delta) } } @@ -722,36 +778,49 @@ The `BlockchainBackend` provides the actual functionality of the blockchain. ```cadence /// BlockchainBackend is the interface to be implemented by the backend providers. /// -access(all) struct interface BlockchainBackend { +access(all) +struct interface BlockchainBackend { - access(all) fun executeScript(_ script: String, _ arguments: [AnyStruct]): ScriptResult + access(all) + fun executeScript(_ script: String, _ arguments: [AnyStruct]): ScriptResult - access(all) fun createAccount(): Account + access(all) + fun createAccount(): Account - access(all) fun addTransaction(_ tx: Transaction) + access(all) + fun addTransaction(_ tx: Transaction) - access(all) fun executeNextTransaction(): TransactionResult? + access(all) + fun executeNextTransaction(): TransactionResult? - access(all) fun commitBlock() + access(all) + fun commitBlock() - access(all) fun deployContract( + access(all) + fun deployContract( name: String, code: String, account: Account, arguments: [AnyStruct] ): Error? - access(all) fun useConfiguration(_ configuration: Configuration) + access(all) + fun useConfiguration(_ configuration: Configuration) - access(all) fun logs(): [String] + access(all) + fun logs(): [String] - access(all) fun serviceAccount(): Account + access(all) + fun serviceAccount(): Account - access(all) fun events(_ type: Type?): [AnyStruct] + access(all) + fun events(_ type: Type?): [AnyStruct] - access(all) fun reset(to height: UInt64) + access(all) + fun reset(to height: UInt64) - access(all) fun moveTime(by delta: Fix64) + access(all) + fun moveTime(by delta: Fix64) } ``` @@ -764,7 +833,8 @@ It returns a `Blockchain` which is backed by a new [Flow Emulator](https://devel ```cadence import Test -access(all) let blockchain = Test.newEmulatorBlockchain() +access(all) +let blockchain = Test.newEmulatorBlockchain() ``` ### Creating accounts @@ -775,10 +845,14 @@ An account can be created using the `createAccount` function. ```cadence import Test -access(all) let blockchain = Test.newEmulatorBlockchain() -access(all) let account = blockchain.createAccount() +access(all) +let blockchain = Test.newEmulatorBlockchain() + +access(all) +let account = blockchain.createAccount() -access(all) fun testExample() { +access(all) +fun testExample() { log(account.address) } ``` @@ -798,9 +872,14 @@ The returned account consists of the `address` of the account, and a `publicKey` ```cadence /// Account represents info about the account created on the blockchain. /// -access(all) struct Account { - access(all) let address: Address - access(all) let publicKey: PublicKey +access(all) +struct Account { + + access(all) + let address: Address + + access(all) + let publicKey: PublicKey init(address: Address, publicKey: PublicKey) { self.address = address @@ -817,9 +896,11 @@ The function takes script-code as the first argument, and the script-arguments a ```cadence import Test -access(all) let blockchain = Test.newEmulatorBlockchain() +access(all) +let blockchain = Test.newEmulatorBlockchain() -access(all) fun testExample() { +access(all) +fun testExample() { let code = "access(all) fun main(name: String): String { return \"Hello, \".concat(name) }" let args = ["Peter"] @@ -842,10 +923,17 @@ successful, or an `error` otherwise (see [errors](#errors) section for more deta ```cadence /// The result of a script execution. /// -access(all) struct ScriptResult { - access(all) let status: ResultStatus - access(all) let returnValue: AnyStruct? - access(all) let error: Error? +access(all) +struct ScriptResult { + + access(all) + let status: ResultStatus + + access(all) + let returnValue: AnyStruct? + + access(all) + let error: Error? init(status: ResultStatus, returnValue: AnyStruct?, error: Error?) { self.status = status @@ -863,11 +951,20 @@ a list of signers that would sign the transaction, and the transaction arguments ```cadence /// Transaction that can be submitted and executed on the blockchain. /// -access(all) struct Transaction { - access(all) let code: String - access(all) let authorizers: [Address] - access(all) let signers: [Account] - access(all) let arguments: [AnyStruct] +access(all) +struct Transaction { + + access(all) + let code: String + + access(all) + let authorizers: [Address] + + access(all) + let signers: [Account] + + access(all) + let arguments: [AnyStruct] init(code: String, authorizers: [Address], signers: [Account], arguments: [AnyStruct]) { self.code = code @@ -883,12 +980,16 @@ The number of authorizers must match the number of `&Account` parameters in the ```cadence import Test -access(all) let blockchain = Test.newEmulatorBlockchain() -access(all) let account = blockchain.createAccount() +access(all) +let blockchain = Test.newEmulatorBlockchain() + +access(all) +let account = blockchain.createAccount() // There are two ways to execute the created transaction. -access(all) fun testExample() { +access(all) +fun testExample() { let tx = Test.Transaction( code: "transaction { prepare(acct: &Account) {} execute{} }", authorizers: [account.address], @@ -904,7 +1005,8 @@ access(all) fun testExample() { Test.expect(txResult, Test.beSucceeded()) } -access(all) fun testExampleTwo() { +access(all) +fun testExampleTwo() { let tx = Test.Transaction( code: "transaction { prepare(acct: &Account) {} execute{} }", authorizers: [account.address], @@ -927,9 +1029,14 @@ The result of a transaction consists of the status of the execution, and an `Err ```cadence /// The result of a transaction execution. /// -access(all) struct TransactionResult { - access(all) let status: ResultStatus - access(all) let error: Error? +access(all) +struct TransactionResult { + + access(all) + let status: ResultStatus + + access(all) + let error: Error? init(status: ResultStatus, error: Error?) { self.status = status @@ -945,10 +1052,14 @@ access(all) struct TransactionResult { ```cadence import Test -access(all) let blockchain = Test.newEmulatorBlockchain() -access(all) let account = blockchain.createAccount() +access(all) +let blockchain = Test.newEmulatorBlockchain() + +access(all) +let account = blockchain.createAccount() -access(all) fun testExample() { +access(all) +fun testExample() { let tx = Test.Transaction( code: "transaction { prepare(acct: &Account) {} execute{} }", authorizers: [account.address], @@ -972,14 +1083,18 @@ A contract can be deployed using the `deployContract` function of the `Blockchai Suppose we have this contract (`Foo.cdc`): ```cadence -access(all) contract Foo { - access(all) let msg: String +access(all) +contract Foo { + + access(all) + let msg: String init(_ msg: String) { self.msg = msg } - access(all) fun sayHello(): String { + access(all) + fun sayHello(): String { return self.msg } } @@ -988,10 +1103,14 @@ access(all) contract Foo { ```cadence import Test -access(all) let blockchain = Test.newEmulatorBlockchain() -access(all) let account = blockchain.createAccount() +access(all) +let blockchain = Test.newEmulatorBlockchain() + +access(all) +let account = blockchain.createAccount() -access(all) fun testExample() { +access(all) +fun testExample() { let contractCode = Test.readFile("Foo.cdc") let err = blockchain.deployContract( name: "Foo", @@ -1023,8 +1142,11 @@ The `Configuration` struct consists of a mapping of import locations to their ad /// Configuration to be used by the blockchain. /// Can be used to set the address mapping. /// -access(all) struct Configuration { - access(all) let addresses: {String: Address} +access(all) +struct Configuration { + + access(all) + let addresses: {String: Address} init(addresses: {String: Address}) { self.addresses = addresses @@ -1047,7 +1169,8 @@ Suppose this script is saved in `say_hello.cdc`. ```cadence import "Foo" -access(all) fun main(): String { +access(all) +fun main(): String { return Foo.sayHello() } ``` @@ -1057,10 +1180,14 @@ Then, before executing the script, the address mapping can be specified as follo ```cadence import Test -access(all) let blockchain = Test.newEmulatorBlockchain() -access(all) let account = blockchain.createAccount() +access(all) +let blockchain = Test.newEmulatorBlockchain() -access(all) fun setup() { +access(all) +let account = blockchain.createAccount() + +access(all) +fun setup() { blockchain.useConfiguration(Test.Configuration({ "Foo": account.address })) @@ -1076,7 +1203,8 @@ access(all) fun setup() { Test.expect(err, Test.beNil()) } -access(all) fun testExample() { +access(all) +fun testExample() { let script = Test.readFile("say_hello.cdc") let scriptResult = blockchain.executeScript(script, []) @@ -1099,8 +1227,11 @@ It contains a message indicating why the operation failed. ```cadence // Error is returned if something has gone wrong. // -access(all) struct Error { - access(all) let message: String +access(all) +struct Error { + + access(all) + let message: String init(_ message: String) { self.message = message @@ -1113,10 +1244,14 @@ An `Error` can be asserted against its presence or absence. ```cadence import Test -access(all) let blockchain = Test.newEmulatorBlockchain() -access(all) let account = blockchain.createAccount() +access(all) +let blockchain = Test.newEmulatorBlockchain() + +access(all) +let account = blockchain.createAccount() -access(all) fun testExample() { +access(all) +fun testExample() { let script = Test.readFile("say_hello.cdc") let scriptResult = blockchain.executeScript(script, []) @@ -1148,17 +1283,22 @@ We can also assert that certain events were emitted from the blockchain, up to t Suppose we have this contract (`Foo.cdc`): ```cadence -access(all) contract Foo { - access(all) let msg: String +access(all) +contract Foo { + + access(all) + let msg: String - access(all) event ContractInitialized(msg: String) + access(all) + event ContractInitialized(msg: String) init(_ msg: String) { self.msg = msg emit ContractInitialized(msg: self.msg) } - access(all) fun sayHello(): String { + access(all) + fun sayHello(): String { return self.msg } } @@ -1167,10 +1307,14 @@ access(all) contract Foo { ```cadence import Test -access(all) let blockchain = Test.newEmulatorBlockchain() -access(all) let account = blockchain.createAccount() +access(all) +let blockchain = Test.newEmulatorBlockchain() -access(all) fun setup() { +access(all) +let account = blockchain.createAccount() + +access(all) +fun setup() { blockchain.useConfiguration(Test.Configuration({ "Foo": account.address })) @@ -1214,7 +1358,8 @@ import "ExampleNFT" import "NFTStorefrontV2" import "NFTStorefront" -access(all) fun main(): [String] { +access(all) +fun main(): [String] { return [ Type().identifier, Type().identifier, @@ -1226,9 +1371,11 @@ access(all) fun main(): [String] { ```cadence import Test -access(all) let blockchain = Test.newEmulatorBlockchain() +access(all) +let blockchain = Test.newEmulatorBlockchain() -access(all) fun testExample() { +access(all) +fun testExample() { let script = Test.readFile("get_type_ids.cdc") let scriptResult = blockchain.executeScript(script, []) @@ -1267,10 +1414,14 @@ The `Blockchain.logs()` method aggregates all logs from contracts/scripts/transa ```cadence import Test -access(all) let blockchain = Test.newEmulatorBlockchain() -access(all) let account = blockchain.createAccount() +access(all) +let blockchain = Test.newEmulatorBlockchain() + +access(all) +let account = blockchain.createAccount() -access(all) fun testExample() { +access(all) +fun testExample() { let tx = Test.Transaction( code: "transaction { prepare(acct: &Account) {} execute{ log(\"in a transaction\") } }", authorizers: [account.address], diff --git a/versioned_docs/version-1.0/tutorial/02-hello-world.md b/versioned_docs/version-1.0/tutorial/02-hello-world.md index 4170bcf..61b30dc 100644 --- a/versioned_docs/version-1.0/tutorial/02-hello-world.md +++ b/versioned_docs/version-1.0/tutorial/02-hello-world.md @@ -143,12 +143,14 @@ Open the Account `0x01` tab with the file called ```cadence HelloWorld.cdc // HelloWorld.cdc // -access(all) contract HelloWorld { +access(all) +contract HelloWorld { // Declare a public field of type String. // // All fields must be initialized in the initializer. - access(all) let greeting: String + access(all) + let greeting: String // The initializer is required if the contract contains any fields. init() { @@ -156,7 +158,8 @@ access(all) contract HelloWorld { } // Public function that returns our friendly greeting! - access(all) fun hello(): String { + access(all) + fun hello(): String { return self.greeting } } diff --git a/versioned_docs/version-1.0/tutorial/03-resources.md b/versioned_docs/version-1.0/tutorial/03-resources.md index 6bb55a2..8d90f13 100644 --- a/versioned_docs/version-1.0/tutorial/03-resources.md +++ b/versioned_docs/version-1.0/tutorial/03-resources.md @@ -53,8 +53,11 @@ Resources are one of Cadence's defining features. In Cadence, resources are a composite type like a struct or a class, but with some special rules. Here is an example definition of a resource: ```cadence -access(all) resource Money { - access(all) let balance: Int +access(all) +resource Money { + + access(all) + let balance: Int init() { self.balance = 0 @@ -103,21 +106,25 @@ Open the Account `0x01` tab with file named `HelloWorldResource.cdc`.
```cadence HelloWorldResource.cdc -access(all) contract HelloWorld { +access(all) +contract HelloWorld { // Declare a resource that only includes one function. - access(all) resource HelloAsset { + access(all) + resource HelloAsset { // A transaction can call this function to get the "Hello, World!" // message from the resource. - access(all) fun hello(): String { + access(all) + fun hello(): String { return "Hello, World!" } } // We're going to use the built-in create function to create a new instance // of the HelloAsset resource - access(all) fun createHelloAsset(): @HelloAsset { + access(all) + fun createHelloAsset(): @HelloAsset { return <-create HelloAsset() } @@ -154,8 +161,10 @@ Let's walk through this contract in more detail, starting with the resource. Resources are one of the most important things that Cadence introduces to the smart contract design experience: ```cadence -access(all) resource HelloAsset { - access(all) fun hello(): String { +access(all) +resource HelloAsset { + access(all) + fun hello(): String { return "Hello, World!" } } @@ -200,7 +209,8 @@ This prevents anyone from being able to create arbitrary amounts of resource obj In this example, we declared a function that can create `HelloAsset` resources: ```cadence -access(all) fun createHelloAsset(): @HelloAsset { +access(all) +fun createHelloAsset(): @HelloAsset { return <-create HelloAsset() } ``` diff --git a/versioned_docs/version-1.0/tutorial/04-capabilities.md b/versioned_docs/version-1.0/tutorial/04-capabilities.md index 4af4bd3..fff642b 100644 --- a/versioned_docs/version-1.0/tutorial/04-capabilities.md +++ b/versioned_docs/version-1.0/tutorial/04-capabilities.md @@ -88,21 +88,25 @@ Open the Account `0x01` tab with file named `HelloWorldResource.cdc`.
```cadence HelloWorldResource-2.cdc -access(all) contract HelloWorld { +access(all) +contract HelloWorld { // Declare a resource that only includes one function. - access(all) resource HelloAsset { + access(all) + resource HelloAsset { // A transaction can call this function to get the "Hello, World!" // message from the resource. - access(all) fun hello(): String { + access(all) + fun hello(): String { return "Hello, World!" } } // We're going to use the built-in create function to create a new instance // of the HelloAsset resource - access(all) fun createHelloAsset(): @HelloAsset { + access(all) + fun createHelloAsset(): @HelloAsset { return <-create HelloAsset() } @@ -329,7 +333,8 @@ Open the file `Script1.cdc`. ```cadence Script1.cdc import HelloWorld from 0x01 -access(all) fun main() { +access(all) +fun main() { // Cadence code can get an account's public account object // by using the getAccount() built-in function. diff --git a/versioned_docs/version-1.0/tutorial/05-non-fungible-tokens-1.md b/versioned_docs/version-1.0/tutorial/05-non-fungible-tokens-1.md index de32f5c..6c5e02a 100644 --- a/versioned_docs/version-1.0/tutorial/05-non-fungible-tokens-1.md +++ b/versioned_docs/version-1.0/tutorial/05-non-fungible-tokens-1.md @@ -153,15 +153,19 @@ Open Account `0x01` to see `BasicNFT.cdc`. ```cadence BasicNFT.cdc -access(all) contract BasicNFT { +access(all) +contract BasicNFT { // Declare the NFT resource type - access(all) resource NFT { + access(all) + resource NFT { // The unique ID that differentiates each NFT - access(all) let id: UInt64 + access(all) + let id: UInt64 // String mapping to hold metadata - access(all) var metadata: {String: String} + access(all) + var metadata: {String: String} // Initialize both fields in the initializer init(initID: UInt64) { @@ -171,7 +175,8 @@ access(all) contract BasicNFT { } // Function to create a new NFT - access(all) fun createNFT(id: UInt64): @NFT { + access(all) + fun createNFT(id: UInt64): @NFT { return <-create NFT(initID: id) } diff --git a/versioned_docs/version-1.0/tutorial/05-non-fungible-tokens-2.md b/versioned_docs/version-1.0/tutorial/05-non-fungible-tokens-2.md index 1c32735..f862db6 100644 --- a/versioned_docs/version-1.0/tutorial/05-non-fungible-tokens-2.md +++ b/versioned_docs/version-1.0/tutorial/05-non-fungible-tokens-2.md @@ -82,7 +82,8 @@ This example uses a [**Dictionary**: a mutable, unordered collection of key-valu ```cadence // Keys are `Int` // Values are `NFT` -access(all) let myNFTs: @{Int: NFT} +access(all) +let myNFTs: @{Int: NFT} ``` In a dictionary, all keys must have the same type, and all values must have the same type. @@ -137,22 +138,29 @@ It contains what was already in `BasicNFT.cdc` plus additional resource declarat // // Learn more about non-fungible tokens in this tutorial: https://developers.flow.com/cadence/tutorial/non-fungible-tokens-1 -access(all) contract ExampleNFT { +access(all) +contract ExampleNFT { // Declare Path constants so paths do not have to be hardcoded // in transactions and scripts - access(all) let CollectionStoragePath: StoragePath - access(all) let CollectionPublicPath: PublicPath - access(all) let MinterStoragePath: StoragePath + access(all) + let CollectionStoragePath: StoragePath + access(all) + let CollectionPublicPath: PublicPath + access(all) + let MinterStoragePath: StoragePath // Tracks the unique IDs of the NFT - access(all) var idCount: UInt64 + access(all) + var idCount: UInt64 // Declare the NFT resource type - access(all) resource NFT { + access(all) + resource NFT { // The unique ID that differentiates each NFT - access(all) let id: UInt64 + access(all) + let id: UInt64 // Initialize both fields in the initializer init(initID: UInt64) { @@ -164,21 +172,27 @@ access(all) contract ExampleNFT { // to create public, restricted references to their NFT Collection. // They would use this to publicly expose only the deposit, getIDs, // and idExists fields in their Collection - access(all) resource interface NFTReceiver { + access(all) + resource interface NFTReceiver { - access(all) fun deposit(token: @NFT) + access(all) + fun deposit(token: @NFT) - access(all) fun getIDs(): [UInt64] + access(all) + fun getIDs(): [UInt64] - access(all) fun idExists(id: UInt64): Bool + access(all) + fun idExists(id: UInt64): Bool } // The definition of the Collection resource that // holds the NFTs that a user owns - access(all) resource Collection: NFTReceiver { + access(all) + resource Collection: NFTReceiver { // dictionary of NFT conforming tokens // NFT is a resource type with an `UInt64` ID field - access(all) var ownedNFTs: @{UInt64: NFT} + access(all) + var ownedNFTs: @{UInt64: NFT} // Initialize the NFTs field to an empty collection init () { @@ -189,7 +203,8 @@ access(all) contract ExampleNFT { // // Function that removes an NFT from the collection // and moves it to the calling context - access(all) fun withdraw(withdrawID: UInt64): @NFT { + access(all) + fun withdraw(withdrawID: UInt64): @NFT { // If the NFT isn't found, the transaction panics and reverts let token <- self.ownedNFTs.remove(key: withdrawID)! @@ -200,7 +215,8 @@ access(all) contract ExampleNFT { // // Function that takes a NFT as an argument and // adds it to the collections dictionary - access(all) fun deposit(token: @NFT) { + access(all) + fun deposit(token: @NFT) { // add the new token to the dictionary with a force assignment // if there is already a value at that key, it will fail and revert self.ownedNFTs[token.id] <-! token @@ -208,18 +224,21 @@ access(all) contract ExampleNFT { // idExists checks to see if a NFT // with the given ID exists in the collection - access(all) fun idExists(id: UInt64): Bool { + access(all) + fun idExists(id: UInt64): Bool { return self.ownedNFTs[id] != nil } // getIDs returns an array of the IDs that are in the collection - access(all) fun getIDs(): [UInt64] { + access(all) + fun getIDs(): [UInt64] { return self.ownedNFTs.keys } } // creates a new empty Collection resource and returns it - access(all) fun createEmptyCollection(): @Collection { + access(all) + fun createEmptyCollection(): @Collection { return <- create Collection() } @@ -227,7 +246,8 @@ access(all) contract ExampleNFT { // // Function that mints a new NFT with a new ID // and returns it to the caller - access(all) fun mintNFT(): @NFT { + access(all) + fun mintNFT(): @NFT { // create a new NFT var newNFT <- create NFT(initID: self.idCount) @@ -304,7 +324,8 @@ of the keys of the dictionary using the built-in `keys` function. ```cadence // getIDs returns an array of the IDs that are in the collection -access(all) fun getIDs(): [UInt64] { +access(all) +fun getIDs(): [UInt64] { return self.ownedNFTs.keys } ``` @@ -360,13 +381,17 @@ is only accessible by its owner. To give external accounts access to the `deposi the `getIDs` function, and the `idExists` function, the owner creates an interface that only includes those fields: ```cadence -access(all) resource interface NFTReceiver { +access(all) +resource interface NFTReceiver { - access(all) fun deposit(token: @NFT) + access(all) + fun deposit(token: @NFT) - access(all) fun getIDs(): [UInt64] + access(all) + fun getIDs(): [UInt64] - access(all) fun idExists(id: UInt64): Bool + access(all) + fun idExists(id: UInt64): Bool } ``` @@ -411,7 +436,8 @@ Open the script file named `Print 0x01 NFTs`. import ExampleNFT from 0x01 // Print the NFTs owned by account 0x01. -access(all) fun main() { +access(all) +fun main() { // Get the public account object for account 0x01 let nftOwner = getAccount(0x01) @@ -504,7 +530,8 @@ This prints a list of the NFTs that account `0x01` owns. import ExampleNFT from 0x01 // Print the NFTs owned by account 0x01. -access(all) fun main() { +access(all) +fun main() { // Get the public account object for account 0x01 let nftOwner = getAccount(0x01) @@ -629,7 +656,8 @@ Execute the script `Print all NFTs` to see the tokens in each account: import ExampleNFT from 0x01 // Print the NFTs owned by accounts 0x01 and 0x02. -access(all) fun main() { +access(all) +fun main() { // Get both public account objects let account1 = getAccount(0x01) diff --git a/versioned_docs/version-1.0/tutorial/06-fungible-tokens.md b/versioned_docs/version-1.0/tutorial/06-fungible-tokens.md index c81298c..10d53da 100644 --- a/versioned_docs/version-1.0/tutorial/06-fungible-tokens.md +++ b/versioned_docs/version-1.0/tutorial/06-fungible-tokens.md @@ -42,11 +42,13 @@ In traditional software and smart contracts, balances for each user are tracked // DO NOT USE THIS CODE FOR YOUR PROJECT contract LedgerToken { // Tracks every user's balance - access(contract) let balances: {Address: UFix64} + access(contract) + let balances: {Address: UFix64} // Transfer tokens from one user to the other // by updating their balances in the central ledger - access(all) fun transfer(from: Address, to: Address, amount: UFix64) { + access(all) + fun transfer(from: Address, to: Address, amount: UFix64) { balances[from] = balances[from] - amount balances[to] = balances[to] + amount } @@ -194,23 +196,27 @@ It is important to remember that each account stores only a copy of the `Vault` The `ExampleToken` contract only needs to be stored in the initial account that manages the token definitions. ```cadence Token.cdc -access(all) resource Vault: Provider, Receiver { +access(all) +resource Vault: Provider, Receiver { // Balance of a user's Vault // we use unsigned fixed point numbers for balances // because they can represent decimals and do not allow negative values - access(all) var balance: UFix64 + access(all) + var balance: UFix64 init(balance: UFix64) { self.balance = balance } - access(all) fun withdraw(amount: UFix64): @Vault { + access(all) + fun withdraw(amount: UFix64): @Vault { self.balance = self.balance - amount return <-create Vault(balance: amount) } - access(all) fun deposit(from: @Vault) { + access(all) + fun deposit(from: @Vault) { self.balance = self.balance + from.balance destroy from } @@ -229,7 +235,8 @@ The language requires that the initialization function `init`, which is only run // Balance of a user's Vault // we use unsigned fixed-point integers for balances because they do not require the // concept of a negative number and allow for more clear precision -access(all) var balance: UFix64 +access(all) +var balance: UFix64 init(balance: UFix64) { self.balance = balance @@ -244,7 +251,8 @@ the balance field is no longer initialized. Then, the deposit function is available for any account to transfer tokens to. ```cadence -access(all) fun deposit(from: @Vault) { +access(all) +fun deposit(from: @Vault) { self.balance = self.balance + from.balance destroy from } @@ -263,7 +271,8 @@ When interacting with resources, you use the `@` symbol to specify the type, and when moving the resource, such as assigning the resource, when passing it as an argument to a function, or when returning it from a function. ```cadence -access(all) fun withdraw(amount: UInt64): @Vault { +access(all) +fun withdraw(amount: UInt64): @Vault { ``` This `@` symbol is required when specifying a resource **type** for a field, an argument, or a return value. @@ -332,7 +341,8 @@ open and should see the code below. // This is a basic implementation of a Fungible Token and is NOT meant to be used in production // See the Flow Fungible Token standard for real examples: https://github.com/onflow/flow-ft -access(all) contract BasicToken { +access(all) +contract BasicToken { // Vault // @@ -346,10 +356,12 @@ access(all) contract BasicToken { // out of thin air. A special Minter resource or constructor function needs to be defined to mint // new tokens. // - access(all) resource Vault { + access(all) + resource Vault { // keeps track of the total balance of the account's tokens - access(all) var balance: UFix64 + access(all) + var balance: UFix64 // initialize the balance at resource creation time init(balance: UFix64) { @@ -366,7 +378,8 @@ access(all) contract BasicToken { // created Vault to the context that called so it can be deposited // elsewhere. // - access(all) fun withdraw(amount: UFix64): @Vault { + access(all) + fun withdraw(amount: UFix64): @Vault { self.balance = self.balance - amount return <-create Vault(balance: amount) } @@ -379,7 +392,8 @@ access(all) contract BasicToken { // It is allowed to destroy the sent Vault because the Vault // was a temporary holder of the tokens. The Vault's balance has // been consumed and therefore can be destroyed. - access(all) fun deposit(from: @Vault) { + access(all) + fun deposit(from: @Vault) { self.balance = self.balance + from.balance destroy from } @@ -392,7 +406,8 @@ access(all) contract BasicToken { // and store the returned Vault in their storage in order to allow their // account to be able to receive deposits of this token type. // - access(all) fun createVault(): @Vault { + access(all) + fun createVault(): @Vault { return <-create Vault(balance: 30.0) } @@ -556,8 +571,10 @@ Here is an example of how interfaces for the `Vault` resource we defined above w // Interface that enforces the requirements for withdrawing // tokens from the implementing type // -access(all) resource interface Provider { - access(all) fun withdraw(amount: UFix64): @Vault { +access(all) +resource interface Provider { + access(all) + fun withdraw(amount: UFix64): @Vault { post { result.balance == amount: "Withdrawal amount must be the same as the balance of the withdrawn Vault" @@ -567,19 +584,23 @@ access(all) resource interface Provider { // Interface that enforces the requirements for depositing // tokens into the implementing type // -access(all) resource interface Receiver { +access(all) +resource interface Receiver { // There aren't any meaningful requirements for only a deposit function // but this still shows that the deposit function is required in an implementation. - access(all) fun deposit(from: @Vault) + access(all) + fun deposit(from: @Vault) } // Balance // // Interface that specifies a public `balance` field for the vault // -access(all) resource interface Balance { - access(all) var balance: UFix64 +access(all) +resource interface Balance { + access(all) + var balance: UFix64 } ``` @@ -662,7 +683,8 @@ We already use this pattern in the `VaultMinter` resource in the `mintTokens` fu // using their `Receiver` capability. // We say `&AnyResource{Receiver}` to say that the recipient can be any resource // as long as it implements the ExampleToken.Receiver interface -access(all) fun mintTokens(amount: UFix64, recipient: Capability<&AnyResource{Receiver}>) { +access(all) +fun mintTokens(amount: UFix64, recipient: Capability<&AnyResource{Receiver}>) { let recipientRef = recipient.borrow() ?? panic("Could not borrow a receiver reference to the vault") @@ -976,7 +998,8 @@ Open the script named `Get Balances` in the scripts pane. import FungibleToken from 0x02 // This script reads the Vault balances of two accounts. -access(all) fun main() { +access(all) +fun main() { // Get the accounts' public account objects let acct2 = getAccount(0x02) let acct3 = getAccount(0x03) diff --git a/versioned_docs/version-1.0/tutorial/07-marketplace-setup.md b/versioned_docs/version-1.0/tutorial/07-marketplace-setup.md index 09eb148..26c801c 100644 --- a/versioned_docs/version-1.0/tutorial/07-marketplace-setup.md +++ b/versioned_docs/version-1.0/tutorial/07-marketplace-setup.md @@ -177,7 +177,8 @@ import ExampleNFT from 0x02 // // Account 0x01: Vault Balance = 40, NFT.id = 1 // Account 0x02: Vault Balance = 20, No NFTs -access(all) fun main() { +access(all) +fun main() { // Get the accounts' public account objects let acct1 = getAccount(0x01) let acct2 = getAccount(0x02) diff --git a/versioned_docs/version-1.0/tutorial/08-marketplace-compose.md b/versioned_docs/version-1.0/tutorial/08-marketplace-compose.md index 31a24ee..2e3aef2 100644 --- a/versioned_docs/version-1.0/tutorial/08-marketplace-compose.md +++ b/versioned_docs/version-1.0/tutorial/08-marketplace-compose.md @@ -110,7 +110,8 @@ import ExampleNFT from 0x02 // // Account 0x01: Vault Balance = 40, NFT.id = 1 // Account 0x02: Vault Balance = 20, No NFTs -access(all) fun main() { +access(all) +fun main() { // Get the accounts' public account objects let acct1 = getAccount(0x01) let acct2 = getAccount(0x02) @@ -219,27 +220,39 @@ import ExampleNFT from 0x02 // // https://github.com/onflow/nft-storefront -access(all) contract ExampleMarketplace { +access(all) +contract ExampleMarketplace { // Event that is emitted when a new NFT is put up for sale - access(all) event ForSale(id: UInt64, price: UFix64, owner: Address?) + access(all) + event ForSale(id: UInt64, price: UFix64, owner: Address?) // Event that is emitted when the price of an NFT changes - access(all) event PriceChanged(id: UInt64, newPrice: UFix64, owner: Address?) + access(all) + event PriceChanged(id: UInt64, newPrice: UFix64, owner: Address?) // Event that is emitted when a token is purchased - access(all) event TokenPurchased(id: UInt64, price: UFix64, seller: Address?, buyer: Address?) + access(all) + event TokenPurchased(id: UInt64, price: UFix64, seller: Address?, buyer: Address?) // Event that is emitted when a seller withdraws their NFT from the sale - access(all) event SaleCanceled(id: UInt64, seller: Address?) + access(all) + event SaleCanceled(id: UInt64, seller: Address?) // Interface that users will publish for their Sale collection // that only exposes the methods that are supposed to be public // - access(all) resource interface SalePublic { - access(all) fun purchase(tokenID: UInt64, recipient: Capability<&AnyResource{ExampleNFT.NFTReceiver}>, buyTokens: @ExampleToken.Vault) - access(all) fun idPrice(tokenID: UInt64): UFix64? - access(all) fun getIDs(): [UInt64] + access(all) + resource interface SalePublic { + + access(all) + fun purchase(tokenID: UInt64, recipient: Capability<&AnyResource{ExampleNFT.NFTReceiver}>, buyTokens: @ExampleToken.Vault) + + access(all) + fun idPrice(tokenID: UInt64): UFix64? + + access(all) + fun getIDs(): [UInt64] } // SaleCollection @@ -247,18 +260,22 @@ access(all) contract ExampleMarketplace { // NFT Collection object that allows a user to put their NFT up for sale // where others can send fungible tokens to purchase it // - access(all) resource SaleCollection: SalePublic { + access(all) + resource SaleCollection: SalePublic { /// A capability for the owner's collection - access(self) var ownerCollection: Capability<&ExampleNFT.Collection> + access(self) + var ownerCollection: Capability<&ExampleNFT.Collection> // Dictionary of the prices for each NFT by ID - access(self) var prices: {UInt64: UFix64} + access(self) + var prices: {UInt64: UFix64} // The fungible token vault of the owner of this sale. // When someone buys a token, this resource can deposit // tokens into their account. - access(account) let ownerVault: Capability<&AnyResource{ExampleToken.Receiver}> + access(account) + let ownerVault: Capability<&AnyResource{ExampleToken.Receiver}> init (ownerCollection: Capability<&ExampleNFT.Collection>, ownerVault: Capability<&AnyResource{ExampleToken.Receiver}>) { @@ -278,7 +295,8 @@ access(all) contract ExampleMarketplace { } // cancelSale gives the owner the opportunity to cancel a sale in the collection - access(all) fun cancelSale(tokenID: UInt64) { + access(all) + fun cancelSale(tokenID: UInt64) { // remove the price self.prices.remove(key: tokenID) self.prices[tokenID] = nil @@ -287,7 +305,8 @@ access(all) contract ExampleMarketplace { } // listForSale lists an NFT for sale in this collection - access(all) fun listForSale(tokenID: UInt64, price: UFix64) { + access(all) + fun listForSale(tokenID: UInt64, price: UFix64) { pre { self.ownerCollection.borrow()!.idExists(id: tokenID): "NFT to be listed does not exist in the owner's collection" @@ -299,14 +318,16 @@ access(all) contract ExampleMarketplace { } // changePrice changes the price of a token that is currently for sale - access(all) fun changePrice(tokenID: UInt64, newPrice: UFix64) { + access(all) + fun changePrice(tokenID: UInt64, newPrice: UFix64) { self.prices[tokenID] = newPrice emit PriceChanged(id: tokenID, newPrice: newPrice, owner: self.owner?.address) } // purchase lets a user send tokens to purchase an NFT that is for sale - access(all) fun purchase(tokenID: UInt64, recipient: Capability<&AnyResource{ExampleNFT.NFTReceiver}>, buyTokens: @ExampleToken.Vault) { + access(all) + fun purchase(tokenID: UInt64, recipient: Capability<&AnyResource{ExampleNFT.NFTReceiver}>, buyTokens: @ExampleToken.Vault) { pre { self.prices[tokenID] != nil: "No token matching this ID for sale!" @@ -338,18 +359,21 @@ access(all) contract ExampleMarketplace { } // idPrice returns the price of a specific token in the sale - access(all) fun idPrice(tokenID: UInt64): UFix64? { + access(all) + fun idPrice(tokenID: UInt64): UFix64? { return self.prices[tokenID] } // getIDs returns an array of token IDs that are for sale - access(all) fun getIDs(): [UInt64] { + access(all) + fun getIDs(): [UInt64] { return self.prices.keys } } // createCollection returns a new collection resource to the caller - access(all) fun createSaleCollection(ownerCollection: Capability<&ExampleNFT.Collection>, + access(all) + fun createSaleCollection(ownerCollection: Capability<&ExampleNFT.Collection>, ownerVault: Capability<&AnyResource{ExampleToken.Receiver}>): @SaleCollection { return <- create SaleCollection(ownerCollection: ownerCollection, ownerVault: ownerVault) } @@ -374,16 +398,20 @@ that was explained in [Non-Fungible Tokens](./05-non-fungible-tokens-1.md), with ```cadence // Event that is emitted when a new NFT is put up for sale - access(all) event ForSale(id: UInt64, price: UFix64, owner: Address?) + access(all) + event ForSale(id: UInt64, price: UFix64, owner: Address?) // Event that is emitted when the price of an NFT changes - access(all) event PriceChanged(id: UInt64, newPrice: UFix64, owner: Address?) + access(all) + event PriceChanged(id: UInt64, newPrice: UFix64, owner: Address?) // Event that is emitted when a token is purchased - access(all) event TokenPurchased(id: UInt64, price: UFix64, seller: Address?, buyer: Address?) + access(all) + event TokenPurchased(id: UInt64, price: UFix64, seller: Address?, buyer: Address?) // Event that is emitted when a seller withdraws their NFT from the sale - access(all) event SaleCanceled(id: UInt64, seller: Address?) + access(all) + event SaleCanceled(id: UInt64, seller: Address?) ``` This contract has a few new features and concepts that are important to cover: @@ -401,7 +429,8 @@ when getting information about their users' accounts or generating analytics. Events are declared by indicating [the access level](../language/access-control.md), `event`, and the name and parameters of the event, like a function declaration: ```cadence -access(all) event ForSale(id: UInt64, price: UFix64, owner: Address?) +access(all) +event ForSale(id: UInt64, price: UFix64, owner: Address?) ``` Events cannot modify state at all; they indicate when important actions happen in the smart contract. @@ -462,12 +491,14 @@ We store two different capabilities in the marketplace sale collection: ```cadence /// A capability for the owner's collection -access(self) var ownerCollection: Capability<&ExampleNFT.Collection> +access(self) +var ownerCollection: Capability<&ExampleNFT.Collection> // The fungible token vault of the owner of this sale. // When someone buys a token, this resource can deposit // tokens into their account. -access(account) let ownerVault: Capability<&AnyResource{ExampleToken.Receiver}> +access(account) +let ownerVault: Capability<&AnyResource{ExampleToken.Receiver}> ``` If an object like a contract or resource owns a capability, they can borrow a reference to that capability at any time @@ -489,12 +520,14 @@ One last piece to consider about capabilities is the decision about when to use This tutorial used to have the `SaleCollection` directly store the NFTs that were for sale, like so: ```cadence -access(all) resource SaleCollection: SalePublic { +access(all) +resource SaleCollection: SalePublic { /// Dictionary of NFT objects for sale /// Maps ID to NFT resource object /// Not recommended - access(self) var forSale: @{UInt64: ExampleNFT.NFT} + access(self) + var forSale: @{UInt64: ExampleNFT.NFT} } ``` @@ -585,7 +618,8 @@ import ExampleNFT from 0x02 import ExampleMarketplace from 0x03 // This script prints the NFTs that account 0x01 has for sale. -access(all) fun main() { +access(all) +fun main() { // Get the public account object for account 0x01 let account1 = getAccount(0x01) @@ -713,7 +747,8 @@ import ExampleMarketplace from 0x03 // // Account 1: Vault balance = 50, No NFTs // Account 2: Vault balance = 10, NFT ID=1 -access(all) fun main() { +access(all) +fun main() { // Get the accounts' public account objects let acct1 = getAccount(0x01) let acct2 = getAccount(0x02) @@ -806,14 +841,17 @@ If we wanted to build a central marketplace on-chain, we could use a contract th ```cadence CentralMarketplace.cdc // Marketplace would be the central contract where people can post their sale // references so that anyone can access them -access(all) contract Marketplace { +access(all) +contract Marketplace { // Data structure to store active sales - access(all) var tokensForSale: {Address: Capability<&SaleCollection>)} + access(all) + var tokensForSale: {Address: Capability<&SaleCollection>)} // listSaleCollection lists a users sale reference in the array // and returns the index of the sale so that users can know // how to remove it from the marketplace - access(all) fun listSaleCollection(collection: Capability<&SaleCollection>) { + access(all) + fun listSaleCollection(collection: Capability<&SaleCollection>) { let saleRef = collection.borrow() ?? panic("Invalid sale collection capability") @@ -822,7 +860,8 @@ access(all) contract Marketplace { // removeSaleCollection removes a user's sale from the array // of sale references - access(all) fun removeSaleCollection(owner: Address) { + access(all) + fun removeSaleCollection(owner: Address) { self.tokensForSale[owner] = nil } diff --git a/versioned_docs/version-1.0/tutorial/09-voting.md b/versioned_docs/version-1.0/tutorial/09-voting.md index 6cd4e34..89c3999 100644 --- a/versioned_docs/version-1.0/tutorial/09-voting.md +++ b/versioned_docs/version-1.0/tutorial/09-voting.md @@ -86,25 +86,31 @@ The deployed contract should have the following contents: * */ -access(all) contract ApprovalVoting { +access(all) +contract ApprovalVoting { //list of proposals to be approved - access(all) var proposals: [String] + access(all) + var proposals: [String] // number of votes per proposal - access(all) let votes: {Int: Int} + access(all) + let votes: {Int: Int} // This is the resource that is issued to users. // When a user gets a Ballot object, they call the `vote` function // to include their votes, and then cast it in the smart contract // using the `cast` function to have their vote included in the polling - access(all) resource Ballot { + access(all) + resource Ballot { // array of all the proposals - access(all) let proposals: [String] + access(all) + let proposals: [String] // corresponds to an array index in proposals after a vote - access(all) var choices: {Int: Bool} + access(all) + var choices: {Int: Bool} init() { self.proposals = ApprovalVoting.proposals @@ -120,7 +126,8 @@ access(all) contract ApprovalVoting { // modifies the ballot // to indicate which proposals it is voting for - access(all) fun vote(proposal: Int) { + access(all) + fun vote(proposal: Int) { pre { self.proposals[proposal] != nil: "Cannot vote for a proposal that doesn't exist" } @@ -130,10 +137,12 @@ access(all) contract ApprovalVoting { // Resource that the Administrator of the vote controls to // initialize the proposals and to pass out ballot resources to voters - access(all) resource Administrator { + access(all) + resource Administrator { // function to initialize all the proposals for the voting - access(all) fun initializeProposals(_ proposals: [String]) { + access(all) + fun initializeProposals(_ proposals: [String]) { pre { ApprovalVoting.proposals.length == 0: "Proposals can only be initialized once" proposals.length > 0: "Cannot initialize with no proposals" @@ -150,14 +159,16 @@ access(all) contract ApprovalVoting { // The admin calls this function to create a new Ballot // that can be transferred to another user - access(all) fun issueBallot(): @Ballot { + access(all) + fun issueBallot(): @Ballot { return <-create Ballot() } } // A user moves their ballot to this function in the contract where // its votes are tallied and the ballot is destroyed - access(all) fun cast(ballot: @Ballot) { + access(all) + fun cast(ballot: @Ballot) { var index = 0 // look through the ballot while index < self.proposals.length { @@ -190,7 +201,8 @@ This contract implements a simple voting mechanism where an `Administrator` can ```cadence // function to initialize all the proposals for the voting -access(all) fun initializeProposals(_ proposals: [String]) { +access(all) +fun initializeProposals(_ proposals: [String]) { pre { ApprovalVoting.proposals.length == 0: "Proposals can only be initialized once" proposals.length > 0: "Cannot initialize with no proposals" @@ -209,7 +221,8 @@ access(all) fun initializeProposals(_ proposals: [String]) { Then they can give `Ballot` resources to other accounts. The other accounts can record their votes on their `Ballot` resource by calling the `vote` function. ```cadence -access(all) fun vote(proposal: Int) { +access(all) +fun vote(proposal: Int) { pre { self.proposals[proposal] != nil: "Cannot vote for a proposal that doesn't exist" } @@ -222,7 +235,8 @@ After a user has voted, they submit their vote to the central smart contract by ```cadence // A user moves their ballot to this function in the contract where // its votes are tallied and the ballot is destroyed -access(all) fun cast(ballot: @Ballot) { +access(all) +fun cast(ballot: @Ballot) { var index = 0 // look through the ballot while index < self.proposals.length { @@ -400,7 +414,8 @@ import ApprovalVoting from 0x01 // This script allows anyone to read the tallied votes for each proposal // -access(all) fun main() { +access(all) +fun main() { // Access the public fields of the contract to log // the proposal names and vote counts diff --git a/versioned_docs/version-1.0/tutorial/10-resources-compose.md b/versioned_docs/version-1.0/tutorial/10-resources-compose.md index 27f9e25..e641b8a 100644 --- a/versioned_docs/version-1.0/tutorial/10-resources-compose.md +++ b/versioned_docs/version-1.0/tutorial/10-resources-compose.md @@ -92,12 +92,18 @@ The deployed contract should have the following contents: // support even more powerful versions of this. // -access(all) contract KittyVerse { +access(all) +contract KittyVerse { // KittyHat is a special resource type that represents a hat - access(all) resource KittyHat { - access(all) let id: Int - access(all) let name: String + access(all) + resource KittyHat { + + access(all) + let id: Int + + access(all) + let name: String init(id: Int, name: String) { self.id = id @@ -105,7 +111,8 @@ access(all) contract KittyVerse { } // An example of a function someone might put in their hat resource - access(all) fun tipHat(): String { + access(all) + fun tipHat(): String { if self.name == "Cowboy Hat" { return "Howdy Y'all" } else if self.name == "Top Hat" { @@ -117,41 +124,49 @@ access(all) contract KittyVerse { } // Create a new hat - access(all) fun createHat(id: Int, name: String): @KittyHat { + access(all) + fun createHat(id: Int, name: String): @KittyHat { return <-create KittyHat(id: id, name: name) } - access(all) resource Kitty { + access(all) + resource Kitty { - access(all) let id: Int + access(all) + let id: Int // place where the Kitty hats are stored - access(all) var items: @{String: KittyHat} + access(all) + var items: @{String: KittyHat} init(newID: Int) { self.id = newID self.items <- {} } - access(all) fun getKittyItems(): @{String: KittyHat} { + access(all) + fun getKittyItems(): @{String: KittyHat} { var other: @{String:KittyHat} <- {} self.items <-> other return <- other } - access(all) fun setKittyItems(items: @{String: KittyHat}) { + access(all) + fun setKittyItems(items: @{String: KittyHat}) { var other <- items self.items <-> other destroy other } - access(all) fun removeKittyItem(key: String): @KittyHat? { + access(all) + fun removeKittyItem(key: String): @KittyHat? { var removed <- self.items.remove(key: key) return <- removed } } - access(all) fun createKitty(): @Kitty { + access(all) + fun createKitty(): @Kitty { return <-create Kitty(newID: 1) } @@ -165,7 +180,8 @@ The hats are stored in a variable in the Kitty resource. ```cadence // place where the Kitty hats are stored - access(all) var items: <-{String: KittyHat} + access(all) + var items: <-{String: KittyHat} ``` A Kitty owner can take the hats off the Kitty and transfer them individually. Or the owner can transfer a Kitty that owns a hat, and the hat will go along with the Kitty.