diff --git a/MAINTENANCE.MD b/MAINTENANCE.MD new file mode 100644 index 000000000..13f939c17 --- /dev/null +++ b/MAINTENANCE.MD @@ -0,0 +1,307 @@ +# Soroban Target Maintenance Policy + +This document defines the maintenance and compatibility expectations for the Soroban target. + +## Status + +The Soroban target is currently considered **experimental**. + +This means: + +- the target is actively maintained +- core functionality is expected to work for supported features +- some language features and platform integrations are not supported or may still change +- breaking changes may occur when required by correctness, upstream Soroban changes, or architectural improvements + +Experimental does **not** mean unmaintained. It means the support surface is explicitly scoped and evolves with the platform. + +--- + +## Goals + +The Soroban backend aims to: + +- make Soroban more accessible to Solidity developers +- document all meaningful deviations from `solc` and from EVM behavior +- evolve alongside the Soroban platform in a predictable way + +--- + +## Non-Goals + +The Soroban backend does not currently guarantee: + +- full Solidity language parity with `solc` +- identical runtime semantics to the EVM + +--- + +## Support Levels + +Each Soroban-related feature falls into one of three categories. + +### Supported + +A feature marked **Supported**: + +- is covered by automated tests +- is documented +- is expected to remain stable across patch releases + +### Experimental + +A feature marked **Experimental**: + +- is available for use +- may have incomplete edge-case coverage +- may be removed or redesigned if needed + +### Unsupported + +A feature marked **Unsupported**: + +- is not intended to work on Soroban +- must not silently compile into incorrect behavior + +--- + +## Compatibility Policy + +This policy defines maintenance expectations. The detailed compatibility behavior is documented in the published Solang docs. + +Soroban compatibility expectations are divided into two scopes: + +- Solidity language compatibility +- Solang and Soroban Rust SDK differences + +This section does not define guarantees for Soroban protocol-version compatibility or tooling-version compatibility. + +The detailed compatibility documentation lives in the published Solang docs: + +- [Soroban Solidity Language Compatibility](https://solang.readthedocs.io/en/latest/targets/soroban_language_compatibility.html) +- [Solang and Soroban Rust SDK Differences](https://solang.readthedocs.io/en/latest/targets/soroban_rust_sdk_differences.html) + +### Solidity Language Compatibility + +Authoritative docs: [Soroban Solidity Language Compatibility](https://solang.readthedocs.io/en/latest/targets/soroban_language_compatibility.html) + +Solang aims for source-level Solidity familiarity, not EVM equivalence. + +This includes language features and semantics such as: + +- types +- structs +- arrays +- mappings +- function behavior +- authentication-related language differences from standard Solidity usage + +Examples include differences such as Soroban host-based authorization flows, where authentication is performed through Soroban auth mechanisms rather than typical Solidity or EVM patterns like direct `msg.sender` checks. + +Where Soroban differs from normal Solidity or from EVM assumptions, Solang will prefer one of the following: + +- document the difference +- emit a warning +- reject the construct + +Silent semantic mismatches should be treated as bugs. + +### Solang and Soroban Rust SDK Differences + +Authoritative docs: [Solang and Soroban Rust SDK Differences](https://solang.readthedocs.io/en/latest/targets/soroban_rust_sdk_differences.html) + +Solang also documents where its Soroban implementation differs from common patterns used by the Rust SDK. + +This includes differences such as: + +- storage layout and key structure for contract state +- representation of arrays and vectors in storage, including `VecObject`-backed layouts +- representation of structs and nested values in storage +- host object and handle conventions needed to interact with Soroban contracts written in Rust + +Examples include differences or compatibility requirements around storage representation, such as arrays of native types being stored through `VecObject` handles, and structs or arrays of structs being represented through composite storage keys rather than EVM-style slot packing. + +This scope is about documented differences in representation and implementation choices. +It is not a general guarantee of raw storage compatibility. + +When Solang uses a different layout or access pattern than a Rust SDK contract would typically use, that difference should be documented clearly. +Undocumented mismatches in documented areas should be treated as bugs. + +--- + +## Release Policy + +### Patch Releases + +Patch releases may include: + +- bug fixes +- diagnostic improvements +- documentation improvements +- non-breaking test and tooling updates +- correctness fixes for clearly incorrect existing behavior + +Patch releases should not intentionally introduce new breaking Soroban semantics unless the current behavior is wrong and keeping it would be more harmful. + +### Minor Releases + +Minor releases may include: + +- new Soroban features +- Soroban backend refactors +- changes required by upstream protocol or tooling evolution +- breaking changes, with migration notes + +Every Soroban-breaking change in a minor release should include: + +- a short description of the change +- the reason for the change +- who is affected +- migration guidance where applicable + +--- + +## Upstream Change Handling + +When Soroban platform changes occur, maintainers should classify them as one of: + +- no action needed +- tooling-only update +- compiler/runtime behavior update required +- breaking change requiring user migration + +Protocol upgrades and upstream breaking changes take priority over new feature work. + +--- + +## Testing Requirements + +A Soroban feature should not be considered Supported unless it is covered by tests appropriate to its risk. + +The Soroban CI suite should include, where applicable: + +- compile-time tests +- negative tests for unsupported constructs +- runtime tests against a local Soroban environment +- regression tests for prior bugs +- integration tests for common contract patterns + +Priority test areas include: + +- storage behavior +- contract initialization +- authorization/auth-related behavior +- cross-contract calls +- ABI/spec generation and decoding expectations +- integer and data-layout correctness +- failure/revert/error behavior where relevant + +Every confirmed Soroban bug should add a regression test when feasible. + +--- + +## Bug Triage Priorities + +### P0 — Critical + +Examples: + +- miscompilation +- security-sensitive incorrect behavior +- incorrect authorization behavior +- incorrect storage behavior +- breakage caused by Soroban protocol/tooling upgrades + +These issues should take precedence over feature development. + +### P1 — High + +Examples: + +- valid Soroban-target contracts rejected unexpectedly +- major supported feature broken +- deployment/invocation workflow broken + +### P2 — Normal + +Examples: + +- diagnostics quality +- missing warnings +- documentation gaps +- edge-case issues in experimental areas + +--- + +## Documentation Requirements + +Soroban behavior should be documented in a way users can rely on. + +At minimum, the project should maintain: + +- a Soroban compatibility matrix +- a list of unsupported features +- a list of known differences from `solc` / EVM expectations +- migration notes for breaking changes +- examples for supported Soroban workflows + +If a feature is not documented and not tested, it should not be treated as stable. + +--- + +## Deprecation Policy + +When support is planned to be removed for: + +- a protocol version +- a tooling version +- a Soroban-specific feature shape +- an experimental interface + +the project should communicate this in advance whenever feasible through: + +- release notes +- migration notes +- warnings in docs and/or compiler diagnostics where appropriate + +Immediate removals may still occur if required by correctness or upstream incompatibility. + +--- + +## Definition of Production Readiness + +The Soroban target should only be described as production-ready when all of the following are true: + +- a compatibility matrix exists and is maintained +- core supported features have stable regression coverage +- at least one full upstream protocol transition has been handled cleanly +- no known critical miscompilation bugs remain open in supported areas +- major behavioral differences are documented +- users have a clear upgrade and migration path + +Until then, users should treat the Soroban target as suitable for experimentation, prototyping, evaluation, and controlled pilots. + +--- + +## Maintainer Expectations + +The Soroban backend should have: + +- at least one named primary maintainer +- at least one backup reviewer familiar with the target +- a release checklist for Soroban-affecting changes + +Ownership is required for the policy to be meaningful. + +--- + +## Summary + +In short, the Soroban target is maintained with the following principles: + +- correctness over feature count +- explicit support levels +- clear compatibility boundaries +- fast reaction to upstream Soroban changes +- no silent incorrect behavior +- documented breaking changes diff --git a/README.md b/README.md index 29cd3a157..852073a70 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,12 @@ stellar contract invoke --network testnet --id CDGUMUXA6IRRVMMKIVQJWLZZONDXBJ4AI ℹ️ Signing transaction: e0d68ae85bfbe0fceed8bcadd6613e12b3159f27dbf7c18e35e94de2b4a11ee2 ``` +For the current Soroban support matrix, see the +[`Soroban support matrix`](https://solang.readthedocs.io/en/latest/targets/soroban_support_matrix.html). +For Soroban compatibility details, see the +[`Soroban target docs`](https://solang.readthedocs.io/en/latest/targets/soroban.html). +The repository-level Soroban maintenance policy lives in [`MAINTENANCE.MD`](MAINTENANCE.MD). + ## Tentative roadmap diff --git a/docs/targets/soroban.rst b/docs/targets/soroban.rst index 6c51870c8..f96e3dc83 100644 --- a/docs/targets/soroban.rst +++ b/docs/targets/soroban.rst @@ -1,115 +1,42 @@ Soroban ======== -.. note:: - Soroban target is currently in Pre-Alpha stage, a lot of features are not yet implemented. - You can find supported examples in the `examples directory `_. +.. toctree:: + :maxdepth: 1 + :hidden: -Soroban is the smart contracts platform on the Stellar network. The soroban environment is an interface that exposes the blockchain's facilities to the contract, such as the ability to read and write to the ledger, send and receive payments, and access account information. + soroban_support_matrix + soroban_examples_coverage + soroban_language_compatibility + soroban_rust_sdk_differences -The environment has two sides: `Host and Guest `_. Code in the host environment implements the environment interface; code in the guest environment uses the environment interface. +.. note:: + The Soroban target is still pre-alpha. -The guest environment is an isolated WASM virtual machine, which means that smart contracts should constitue of a WASM module which may contain calls to the host environment. +Solang can compile Solidity contracts for the Soroban smart contract platform on Stellar. +The Soroban target is already useful for a growing subset of contracts, but it is not yet feature-complete. -Values communicated between the contract WASM code and the host environment are all encoded as soroban `Vals`. A `Val` is a unsigned 64-bit integer, with a tag the represents the type of the Val. For cases where the type does not fir in the 64-bit integer, the Val contains a pointer to the data in the host environment. +Documentation ++++++++++++++ -`CAP-0046-1 `_ goes into more detail about the Soroban environment and how it works. +The Soroban documentation is split into the following sections: +- `Soroban support matrix `_ for the current supported and unsupported feature set +- `Soroban examples coverage `_ for upstream `stellar/soroban-examples` coverage and the corresponding Solang Solidity examples +- `Soroban Solidity language compatibility `_ for Solidity on EVM language differences i.e authorizations syntax. +- `Solang and Soroban Rust SDK differences `_ for differences between Solang and Soroban Rust SDK i.e storage layout. +For the upstream Rust examples themselves, see `stellar/soroban-examples `_. +Status +++++++ +The Soroban target is experimental. It is usable for a documented subset of Solidity contracts, but it is not yet feature-complete or production-ready. See the `Soroban support matrix `_. -Solidity for Soroban: changes to note -+++++++++++++++++++++++++++++++++++++ - - - - - -Authentication and Authorization -________________________________ - -Authentication in Solidity is mostly done using the `msg.sender` variable, which contains the address of the caller. In Soroban, this is not available, and instead, the contract authorizes the caller by an invokation of `multiple host functions `_ which take an `Address` as an argument. - -For example, this is a simple contract that only allows the owner to call the `set` function: - -.. code-block:: solidity - - pragma solidity ^0.8.20; - - contract OnlyOwner { - address owner; - uint - - constructor() { - owner = msg.sender; - } - - function set(uint256 value) public { - require(msg.sender == owner, "Only owner can call this function"); - // Set the value - } - } - - -In Soroban, this would be written as: - -.. code-block:: solidity - - contract auth { - - address public owner; - uint64 public counter; - - constructor(address _owner) public { - owner = _owner; - } - - function increment() public returns (uint64) { - - owner.requireAuth(); - - counter = counter + 1; - - return counter; - } - } - - - -The `requireAuth()` Builtin function will result in a host function call to the Soroban host environment, which will check if the caller is the owner of the contract. If not, the contract will revert. - - - -Storage Types -______________ - -In Soroban, there exists `three storage types: Persistent, Temporary and Instance `_. -You can specify the storage type of a variable by using the `persistent`, `temporary` or `instance` keyword before the variable type. - -.. code-block:: solidity - - contract storage_types { - - uint64 public temporary counter = 1; - uint64 public instance counter1 = 1; - uint64 public persistent counter2 = 2; - uint64 public counter3 = 2; - - function inc() public { - counter++; - counter1++; - counter2++; - counter3++; - } - - function dec() public { - counter--; - counter1--; - counter2--; - counter3--; - } - } - +Developers should rely on the support matrix and compatibility pages for the current documented behavior. +Background +++++++++++ +Soroban contracts run as Wasm modules and communicate with the Soroban host through Soroban ``Val`` values and host objects. +For platform background, see `Host and Guest `_ and `CAP-0046-1 `_. diff --git a/docs/targets/soroban_examples_coverage.rst b/docs/targets/soroban_examples_coverage.rst new file mode 100644 index 000000000..2b9175b6f --- /dev/null +++ b/docs/targets/soroban_examples_coverage.rst @@ -0,0 +1,186 @@ +Soroban Examples Coverage +========================= + +This page maps upstream examples from `stellar/soroban-examples `_ to documented Solang Solidity examples or coverage in this repository. + +The table below only includes upstream examples for which this repository currently has a clear Solidity counterpart or nearest documented coverage example. Absence from this table does not prove that an upstream example is impossible in Solang; it means there is not yet a documented counterpart in this repository. + +For the current feature-oriented support status, see :doc:`soroban_support_matrix`. + +Documented Counterparts ++++++++++++++++++++++++ + +.. list-table:: + :header-rows: 1 + + * - Upstream Rust example + - Solang Solidity example or coverage + - Notes + * - `alloc `_ + - `tests/soroban_testcases/alloc.rs `_ + - Covered by Solidity testcases for dynamic memory arrays, including vector allocation, ``push()``, iteration, and summation. + * - `atomic_swap `_ + - `docs/examples/soroban/atomic_swap `_ + - Atomic swap between two parties, with companion token contracts. + * - `atomic_multiswap `_ + - `docs/examples/soroban/atomic_swap `_ and `tests/soroban_testcases/alloc.rs `_ + - Closest documented Solang coverage is the atomic-swap example plus array and loop support used for batching-style logic. A dedicated standalone Solidity multiswap example is not yet present in this repository. + * - `auth `_ + - `docs/examples/soroban/auth.sol `_ + - Simple host-managed authorization via ``requireAuth()``. + * - `cross_contract `_ + - `integration/soroban/caller.sol `_ and `integration/soroban/callee.sol `_ + - Covered in `cross_contract.spec.js `_. + * - `deep_contract_auth `_ + - `docs/examples/soroban/deep_auth `_ + - Nested contract authorization via ``authAsCurrContract(...)``. + * - `hello_world `_ + - `integration/soroban/callee.sol `_ + - Closest local Solidity counterpart for a minimal callable contract. Solang does not currently ship a string-vector hello-world example with the same interface. + * - `increment `_ + - `integration/soroban/counter.sol `_ + - Closest local counterpart for a stored counter that can be incremented. + * - `liquidity_pool `_ + - `docs/examples/soroban/liquidity_pool `_ + - Liquidity-pool and token-swap example with companion token contracts. + * - `logging `_ + - `docs/examples/soroban/error.sol `_ + - Demonstrates ``print()``-based runtime logging in Solang. + * - `timelock `_ + - `docs/examples/soroban/timelock `_ + - Timelock-style example using enums, mappings, authorization, and ``block.timestamp``. + * - `token `_ + - `docs/examples/soroban/token.sol `_ + - Token-style contract with balances, allowances, and Soroban auth. + * - `ttl `_ + - `docs/examples/soroban/ttl_storage.sol `_ + - Extending TTL on stored contract data. + +Solidity Translations ++++++++++++++++++++++ + +The following abridged snippets show how selected upstream Soroban examples are expressed in Solang Solidity. + +auth +^^^^ + +Upstream Soroban example: `auth `_ + +Solang Solidity example: `docs/examples/soroban/auth.sol `_ + +.. code-block:: solidity + + contract auth { + address public owner = + address"GDRIX624OGPQEX264NY72UKOJQUASHU3PYKL6DDPGSTWXWJSBOTR6N7W"; + + uint64 public instance counter = 20; + + function increment() public returns (uint64) { + owner.requireAuth(); + counter = counter + 1; + return counter; + } + } + +token +^^^^^ + +Upstream Soroban example: `token `_ + +Solang Solidity example: `docs/examples/soroban/token.sol `_ + +.. code-block:: solidity + + contract token { + address public admin; + mapping(address => int128) public balances; + + constructor(address _admin, string memory _name, string memory _symbol, uint32 _decimals) { + admin = _admin; + } + + function mint(address to, int128 amount) public { + require(amount >= 0, "Amount must be non-negative"); + admin.requireAuth(); + balances[to] = balances[to] + amount; + } + + function transfer(address from, address to, int128 amount) public { + from.requireAuth(); + balances[from] = balances[from] - amount; + balances[to] = balances[to] + amount; + } + } + +timelock +^^^^^^^^ + +Upstream Soroban example: `timelock `_ + +Solang Solidity example: `docs/examples/soroban/timelock/timelock.sol `_ + +.. code-block:: solidity + + contract timelock { + enum TimeBoundKind { Before, After } + + struct TimeLock { + TimeBoundKind kind; + uint64 bound_timestamp; + address claimant; + uint64 amount; + } + + mapping(address => TimeLock) public timelocks; + + function is_claimable(address claimant) public view returns (bool) { + TimeLock storage tl = timelocks[claimant]; + return block.timestamp >= tl.bound_timestamp; + } + } + +ttl +^^^ + +Upstream Soroban example: `ttl `_ + +Solang Solidity example: `docs/examples/soroban/ttl_storage.sol `_ + +.. code-block:: solidity + + contract ttl_storage { + uint64 public persistent pCount = 11; + uint64 temporary tCount = 7; + uint64 instance iCount = 3; + + function extend_persistent_ttl() public view returns (int64) { + return pCount.extendTtl(1000, 5000); + } + + function extend_temp_ttl() public view returns (int64) { + return tCount.extendTtl(3000, 7000); + } + } + +Upstream Examples Not Yet Documented as Supported ++++++++++++++++++++++++++++++++++++++++++++++++++ + +The following upstream examples do not currently have a documented Solidity counterpart, as some needed Soroban features are not yet supported. +- `bls_signature `_ +- `custom_types `_ +- `deployer `_ +- `errors `_ +- `eth_abi `_ +- `events `_ +- `fuzzing `_ +- `merkle_distribution `_ +- `mint-lock `_ +- `other_custom_types `_ +- `privacy-pools `_ +- `simple_account `_ +- `single_offer `_ +- `upgradeable_contract `_ +- `workspace `_ + +Want to add support for one of the remaining examples? Open a pull request against `hyperledger-solang/solang `_ and follow the `contribution guide `_. diff --git a/docs/targets/soroban_language_compatibility.rst b/docs/targets/soroban_language_compatibility.rst new file mode 100644 index 000000000..119a8d78a --- /dev/null +++ b/docs/targets/soroban_language_compatibility.rst @@ -0,0 +1,151 @@ +Soroban Solidity Language Compatibility +======================================= + +This page documents the Solidity-facing compatibility expectations for the Soroban target. +It focuses on source-level language behavior: how Solidity constructs map to Soroban, where behavior differs from normal EVM expectations, and which Soroban-specific constructs developers should expect to use. + +This page is about language compatibility, not storage-layout differences. For Solang-specific storage representation and differences from common Rust SDK patterns, see :doc:`soroban_rust_sdk_differences`. + +Source-Level Compatibility +++++++++++++++++++++++++++ + +Solang aims for source-level Solidity familiarity on Soroban, not EVM equivalence. + +In practice, that means: + +- familiar Solidity syntax should compile where the Soroban backend supports it +- Solang may warn on Soroban-specific constraints rather than silently changing behavior +- when Soroban cannot support a construct safely, Solang should reject it rather than compile incorrect semantics + +The current supported and unsupported feature set is tracked on :doc:`soroban_support_matrix`. + +Authorization Model ++++++++++++++++++++ + +The clearest Solidity-language difference on Soroban is authorization. + +On EVM chains, access control is often written in terms of ``msg.sender``. Soroban does not expose authorization through ``msg.sender`` in the same way. Instead, authorization is performed by the Soroban host for a specific ``address``. + +An EVM-style ownership check often looks like this: + +.. code-block:: solidity + + pragma solidity ^0.8.20; + + contract OnlyOwner { + address owner; + + constructor() { + owner = msg.sender; + } + + function set(uint256 value) public { + require(msg.sender == owner, "Only owner can call this function"); + } + } + +On Soroban, the same intent should be written using ``requireAuth()`` on the address that must authorize the call: + +.. code-block:: solidity + + contract auth { + address public owner; + uint64 public counter; + + constructor(address _owner) public { + owner = _owner; + } + + function increment() public returns (uint64) { + owner.requireAuth(); + counter = counter + 1; + return counter; + } + } + +The ``requireAuth()`` builtin calls into the Soroban host, which verifies that the address authorized the invocation. This is the Soroban-native pattern developers should expect to use instead of direct ``msg.sender`` comparisons. + +For deeper authorization chains that pass through another contract, Solang also supports ``auth.authAsCurrContract(...)``. See: + +- the `deep auth example `_ +- `docs/examples/soroban/auth.sol `_ +- `tests/soroban_testcases/auth.rs `_ + +Storage Classes and Lifetime +++++++++++++++++++++++++++++ + +Soroban has `three storage types: Persistent, Temporary and Instance `_. +Solang exposes these directly in the language with Soroban-only storage class keywords: + +- ``persistent`` +- ``temporary`` +- ``instance`` + +For example: + +.. code-block:: solidity + + contract storage_types { + uint64 public temporary var = 1; + uint64 public instance var1 = 1; + uint64 public persistent var2 = 2; + uint64 public var3 = 2; + + function inc() public { + var++; + var1++; + var2++; + var3++; + } + } + +If no storage class is written, the variable defaults to persistent storage. + +This is a Soroban-specific language extension rather than standard Solidity behavior. Developers should treat it as part of the Soroban target surface, not portable Solidity syntax. + +Related Soroban-only lifetime helpers are available through builtins such as ``extendTtl(...)`` and ``extendInstanceTtl(...)``. See :doc:`../language/builtins` and: + +- `docs/examples/soroban/storage_types.sol `_ +- `docs/examples/soroban/ttl_storage.sol `_ +- `tests/soroban_testcases/ttl.rs `_ + +Types, Structs, Arrays, and Mappings +++++++++++++++++++++++++++++++++++++ + +The Soroban backend supports a growing subset of Solidity types and compound constructs, including the tested use of: + +- primitive types such as ``bool``, ``address``, ``string``, ``uint32``, ``uint64``, ``int32``, ``int64``, ``int128``, ``uint128``, ``uint256``, and ``int256`` +- structs in storage +- mappings and nested mappings +- memory arrays and storage arrays + +These are Solidity-facing language features, but some of their behavior is constrained by Soroban's host representation and storage model. +For the storage and representation side of those features, see :doc:`soroban_rust_sdk_differences`. + +Current documented support is summarized on :doc:`soroban_support_matrix`. + +Integer Widths +++++++++++++++ + +Soroban only natively supports integer widths ``32``, ``64``, ``128``, and ``256``. +When a contract uses another integer width, Solang rounds the width up to the next supported Soroban size: + +- ``1..=32`` becomes ``32`` +- ``33..=64`` becomes ``64`` +- ``65..=128`` becomes ``128`` +- ``129..=256`` becomes ``256`` + +By default, this produces a warning. If you compile with ``--strict-soroban-types``, the same cases become compilation errors instead. + +This is another case where Solang preserves Solidity source compatibility where practical, but makes the Soroban-specific constraint visible rather than silently pretending arbitrary integer widths are native to the runtime. + +Current Expectation ++++++++++++++++++++ + +When writing Solidity for Soroban, developers should expect: + +- Solidity-like syntax where supported +- explicit Soroban-specific language differences where the runtime requires them +- warnings or rejections instead of silent mismatches + +For the current support matrix, see :doc:`soroban_support_matrix`. diff --git a/docs/targets/soroban_rust_sdk_differences.rst b/docs/targets/soroban_rust_sdk_differences.rst new file mode 100644 index 000000000..01ff672b0 --- /dev/null +++ b/docs/targets/soroban_rust_sdk_differences.rst @@ -0,0 +1,87 @@ +Solang and Soroban Rust SDK Differences +======================================= + +This page documents how Solang represents Solidity contracts on Soroban, and how that representation differs from common patterns used by the Soroban Rust SDK. + +It focuses on data representation and storage layout. + +For Solidity-facing language differences such as authorization syntax or Soroban storage class keywords, see :doc:`soroban_language_compatibility`. + +Summary ++++++++ + +Solang and the Soroban Rust SDK target the same platform, but they do not necessarily use the same internal representations. + +On Soroban, Solang uses a compiler-defined storage model for Solidity state. Arrays, structs, and nested values are lowered according to Solang's code generation strategy, not according to any Rust SDK storage convention. Developers should rely on documented Solang behavior and should not assume raw storage compatibility with handwritten Rust SDK contracts unless that layout is explicitly documented. + +Storage Layout Overview ++++++++++++++++++++++++ + +Solang does not use EVM slot packing on Soroban. +Instead, it lowers Solidity state into Soroban storage using compiler-defined keys and Soroban host values. + +The right mental model is: + +- Soroban storage classes choose the ledger namespace: persistent, temporary, or instance +- Solang chooses how a Solidity variable, struct field, or array element is represented within that storage +- documented Solang behavior is what developers should rely on, not assumptions about a Rust SDK contract's internal layout + +Arrays in Storage ++++++++++++++++++ + +For arrays of native value types, Solang uses a ``VecObject``-backed storage model. + +In current Soroban code generation, storage array operations: + +- load the stored ``VecObject`` handle from contract storage +- apply the relevant vector operation +- write the resulting handle back to storage + +This is closer to Soroban's host vector model than to EVM-style contiguous slot arithmetic. + +Relevant examples and implementation references: + +- `atomic_swap `_ +- `liquidity_pool `_ +- `src/emit/soroban/target.rs `_ + +Structs in Storage +++++++++++++++++++ + +Struct storage is also Soroban-specific. + +Rather than packing a whole struct into a single EVM-like storage region, Solang encodes struct fields as Soroban values and stores fields separately under composite keys derived from the struct's storage slot and field position. + +As a consequence: + +- reading a single field can be relatively direct +- reading a whole struct requires loading each stored field and reconstructing the struct in memory +- full-struct loads are more expensive than field-level access + +Relevant examples: + +- `timelock.sol `_ +- `liquidity_pool.sol `_ + +Nested Values and Composite Keys +++++++++++++++++++++++++++++++++ + +Arrays of custom types, including arrays of structs, follow a sparse storage approach. + +The important point is that nested values are not stored like flat EVM slot ranges. Instead, the storage key tracks access structure. In current Solang Soroban support, that means: + +- the first part of the key identifies the Solidity storage slot +- later parts of the key identify field positions or indexes within the nested access path + +This layout is chosen to make nested mutation practical on Soroban, but it also means developers should not assume Rust SDK-like or EVM-like key shapes unless Solang explicitly documents them. + +What Developers Should Not Assume ++++++++++++++++++++++++++++++++++ + +When comparing Solang with handwritten Rust SDK contracts, developers should not assume: + +- identical raw storage keys +- identical internal layouts for arrays, structs, or nested values +- safe direct reads or writes across Solidity and Rust contracts at the raw storage level unless the layout is explicitly documented + +For the current target status and support matrix, see :doc:`soroban_support_matrix`. diff --git a/docs/targets/soroban_support_matrix.rst b/docs/targets/soroban_support_matrix.rst new file mode 100644 index 000000000..a6e20d00f --- /dev/null +++ b/docs/targets/soroban_support_matrix.rst @@ -0,0 +1,87 @@ +Soroban Support Matrix +====================== + +This page is the documentation for feature support status on the Soroban target. + +This support matrix documents the Soroban features Solang currently intends to support. It should be read as a statement of documented target behavior, not as a claim of exhaustive coverage. Stronger completeness claims would require broader automated validation, such as fuzzing and differential testing, and that work is still in progress. + +The Soroban target as a whole is still pre-alpha and experimental. + +Related documentation: + +.. list-table:: + :header-rows: 1 + + * - Page + - Purpose + * - :doc:`soroban_examples_coverage` + - Upstream `stellar/soroban-examples` coverage and the corresponding Solang Solidity examples. + * - :doc:`soroban_language_compatibility` + - Solidity-facing differences and Soroban-specific language behavior. + * - :doc:`soroban_rust_sdk_differences` + - Storage layout, host-value representation, and differences from common Rust SDK patterns. + +Language Features ++++++++++++++++++ + +.. list-table:: + :header-rows: 1 + + * - Feature area + - Status + - Details and examples + * - Contract model + - Supported + - Constructors with arguments, public functions, and public getters. Examples: `token.sol `_, `timelock.sol `_, and `storage_types.sol `_. + * - Core types and collections + - Supported + - Primitive types, ``uint256`` and ``int256``, documented struct shapes, mappings and nested mappings, and memory/storage arrays. Examples: `token.sol `_, `timelock.sol `_, `liquidity_pool.sol `_, `atomic_swap `_, and `liquidity_pool `_. + * - Events and logs + - Partially supported + - ``print()`` and runtime error logging are available. Solidity events are not. Example: `error.sol `_. + * - Complex user-defined and composite types + - Partial support + - Coverage is still limited. More complex user-defined types and deeper composite values, such as nested structs, might not compile in some cases. + * - Yul and inline assembly + - Unsupported + - Not supported on the Soroban target. + * - Solidity hash and crypto builtins + - Unsupported + - Not yet supported on the Soroban target. + +The exact Solidity support boundary can only be characterized with broader fuzzing and related validation, and that work is still in progress. + +If you run into a missing Solidity feature on Soroban, please `open an issue `_. + +Soroban Features +++++++++++++++++ + +.. list-table:: + :header-rows: 1 + + * - Feature area + - Status + - Details and examples + * - Authorization + - Supported + - ``address.requireAuth()`` and ``auth.authAsCurrContract(...)``. Examples: `auth.sol `_, `token.sol `_, `timelock.sol `_, and `deep_auth `_. + * - Cross-contract calls + - Supported + - ``address.call(...)`` and the documented ABI encode/decode flows around it. Examples: `deep_auth `_ and `cross_contract.spec.js `_. + * - Storage classes and TTL + - Supported + - Storage classes ``persistent``, ``temporary``, and ``instance``, plus ``extendTtl(...)`` and ``extendInstanceTtl(...)``. Examples: `storage_types.sol `_ and `ttl_storage.sol `_. + * - Soroban utilities + - Supported + - ``block.timestamp``. Example: `timelock.sol `_. + * - Creating contracts with ``new`` + - Unsupported + - Contract creation from Solidity is not supported on Soroban. + * - Native value transfer and payable-style flows + - Unsupported + - This is not part of the documented Solang support surface on Soroban. + * - ``selfdestruct`` + - Unsupported + - Not supported on the Soroban target. + +Where a feature has target-specific behavior rather than being simply supported or unsupported, that behavior is documented in the compatibility pages linked above.