@rootzero/contracts 0.9.2 → 0.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/Commands.sol +4 -3
  2. package/Core.sol +3 -0
  3. package/Cursors.sol +1 -1
  4. package/README.md +18 -24
  5. package/blocks/Cursors.sol +332 -335
  6. package/blocks/Keys.sol +38 -57
  7. package/blocks/Schema.sol +55 -114
  8. package/blocks/Writers.sol +361 -255
  9. package/commands/Base.sol +6 -48
  10. package/commands/Burn.sol +4 -4
  11. package/commands/Credit.sol +5 -4
  12. package/commands/Debit.sol +6 -5
  13. package/commands/Deposit.sol +17 -14
  14. package/commands/Provision.sol +17 -14
  15. package/commands/Transfer.sol +4 -4
  16. package/commands/Withdraw.sol +5 -4
  17. package/commands/admin/AllowAssets.sol +3 -3
  18. package/commands/admin/Allowance.sol +3 -3
  19. package/commands/admin/Authorize.sol +3 -3
  20. package/commands/admin/DenyAssets.sol +3 -3
  21. package/commands/admin/Destroy.sol +1 -1
  22. package/commands/admin/Execute.sol +9 -8
  23. package/commands/admin/Init.sol +1 -1
  24. package/commands/admin/Unauthorize.sol +3 -3
  25. package/core/Access.sol +11 -0
  26. package/core/Context.sol +11 -13
  27. package/core/Payable.sol +57 -0
  28. package/core/Pipeline.sol +55 -0
  29. package/docs/Schema.md +194 -0
  30. package/events/Admin.sol +5 -1
  31. package/events/Command.sol +6 -2
  32. package/events/Listing.sol +3 -4
  33. package/events/Peer.sol +5 -3
  34. package/events/Query.sol +5 -2
  35. package/package.json +2 -2
  36. package/peer/AllowAssets.sol +3 -3
  37. package/peer/Allowance.sol +3 -3
  38. package/peer/BalancePull.sol +43 -0
  39. package/peer/DenyAssets.sol +3 -3
  40. package/peer/Pipe.sol +38 -0
  41. package/peer/Settle.sol +3 -3
  42. package/queries/Assets.sol +7 -6
  43. package/queries/Balances.sol +5 -4
  44. package/queries/Positions.sol +14 -14
  45. package/utils/Value.sol +8 -14
  46. package/commands/Pipe.sol +0 -67
  47. package/docs/GETTING_STARTED.md +0 -294
  48. package/peer/AssetPull.sol +0 -43
@@ -12,15 +12,22 @@ struct Writer {
12
12
  uint i;
13
13
  /// @dev Logical buffer capacity in bytes; writers should not advance past this limit.
14
14
  uint end;
15
+ /// @dev Whether append helpers may expand the backing buffer when more capacity is needed.
16
+ bool growable;
15
17
  /// @dev Destination buffer. Physical capacity may be padded up to a full 32-byte word;
16
18
  /// final length is set to `i` by `finish`.
17
19
  bytes dst;
18
20
  }
19
21
 
20
- // Fixed-point scaling denominator for output-count allocation.
21
- // A `scaledRatio` of `ALLOC_SCALE` means 1:1 (one output block per input block).
22
- // `2 * ALLOC_SCALE` means 2:1; non-integer ratios revert with `BadWriterRatio`.
23
- uint constant ALLOC_SCALE = 10_000;
22
+ /// @title Hints
23
+ /// @notice Initial per-block capacity estimates for growable writers.
24
+ library Hints {
25
+ uint constant Any = 128;
26
+ uint constant Bytes = 128;
27
+ uint constant Step = 256;
28
+ uint constant Call = 256;
29
+ uint constant Context = 512;
30
+ }
24
31
 
25
32
  /// @title Writers
26
33
  /// @notice Response block stream builder for the rootzero protocol.
@@ -36,8 +43,6 @@ library Writers {
36
43
  error IncompleteWriter();
37
44
  /// @dev An alloc function received a zero count, or `finish` found no bytes written.
38
45
  error EmptyRequest();
39
- /// @dev `scaledRatio * count` is not evenly divisible by `ALLOC_SCALE`.
40
- error BadWriterRatio();
41
46
  /// @dev A fixed-width low-level writer received an invalid final-word keep length.
42
47
  error InvalidKeep();
43
48
 
@@ -54,25 +59,35 @@ library Writers {
54
59
  // Extra 32 bytes ensure mstore in write/append32 never reaches past allocated memory,
55
60
  // even when a sub-word packed write starts within the last 31 bytes of the logical region.
56
61
  uint padded = ((len + 31) & ~uint(31)) + 32;
57
- writer = Writer({i: 0, end: len, dst: new bytes(padded)});
62
+ writer = Writer({i: 0, end: len, growable: false, dst: new bytes(padded)});
63
+ }
64
+
65
+ /// @notice Allocate a growable writer with an initial logical byte capacity.
66
+ /// @param hint Initial logical byte capacity to allocate.
67
+ /// @return writer Freshly allocated growable writer positioned at index 0.
68
+ function dynamic(uint hint) internal pure returns (Writer memory writer) {
69
+ writer = alloc(hint);
70
+ writer.growable = true;
58
71
  }
59
72
 
60
73
  /// @notice Core allocation routine used by all counted `alloc*` helpers.
61
- /// Computes `(count * scaledRatio / ALLOC_SCALE) * blockLen` and allocates that many bytes.
62
- /// @param count Number of input blocks.
63
- /// @param scaledRatio Output-to-input ratio in `ALLOC_SCALE` units.
74
+ /// Computes `count * blockLen` and allocates that many bytes.
75
+ /// @param count Number of output blocks.
64
76
  /// @param blockLen Logical byte size of each output block (including 8-byte header).
65
77
  /// @return writer Allocated writer.
66
- function allocFromScaledCount(
67
- uint count,
68
- uint scaledRatio,
69
- uint blockLen
70
- ) internal pure returns (Writer memory writer) {
78
+ function allocFromCount(uint count, uint blockLen) internal pure returns (Writer memory writer) {
71
79
  if (count == 0) revert EmptyRequest();
72
- uint scaledCount = count * scaledRatio;
73
- if (scaledCount % ALLOC_SCALE != 0) revert BadWriterRatio();
74
- uint len = (scaledCount / ALLOC_SCALE) * blockLen;
75
- writer = alloc(len);
80
+ writer = alloc(count * blockLen);
81
+ }
82
+
83
+ /// @notice Core allocation routine used by counted growable `alloc*` helpers.
84
+ /// Computes `count * hint` and allocates an expandable writer with that initial capacity.
85
+ /// @param count Number of output blocks.
86
+ /// @param hint Initial logical byte capacity per output block.
87
+ /// @return writer Allocated growable writer.
88
+ function allocFromHint(uint count, uint hint) internal pure returns (Writer memory writer) {
89
+ if (count == 0) revert EmptyRequest();
90
+ writer = dynamic(count * hint);
76
91
  }
77
92
 
78
93
  /// @notice Allocate a writer sized for exactly `count` dynamic blocks with a shared payload length.
@@ -81,180 +96,131 @@ library Writers {
81
96
  /// @param payloadLen Payload byte length for each block.
82
97
  /// @return writer Allocated writer.
83
98
  function allocBytes(uint count, uint payloadLen) internal pure returns (Writer memory writer) {
84
- return allocFromScaledCount(count, ALLOC_SCALE, Sizes.Header + payloadLen);
99
+ return allocFromCount(count, Sizes.Header + payloadLen);
100
+ }
101
+
102
+ /// @notice Allocate a writer for `count` variable-sized blocks using a per-block capacity hint.
103
+ /// @dev The backing buffer expands automatically if encoded blocks exceed the initial hint.
104
+ /// @param count Number of blocks to allocate space for.
105
+ /// @return writer Allocated growable writer.
106
+ function allocAny(uint count) internal pure returns (Writer memory writer) {
107
+ return allocFromHint(count, Hints.Any);
108
+ }
109
+
110
+ /// @notice Allocate a writer for `count` BYTES blocks using a per-block capacity hint.
111
+ /// @dev The backing buffer expands automatically if encoded bytes blocks exceed the initial hint.
112
+ /// @param count Number of bytes blocks to allocate space for.
113
+ /// @return writer Allocated growable writer.
114
+ function allocBytes(uint count) internal pure returns (Writer memory writer) {
115
+ return allocFromHint(count, Hints.Bytes);
85
116
  }
86
117
 
87
- /// @notice Allocate a writer sized for exactly `count` 32-byte-payload blocks (1:1 ratio).
118
+ /// @notice Allocate a writer sized for exactly `count` 32-byte-payload blocks.
88
119
  /// @param count Number of blocks to allocate space for.
89
120
  /// @return writer Allocated writer.
90
121
  function alloc32s(uint count) internal pure returns (Writer memory writer) {
91
- return allocFromScaledCount(count, ALLOC_SCALE, Sizes.B32);
122
+ return allocFromCount(count, Sizes.B32);
92
123
  }
93
124
 
94
- /// @notice Allocate a writer sized for exactly `count` 64-byte-payload blocks (1:1 ratio).
125
+ /// @notice Allocate a writer sized for exactly `count` 64-byte-payload blocks.
95
126
  /// @param count Number of blocks to allocate space for.
96
127
  /// @return writer Allocated writer.
97
128
  function alloc64s(uint count) internal pure returns (Writer memory writer) {
98
- return allocFromScaledCount(count, ALLOC_SCALE, Sizes.B64);
129
+ return allocFromCount(count, Sizes.B64);
99
130
  }
100
131
 
101
- /// @notice Allocate a writer sized for exactly `count` 96-byte-payload blocks (1:1 ratio).
132
+ /// @notice Allocate a writer sized for exactly `count` 96-byte-payload blocks.
102
133
  /// @param count Number of blocks to allocate space for.
103
134
  /// @return writer Allocated writer.
104
135
  function alloc96s(uint count) internal pure returns (Writer memory writer) {
105
- return allocFromScaledCount(count, ALLOC_SCALE, Sizes.B96);
136
+ return allocFromCount(count, Sizes.B96);
106
137
  }
107
138
 
108
- /// @notice Allocate a writer sized for exactly `count` 128-byte-payload blocks (1:1 ratio).
139
+ /// @notice Allocate a writer sized for exactly `count` 128-byte-payload blocks.
109
140
  /// @param count Number of blocks to allocate space for.
110
141
  /// @return writer Allocated writer.
111
142
  function alloc128s(uint count) internal pure returns (Writer memory writer) {
112
- return allocFromScaledCount(count, ALLOC_SCALE, Sizes.B128);
143
+ return allocFromCount(count, Sizes.B128);
113
144
  }
114
145
 
115
- /// @notice Allocate a writer sized for exactly `count` 160-byte-payload blocks (1:1 ratio).
146
+ /// @notice Allocate a writer sized for exactly `count` 160-byte-payload blocks.
116
147
  /// @param count Number of blocks to allocate space for.
117
148
  /// @return writer Allocated writer.
118
149
  function alloc160s(uint count) internal pure returns (Writer memory writer) {
119
- return allocFromScaledCount(count, ALLOC_SCALE, Sizes.B160);
120
- }
121
-
122
- /// @notice Allocate a writer for dynamic blocks with a shared payload length and custom output ratio.
123
- /// Each block reserves `Sizes.Header + payloadLen` bytes.
124
- /// @param count Number of input blocks.
125
- /// @param scaledRatio Output count multiplier expressed in `ALLOC_SCALE` units.
126
- /// @param payloadLen Payload byte length for each block.
127
- /// @return writer Allocated writer.
128
- function allocScaledBytes(
129
- uint count,
130
- uint scaledRatio,
131
- uint payloadLen
132
- ) internal pure returns (Writer memory writer) {
133
- return allocFromScaledCount(count, scaledRatio, Sizes.Header + payloadLen);
134
- }
135
-
136
- /// @notice Allocate a writer for 32-byte-payload blocks with a custom output-to-input ratio.
137
- /// @param count Number of input blocks.
138
- /// @param scaledRatio Output count multiplier expressed in `ALLOC_SCALE` units.
139
- /// @return writer Allocated writer.
140
- function allocScaled32s(uint count, uint scaledRatio) internal pure returns (Writer memory writer) {
141
- return allocFromScaledCount(count, scaledRatio, Sizes.B32);
142
- }
143
-
144
- /// @notice Allocate a writer for 64-byte-payload blocks with a custom output-to-input ratio.
145
- /// @param count Number of input blocks.
146
- /// @param scaledRatio Output count multiplier expressed in `ALLOC_SCALE` units.
147
- /// @return writer Allocated writer.
148
- function allocScaled64s(uint count, uint scaledRatio) internal pure returns (Writer memory writer) {
149
- return allocFromScaledCount(count, scaledRatio, Sizes.B64);
150
- }
151
-
152
- /// @notice Allocate a writer for 96-byte-payload blocks with a custom output-to-input ratio.
153
- /// @param count Number of input blocks.
154
- /// @param scaledRatio Output count multiplier expressed in `ALLOC_SCALE` units.
155
- /// @return writer Allocated writer.
156
- function allocScaled96s(uint count, uint scaledRatio) internal pure returns (Writer memory writer) {
157
- return allocFromScaledCount(count, scaledRatio, Sizes.B96);
158
- }
159
-
160
- /// @notice Allocate a writer for 128-byte-payload blocks with a custom output-to-input ratio.
161
- /// @param count Number of input blocks.
162
- /// @param scaledRatio Output count multiplier expressed in `ALLOC_SCALE` units.
163
- /// @return writer Allocated writer.
164
- function allocScaled128s(uint count, uint scaledRatio) internal pure returns (Writer memory writer) {
165
- return allocFromScaledCount(count, scaledRatio, Sizes.B128);
166
- }
167
-
168
- /// @notice Allocate a writer for 160-byte-payload blocks with a custom output-to-input ratio.
169
- /// @param count Number of input blocks.
170
- /// @param scaledRatio Output count multiplier expressed in `ALLOC_SCALE` units.
171
- /// @return writer Allocated writer.
172
- function allocScaled160s(uint count, uint scaledRatio) internal pure returns (Writer memory writer) {
173
- return allocFromScaledCount(count, scaledRatio, Sizes.B160);
150
+ return allocFromCount(count, Sizes.B160);
174
151
  }
175
152
 
176
153
  /// @notice Allocate a writer sized for exactly `count` STATUS form blocks.
177
154
  /// @param count Number of blocks to allocate space for.
178
155
  /// @return writer Allocated writer.
179
156
  function allocStatuses(uint count) internal pure returns (Writer memory writer) {
180
- return alloc32s(count);
157
+ return allocFromCount(count, Sizes.Status);
181
158
  }
182
159
 
183
- /// @notice Allocate a writer sized for exactly `count` ASSET blocks (1:1 ratio).
160
+ /// @notice Allocate a writer sized for exactly `count` ASSET blocks.
184
161
  /// @param count Number of asset blocks to allocate space for.
185
162
  /// @return writer Allocated writer.
186
163
  function allocAssets(uint count) internal pure returns (Writer memory writer) {
187
164
  return alloc64s(count);
188
165
  }
189
166
 
190
- /// @notice Allocate a writer sized for exactly `count` AMOUNT blocks (1:1 ratio).
167
+ /// @notice Allocate a writer sized for exactly `count` AMOUNT blocks.
191
168
  /// @param count Number of amount blocks to allocate space for.
192
169
  /// @return writer Allocated writer.
193
170
  function allocAmounts(uint count) internal pure returns (Writer memory writer) {
194
171
  return alloc96s(count);
195
172
  }
196
173
 
197
- /// @notice Allocate a writer sized for exactly `count` BALANCE blocks (1:1 ratio).
174
+ /// @notice Allocate a writer sized for exactly `count` BALANCE blocks.
198
175
  /// @param count Number of balance blocks to allocate space for.
199
176
  /// @return writer Allocated writer.
200
177
  function allocBalances(uint count) internal pure returns (Writer memory writer) {
201
178
  return alloc96s(count);
202
179
  }
203
180
 
204
- /// @notice Allocate a writer sized for exactly `count` ACCOUNT_AMOUNT form blocks (1:1 ratio).
181
+ /// @notice Allocate a writer sized for exactly `count` ACCOUNT_AMOUNT form blocks.
205
182
  /// @param count Number of account amount blocks to allocate space for.
206
183
  /// @return writer Allocated writer.
207
184
  function allocAccountAmounts(uint count) internal pure returns (Writer memory writer) {
208
185
  return alloc128s(count);
209
186
  }
210
187
 
211
- /// @notice Allocate a writer sized for exactly `count` CUSTODY blocks (1:1 ratio).
188
+ /// @notice Allocate a writer sized for exactly `count` CUSTODY blocks.
212
189
  /// @param count Number of custody blocks to allocate space for.
213
190
  /// @return writer Allocated writer.
214
191
  function allocCustodies(uint count) internal pure returns (Writer memory writer) {
215
192
  return alloc128s(count);
216
193
  }
217
194
 
218
- /// @notice Allocate a writer sized for exactly `count` TRANSACTION blocks (1:1 ratio).
195
+ /// @notice Allocate a writer sized for exactly `count` TRANSACTION blocks.
219
196
  /// @param count Number of transaction blocks to allocate space for.
220
197
  /// @return writer Allocated writer.
221
198
  function allocTransactions(uint count) internal pure returns (Writer memory writer) {
222
199
  return alloc160s(count);
223
200
  }
224
201
 
225
- /// @notice Allocate a writer for ASSET blocks with a custom output-to-input ratio.
226
- /// @param count Number of input blocks.
227
- /// @param scaledRatio Output count multiplier expressed in `ALLOC_SCALE` units
228
- /// (e.g. `ALLOC_SCALE` = 1:1, `2 * ALLOC_SCALE` = 2:1).
229
- /// @return writer Allocated writer.
230
- function allocScaledAssets(uint count, uint scaledRatio) internal pure returns (Writer memory writer) {
231
- return allocScaled64s(count, scaledRatio);
202
+ /// @notice Allocate a writer for `count` STEP blocks using a per-block capacity hint.
203
+ /// @dev The backing buffer expands automatically if encoded steps exceed the initial hint.
204
+ /// @param count Number of step blocks to allocate space for.
205
+ /// @return writer Allocated growable writer.
206
+ function allocSteps(uint count) internal pure returns (Writer memory writer) {
207
+ return allocFromHint(count, Hints.Step);
232
208
  }
233
209
 
234
- /// @notice Allocate a writer for AMOUNT blocks with a custom output-to-input ratio.
235
- /// @param count Number of input blocks.
236
- /// @param scaledRatio Output count multiplier expressed in `ALLOC_SCALE` units
237
- /// (e.g. `ALLOC_SCALE` = 1:1, `2 * ALLOC_SCALE` = 2:1).
238
- /// @return writer Allocated writer.
239
- function allocScaledAmounts(uint count, uint scaledRatio) internal pure returns (Writer memory writer) {
240
- return allocScaled96s(count, scaledRatio);
210
+ /// @notice Allocate a writer for `count` CALL blocks using a per-block capacity hint.
211
+ /// @dev The backing buffer expands automatically if encoded calls exceed the initial hint.
212
+ /// @param count Number of call blocks to allocate space for.
213
+ /// @return writer Allocated growable writer.
214
+ function allocCalls(uint count) internal pure returns (Writer memory writer) {
215
+ return allocFromHint(count, Hints.Call);
241
216
  }
242
217
 
243
- /// @notice Allocate a writer for BALANCE blocks with a custom output-to-input ratio.
244
- /// @param count Number of input blocks.
245
- /// @param scaledRatio Output count multiplier expressed in `ALLOC_SCALE` units
246
- /// (e.g. `ALLOC_SCALE` = 1:1, `2 * ALLOC_SCALE` = 2:1).
247
- /// @return writer Allocated writer.
248
- function allocScaledBalances(uint count, uint scaledRatio) internal pure returns (Writer memory writer) {
249
- return allocScaled96s(count, scaledRatio);
250
- }
251
-
252
- /// @notice Allocate a writer for CUSTODY blocks with a custom output-to-input ratio.
253
- /// @param count Number of input blocks.
254
- /// @param scaledRatio Output count multiplier in `ALLOC_SCALE` units.
255
- /// @return writer Allocated writer.
256
- function allocScaledCustodies(uint count, uint scaledRatio) internal pure returns (Writer memory writer) {
257
- return allocScaled128s(count, scaledRatio);
218
+ /// @notice Allocate a writer for `count` CONTEXT blocks using a per-block capacity hint.
219
+ /// @dev The backing buffer expands automatically if encoded contexts exceed the initial hint.
220
+ /// @param count Number of context blocks to allocate space for.
221
+ /// @return writer Allocated growable writer.
222
+ function allocContexts(uint count) internal pure returns (Writer memory writer) {
223
+ return allocFromHint(count, Hints.Context);
258
224
  }
259
225
 
260
226
  // -------------------------------------------------------------------------
@@ -276,14 +242,6 @@ library Writers {
276
242
  }
277
243
  }
278
244
 
279
- /// @notice Commit a logical writer advance after a low-level write.
280
- /// @dev Low-level write helpers validate the padded backing buffer. This
281
- /// enforces the caller-requested logical capacity recorded in `end`.
282
- function commit(Writer memory writer, uint next) private pure {
283
- if (next > writer.end) revert WriterOverflow();
284
- writer.i = next;
285
- }
286
-
287
245
  /// @notice Write raw bytes directly into `dst` at byte offset `i` without a block header.
288
246
  /// @param dst Destination buffer.
289
247
  /// @param i Write offset within `dst`.
@@ -535,57 +493,160 @@ library Writers {
535
493
  }
536
494
  }
537
495
 
538
- /// @notice Write a dynamic block with a fixed 32-byte head word.
539
- /// @param dst Destination buffer; must have at least `i + Sizes.B32 + tail.length` bytes.
496
+ /// @notice Write a block with a 32-byte head and two nested BYTES payloads.
497
+ /// @param dst Destination buffer; must have at least `i + Sizes.B32 + 2 * Sizes.Header + b.length + c.length` bytes.
540
498
  /// @param i Write offset within `dst`.
541
- /// @param key Block type key.
499
+ /// @param key Block key.
542
500
  /// @param a Fixed head word.
543
- /// @param tail Dynamic payload bytes appended after the head.
501
+ /// @param b First raw nested payload.
502
+ /// @param c Second raw nested payload.
544
503
  /// @return next Byte offset immediately after the written block.
545
- function writeBlockHead32(
504
+ function writeBlock32BytesBytes(
546
505
  bytes memory dst,
547
506
  uint i,
548
507
  bytes4 key,
549
508
  bytes32 a,
550
- bytes memory tail
509
+ bytes memory b,
510
+ bytes memory c
551
511
  ) internal pure returns (uint next) {
552
- uint len = 32 + tail.length;
512
+ uint bLen = b.length;
513
+ uint len = 32 + 2 * Sizes.Header + bLen + c.length;
553
514
  next = i + Sizes.Header + len;
554
- if (i + Sizes.B32 + tail.length > dst.length) revert WriterOverflow();
555
- uint p = writeHeader(dst, i, key, uint32(max32(len)));
556
- assembly ("memory-safe") {
557
- mstore(add(p, 0x08), a)
558
- mcopy(add(p, 0x28), add(tail, 0x20), mload(tail))
515
+ if (next > dst.length) revert WriterOverflow();
516
+
517
+ {
518
+ uint p = writeHeader(dst, i, key, uint32(max32(len)));
519
+ assembly ("memory-safe") {
520
+ mstore(add(p, 0x08), a)
521
+ }
522
+ }
523
+
524
+ {
525
+ uint q = writeHeader(dst, i + Sizes.Header + 32, Keys.Bytes, uint32(max32(bLen)));
526
+ assembly ("memory-safe") {
527
+ mcopy(add(q, 0x08), add(b, 0x20), mload(b))
528
+ }
529
+ }
530
+
531
+ {
532
+ uint r = writeHeader(dst, i + Sizes.Header + 32 + Sizes.Header + bLen, Keys.Bytes, uint32(max32(c.length)));
533
+ assembly ("memory-safe") {
534
+ mcopy(add(r, 0x08), add(c, 0x20), mload(c))
535
+ }
559
536
  }
560
537
  }
561
538
 
562
- /// @notice Write a dynamic block with a fixed 64-byte head.
563
- /// @param dst Destination buffer; must have at least `i + Sizes.B64 + tail.length` bytes.
539
+ /// @notice Write a block with a 64-byte head and two nested BYTES payloads.
540
+ /// @param dst Destination buffer; must have at least `i + Sizes.B64 + 2 * Sizes.Header + c.length + d.length` bytes.
564
541
  /// @param i Write offset within `dst`.
565
- /// @param key Block type key.
566
- /// @param a First fixed head word.
567
- /// @param b Second fixed head word.
568
- /// @param tail Dynamic payload bytes appended after the head.
542
+ /// @param key Block key.
543
+ /// @param a First head word.
544
+ /// @param b Second head word.
545
+ /// @param c First raw nested payload.
546
+ /// @param d Second raw nested payload.
569
547
  /// @return next Byte offset immediately after the written block.
570
- function writeBlockHead64(
548
+ function writeBlock64BytesBytes(
571
549
  bytes memory dst,
572
550
  uint i,
573
551
  bytes4 key,
574
552
  bytes32 a,
575
553
  bytes32 b,
576
- bytes memory tail
554
+ bytes memory c,
555
+ bytes memory d
577
556
  ) internal pure returns (uint next) {
578
- uint len = 64 + tail.length;
557
+ uint cLen = c.length;
558
+ uint len = 64 + 2 * Sizes.Header + cLen + d.length;
579
559
  next = i + Sizes.Header + len;
580
- if (i + Sizes.B64 + tail.length > dst.length) revert WriterOverflow();
581
- uint p = writeHeader(dst, i, key, uint32(max32(len)));
582
- assembly ("memory-safe") {
583
- mstore(add(p, 0x08), a)
584
- mstore(add(p, 0x28), b)
585
- mcopy(add(p, 0x48), add(tail, 0x20), mload(tail))
560
+ if (next > dst.length) revert WriterOverflow();
561
+
562
+ {
563
+ uint p = writeHeader(dst, i, key, uint32(max32(len)));
564
+ assembly ("memory-safe") {
565
+ mstore(add(p, 0x08), a)
566
+ mstore(add(p, 0x28), b)
567
+ }
568
+ }
569
+
570
+ {
571
+ uint q = writeHeader(dst, i + Sizes.Header + 64, Keys.Bytes, uint32(max32(cLen)));
572
+ assembly ("memory-safe") {
573
+ mcopy(add(q, 0x08), add(c, 0x20), mload(c))
574
+ }
575
+ }
576
+
577
+ {
578
+ uint r = writeHeader(dst, i + Sizes.Header + 64 + Sizes.Header + cLen, Keys.Bytes, uint32(max32(d.length)));
579
+ assembly ("memory-safe") {
580
+ mcopy(add(r, 0x08), add(d, 0x20), mload(d))
581
+ }
586
582
  }
587
583
  }
588
584
 
585
+ /// @notice Write a block with a 64-byte head and nested BYTES payload.
586
+ /// @param dst Destination buffer; must have at least `i + Sizes.B64 + Sizes.Header + c.length` bytes.
587
+ /// @param i Write offset within `dst`.
588
+ /// @param key Block key.
589
+ /// @param a First head word.
590
+ /// @param b Second head word.
591
+ /// @param c Raw nested payload.
592
+ /// @return next Byte offset immediately after the written block.
593
+ function writeBlock64Bytes(
594
+ bytes memory dst,
595
+ uint i,
596
+ bytes4 key,
597
+ bytes32 a,
598
+ bytes32 b,
599
+ bytes memory c
600
+ ) internal pure returns (uint next) {
601
+ uint cLen = c.length;
602
+ uint len = 64 + Sizes.Header + cLen;
603
+ next = i + Sizes.Header + len;
604
+ if (next > dst.length) revert WriterOverflow();
605
+
606
+ {
607
+ uint p = writeHeader(dst, i, key, uint32(max32(len)));
608
+ assembly ("memory-safe") {
609
+ mstore(add(p, 0x08), a)
610
+ mstore(add(p, 0x28), b)
611
+ }
612
+ }
613
+
614
+ {
615
+ uint q = writeHeader(dst, i + Sizes.Header + 64, Keys.Bytes, uint32(max32(cLen)));
616
+ assembly ("memory-safe") {
617
+ mcopy(add(q, 0x08), add(c, 0x20), mload(c))
618
+ }
619
+ }
620
+ }
621
+
622
+ /// @notice Reserve physical write space and advance the logical writer position.
623
+ /// Fixed writers may use padded backing space but cannot advance past logical capacity;
624
+ /// growable writers expand when `touch` exceeds current capacity.
625
+ /// @return i Original write offset.
626
+ function reserve(Writer memory writer, uint next, uint touch) private pure returns (uint i) {
627
+ i = writer.i;
628
+ if (writer.growable) {
629
+ if (touch > writer.end) {
630
+ uint end = writer.end == 0 ? 64 : writer.end * 2;
631
+ while (end < touch) {
632
+ end *= 2;
633
+ }
634
+
635
+ uint padded = ((end + 31) & ~uint(31)) + 32;
636
+ bytes memory src = writer.dst;
637
+ bytes memory dst = new bytes(padded);
638
+ assembly ("memory-safe") {
639
+ mcopy(add(dst, 0x20), add(src, 0x20), i)
640
+ }
641
+ writer.end = end;
642
+ writer.dst = dst;
643
+ }
644
+ } else if (touch > writer.dst.length) revert WriterOverflow();
645
+
646
+ if (next > writer.end) revert WriterOverflow();
647
+ writer.i = next;
648
+ }
649
+
589
650
  // -------------------------------------------------------------------------
590
651
  // Append helpers
591
652
  // -------------------------------------------------------------------------
@@ -594,7 +655,9 @@ library Writers {
594
655
  /// @param writer Destination writer; `i` is advanced by `data.length`.
595
656
  /// @param data Bytes to append.
596
657
  function append(Writer memory writer, bytes memory data) internal pure {
597
- commit(writer, write(writer.dst, writer.i, data));
658
+ uint next = writer.i + data.length;
659
+ uint i = reserve(writer, next, next);
660
+ write(writer.dst, i, data);
598
661
  }
599
662
 
600
663
  /// @notice Append a raw 32-byte word without a block header.
@@ -602,7 +665,10 @@ library Writers {
602
665
  /// @param value Word to append.
603
666
  /// @param keep Number of bytes to keep from the word (1..32).
604
667
  function append32(Writer memory writer, bytes32 value, uint keep) internal pure {
605
- commit(writer, write32(writer.dst, writer.i, value, keep));
668
+ uint i = writer.i;
669
+ uint next = i + keep;
670
+ i = reserve(writer, next, i + 32);
671
+ write32(writer.dst, i, value, keep);
606
672
  }
607
673
 
608
674
  /// @notice Append two raw 32-byte words without a block header.
@@ -611,7 +677,10 @@ library Writers {
611
677
  /// @param b Second word to append.
612
678
  /// @param keep Number of bytes to keep from the final word (1..32).
613
679
  function append64(Writer memory writer, bytes32 a, bytes32 b, uint keep) internal pure {
614
- commit(writer, write64(writer.dst, writer.i, a, b, keep));
680
+ uint i = writer.i;
681
+ uint next = i + 32 + keep;
682
+ i = reserve(writer, next, i + 64);
683
+ write64(writer.dst, i, a, b, keep);
615
684
  }
616
685
 
617
686
  /// @notice Append three raw 32-byte words without a block header.
@@ -621,7 +690,10 @@ library Writers {
621
690
  /// @param c Third word to append.
622
691
  /// @param keep Number of bytes to keep from the final word (1..32).
623
692
  function append96(Writer memory writer, bytes32 a, bytes32 b, bytes32 c, uint keep) internal pure {
624
- commit(writer, write96(writer.dst, writer.i, a, b, c, keep));
693
+ uint i = writer.i;
694
+ uint next = i + 64 + keep;
695
+ i = reserve(writer, next, i + 96);
696
+ write96(writer.dst, i, a, b, c, keep);
625
697
  }
626
698
 
627
699
  /// @notice Append a dynamic block.
@@ -629,7 +701,9 @@ library Writers {
629
701
  /// @param key Block type key.
630
702
  /// @param data Dynamic payload bytes.
631
703
  function appendBlock(Writer memory writer, bytes4 key, bytes memory data) internal pure {
632
- commit(writer, writeBlock(writer.dst, writer.i, key, data));
704
+ uint next = writer.i + Sizes.Header + data.length;
705
+ uint i = reserve(writer, next, next);
706
+ writeBlock(writer.dst, i, key, data);
633
707
  }
634
708
 
635
709
  /// @notice Append a fixed-width 32-byte-payload block.
@@ -638,7 +712,10 @@ library Writers {
638
712
  /// @param a First payload word.
639
713
  /// @param keep Number of bytes to keep from the final payload word (1..32).
640
714
  function appendBlock32(Writer memory writer, bytes4 key, bytes32 a, uint keep) internal pure {
641
- commit(writer, writeBlock32(writer.dst, writer.i, key, a, keep));
715
+ uint i = writer.i;
716
+ uint next = i + Sizes.Header + keep;
717
+ i = reserve(writer, next, i + Sizes.B32);
718
+ writeBlock32(writer.dst, i, key, a, keep);
642
719
  }
643
720
 
644
721
  /// @notice Append a fixed-width 64-byte-payload block.
@@ -648,7 +725,10 @@ library Writers {
648
725
  /// @param b Second payload word.
649
726
  /// @param keep Number of bytes to keep from the final payload word (1..32).
650
727
  function appendBlock64(Writer memory writer, bytes4 key, bytes32 a, bytes32 b, uint keep) internal pure {
651
- commit(writer, writeBlock64(writer.dst, writer.i, key, a, b, keep));
728
+ uint i = writer.i;
729
+ uint next = i + Sizes.Header + 32 + keep;
730
+ i = reserve(writer, next, i + Sizes.B64);
731
+ writeBlock64(writer.dst, i, key, a, b, keep);
652
732
  }
653
733
 
654
734
  /// @notice Append a fixed-width 96-byte-payload block.
@@ -659,7 +739,10 @@ library Writers {
659
739
  /// @param c Third payload word.
660
740
  /// @param keep Number of bytes to keep from the final payload word (1..32).
661
741
  function appendBlock96(Writer memory writer, bytes4 key, bytes32 a, bytes32 b, bytes32 c, uint keep) internal pure {
662
- commit(writer, writeBlock96(writer.dst, writer.i, key, a, b, c, keep));
742
+ uint i = writer.i;
743
+ uint next = i + Sizes.Header + 64 + keep;
744
+ i = reserve(writer, next, i + Sizes.B96);
745
+ writeBlock96(writer.dst, i, key, a, b, c, keep);
663
746
  }
664
747
 
665
748
  /// @notice Append a fixed-width 128-byte-payload block.
@@ -679,7 +762,10 @@ library Writers {
679
762
  bytes32 d,
680
763
  uint keep
681
764
  ) internal pure {
682
- commit(writer, writeBlock128(writer.dst, writer.i, key, a, b, c, d, keep));
765
+ uint i = writer.i;
766
+ uint next = i + Sizes.Header + 96 + keep;
767
+ i = reserve(writer, next, i + Sizes.B128);
768
+ writeBlock128(writer.dst, i, key, a, b, c, d, keep);
683
769
  }
684
770
 
685
771
  /// @notice Append a fixed-width 160-byte-payload block.
@@ -701,39 +787,111 @@ library Writers {
701
787
  bytes32 e,
702
788
  uint keep
703
789
  ) internal pure {
704
- commit(writer, writeBlock160(writer.dst, writer.i, key, a, b, c, d, e, keep));
790
+ uint i = writer.i;
791
+ uint next = i + Sizes.Header + 128 + keep;
792
+ i = reserve(writer, next, i + Sizes.B160);
793
+ writeBlock160(writer.dst, i, key, a, b, c, d, e, keep);
705
794
  }
706
795
 
707
- /// @notice Append a dynamic block with a fixed 32-byte head word.
708
- /// @param writer Destination writer; `i` is advanced by `Sizes.B32 + tail.length`.
709
- /// @param key Block type key.
796
+ /// @notice Append a block with a 32-byte head and two nested BYTES payloads.
797
+ /// @param writer Destination writer; `i` is advanced by the encoded block length.
798
+ /// @param key Block key.
710
799
  /// @param a Fixed head word.
711
- /// @param tail Dynamic payload bytes appended after the head.
712
- function appendBlockHead32(Writer memory writer, bytes4 key, bytes32 a, bytes memory tail) internal pure {
713
- commit(writer, writeBlockHead32(writer.dst, writer.i, key, a, tail));
714
- }
715
-
716
- /// @notice Append a dynamic block with a fixed 64-byte head.
717
- /// @param writer Destination writer; `i` is advanced by `Sizes.B64 + tail.length`.
718
- /// @param key Block type key.
719
- /// @param a First fixed head word.
720
- /// @param b Second fixed head word.
721
- /// @param tail Dynamic payload bytes appended after the head.
722
- function appendBlockHead64(
800
+ /// @param b First raw nested payload.
801
+ /// @param c Second raw nested payload.
802
+ function appendBlock32BytesBytes(
803
+ Writer memory writer,
804
+ bytes4 key,
805
+ bytes32 a,
806
+ bytes memory b,
807
+ bytes memory c
808
+ ) internal pure {
809
+ uint i = writer.i;
810
+ uint next = i + Sizes.B32 + 2 * Sizes.Header + b.length + c.length;
811
+ i = reserve(writer, next, next);
812
+ writeBlock32BytesBytes(writer.dst, i, key, a, b, c);
813
+ }
814
+
815
+ /// @notice Append a block with a 64-byte head and two nested BYTES payloads.
816
+ /// @param writer Destination writer; `i` is advanced by the encoded block length.
817
+ /// @param key Block key.
818
+ /// @param a First head word.
819
+ /// @param b Second head word.
820
+ /// @param c First raw nested payload.
821
+ /// @param d Second raw nested payload.
822
+ function appendBlock64BytesBytes(
723
823
  Writer memory writer,
724
824
  bytes4 key,
725
825
  bytes32 a,
726
826
  bytes32 b,
727
- bytes memory tail
827
+ bytes memory c,
828
+ bytes memory d
829
+ ) internal pure {
830
+ uint i = writer.i;
831
+ uint next = i + Sizes.B64 + 2 * Sizes.Header + c.length + d.length;
832
+ i = reserve(writer, next, next);
833
+ writeBlock64BytesBytes(writer.dst, i, key, a, b, c, d);
834
+ }
835
+
836
+ /// @notice Append a block with a 64-byte head and nested BYTES payload.
837
+ /// @param writer Destination writer; `i` is advanced by the encoded block length.
838
+ /// @param key Block key.
839
+ /// @param a First head word.
840
+ /// @param b Second head word.
841
+ /// @param c Raw nested payload.
842
+ function appendBlock64Bytes(Writer memory writer, bytes4 key, bytes32 a, bytes32 b, bytes memory c) internal pure {
843
+ uint i = writer.i;
844
+ uint next = i + Sizes.B64 + Sizes.Header + c.length;
845
+ i = reserve(writer, next, next);
846
+ writeBlock64Bytes(writer.dst, i, key, a, b, c);
847
+ }
848
+
849
+ /// @notice Append a BYTES block.
850
+ /// @param writer Destination writer; `i` is advanced by the encoded BYTES block length.
851
+ /// @param data Raw bytes payload.
852
+ function appendBytes(Writer memory writer, bytes memory data) internal pure {
853
+ appendBlock(writer, Keys.Bytes, data);
854
+ }
855
+
856
+ /// @notice Append a STEP block with a nested request BYTES payload.
857
+ /// @param writer Destination writer; `i` is advanced by the encoded STEP block length.
858
+ /// @param target Command target identifier.
859
+ /// @param value Native value forwarded with the step.
860
+ /// @param request Raw nested request payload.
861
+ function appendStep(Writer memory writer, uint target, uint value, bytes memory request) internal pure {
862
+ appendBlock64Bytes(writer, Keys.Step, bytes32(target), bytes32(value), request);
863
+ }
864
+
865
+ /// @notice Append a CALL block with a nested payload BYTES block.
866
+ /// @param writer Destination writer; `i` is advanced by the encoded CALL block length.
867
+ /// @param target Call target identifier.
868
+ /// @param value Native value forwarded with the call.
869
+ /// @param data Raw nested call payload.
870
+ function appendCall(Writer memory writer, uint target, uint value, bytes memory data) internal pure {
871
+ appendBlock64Bytes(writer, Keys.Call, bytes32(target), bytes32(value), data);
872
+ }
873
+
874
+ /// @notice Append a CONTEXT block with a value budget and nested state/request BYTES payloads.
875
+ /// @param writer Destination writer; `i` is advanced by the encoded CONTEXT block length.
876
+ /// @param account Command account identifier.
877
+ /// @param value Native value budget assigned to the context.
878
+ /// @param state Raw nested state payload.
879
+ /// @param request Raw nested request payload.
880
+ function appendContext(
881
+ Writer memory writer,
882
+ bytes32 account,
883
+ uint value,
884
+ bytes memory state,
885
+ bytes memory request
728
886
  ) internal pure {
729
- commit(writer, writeBlockHead64(writer.dst, writer.i, key, a, b, tail));
887
+ appendBlock64BytesBytes(writer, Keys.Context, account, bytes32(value), state, request);
730
888
  }
731
889
 
732
890
  /// @notice Append a STATUS form block.
733
- /// @param writer Destination writer; `i` is advanced by `Sizes.B32`.
891
+ /// @param writer Destination writer; `i` is advanced by `Sizes.Status`.
734
892
  /// @param ok Status value to encode.
735
893
  function appendStatus(Writer memory writer, bool ok) internal pure {
736
- commit(writer, writeBlock32(writer.dst, writer.i, Keys.Status, ok ? bytes32(uint(1)) : bytes32(0), 32));
894
+ appendBlock32(writer, Keys.Status, ok ? bytes32(uint(1) << 248) : bytes32(0), 1);
737
895
  }
738
896
 
739
897
  /// @notice Append a BALANCE block using separate field values.
@@ -742,17 +900,14 @@ library Writers {
742
900
  /// @param meta Asset metadata slot.
743
901
  /// @param amount Token amount.
744
902
  function appendBalance(Writer memory writer, bytes32 asset, bytes32 meta, uint amount) internal pure {
745
- commit(writer, writeBlock96(writer.dst, writer.i, Keys.Balance, asset, meta, bytes32(amount), 32));
903
+ appendBlock96(writer, Keys.Balance, asset, meta, bytes32(amount), 32);
746
904
  }
747
905
 
748
906
  /// @notice Append a BALANCE block from a struct.
749
907
  /// @param writer Destination writer; `i` is advanced by `Sizes.Balance`.
750
908
  /// @param value Balance fields to encode.
751
909
  function appendBalance(Writer memory writer, AssetAmount memory value) internal pure {
752
- commit(
753
- writer,
754
- writeBlock96(writer.dst, writer.i, Keys.Balance, value.asset, value.meta, bytes32(value.amount), 32)
755
- );
910
+ appendBalance(writer, value.asset, value.meta, value.amount);
756
911
  }
757
912
 
758
913
  /// @notice Append an AMOUNT block using separate field values.
@@ -761,17 +916,14 @@ library Writers {
761
916
  /// @param meta Asset metadata slot.
762
917
  /// @param amount Token amount.
763
918
  function appendAmount(Writer memory writer, bytes32 asset, bytes32 meta, uint amount) internal pure {
764
- commit(writer, writeBlock96(writer.dst, writer.i, Keys.Amount, asset, meta, bytes32(amount), 32));
919
+ appendBlock96(writer, Keys.Amount, asset, meta, bytes32(amount), 32);
765
920
  }
766
921
 
767
922
  /// @notice Append an AMOUNT block from a struct.
768
923
  /// @param writer Destination writer; `i` is advanced by `Sizes.Balance`.
769
924
  /// @param value Amount fields to encode.
770
925
  function appendAmount(Writer memory writer, AssetAmount memory value) internal pure {
771
- commit(
772
- writer,
773
- writeBlock96(writer.dst, writer.i, Keys.Amount, value.asset, value.meta, bytes32(value.amount), 32)
774
- );
926
+ appendAmount(writer, value.asset, value.meta, value.amount);
775
927
  }
776
928
 
777
929
  /// @notice Append an ACCOUNT_AMOUNT form block using separate field values.
@@ -787,29 +939,14 @@ library Writers {
787
939
  bytes32 meta,
788
940
  uint amount
789
941
  ) internal pure {
790
- commit(
791
- writer,
792
- writeBlock128(writer.dst, writer.i, Keys.AccountAmount, account, asset, meta, bytes32(amount), 32)
793
- );
942
+ appendBlock128(writer, Keys.AccountAmount, account, asset, meta, bytes32(amount), 32);
794
943
  }
795
944
 
796
945
  /// @notice Append an ACCOUNT_AMOUNT form block from a struct.
797
946
  /// @param writer Destination writer; `i` is advanced by `Sizes.B128`.
798
947
  /// @param value Account amount fields to encode.
799
948
  function appendAccountAmount(Writer memory writer, AccountAmount memory value) internal pure {
800
- commit(
801
- writer,
802
- writeBlock128(
803
- writer.dst,
804
- writer.i,
805
- Keys.AccountAmount,
806
- value.account,
807
- value.asset,
808
- value.meta,
809
- bytes32(value.amount),
810
- 32
811
- )
812
- );
949
+ appendAccountAmount(writer, value.account, value.asset, value.meta, value.amount);
813
950
  }
814
951
 
815
952
  /// @notice Append an ASSET block.
@@ -817,7 +954,7 @@ library Writers {
817
954
  /// @param asset Asset identifier.
818
955
  /// @param meta Asset metadata slot.
819
956
  function appendAsset(Writer memory writer, bytes32 asset, bytes32 meta) internal pure {
820
- commit(writer, writeBlock64(writer.dst, writer.i, Keys.Asset, asset, meta, 32));
957
+ appendBlock64(writer, Keys.Asset, asset, meta, 32);
821
958
  }
822
959
 
823
960
  /// @notice Append a BOUNTY block to the writer.
@@ -825,7 +962,7 @@ library Writers {
825
962
  /// @param amount Relayer reward amount.
826
963
  /// @param relayer Relayer account identifier.
827
964
  function appendBounty(Writer memory writer, uint amount, bytes32 relayer) internal pure {
828
- commit(writer, writeBlock64(writer.dst, writer.i, Keys.Bounty, bytes32(amount), relayer, 32));
965
+ appendBlock64(writer, Keys.Bounty, bytes32(amount), relayer, 32);
829
966
  }
830
967
 
831
968
  /// @notice Append a CUSTODY block using separate field values.
@@ -835,10 +972,7 @@ library Writers {
835
972
  /// @param meta Asset metadata slot.
836
973
  /// @param amount Token amount.
837
974
  function appendCustody(Writer memory writer, uint host, bytes32 asset, bytes32 meta, uint amount) internal pure {
838
- commit(
839
- writer,
840
- writeBlock128(writer.dst, writer.i, Keys.Custody, bytes32(host), asset, meta, bytes32(amount), 32)
841
- );
975
+ appendBlock128(writer, Keys.Custody, bytes32(host), asset, meta, bytes32(amount), 32);
842
976
  }
843
977
 
844
978
  /// @notice Append a CUSTODY block from a host and asset amount.
@@ -846,57 +980,29 @@ library Writers {
846
980
  /// @param host Host node ID.
847
981
  /// @param value Custody fields to encode.
848
982
  function appendCustody(Writer memory writer, uint host, AssetAmount memory value) internal pure {
849
- commit(
850
- writer,
851
- writeBlock128(
852
- writer.dst,
853
- writer.i,
854
- Keys.Custody,
855
- bytes32(host),
856
- value.asset,
857
- value.meta,
858
- bytes32(value.amount),
859
- 32
860
- )
861
- );
983
+ appendCustody(writer, host, value.asset, value.meta, value.amount);
862
984
  }
863
985
 
864
986
  /// @notice Append a CUSTODY block from a host amount struct.
865
987
  /// @param writer Destination writer; `i` is advanced by `Sizes.HostAmount`.
866
988
  /// @param value Custody fields to encode.
867
989
  function appendCustody(Writer memory writer, HostAmount memory value) internal pure {
868
- commit(
869
- writer,
870
- writeBlock128(
871
- writer.dst,
872
- writer.i,
873
- Keys.Custody,
874
- bytes32(value.host),
875
- value.asset,
876
- value.meta,
877
- bytes32(value.amount),
878
- 32
879
- )
880
- );
990
+ appendCustody(writer, value.host, value.asset, value.meta, value.amount);
881
991
  }
882
992
 
883
993
  /// @notice Append a TRANSACTION block from a struct.
884
994
  /// @param writer Destination writer; `i` is advanced by `Sizes.Transaction`.
885
995
  /// @param value Transfer record fields to encode.
886
996
  function appendTransaction(Writer memory writer, Tx memory value) internal pure {
887
- commit(
997
+ appendBlock160(
888
998
  writer,
889
- writeBlock160(
890
- writer.dst,
891
- writer.i,
892
- Keys.Transaction,
893
- bytes32(value.from),
894
- bytes32(value.to),
895
- value.asset,
896
- value.meta,
897
- bytes32(value.amount),
898
- 32
899
- )
999
+ Keys.Transaction,
1000
+ bytes32(value.from),
1001
+ bytes32(value.to),
1002
+ value.asset,
1003
+ value.meta,
1004
+ bytes32(value.amount),
1005
+ 32
900
1006
  );
901
1007
  }
902
1008