@@ -3,331 +3,11 @@ title: Contracts
33sidebar_position : 5
44---
55
6- Accounts store [ contracts] ( ../contracts.mdx ) .
7- A contract can also just be an [ interface] ( ../interfaces.mdx ) .
6+ Accounts store contracts. A contract can also just be an [ interface] ( ../interfaces.mdx ) .
87
9- An account exposes its inbox through the ` contracts ` field,
10- which has the type ` Account.Contracts ` .
8+ See [ Contracts] for more information.
119
12- ## ` Account.Contracts `
10+ < !-- Relative links. Will not render on the page -->
1311
14- ``` cadence
15- access(all)
16- struct Contracts {
17-
18- /// The names of all contracts deployed in the account.
19- access(all)
20- let names: [String]
21-
22- /// Returns the deployed contract for the contract/contract interface with the given name in the account, if any.
23- ///
24- /// Returns nil if no contract/contract interface with the given name exists in the account.
25- access(all)
26- view fun get(name: String): DeployedContract?
27-
28- /// Returns a reference of the given type to the contract with the given name in the account, if any.
29- ///
30- /// Returns nil if no contract with the given name exists in the account,
31- /// or if the contract does not conform to the given type.
32- access(all)
33- view fun borrow<T: &Any>(name: String): T?
34-
35- /// Adds the given contract to the account.
36- ///
37- /// The `code` parameter is the UTF-8 encoded representation of the source code.
38- /// The code must contain exactly one contract or contract interface,
39- /// which must have the same name as the `name` parameter.
40- ///
41- /// All additional arguments that are given are passed further to the initializer
42- /// of the contract that is being deployed.
43- ///
44- /// The function fails if a contract/contract interface with the given name already exists in the account,
45- /// if the given code does not declare exactly one contract or contract interface,
46- /// or if the given name does not match the name of the contract/contract interface declaration in the code.
47- ///
48- /// Returns the deployed contract.
49- access(Contracts | AddContract)
50- fun add(
51- name: String,
52- code: [UInt8]
53- ): DeployedContract
54-
55- /// Updates the code for the contract/contract interface in the account.
56- ///
57- /// The `code` parameter is the UTF-8 encoded representation of the source code.
58- /// The code must contain exactly one contract or contract interface,
59- /// which must have the same name as the `name` parameter.
60- ///
61- /// Does **not** run the initializer of the contract/contract interface again.
62- /// The contract instance in the world state stays as is.
63- ///
64- /// Fails if no contract/contract interface with the given name exists in the account,
65- /// if the given code does not declare exactly one contract or contract interface,
66- /// or if the given name does not match the name of the contract/contract interface declaration in the code.
67- ///
68- /// Returns the deployed contract for the updated contract.
69- access(Contracts | UpdateContract)
70- fun update(name: String, code: [UInt8]): DeployedContract
71-
72- /// Removes the contract/contract interface from the account which has the given name, if any.
73- ///
74- /// Returns the removed deployed contract, if any.
75- ///
76- /// Returns nil if no contract/contract interface with the given name exists in the account.
77- access(Contracts | RemoveContract)
78- fun remove(name: String): DeployedContract?
79- }
80-
81- entitlement Contracts
82-
83- entitlement AddContract
84- entitlement UpdateContract
85- entitlement RemoveContract
86- ```
87-
88- ## Deployed contract
89-
90- Accounts store "deployed contracts," that is, the code of the contract:
91-
92- ``` cadence
93- access(all)
94- struct DeployedContract {
95- /// The address of the account where the contract is deployed at.
96- access(all)
97- let address: Address
98-
99- /// The name of the contract.
100- access(all)
101- let name: String
102-
103- /// The code of the contract.
104- access(all)
105- let code: [UInt8]
106-
107- /// Returns an array of `Type` objects representing all the public type declarations in this contract
108- /// (e.g. structs, resources, enums).
109- ///
110- /// For example, given a contract
111- /// ```
112- /// contract Foo {
113- ///
114- /// access(all)
115- /// struct Bar {...}
116- ///
117- /// access(all)
118- /// resource Qux {...}
119- /// }
120- /// ```
121- /// then `.publicTypes()` will return an array equivalent to the expression `[Type<Bar>(), Type<Qux>()]`
122- access(all)
123- view fun publicTypes(): [Type]
124- }
125- ```
126-
127- Note that this is type only provides information about a deployed contract,
128- it is not the contract instance, the result of importing a contract.
129-
130- ## Getting a deployed contract
131-
132- The function ` contracts.get ` retrieves a deployed contract:
133-
134- ``` cadence
135- access(all)
136- view fun get(name: String): DeployedContract?
137- ```
138-
139- The function returns the [ deployed contract] ( #deployed-contract ) with the given name, if any.
140- If no contract with the given name exists in the account, the function returns ` nil ` .
141-
142- For example, assuming that an account has a contract named ` Test ` deployed to it,
143- the contract can be retrieved as follows:
144-
145- ``` cadence
146- let account = getAccount(0x1)
147- let contract = account.contracts.get(name: "Test")
148- ```
149-
150- ## Borrowing a deployed contract
151-
152- Contracts can be "borrowed" to effectively perform a dynamic import dependent on a specific execution path.
153-
154- This is in contrast to a typical import statement, for example ` import T from 0x1 ` ,
155- which statically imports a contract.
156-
157- The ` contracts.borrow ` function obtains a reference to a contract instance:
158-
159- ``` cadence
160- access(all)
161- view fun borrow<T: &Any>(name: String): T?
162- ```
163-
164- The functions returns a reference to the contract instance stored with that name on the account,
165- if it exists, and if it has the provided type ` T ` .
166- If no contract with the given name exists in the account, the function returns ` nil ` .
167-
168- For example, assuming that a contract named ` Test `
169- which conforms to the ` TestInterface ` interface is deployed to an account,
170- a reference to the contract instance can obtained be as follows:
171-
172- ``` cadence
173- let account = getAccount(0x1)
174- let contract: &TestInterface = account.contracts.borrow<&TestInterface>(name: "Test")
175- ```
176-
177- This is similar to the import statement
178-
179- ``` cadence
180- import Test from 0x1
181- ```
182-
183- ## Deploying a new contract
184-
185- The ` contracts.add ` function deploys a new contract to an account:
186-
187- ``` cadence
188- access(Contracts | AddContract)
189- fun add(
190- name: String,
191- code: [UInt8],
192- ... contractInitializerArguments
193- ): DeployedContract
194- ```
195-
196- Calling the ` add ` function requires access to an account via a reference which is authorized
197- with the coarse-grained ` Contracts ` entitlement (` auth(Contracts) &Account ` ),
198- or the fine-grained ` AddContract ` entitlement (` auth(AddContract) &Account ` ).
199-
200- The ` code ` parameter is the UTF-8 encoded representation of the source code.
201- The code must contain exactly one contract or contract interface,
202- which must have the same name as the ` name ` parameter.
203-
204- The ` add ` function passes all extra arguments of the call (` contractInitializerArguments ` )
205- to the initializer of the contract.
206-
207- If a contract with the given name already exists in the account,
208- if the given code does not declare exactly one contract or contract interface,
209- or if the given name does not match the name of the contract declaration in the code,
210- then the function aborts the program.
211-
212- When the deployment succeeded, the function returns the [ deployed contract] ( #deployed-contract ) .
213-
214- For example, assuming the following contract code should be deployed:
215-
216- ``` cadence
217- access(all)
218- contract Test {
219-
220- access(all)
221- let message: String
222-
223- init(message: String) {
224- self.message = message
225- }
226- }
227- ```
228-
229- The contract can be deployed as follows:
230-
231- ``` cadence
232- transaction(code: String) {
233- prepare(signer: auth(AddContract) &Account) {
234- signer.contracts.add(
235- name: "Test",
236- code: code.utf8,
237- message: "I'm a new contract in an existing account"
238- )
239- }
240- }
241- ```
242-
243- ## Updating a deployed contract
244-
245- The ` contracts.update ` function updates the code of an existing contract:
246-
247- ``` cadence
248- access(Contracts | UpdateContract)
249- fun update(name: String, code: [UInt8]): DeployedContract
250- ```
251-
252- Calling the ` update ` function requires access to an account via a reference which is authorized
253- with the coarse-grained ` Contracts ` entitlement (` auth(Contracts) &Account ` ),
254- or the fine-grained ` UpdateContract ` entitlement (` auth(UpdateContract) &Account ` ).
255-
256- The ` code ` parameter is the UTF-8 encoded representation of the source code.
257- The code must contain exactly one contract or contract interface,
258- which must have the same name as the ` name ` parameter.
259-
260- If no contract with the given name exists in the account,
261- if the given code does not declare exactly one contract or contract interface,
262- or if the given name does not match the name of the contract declaration in the code,
263- then the function aborts the program.
264-
265- When the update succeeded, the function returns the [ deployed contract] ( #deployed-contract ) .
266-
267- :::warning
268-
269- The ` update ` function does ** not** run the initializer of the contract again.
270-
271- Updating a contract does ** not** change the contract instance and its existing stored data.
272- A contract update only changes the code a contract.
273-
274- Is only possible to update contracts in ways that keep data consistency.
275- [ Certain restrictions apply] ( ../contract-updatability.md ) .
276-
277- :::
278-
279- For example, assuming that a contract named ` Test ` is already deployed to the account,
280- and it should be updated with the following contract code:
281-
282- ``` cadence
283- access(all)
284- contract Test {
285-
286- access(all)
287- let message: String
288-
289- init(message: String) {
290- self.message = message
291- }
292- }
293- ```
294-
295- The contract can be updated as follows:
296-
297- ``` cadence
298- transaction(code: String) {
299- prepare(signer: auth(UpdateContract) &Account) {
300- signer.contracts.update(
301- name: "Test",
302- code: code
303- )
304- }
305- }
306- ```
307-
308- ## Removing a deployed contract
309-
310- The ` contracts.remove ` function removes a deployed contract from an account:
311-
312- ``` cadence
313- access(Contracts | RemoveContract)
314- fun remove(name: String): DeployedContract?
315- ```
316-
317- Calling the ` remove ` function requires access to an account via a reference which is authorized
318- with the coarse-grained ` Contracts ` entitlement (` auth(Contracts) &Account ` ),
319- or the fine-grained ` RemoveContract ` entitlement (` auth(RemoveContract) &Account ` ).
320-
321- The function removes the contract from the account which has the given name and returns it.
322- If no contract with the given name exists in the account, the function returns ` nil ` .
323-
324- For example, assuming that a contract named ` Test ` is deployed to an account,
325- the contract can be removed as follows:
326-
327- ``` cadence
328- transaction(code: String) {
329- prepare(signer: auth(RemoveContract) &Account) {
330- signer.contracts.remove(name: "Test",)
331- }
332- }
333- ```
12+ [Contracts]: ../contracts.mdx
13+ [interface]: ../interfaces.mdx
0 commit comments