|
| 1 | +--- |
| 2 | +id: intrinsics |
| 3 | +title: Intrinsics |
| 4 | +sidebar_label: Intrinsics |
| 5 | +--- |
| 6 | + |
| 7 | +[general tags]: # "intrinsic, dynamic_call, dynamic_contains, dynamic_get, dynamic_get_or_use, dynamic_dispatch, finalize" |
| 8 | + |
| 9 | +Intrinsics are low-level operations built into the compiler. They complement Leo's high-level abstractions and are useful when those abstractions aren't expressive enough for a particular use case. They are prefixed with `_` to make them visually distinct from user-defined functions. |
| 10 | + |
| 11 | +--- |
| 12 | + |
| 13 | +## `_dynamic_call` |
| 14 | + |
| 15 | +Calls a function on a remote program determined at runtime, without requiring an interface definition. The target program, network, and function name are supplied as runtime values, and the full type signature is declared in the generic type parameters. |
| 16 | + |
| 17 | +Only valid in transition contexts β it cannot be used inside `final fn` functions or `final {}` blocks. |
| 18 | + |
| 19 | +### Syntax |
| 20 | + |
| 21 | +``` |
| 22 | +_dynamic_call::[TYPE_PARAMS](prog, net, func, ...args) |
| 23 | +``` |
| 24 | + |
| 25 | +- `prog` β the target program name, as a value of type `identifier` or a `field` representing an identifier |
| 26 | +- `net` β the network, as a value of type `identifier` or a `field` representing an identifier; currently only `'aleo'` is valid |
| 27 | +- `func` β the function name to call, as a value of type `identifier` or a `field` representing an identifier |
| 28 | +- `...args` β the function arguments, matching the input types declared in `TYPE_PARAMS` |
| 29 | + |
| 30 | +### Type parameters |
| 31 | + |
| 32 | +Type parameters follow one rule: **the last entry is the return type; all preceding entries are input types** with an optional visibility modifier (`public` or `private`). Omitting type parameters entirely means void return with compiler-inferred input visibility. |
| 33 | + |
| 34 | +#### No type parameters β void return |
| 35 | + |
| 36 | +```leo |
| 37 | +_dynamic_call(prog, net, func, x); |
| 38 | +``` |
| 39 | + |
| 40 | +#### Return type only β inputs are `private` by default |
| 41 | + |
| 42 | +```leo |
| 43 | +let result: u64 = _dynamic_call::[u64](prog, net, func, x); |
| 44 | +``` |
| 45 | + |
| 46 | +#### Explicit input visibility |
| 47 | + |
| 48 | +All type params before the last are input types. Each can carry a visibility modifier: |
| 49 | + |
| 50 | +```leo |
| 51 | +// One public input, then the return type |
| 52 | +let result: u64 = _dynamic_call::[public u64, u64](prog, net, func, x); |
| 53 | +``` |
| 54 | + |
| 55 | +#### Multiple inputs |
| 56 | + |
| 57 | +```leo |
| 58 | +let (a, b): (u32, u32) = _dynamic_call::[public u32, public u32, (u32, u32)](prog, net, func, x, y); |
| 59 | +``` |
| 60 | + |
| 61 | +#### Void return with input annotations |
| 62 | + |
| 63 | +Use `()` as the return type: |
| 64 | + |
| 65 | +```leo |
| 66 | +_dynamic_call::[public u64, ()](prog, net, func, x); |
| 67 | +``` |
| 68 | + |
| 69 | +#### `Final` return |
| 70 | + |
| 71 | +When the called function returns a `Final`, include it in a tuple: |
| 72 | + |
| 73 | +```leo |
| 74 | +let (val, f): (u32, Final) = _dynamic_call::[(u32, Final)](target, 'aleo', 'increment', val); |
| 75 | +return (val, final { |
| 76 | + f.run(); |
| 77 | +}); |
| 78 | +``` |
| 79 | + |
| 80 | +#### `dyn record` inputs and outputs |
| 81 | + |
| 82 | +```leo |
| 83 | +let result: dyn record = _dynamic_call::[dyn record, dyn record](prog, net, func, token); |
| 84 | +``` |
| 85 | + |
| 86 | +### Restrictions |
| 87 | + |
| 88 | +`_dynamic_call` is **not** allowed in `final fn` functions or `final {}` blocks. |
| 89 | + |
| 90 | +--- |
| 91 | + |
| 92 | +## `_dynamic_contains` |
| 93 | + |
| 94 | +Checks whether a key exists in a mapping belonging to another program, determined at runtime. Only valid inside `final fn` functions or `final {}` blocks. |
| 95 | + |
| 96 | +### Syntax |
| 97 | + |
| 98 | +```leo |
| 99 | +let exists: bool = _dynamic_contains(prog, net, mapping, key); |
| 100 | +``` |
| 101 | + |
| 102 | +- `prog` β the target program name, as a value of type `identifier` or a `field` representing an identifier |
| 103 | +- `net` β the network, as a value of type `identifier` or a `field` representing an identifier; currently only `'aleo'` is valid |
| 104 | +- `mapping` β the mapping name on the target program, as a value of type `identifier` or a `field` representing an identifier |
| 105 | +- `key` β a value whose type matches the target mapping's key type |
| 106 | + |
| 107 | +Returns `true` if `key` is present, `false` otherwise. |
| 108 | + |
| 109 | +### Example |
| 110 | + |
| 111 | +```leo showLineNumbers |
| 112 | +program checker.aleo { |
| 113 | + mapping seen: address => bool; |
| 114 | +
|
| 115 | + fn check(prog: field, net: field, map: field, key: address) -> Final { |
| 116 | + return final { finalize_check(prog, net, map, key); }; |
| 117 | + } |
| 118 | +
|
| 119 | + @noupgrade |
| 120 | + constructor() {} |
| 121 | +} |
| 122 | +
|
| 123 | +final fn finalize_check(prog: field, net: field, map: field, key: address) { |
| 124 | + let exists: bool = _dynamic_contains(prog, net, map, key); |
| 125 | + Mapping::set(seen, key, exists); |
| 126 | +} |
| 127 | +``` |
| 128 | + |
| 129 | +--- |
| 130 | + |
| 131 | +## `_dynamic_get` |
| 132 | + |
| 133 | +Reads a value from a mapping belonging to another program, determined at runtime. Only valid inside `final fn` functions or `final {}` blocks. |
| 134 | + |
| 135 | +Fails at runtime if the key is not present β use [`_dynamic_get_or_use`](#_dynamic_get_or_use) when the key may be absent. |
| 136 | + |
| 137 | +### Syntax |
| 138 | + |
| 139 | +```leo |
| 140 | +let val: T = _dynamic_get::[T](prog, net, mapping, key); |
| 141 | +``` |
| 142 | + |
| 143 | +- `prog` β the target program name, as a value of type `identifier` or a `field` representing an identifier |
| 144 | +- `net` β the network, as a value of type `identifier` or a `field` representing an identifier; currently only `'aleo'` is valid |
| 145 | +- `mapping` β the mapping name on the target program, as a value of type `identifier` or a `field` representing an identifier |
| 146 | +- `key` β a value whose type matches the target mapping's key type |
| 147 | +- `T` β must match the target mapping's value type |
| 148 | + |
| 149 | +### Example |
| 150 | + |
| 151 | +```leo showLineNumbers |
| 152 | +program reader.aleo { |
| 153 | + mapping result: address => u64; |
| 154 | +
|
| 155 | + fn read(prog: field, net: field, map: field, key: address) -> Final { |
| 156 | + return final { finalize_read(prog, net, map, key); }; |
| 157 | + } |
| 158 | +
|
| 159 | + @noupgrade |
| 160 | + constructor() {} |
| 161 | +} |
| 162 | +
|
| 163 | +final fn finalize_read(prog: field, net: field, map: field, key: address) { |
| 164 | + let val: u64 = _dynamic_get::[u64](prog, net, map, key); |
| 165 | + Mapping::set(result, key, val); |
| 166 | +} |
| 167 | +``` |
| 168 | + |
| 169 | +For example, using identifier literals: |
| 170 | + |
| 171 | +```leo |
| 172 | +let val: u64 = _dynamic_get::[u64]('some_program', 'aleo', 'balances', key); |
| 173 | +``` |
| 174 | + |
| 175 | +--- |
| 176 | + |
| 177 | +## `_dynamic_get_or_use` |
| 178 | + |
| 179 | +Reads a value from a mapping belonging to another program, determined at runtime, returning a default value if the key is absent. Only valid inside `final fn` functions or `final {}` blocks. |
| 180 | + |
| 181 | +### Syntax |
| 182 | + |
| 183 | +```leo |
| 184 | +let val: T = _dynamic_get_or_use::[T](prog, net, mapping, key, default); |
| 185 | +``` |
| 186 | + |
| 187 | +- `prog` β the target program name, as a value of type `identifier` or a `field` representing an identifier |
| 188 | +- `net` β the network, as a value of type `identifier` or a `field` representing an identifier; currently only `'aleo'` is valid |
| 189 | +- `mapping` β the mapping name on the target program, as a value of type `identifier` or a `field` representing an identifier |
| 190 | +- `key` β a value whose type matches the target mapping's key type |
| 191 | +- `default` β the fallback value returned when `key` is absent; must be the same type as `T` |
| 192 | +- `T` β must match the target mapping's value type |
| 193 | + |
| 194 | +### Example |
| 195 | + |
| 196 | +```leo showLineNumbers |
| 197 | +program reader.aleo { |
| 198 | + mapping result: address => u64; |
| 199 | +
|
| 200 | + fn read(prog: field, net: field, map: field, key: address) -> Final { |
| 201 | + return final { finalize_read(prog, net, map, key); }; |
| 202 | + } |
| 203 | +
|
| 204 | + @noupgrade |
| 205 | + constructor() {} |
| 206 | +} |
| 207 | +
|
| 208 | +final fn finalize_read(prog: field, net: field, map: field, key: address) { |
| 209 | + let val: u64 = _dynamic_get_or_use::[u64](prog, net, map, key, 0u64); |
| 210 | + Mapping::set(result, key, val); |
| 211 | +} |
| 212 | +``` |
0 commit comments