OWB - Week #3 Cadence Challenge/Assignment

For this week’s technical challenge/homework, we want you to continue getting familiar with Cadence:

  1. Make sure you have read the introduction, Getting Started, and completed all the tutorials at docs.onflow.org. Also start reading the cadence language reference to get more familiar with all the details of Cadence.
  2. If there is ANY confusion about any of the features used in these tutorials, PLEASE write down the areas where you are confused and surface them in the forum. We want to make our documentation and tutorials as clear as possible and we need feedback from YOU to help improve them. Please don’t be afraid to ask for help. We really want to help you understand and your feedback will be extremely valuable for future newcomers to Flow.
  3. Only move to this step if you feel comfortable with #2. Your top priority is to get comfortable with Cadence, so if it takes all the time you dedicate to this to understand Cadence better, then you don’t need to work on this part.
  4. If you do feel comfortable enough with Cadence, we would like you to take the example Voting smart contract from the tutorial and make some of your own additions to it. You might try to implement a specific voting algorithm, make it so that the votes are for supporting a specific smart contract, or maybe add some more restrictions about when votes can be submitted, how many votes a resource can send, or anything else. Feel free to ask us questions if you need feedback on your ideas!
  5. Post your playground projects in the comments of this post or on the discord for feedback!

Again, these challenges/homeworks are optional, but will help with your understanding of Cadence, which is the most important thing. Good luck!

3 Likes

Coin voting

Overview

Simple modification on vote to pass the Token.Balance to count the balance of token holding as the voting count.

Instruction to run

  • Deploy FungibleToken
  • Deploy ApprovalVoting
  • Run Transaction1 with all 4 signers in the order of 1,2,3,4
  • Run Transaction2 with all 4 signers in the order of 1,2,3,4
  • Run Script1.

Results

Even though account 1~3 vote for proposal 1, account 4 has more tokens than others so the second proposal has more voting.

Some observations

  • I spent more time writing transactions than making change on the smartcontract.
  • I am still a bit confused when to use @ and when to use &
  • I didn’t have to return nor destroy Token.Balance resource. Is it because it’s interface?
  • VS Code has a lot better error and warning but couldn’t run this exercise as I couldn’t sign multiple accounts.
1 Like

Hi @makoto,

Nice work!

@ is used in front of resource types.

  • when you declare a variable of a resource type
  • when you declare a function that takes as argument a value of resource type or returns a value of resource type

pub resource SomeResource{
}

var ar: @AnyResoure

var sr: @SomeResource

fun f(resource: @SomeResource): @SomeResource {

}

Hi, @daniel thank you for the info. In my code I actually use & which I guess Got suggestion from vs code. Am I doing it wrong?

Hi @makoto,

Yes you’re doing it right.

& is used for references. References can be used to call methods on resources without moving or owning the resource itself.

There are multiple occurrences where a syntax like this &AnyResource{Receiver} is used so I’ll try to explain what this does, maybe it will make it less confusing.

Interfaces might be known in other languages (Swift for example) under the name protocols.

You declare an interface like this:

`pub resource interface Receiver {

pub fun deposit() { }

}`

Inside the interface you can declare variables and functions (name, return type, and pre/post conditions) that you want other resources (also works for structs and contracts) that conform to the interface to implement.

A resource that will conform to the Receiver interface will have to implement the deposit function. Also this resource might declare other functions.

Somewhere in your code you’ll want to access this resource but you might want to restrict access to only some methods.

To do this you “restrict” your resource to expose only the methods from one of the interfaces it implements. This is a way to implement access control.

Example:

`pub fun mintTokens(amount: UFix64, recipient: &AnyResource{Receiver}) {

}`

This says that the recipient argument will be a reference to any resource that implements the functions declared in the Receiver interface. Any other functions that are implemented in the resource would not be accessible inside the mintTokens function. It’s like you “downgraded” your resource to only be a Receiver.

This would mean that you can pass any resource, not only the ones that conform to Receiver interface.

`pub fun mintTokens(amount: UFix64, recipient: @AnyResource) {

}`

This means you can pas a reference to any resource, not only the ones that conform to Receiver interface.

`pub fun mintTokens(amount: UFix64, recipient: &AnyResource) {

}`

This would not be correct as Receiver is not a resource but a resource interface.

`pub fun mintTokens(amount: UFix64, recipient: @Receiver) {

}`

2 Likes