Skip to content

Commit 8cf67e6

Browse files
committed
generated contract classes
1 parent 32e5b2a commit 8cf67e6

40 files changed

+13118
-6
lines changed

UPDATE_PLAN.md

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,19 @@ Each `REGISTER_USER_PROCEDURE(Name, ID)` maps to `public const ushort Name = ID;
8686

8787
---
8888

89-
## 7. Check struct sizes
89+
## 7. Regenerate smart contract types
90+
91+
```bash
92+
dotnet run --project tools/Qubic.ContractGen
93+
```
94+
95+
This parses all C++ contract headers in `deps/qubic-core/src/contracts/` and regenerates
96+
typed C# classes in `src/Qubic.Core/Contracts/Generated/`. Verify the output compiles
97+
and check for new warnings about unresolved types or array sizes.
98+
99+
---
100+
101+
## 8. Check struct sizes
90102

91103
If network structs changed, verify derived size constants in `QubicConstants.cs`:
92104
- `EntityRecordSize` (64) — `deps/qubic-core/src/network_messages/entity.h`
@@ -99,7 +111,7 @@ Also check if `Qubic.Serialization` readers/writers need updates.
99111

100112
---
101113

102-
## 8. Build and test
114+
## 9. Build and test
103115

104116
```bash
105117
dotnet build
@@ -108,7 +120,7 @@ dotnet test
108120

109121
---
110122

111-
## 9. Publish updated packages
123+
## 10. Publish updated packages
112124

113125
If `Qubic.Crypto` changed:
114126
1. Bump version in `src/Qubic.Crypto/Qubic.Crypto.csproj`
@@ -129,5 +141,6 @@ Then for `Qubic.Core`:
129141
| `src/network_messages/common_def.h` | `QubicConstants.cs` |
130142
| `src/network_messages/network_message_type.h` | `NetworkMessageTypes.cs` |
131143
| `src/contract_core/contract_def.h` | `QubicContracts.cs` |
132-
| `src/contracts/Qx.h` | `QxProcedures.cs` |
133-
| `src/contracts/QUtil.h` | `QutilProcedures.cs` |
144+
| `src/contracts/Qx.h` | `QxProcedures.cs` (obsolete) |
145+
| `src/contracts/QUtil.h` | `QutilProcedures.cs` (obsolete) |
146+
| `src/contracts/*.h` | `Contracts/Generated/*.g.cs` (via ContractGen) |
Lines changed: 346 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,346 @@
1+
// <auto-generated>
2+
// Generated by Qubic.ContractGen from ComputorControlledFund.h.
3+
// Do not edit manually. Re-run the generator after updating deps/qubic-core.
4+
// </auto-generated>
5+
6+
using System.Buffers.Binary;
7+
using Qubic.Core.Contracts;
8+
using Qubic.Core.Payloads;
9+
10+
namespace Qubic.Core.Contracts.Ccf;
11+
12+
/// <summary>Ccf contract (index 8).</summary>
13+
public static class CcfContract
14+
{
15+
/// <summary>Contract index on the Qubic network.</summary>
16+
public const int ContractIndex = 8;
17+
18+
/// <summary>Gets the 32-byte contract public key.</summary>
19+
public static byte[] GetPublicKey() => QubicContracts.GetContractPublicKey(ContractIndex);
20+
21+
/// <summary>Read-only query function IDs.</summary>
22+
public static class Functions
23+
{
24+
/// <summary>GetProposalIndices (inputType=1).</summary>
25+
public const uint GetProposalIndices = 1;
26+
/// <summary>GetProposal (inputType=2).</summary>
27+
public const uint GetProposal = 2;
28+
/// <summary>GetVote (inputType=3).</summary>
29+
public const uint GetVote = 3;
30+
/// <summary>GetVotingResults (inputType=4).</summary>
31+
public const uint GetVotingResults = 4;
32+
/// <summary>GetLatestTransfers (inputType=5).</summary>
33+
public const uint GetLatestTransfers = 5;
34+
/// <summary>GetProposalFee (inputType=6).</summary>
35+
public const uint GetProposalFee = 6;
36+
/// <summary>GetRegularPayments (inputType=7).</summary>
37+
public const uint GetRegularPayments = 7;
38+
}
39+
40+
/// <summary>State-mutating procedure IDs.</summary>
41+
public static class Procedures
42+
{
43+
/// <summary>SetProposal (inputType=1).</summary>
44+
public const uint SetProposal = 1;
45+
/// <summary>Vote (inputType=2).</summary>
46+
public const uint Vote = 2;
47+
}
48+
}
49+
50+
// ═══ Function: GetProposalIndices (inputType=1) ═══
51+
52+
/// <summary>Input for query.</summary>
53+
public readonly struct GetProposalIndicesInput : ISmartContractInput
54+
{
55+
public const int Size = 5;
56+
57+
public int SerializedSize => Size;
58+
59+
public bool ActiveProposals { get; init; }
60+
public int PrevProposalIndex { get; init; }
61+
62+
public byte[] ToBytes()
63+
{
64+
var bytes = new byte[Size];
65+
bytes.AsSpan(0, 1)[0] = (byte)(ActiveProposals ? 1 : 0);
66+
BinaryPrimitives.WriteInt32LittleEndian(bytes.AsSpan(1), PrevProposalIndex);
67+
return bytes;
68+
}
69+
}
70+
71+
/// <summary>Output.</summary>
72+
public readonly struct GetProposalIndicesOutput : ISmartContractOutput<GetProposalIndicesOutput>
73+
{
74+
public ushort NumOfIndices { get; init; }
75+
public ushort[] Indices { get; init; }
76+
77+
public static GetProposalIndicesOutput FromBytes(ReadOnlySpan<byte> data)
78+
{
79+
var indices = new ushort[64];
80+
for (int i = 0; i < 64; i++)
81+
{
82+
indices[i] = BinaryPrimitives.ReadUInt16LittleEndian(data[(2 + i * 2)..]);
83+
}
84+
return new GetProposalIndicesOutput
85+
{
86+
NumOfIndices = BinaryPrimitives.ReadUInt16LittleEndian(data[0..]),
87+
Indices = indices
88+
};
89+
}
90+
}
91+
92+
// ═══ Function: GetProposal (inputType=2) ═══
93+
94+
/// <summary>Input for query.</summary>
95+
public readonly struct GetProposalInput : ISmartContractInput
96+
{
97+
public const int Size = 34;
98+
99+
public int SerializedSize => Size;
100+
101+
public required byte[] SubscriptionDestination { get; init; }
102+
public ushort ProposalIndex { get; init; }
103+
104+
public byte[] ToBytes()
105+
{
106+
var bytes = new byte[Size];
107+
SubscriptionDestination.AsSpan(0, 32).CopyTo(bytes.AsSpan(0));
108+
BinaryPrimitives.WriteUInt16LittleEndian(bytes.AsSpan(32), ProposalIndex);
109+
return bytes;
110+
}
111+
}
112+
113+
/// <summary>Output.</summary>
114+
public readonly struct GetProposalOutput : ISmartContractOutput<GetProposalOutput>
115+
{
116+
public bool Okay { get; init; }
117+
public bool HasSubscriptionProposal { get; init; }
118+
public bool HasActiveSubscription { get; init; }
119+
public byte[] _padding0 { get; init; }
120+
public byte[] _padding1 { get; init; }
121+
public byte[] ProposerPublicKey { get; init; }
122+
public byte[] Proposal { get; init; }
123+
public byte[] Subscription { get; init; }
124+
public byte[] SubscriptionProposal { get; init; }
125+
126+
public static GetProposalOutput FromBytes(ReadOnlySpan<byte> data)
127+
{
128+
var _padding0 = new byte[1];
129+
for (int i = 0; i < 1; i++)
130+
{
131+
_padding0[i] = data.Slice(3 + i * 1, 1)[0];
132+
}
133+
var _padding1 = new byte[4];
134+
for (int i = 0; i < 4; i++)
135+
{
136+
_padding1[i] = data.Slice(4 + i * 1, 1)[0];
137+
}
138+
return new GetProposalOutput
139+
{
140+
Okay = (data.Slice(0, 1)[0] != 0),
141+
HasSubscriptionProposal = (data.Slice(1, 1)[0] != 0),
142+
HasActiveSubscription = (data.Slice(2, 1)[0] != 0),
143+
_padding0 = _padding0,
144+
_padding1 = _padding1,
145+
ProposerPublicKey = data[8..].Slice(0, 32).ToArray(),
146+
Proposal = [] /* unknown type ProposalDataT */,
147+
Subscription = [] /* unknown type SubscriptionData */,
148+
SubscriptionProposal = [] /* unknown type SubscriptionProposalData */
149+
};
150+
}
151+
}
152+
153+
// ═══ Function: GetVote (inputType=3) ═══
154+
155+
/// <summary>Input for query.</summary>
156+
public readonly struct GetVoteInput : ISmartContractInput
157+
{
158+
public const int Size = 34;
159+
160+
public int SerializedSize => Size;
161+
162+
public required byte[] Voter { get; init; }
163+
public ushort ProposalIndex { get; init; }
164+
165+
public byte[] ToBytes()
166+
{
167+
var bytes = new byte[Size];
168+
Voter.AsSpan(0, 32).CopyTo(bytes.AsSpan(0));
169+
BinaryPrimitives.WriteUInt16LittleEndian(bytes.AsSpan(32), ProposalIndex);
170+
return bytes;
171+
}
172+
}
173+
174+
/// <summary>Output.</summary>
175+
public readonly struct GetVoteOutput : ISmartContractOutput<GetVoteOutput>
176+
{
177+
public bool Okay { get; init; }
178+
public byte[] Vote { get; init; }
179+
180+
public static GetVoteOutput FromBytes(ReadOnlySpan<byte> data)
181+
{
182+
return new GetVoteOutput
183+
{
184+
Okay = (data.Slice(0, 1)[0] != 0),
185+
Vote = [] /* unknown type ProposalSingleVoteDataV1 */
186+
};
187+
}
188+
}
189+
190+
// ═══ Function: GetVotingResults (inputType=4) ═══
191+
192+
/// <summary>Input for query.</summary>
193+
public readonly struct GetVotingResultsInput : ISmartContractInput
194+
{
195+
public const int Size = 2;
196+
197+
public int SerializedSize => Size;
198+
199+
public ushort ProposalIndex { get; init; }
200+
201+
public byte[] ToBytes()
202+
{
203+
var bytes = new byte[Size];
204+
BinaryPrimitives.WriteUInt16LittleEndian(bytes.AsSpan(0), ProposalIndex);
205+
return bytes;
206+
}
207+
}
208+
209+
/// <summary>Output.</summary>
210+
public readonly struct GetVotingResultsOutput : ISmartContractOutput<GetVotingResultsOutput>
211+
{
212+
public bool Okay { get; init; }
213+
public byte[] Results { get; init; }
214+
215+
public static GetVotingResultsOutput FromBytes(ReadOnlySpan<byte> data)
216+
{
217+
return new GetVotingResultsOutput
218+
{
219+
Okay = (data.Slice(0, 1)[0] != 0),
220+
Results = [] /* unknown type ProposalSummarizedVotingDataV1 */
221+
};
222+
}
223+
}
224+
225+
// ═══ Function: GetLatestTransfers (inputType=5) ═══
226+
227+
/// <summary>Input for query (empty).</summary>
228+
public readonly struct GetLatestTransfersInput : ISmartContractInput
229+
{
230+
public int SerializedSize => 0;
231+
public byte[] ToBytes() => [];
232+
}
233+
234+
/// <summary>Output (empty).</summary>
235+
public readonly struct GetLatestTransfersOutput : ISmartContractOutput<GetLatestTransfersOutput>
236+
{
237+
public static GetLatestTransfersOutput FromBytes(ReadOnlySpan<byte> data) => new();
238+
}
239+
240+
// ═══ Function: GetProposalFee (inputType=6) ═══
241+
242+
/// <summary>Input for query (empty).</summary>
243+
public readonly struct GetProposalFeeInput : ISmartContractInput
244+
{
245+
public int SerializedSize => 0;
246+
public byte[] ToBytes() => [];
247+
}
248+
249+
/// <summary>Output.</summary>
250+
public readonly struct GetProposalFeeOutput : ISmartContractOutput<GetProposalFeeOutput>
251+
{
252+
public uint ProposalFee { get; init; }
253+
254+
public static GetProposalFeeOutput FromBytes(ReadOnlySpan<byte> data)
255+
{
256+
return new GetProposalFeeOutput
257+
{
258+
ProposalFee = BinaryPrimitives.ReadUInt32LittleEndian(data[0..])
259+
};
260+
}
261+
}
262+
263+
// ═══ Function: GetRegularPayments (inputType=7) ═══
264+
265+
/// <summary>Input for query (empty).</summary>
266+
public readonly struct GetRegularPaymentsInput : ISmartContractInput
267+
{
268+
public int SerializedSize => 0;
269+
public byte[] ToBytes() => [];
270+
}
271+
272+
/// <summary>Output (empty).</summary>
273+
public readonly struct GetRegularPaymentsOutput : ISmartContractOutput<GetRegularPaymentsOutput>
274+
{
275+
public static GetRegularPaymentsOutput FromBytes(ReadOnlySpan<byte> data) => new();
276+
}
277+
278+
// ═══ Procedure: SetProposal (inputType=1) ═══
279+
280+
/// <summary>Input payload for procedure.</summary>
281+
public sealed class SetProposalPayload : ITransactionPayload, ISmartContractInput
282+
{
283+
public const int Size = 20;
284+
285+
public ushort InputType => 1;
286+
public ushort InputSize => Size;
287+
public int SerializedSize => Size;
288+
289+
public byte[] Proposal { get; init; }
290+
public bool IsSubscription { get; init; }
291+
public byte WeeksPerPeriod { get; init; }
292+
public byte[] _padding0 { get; init; }
293+
public uint StartEpoch { get; init; }
294+
public ulong AmountPerPeriod { get; init; }
295+
public uint NumberOfPeriods { get; init; }
296+
297+
public byte[] GetPayloadBytes() => ToBytes();
298+
299+
public byte[] ToBytes()
300+
{
301+
var bytes = new byte[Size];
302+
// TODO: serialize unknown type ProposalDataT for Proposal
303+
bytes.AsSpan(0, 1)[0] = (byte)(IsSubscription ? 1 : 0);
304+
bytes.AsSpan(1, 1)[0] = WeeksPerPeriod;
305+
for (int i = 0; i < 2 && _padding0 != null && i < _padding0.Length; i++)
306+
{
307+
bytes.AsSpan(2 + i * 1)[0] = _padding0[i];
308+
}
309+
BinaryPrimitives.WriteUInt32LittleEndian(bytes.AsSpan(4), StartEpoch);
310+
BinaryPrimitives.WriteUInt64LittleEndian(bytes.AsSpan(8), AmountPerPeriod);
311+
BinaryPrimitives.WriteUInt32LittleEndian(bytes.AsSpan(16), NumberOfPeriods);
312+
return bytes;
313+
}
314+
}
315+
316+
/// <summary>Output.</summary>
317+
public readonly struct SetProposalOutput : ISmartContractOutput<SetProposalOutput>
318+
{
319+
public ushort ProposalIndex { get; init; }
320+
321+
public static SetProposalOutput FromBytes(ReadOnlySpan<byte> data)
322+
{
323+
return new SetProposalOutput
324+
{
325+
ProposalIndex = BinaryPrimitives.ReadUInt16LittleEndian(data[0..])
326+
};
327+
}
328+
}
329+
330+
// ═══ Procedure: Vote (inputType=2) ═══
331+
332+
/// <summary>Input for procedure (empty payload).</summary>
333+
public sealed class VotePayload : ITransactionPayload, ISmartContractInput
334+
{
335+
public ushort InputType => 2;
336+
public ushort InputSize => 0;
337+
public int SerializedSize => 0;
338+
public byte[] GetPayloadBytes() => [];
339+
public byte[] ToBytes() => [];
340+
}
341+
342+
/// <summary>Output (empty).</summary>
343+
public readonly struct VoteOutput : ISmartContractOutput<VoteOutput>
344+
{
345+
public static VoteOutput FromBytes(ReadOnlySpan<byte> data) => new();
346+
}

0 commit comments

Comments
 (0)