|
| 1 | +# Qubic.ContractGen |
| 2 | + |
| 3 | +A code generator that parses C++ smart contract headers from `qubic-core` and produces C# bindings for use with `Qubic.Core`. |
| 4 | + |
| 5 | +## What It Does |
| 6 | + |
| 7 | +Reads the C++ header files in `deps/qubic-core/src/contracts/` and generates one `.g.cs` file per contract into `src/Qubic.Core/Contracts/Generated/`. Each generated file contains: |
| 8 | + |
| 9 | +- A static contract class (e.g. `QxContract`, `QswapContract`) |
| 10 | +- Strongly-typed C# structs for every `_input` and `_output` pair |
| 11 | +- Correct field offsets matching MSVC `/Zp8` struct alignment |
| 12 | +- `Serialize()` / `Deserialize()` methods on each struct for binary round-tripping |
| 13 | +- Function and procedure metadata (ID, name, input/output types) |
| 14 | + |
| 15 | +## Supported Contracts |
| 16 | + |
| 17 | +| Index | Name | Header | |
| 18 | +|-------|------|--------| |
| 19 | +| 1 | Qx | Qx.h | |
| 20 | +| 2 | Quottery | Quottery.h | |
| 21 | +| 3 | Random | Random.h | |
| 22 | +| 4 | Qutil | QUtil.h | |
| 23 | +| 5 | Mlm | MyLastMatch.h | |
| 24 | +| 6 | Gqmprop | GeneralQuorumProposal.h | |
| 25 | +| 7 | Swatch | SupplyWatcher.h | |
| 26 | +| 8 | Ccf | ComputorControlledFund.h | |
| 27 | +| 9 | Qearn | Qearn.h | |
| 28 | +| 10 | Qvault | QVAULT.h | |
| 29 | +| 11 | Msvault | MsVault.h | |
| 30 | +| 12 | Qbay | Qbay.h | |
| 31 | +| 13 | Qswap | Qswap.h | |
| 32 | +| 14 | Nost | Nostromo.h | |
| 33 | +| 15 | Qdraw | Qdraw.h | |
| 34 | +| 16 | Rl | RandomLottery.h | |
| 35 | +| 17 | Qbond | QBond.h | |
| 36 | +| 18 | Qip | QIP.h | |
| 37 | +| 19 | Qraffle | QRaffle.h | |
| 38 | +| 20 | Qrwa | qRWA.h | |
| 39 | +| 21 | Qrp | QReservePool.h | |
| 40 | +| 22 | Qtf | QThirtyFour.h | |
| 41 | +| 23 | Qduel | QDuel.h | |
| 42 | + |
| 43 | +## Usage |
| 44 | + |
| 45 | +```bash |
| 46 | +# Run from the repo root (auto-detects paths) |
| 47 | +dotnet run --project tools/Qubic.ContractGen |
| 48 | + |
| 49 | +# Or pass the repo root explicitly |
| 50 | +dotnet run --project tools/Qubic.ContractGen -- /path/to/Qubic.Net |
| 51 | +``` |
| 52 | + |
| 53 | +Output: |
| 54 | + |
| 55 | +``` |
| 56 | +Headers: /path/to/Qubic.Net/deps/qubic-core/src/contracts |
| 57 | +Output: /path/to/Qubic.Net/src/Qubic.Core/Contracts/Generated |
| 58 | +
|
| 59 | + [01] Qx OK (5 functions, 7 procedures) |
| 60 | + [02] Quottery OK (5 functions, 4 procedures) |
| 61 | + ... |
| 62 | +
|
| 63 | +Generated 22 files, skipped 1. |
| 64 | +``` |
| 65 | + |
| 66 | +## Prerequisites |
| 67 | + |
| 68 | +- .NET 8.0 SDK |
| 69 | +- The `qubic-core` git submodule must be initialized: |
| 70 | + ```bash |
| 71 | + git submodule update --init |
| 72 | + ``` |
| 73 | + |
| 74 | +## Architecture |
| 75 | + |
| 76 | +``` |
| 77 | +Qubic.ContractGen/ |
| 78 | + Program.cs # Entry point, contract registry, orchestration |
| 79 | + Parsing/ |
| 80 | + CppHeaderParser.cs # C++ header lexer/parser |
| 81 | + ContractModel.cs # Intermediate representation (functions, structs, fields) |
| 82 | + TypeMapper.cs # C++ → C# type mapping with alignment info |
| 83 | + Generation/ |
| 84 | + CSharpEmitter.cs # IR → C# code emitter with MSVC /Zp8 layout |
| 85 | +``` |
| 86 | + |
| 87 | +### Parsing Pipeline |
| 88 | + |
| 89 | +1. **CppHeaderParser** reads the `.h` file and extracts the contract's main struct (e.g. `struct QX : public ContractBase`) |
| 90 | +2. Finds all `_input` / `_output` struct pairs and matches them to functions (read-only) or procedures (state-changing) |
| 91 | +3. Resolves typedefs (including contract-internal ones like `typedef Array<Order, 256> OrdersArray`) |
| 92 | +4. Handles nested structs, `Array<T,N>` templates, and `id` (32-byte public key) types |
| 93 | + |
| 94 | +### Code Generation |
| 95 | + |
| 96 | +- **CSharpEmitter** walks the parsed model and produces idiomatic C# with: |
| 97 | + - `[StructLayout]` attributes where useful |
| 98 | + - Manual field offset computation matching MSVC `/Zp8` rules (min of field alignment, 8) |
| 99 | + - `BinaryPrimitives` for little-endian serialization |
| 100 | + - Proper handling of `byte[]` arrays, nested struct arrays, and padding bytes |
0 commit comments