FuelLabs/sway-standards

SRC-11; Contract Factory Standard

bitzoic opened this issue · 0 comments

Motivation

Abstract

The following standard allows for the implementation of a standard ABI for Contract Factories using the Sway Language. The standardized design designates how verification of newly deployed child contracts are handled.

Motivation

A standard interface for Contract Factories provides a safe and effective method of ensuring contracts can verify the validity of another contract as a child of a factory. This is critical on the Fuel Network as contracts cannot deploy other contracts and verification must be done after deployment.

Prior Art

A Contract Factory is a design where a template contract is used and deployed repeatedly with different configurations. These configurations are often minor changes such as pointing to a different asset. All base functionality remains the same.

On Fuel, contracts cannot deploy other contracts. As a result, a Contract Factory on Fuel must register and verify that the bytecode root of a newly deployed child contract matches the expected bytecode root.

When changing something such as a configurable in Sway, the bytecode root is recalculated. As such any differences between child contracts must be made in storage and a constructor/initialization function is required. This issue investigates whether an opcode would allow for the verification of a child contract with differentiating configurable values.

Specification

The following functions MUST be implemented to follow the SRC-11; Contract Factory Standard:

Required Functions

- fn register_contract(child_contract: ContractId)

The register_contract() function verifies that a newly deployed contract is the child of a contract factory.

  • This function MUST verify that the bytecode root of the child_contract contract matches the expected bytecode root.
  • This function MAY add arbitrary conditions checking a contract factory child’s validity, such as verifying storage variables or initialized values.

- fn is_valid(child_contract: ContractId) -> bool

The is_valid() function returns a boolean representing the state of whether a contract is a valid child of the contract factory.

  • This function MUST return true if this is a valid child, otherwise false.

- fn factory_bytecode_root() -> Option<b256>

The factory_bytecode_root() function returns the bytecode root of the default template contract.

  • This function MUST return the bytecode root used to verify contracts against.

Optional Functions

The following are functions that may enhance the use of the SRC-11 standard but ARE NOT required. Function names MUST be followed, however function arguments MAY differentiate between contracts.

- fn get_contract(arguments: Bytes) -> Option<ContractId>

The get_contract() function will return a registered contract factory child contract with specific implementation details specified by arguments.

  • This function MUST return Some(ContractId) IF a contract that follows the specified arguments has been registered with the SRC-11 Contract Factory contract, otherwise None.

Rationale

The SRC-11; Contract Factory Standard is designed to standardize the contract factory design implementation interface between all Fuel instances.

Backwards Compatibility

There are no other standards that the SRC-11 requires compatibility.

Example ABI

abi SRC11 {
     #[storage(read, write)]
     fn register_contract(child_contract: ContractId);
     fn is_valid(child_contract: ContractId) -> bool;
     #[storage(read)]
     fn factory_bytecode_root() -> Option<b256>;
}

abi SRC11_Extension {
     fn get_contract(arguments: Bytes) -> ContractId;
}