Scripts

Scripts let you run non-permanent Cadence scripts on the Flow blockchain. They can return data.

They always need to contain a pub fun main() function as an entry point to the script.

fcl.query is a function that sends Cadence scripts to the chain and receives back decoded responses.

The cadence key inside the object sent to the query function is a JavaScript Tagged Template Literal that we can pass Cadence code into.

Sending your first Script

In the following code snippet we are going to send a script to the Flow blockchain. The script is going to add two numbers, and return them.

1
import * as fcl from "@onflow/fcl"
2
3
const response = await fcl.query({
4
cadence: `
5
pub fun main(): Int {
6
return 1 + 2
7
}
8
`
9
})
10
11
console.log(response) // 3

A more complicated Script

Things like Resources and Structs are fairly common place in Cadence.

In the following code snippet, our script defines a struct called Point, it then returns a list of them.

The closest thing to a Structure in JavaScript is an object. In this case when we decode this response, we would be expecting to get back an array of objects, where the objects have an x and y value.

1
import * as fcl from "@onflow/fcl"
2
3
const response = await fcl.query({
4
cadence: `
5
pub struct Point {
6
pub var x: Int
7
pub var y: Int
8
9
init(x: Int, y: Int) {
10
self.x = x
11
self.y = y
12
}
13
}
14
15
pub fun main(): [Point] {
16
return [Point(x: 1, y: 1), Point(x: 2, y: 2)]
17
}
18
`
19
})
20
21
console.log(response) // [{x:1, y:1}, {x:2, y:2}]

Transforming the data we get back with custom decoders.

In our dapp, we probably have a way of representing these Cadence values internally. In the above example it might be a Point class.

FCL enables us to provide custom decoders that we can use to transform the data we receive from the Flow blockchain at the edge, before anything else in our dapp gets a chance to look at it.

We add these custom decoders by Configuring FCL. This lets us set it once when our dapp starts up and use our normalized data through out the rest of our dapp.

In the below example we will use the concept of a Point again, but this time, we will add a custom decoder, that enables fcl.decode to transform it into a custom JavaScript Point class.

1
import * as fcl from "@onflow/fcl"
2
3
class Point {
4
constructor({ x, y }) {
5
this.x = x
6
this.y = y
7
}
8
}
9
10
fcl.config()
11
.put("decoder.Point", point => new Point(point))
12
13
const response = await fcl.query({
14
cadence: `
15
pub struct Point {
16
pub var x: Int
17
pub var y: Int
18
19
init(x: Int, y: Int) {
20
self.x = x
21
self.y = y
22
}
23
}
24
25
pub fun main(): [Point] {
26
return [Point(x: 1, y: 1), Point(x: 2, y: 2)]
27
}
28
`
29
})
30
31
console.log(response) // [Point{x:1, y:1}, Point{x:2, y:2}]

To learn more about query, check out the API documentation.