-
Notifications
You must be signed in to change notification settings - Fork 115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Upgradeable Contracts #1578
Comments
Decoupling Code and StateCurrently, a contract's state space is prefixed by its address. flowchart TD
State(Global State)
ContractA("Contract A Address")
ContractB("Contract B Address")
ContractC("Contract C Address")
StateA("Contract A State Space")
StateB("Contract B State Space")
StateC("Contract C State Space")
State --> ContractA
State --> ContractB
State --> ContractC
ContractA --> StateA
ContractB --> StateB
ContractC --> StateC
style State stroke:#f9f,stroke-width:4px
style ContractA stroke:#bbf,stroke-width:2px
style ContractB stroke:#bbf,stroke-width:2px
style ContractC stroke:#bbf,stroke-width:2px
style StateA stroke:#bfb,stroke-width:2px
style StateB stroke:#bfb,stroke-width:2px
style StateC stroke:#bfb,stroke-width:2px
The state space of a contract should be decoupled with its code. This way, contracts would have much greater flexibility in interacting with state, and offer a very clean and explicit interface for managing state access and ownership. StateSpace would become a property of contracts, with their own read/write/own permissions. Initially every contract would be instantiated with it's own state space, but would be able to move access and control as it pleases. flowchart TD
State(State)
Space1("State Space 0x1a2b")
Space2("State Space 0x3c4d")
Space3("State Space 0x5e6f")
State --> Space1
State --> Space2
State --> Space3
style State stroke:#f9f,stroke-width:4px
style Space1 stroke:#bbf,stroke-width:2px
style Space2 stroke:#bbf,stroke-width:2px
style Space3 stroke:#bbf,stroke-width:2px
classDiagram
%% Defining the classes
class ContractA {
StateSpace: 0x1a2b
}
class ContractB {
StateSpace: 0x3c4d
}
class ContractC {
StateSpace: 0x5e6f
}
class ContractD {
StateSpace: nil
}
class StateSpace {
owner: Address
writers: map[Address]bool
statePrefix: []byte
}
This design gives contracts much more flexibility regarding state access as contracts can share state and move ownership. A A lightweight implementation of this would expose one additional host function extern fn set_state_access(access: AccessControl)
enum AccessControl {
// gives `contract` write access to this contracts StateSpace
// calling contract must have ownership of its StateSpace
Write(Contract)
// moves ownership to `contract`,
// calling contract must have ownership,
Own(Contract)
// removes all access `contract` has to calling contract
Remove(Contract)
// delegates access control to `contract`
Delegate(Contract)
} Upgrading contracts are quite easy. Contract A
pub fn upgrade(new: Address) {
// validate caller & other logic...
// change owner
set_state_access(AccessControl::own(address))
}
Contract B
pub fn init(contractA: Address) {
// Allow contractA to move ownership to ContractB
set_state_access(AccessControl::delegate(contractA))
} In this example, |
@samliok, just to clarify, What about account balance? Is that something that both an owner and a writer can change or would that just be an owner. It might be helpful to add a small permissions table here |
Yep. |
🧵Discussion regarding upgradable contracts
The text was updated successfully, but these errors were encountered: