F
Flow12mo ago
joshua

joshua | Flow (2024-01-24)

If I define an access(contract) function in a resource interface, does that mean that only code in the interface's contract can call it or only code in the implementation's contract can call it? or both?
8 Replies
Needle
Needle12mo ago
I've created a thread for your message. Please continue any relevant discussion in this thread. You can rename this thread using /title <new title> If this is a technical question that others may benefit from, considering also asking it on Stackoverflow: https://stackoverflow.com/questions/ask?tags=onflow-cadence
joshua
joshuaOP12mo ago
Example:
access(all) contract Burner {

access(all) resource interface Burnable {
access(contract) fun burnCallback()
}

access(all) fun burn(_ r: @AnyResource) {
if let s <- r as @{Burnable} {
s.burnCallback() // IS THIS POSSIBLE?
destroy s
} else {
destroy r
}
}
}

access(all) contract Impl {
access(all) resource Vault: Burner.Burnable {
access(contract) fun burnCallback()

access(all) fun callBurnCallback() {
self.burnCallback() // IS THIS POSSIBLE?
}
}

init() {
let vault <- create Vault()
vault.callBurnCallback()
destroy vault

let vault2 <- create Vault()
Burner.burn(<-vault2)
}
}
access(all) contract Burner {

access(all) resource interface Burnable {
access(contract) fun burnCallback()
}

access(all) fun burn(_ r: @AnyResource) {
if let s <- r as @{Burnable} {
s.burnCallback() // IS THIS POSSIBLE?
destroy s
} else {
destroy r
}
}
}

access(all) contract Impl {
access(all) resource Vault: Burner.Burnable {
access(contract) fun burnCallback()

access(all) fun callBurnCallback() {
self.burnCallback() // IS THIS POSSIBLE?
}
}

init() {
let vault <- create Vault()
vault.callBurnCallback()
destroy vault

let vault2 <- create Vault()
Burner.burn(<-vault2)
}
}
Giovanni S
Giovanni S12mo ago
I believe its access is scoped to anything in the implementing contract Nvm I see what you're saying now
joshua
joshuaOP12mo ago
thats what I'm assuming. I tried this in the playground, but I got an unexpected error with no error message so I'm gonna try it somewhere else actually it looks like both worked that is kind of strange behavior feels like it should be either one or the other, not both I tested it with the init() method that I added to the implementation above
Giovanni S
Giovanni S12mo ago
I guess it makes sense if we think of access(contract) acts as internal? But I agree, it's kind of ambiguous
joshua
joshuaOP12mo ago
wait a sec, I also added this to the init function:
let vault3 <- create Vault()
vault3.burnCallback()
destroy vault3
let vault3 <- create Vault()
vault3.burnCallback()
destroy vault3
and it worked. that definitely shouldn't work, right?
Giovanni S
Giovanni S12mo ago
If vault3.burnCallback() is called from within Impl, I believe that makes sense since the method is defined in an inherited interface as access(contract)
joshua
joshuaOP12mo ago
oh yeah, you're right. I tried it in a transaction and it didn't work @jan.6550
Want results from more Discord servers?
Add your server