jaelis-node 1.10.0 → 2.1.0

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 (173) hide show
  1. package/README.md +156 -439
  2. package/bin/jaelis-node.js +83 -504
  3. package/lib/index.js +31 -2840
  4. package/lib/node.js +309 -0
  5. package/lib/rpc.js +315 -0
  6. package/lib/storage.js +198 -0
  7. package/lib/sync.js +366 -0
  8. package/package.json +19 -53
  9. package/config/default.json +0 -74
  10. package/config/mainnet.json +0 -30
  11. package/config/testnet.json +0 -26
  12. package/lib/JAELIS-VM/lib/adapters/evm-adapter.js +0 -454
  13. package/lib/JAELIS-VM/lib/adapters/index.js +0 -411
  14. package/lib/JAELIS-VM/lib/adapters/svm-adapter.js +0 -457
  15. package/lib/JAELIS-VM/lib/compiler/jir-compiler.js +0 -1097
  16. package/lib/JAELIS-VM/lib/execution/engine.js +0 -1183
  17. package/lib/JAELIS-VM/lib/index.js +0 -440
  18. package/lib/JAELIS-VM/lib/integration/jaelis-integration.js +0 -543
  19. package/lib/JAELIS-VM/lib/serialization/serializer.js +0 -819
  20. package/lib/JAELIS-VM/lib/state/state-manager.js +0 -1116
  21. package/lib/JAELIS-VM/lib/translator/bytecode-translator.js +0 -1222
  22. package/lib/JAELIS-VM/lib/unified/cross-chain-deploy.js +0 -1678
  23. package/lib/JAELIS-VM/lib/unified/cross-chain-state.js +0 -836
  24. package/lib/JAELIS-VM/lib/unified/dynamic-contracts.js +0 -1127
  25. package/lib/JAELIS-VM/lib/unified/index.js +0 -456
  26. package/lib/JAELIS-VM/lib/unified/jaelis-abi.js +0 -1150
  27. package/lib/JAELIS-VM/lib/unified/unified-compiler.js +0 -1350
  28. package/lib/JAELIS-VM/node_modules/.bin/download-cbor-prebuilds +0 -12
  29. package/lib/JAELIS-VM/node_modules/.bin/download-cbor-prebuilds.cmd +0 -17
  30. package/lib/JAELIS-VM/node_modules/.bin/download-cbor-prebuilds.ps1 +0 -28
  31. package/lib/JAELIS-VM/node_modules/.bin/download-msgpackr-prebuilds +0 -12
  32. package/lib/JAELIS-VM/node_modules/.bin/download-msgpackr-prebuilds.cmd +0 -17
  33. package/lib/JAELIS-VM/node_modules/.bin/download-msgpackr-prebuilds.ps1 +0 -28
  34. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages +0 -12
  35. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-optional +0 -12
  36. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-optional.cmd +0 -17
  37. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-optional.ps1 +0 -28
  38. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-test +0 -12
  39. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-test.cmd +0 -17
  40. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-test.ps1 +0 -28
  41. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages.cmd +0 -17
  42. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages.ps1 +0 -28
  43. package/lib/JAELIS-VM/node_modules/.package-lock.json +0 -127
  44. package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/README.md +0 -1
  45. package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/index.js +0 -0
  46. package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/node.abi115.node +0 -0
  47. package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/node.napi.node +0 -0
  48. package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/package.json +0 -17
  49. package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/README.md +0 -1
  50. package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/index.js +0 -0
  51. package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/node.abi115.node +0 -0
  52. package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/node.napi.node +0 -0
  53. package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/package.json +0 -17
  54. package/lib/JAELIS-VM/node_modules/cbor-extract/LICENSE +0 -21
  55. package/lib/JAELIS-VM/node_modules/cbor-extract/README.md +0 -5
  56. package/lib/JAELIS-VM/node_modules/cbor-extract/bin/download-prebuilds.js +0 -11
  57. package/lib/JAELIS-VM/node_modules/cbor-extract/binding.gyp +0 -60
  58. package/lib/JAELIS-VM/node_modules/cbor-extract/index.js +0 -1
  59. package/lib/JAELIS-VM/node_modules/cbor-extract/package.json +0 -50
  60. package/lib/JAELIS-VM/node_modules/cbor-extract/src/extract.cpp +0 -198
  61. package/lib/JAELIS-VM/node_modules/cbor-x/LICENSE +0 -21
  62. package/lib/JAELIS-VM/node_modules/cbor-x/README.md +0 -380
  63. package/lib/JAELIS-VM/node_modules/cbor-x/SECURITY.md +0 -11
  64. package/lib/JAELIS-VM/node_modules/cbor-x/benchmark.md +0 -73
  65. package/lib/JAELIS-VM/node_modules/cbor-x/browser.js +0 -11
  66. package/lib/JAELIS-VM/node_modules/cbor-x/decode.d.ts +0 -2
  67. package/lib/JAELIS-VM/node_modules/cbor-x/decode.js +0 -1300
  68. package/lib/JAELIS-VM/node_modules/cbor-x/dist/decode-no-eval.cjs +0 -1244
  69. package/lib/JAELIS-VM/node_modules/cbor-x/dist/decode-no-eval.cjs.map +0 -1
  70. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.cjs +0 -2509
  71. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.cjs.map +0 -1
  72. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.min.js +0 -2
  73. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.min.js.map +0 -1
  74. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.js +0 -2508
  75. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.js.map +0 -1
  76. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.min.js +0 -2
  77. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.min.js.map +0 -1
  78. package/lib/JAELIS-VM/node_modules/cbor-x/dist/node.cjs +0 -2629
  79. package/lib/JAELIS-VM/node_modules/cbor-x/dist/node.cjs.map +0 -1
  80. package/lib/JAELIS-VM/node_modules/cbor-x/dist/test.js +0 -3343
  81. package/lib/JAELIS-VM/node_modules/cbor-x/dist/test.js.map +0 -1
  82. package/lib/JAELIS-VM/node_modules/cbor-x/encode.d.ts +0 -1
  83. package/lib/JAELIS-VM/node_modules/cbor-x/encode.js +0 -1231
  84. package/lib/JAELIS-VM/node_modules/cbor-x/index.d.ts +0 -79
  85. package/lib/JAELIS-VM/node_modules/cbor-x/index.js +0 -3
  86. package/lib/JAELIS-VM/node_modules/cbor-x/iterators.js +0 -85
  87. package/lib/JAELIS-VM/node_modules/cbor-x/node-index.js +0 -24
  88. package/lib/JAELIS-VM/node_modules/cbor-x/package.json +0 -94
  89. package/lib/JAELIS-VM/node_modules/cbor-x/rollup.config.js +0 -88
  90. package/lib/JAELIS-VM/node_modules/cbor-x/stream.js +0 -61
  91. package/lib/JAELIS-VM/node_modules/cbor-x/webpack.config.js +0 -19
  92. package/lib/JAELIS-VM/node_modules/detect-libc/LICENSE +0 -201
  93. package/lib/JAELIS-VM/node_modules/detect-libc/README.md +0 -163
  94. package/lib/JAELIS-VM/node_modules/detect-libc/index.d.ts +0 -14
  95. package/lib/JAELIS-VM/node_modules/detect-libc/lib/detect-libc.js +0 -313
  96. package/lib/JAELIS-VM/node_modules/detect-libc/lib/elf.js +0 -39
  97. package/lib/JAELIS-VM/node_modules/detect-libc/lib/filesystem.js +0 -51
  98. package/lib/JAELIS-VM/node_modules/detect-libc/lib/process.js +0 -24
  99. package/lib/JAELIS-VM/node_modules/detect-libc/package.json +0 -44
  100. package/lib/JAELIS-VM/node_modules/msgpackr/LICENSE +0 -21
  101. package/lib/JAELIS-VM/node_modules/msgpackr/README.md +0 -372
  102. package/lib/JAELIS-VM/node_modules/msgpackr/SECURITY.md +0 -11
  103. package/lib/JAELIS-VM/node_modules/msgpackr/benchmark.md +0 -67
  104. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.cjs +0 -2407
  105. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.cjs.map +0 -1
  106. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.min.js +0 -2
  107. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.min.js.map +0 -1
  108. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.js +0 -2406
  109. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.js.map +0 -1
  110. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.min.js +0 -2
  111. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.min.js.map +0 -1
  112. package/lib/JAELIS-VM/node_modules/msgpackr/dist/node.cjs +0 -3320
  113. package/lib/JAELIS-VM/node_modules/msgpackr/dist/node.cjs.map +0 -1
  114. package/lib/JAELIS-VM/node_modules/msgpackr/dist/test.js +0 -4540
  115. package/lib/JAELIS-VM/node_modules/msgpackr/dist/test.js.map +0 -1
  116. package/lib/JAELIS-VM/node_modules/msgpackr/dist/unpack-no-eval.cjs +0 -1250
  117. package/lib/JAELIS-VM/node_modules/msgpackr/dist/unpack-no-eval.cjs.map +0 -1
  118. package/lib/JAELIS-VM/node_modules/msgpackr/index.d.cts +0 -91
  119. package/lib/JAELIS-VM/node_modules/msgpackr/index.d.ts +0 -91
  120. package/lib/JAELIS-VM/node_modules/msgpackr/index.js +0 -5
  121. package/lib/JAELIS-VM/node_modules/msgpackr/iterators.js +0 -87
  122. package/lib/JAELIS-VM/node_modules/msgpackr/node-index.js +0 -25
  123. package/lib/JAELIS-VM/node_modules/msgpackr/pack.d.cts +0 -1
  124. package/lib/JAELIS-VM/node_modules/msgpackr/pack.d.ts +0 -1
  125. package/lib/JAELIS-VM/node_modules/msgpackr/pack.js +0 -1141
  126. package/lib/JAELIS-VM/node_modules/msgpackr/package.json +0 -104
  127. package/lib/JAELIS-VM/node_modules/msgpackr/rollup.config.js +0 -88
  128. package/lib/JAELIS-VM/node_modules/msgpackr/stream.js +0 -57
  129. package/lib/JAELIS-VM/node_modules/msgpackr/struct.js +0 -815
  130. package/lib/JAELIS-VM/node_modules/msgpackr/test-worker.js +0 -3
  131. package/lib/JAELIS-VM/node_modules/msgpackr/unpack.d.cts +0 -2
  132. package/lib/JAELIS-VM/node_modules/msgpackr/unpack.d.ts +0 -2
  133. package/lib/JAELIS-VM/node_modules/msgpackr/unpack.js +0 -1221
  134. package/lib/JAELIS-VM/node_modules/msgpackr-extract/LICENSE +0 -21
  135. package/lib/JAELIS-VM/node_modules/msgpackr-extract/README.md +0 -5
  136. package/lib/JAELIS-VM/node_modules/msgpackr-extract/bin/download-prebuilds.js +0 -13
  137. package/lib/JAELIS-VM/node_modules/msgpackr-extract/binding.gyp +0 -63
  138. package/lib/JAELIS-VM/node_modules/msgpackr-extract/index.js +0 -1
  139. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages +0 -12
  140. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-optional +0 -12
  141. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-optional.cmd +0 -17
  142. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-optional.ps1 +0 -28
  143. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-test +0 -12
  144. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-test.cmd +0 -17
  145. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-test.ps1 +0 -28
  146. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages.cmd +0 -17
  147. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages.ps1 +0 -28
  148. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/LICENSE +0 -21
  149. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/README.md +0 -58
  150. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/bin.js +0 -82
  151. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/build-test.js +0 -19
  152. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/index.js +0 -6
  153. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/node-gyp-build.js +0 -236
  154. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/optional.js +0 -7
  155. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/package.json +0 -32
  156. package/lib/JAELIS-VM/node_modules/msgpackr-extract/package.json +0 -50
  157. package/lib/JAELIS-VM/node_modules/msgpackr-extract/src/extract.cpp +0 -274
  158. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/LICENSE +0 -21
  159. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/README.md +0 -58
  160. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/bin.js +0 -77
  161. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/build-test.js +0 -19
  162. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/index.js +0 -224
  163. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/optional.js +0 -7
  164. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/package.json +0 -32
  165. package/lib/JAELIS-VM/package-lock.json +0 -284
  166. package/lib/JAELIS-VM/package.json +0 -38
  167. package/lib/JAELIS-VM/test/comprehensive.test.js +0 -267
  168. package/lib/JAELIS-VM/test/cross-chain-test.js +0 -470
  169. package/lib/JAELIS-VM/test/unified-vm-test.js +0 -459
  170. package/lib/JAELIS-VM/test/unified.test.js +0 -166
  171. package/lib/JAELIS-VM/test/vm.test.js +0 -599
  172. package/lib/settlement-server.js +0 -999
  173. package/lib/vm/index.js +0 -397
@@ -1,1127 +0,0 @@
1
- /**
2
- * JAELIS DYNAMIC CONTRACTS
3
- *
4
- * Contracts that can UPDATE THEMSELVES when the underlying
5
- * VM specs change. No more "deploy new version" BS.
6
- *
7
- * How it works:
8
- * 1. Contracts are stored as UNIFIED AST, not frozen bytecode
9
- * 2. When VM specs update, contracts auto-recompile
10
- * 3. State is preserved, only logic updates
11
- * 4. Cross-contract calls automatically adapt
12
- *
13
- * Example:
14
- * - Solana adds a new opcode for faster hashing
15
- * - Our unified compiler absorbs the new opcode
16
- * - ALL contracts that use hashing get faster automatically
17
- * - No migration, no upgrade, no downtime
18
- *
19
- * @version 0.2.0
20
- * @author Mario Papaleo - JAELIS Foundation
21
- * @patent PATENT PENDING - Self-Updating Smart Contracts
22
- */
23
-
24
- const crypto = require('crypto');
25
- const EventEmitter = require('events');
26
- const { UnifiedCompiler } = require('./unified-compiler');
27
-
28
- /**
29
- * Contract State Store
30
- *
31
- * Separates state from logic - key for dynamic updates!
32
- * Now backed by Core StateManager for LevelDB persistence.
33
- *
34
- * Architecture (Patent Claim 7d - Unified State Manager):
35
- * ContractStateStore → Core StateManager → LevelDB
36
- */
37
- class ContractStateStore {
38
- constructor(contractAddress = null) {
39
- // Contract address for namespacing
40
- this._contractAddress = contractAddress;
41
-
42
- // Core StateManager reference (LevelDB backend)
43
- this._coreState = null;
44
- this._connected = false;
45
-
46
- // Local cache for fast reads (synced with LevelDB)
47
- this._slots = new Map();
48
-
49
- // State version tracking
50
- this.versions = new Map();
51
-
52
- // State snapshots for rollback
53
- this.snapshots = [];
54
- }
55
-
56
- /**
57
- * Connect to Core StateManager for LevelDB persistence
58
- */
59
- connectCoreState(coreStateManager, contractAddress = null) {
60
- this._coreState = coreStateManager;
61
- this._connected = true;
62
- if (contractAddress) {
63
- this._contractAddress = contractAddress;
64
- }
65
- console.log(`[ContractStateStore] Connected to Core StateManager (LevelDB)`);
66
- return this;
67
- }
68
-
69
- /**
70
- * Check if connected to Core StateManager
71
- */
72
- isConnected() {
73
- return this._connected && this._coreState !== null;
74
- }
75
-
76
- /**
77
- * Legacy slots getter for compatibility
78
- */
79
- get slots() {
80
- return this._slots;
81
- }
82
-
83
- read(slot) {
84
- const key = typeof slot === 'string' ? slot : slot.toString('hex');
85
-
86
- // Check local cache
87
- if (this._slots.has(key)) {
88
- return this._slots.get(key);
89
- }
90
-
91
- return Buffer.alloc(32);
92
- }
93
-
94
- /**
95
- * Async read with LevelDB fallback
96
- */
97
- async readAsync(slot) {
98
- const key = typeof slot === 'string' ? slot : slot.toString('hex');
99
-
100
- // Check local cache
101
- if (this._slots.has(key)) {
102
- return this._slots.get(key);
103
- }
104
-
105
- // Try Core StateManager (LevelDB)
106
- if (this._coreState && this._contractAddress) {
107
- try {
108
- const value = await this._coreState.getStorage(this._contractAddress, '0x' + key);
109
- if (value && value !== '0x' + '0'.repeat(64)) {
110
- const buffer = Buffer.from(value.replace('0x', ''), 'hex');
111
- this._slots.set(key, buffer);
112
- return buffer;
113
- }
114
- } catch (e) {
115
- // Slot empty
116
- }
117
- }
118
-
119
- return Buffer.alloc(32);
120
- }
121
-
122
- write(slot, value) {
123
- const key = typeof slot === 'string' ? slot : slot.toString('hex');
124
- const oldValue = this._slots.get(key);
125
-
126
- this._slots.set(key, value);
127
-
128
- // Track version
129
- const version = (this.versions.get(key) || 0) + 1;
130
- this.versions.set(key, version);
131
-
132
- // Persist to Core StateManager (LevelDB) - async fire and forget
133
- if (this._coreState && this._contractAddress) {
134
- const hexValue = Buffer.isBuffer(value) ? '0x' + value.toString('hex') : value;
135
- this._coreState.setStorage(this._contractAddress, '0x' + key, hexValue)
136
- .catch(err => console.error('[ContractStateStore] LevelDB write error:', err));
137
- }
138
-
139
- return { slot, oldValue, newValue: value, version };
140
- }
141
-
142
- /**
143
- * Async write with await for LevelDB
144
- */
145
- async writeAsync(slot, value) {
146
- const key = typeof slot === 'string' ? slot : slot.toString('hex');
147
- const oldValue = this._slots.get(key);
148
-
149
- this._slots.set(key, value);
150
-
151
- // Track version
152
- const version = (this.versions.get(key) || 0) + 1;
153
- this.versions.set(key, version);
154
-
155
- // Persist to Core StateManager (LevelDB)
156
- if (this._coreState && this._contractAddress) {
157
- const hexValue = Buffer.isBuffer(value) ? '0x' + value.toString('hex') : value;
158
- await this._coreState.setStorage(this._contractAddress, '0x' + key, hexValue);
159
- }
160
-
161
- return { slot, oldValue, newValue: value, version };
162
- }
163
-
164
- snapshot() {
165
- const id = this.snapshots.length;
166
- this.snapshots.push(new Map(this._slots));
167
-
168
- // Also snapshot Core StateManager if connected
169
- if (this._coreState && this._coreState.snapshot) {
170
- this._coreSnapshotId = this._coreState.snapshot();
171
- }
172
-
173
- return id;
174
- }
175
-
176
- rollback(snapshotId) {
177
- if (snapshotId < this.snapshots.length) {
178
- this._slots = new Map(this.snapshots[snapshotId]);
179
-
180
- // Also rollback Core StateManager if connected
181
- if (this._coreState && this._coreState.revertToSnapshot && this._coreSnapshotId !== undefined) {
182
- this._coreState.revertToSnapshot(this._coreSnapshotId);
183
- }
184
- }
185
- }
186
-
187
- /**
188
- * Get stats
189
- */
190
- getStats() {
191
- return {
192
- connected: this._connected,
193
- contractAddress: this._contractAddress,
194
- cachedSlots: this._slots.size,
195
- versions: this.versions.size,
196
- snapshots: this.snapshots.length
197
- };
198
- }
199
- }
200
-
201
- /**
202
- * Dynamic Contract
203
- *
204
- * A contract that stores both its AST and bytecode,
205
- * allowing it to recompile when VM specs change.
206
- */
207
- class DynamicContract extends EventEmitter {
208
- constructor(address, source, language) {
209
- super();
210
-
211
- this.address = address;
212
- this.source = source; // Original source code
213
- this.language = language; // Original language
214
- this.ast = null; // Unified AST
215
- this.bytecode = null; // Current bytecode
216
- this.version = 0; // Contract version
217
- this.state = new ContractStateStore();
218
-
219
- // Interface definition (for cross-contract calls)
220
- this.interface = {
221
- functions: new Map(),
222
- events: new Map(),
223
- errors: new Map()
224
- };
225
-
226
- // Upgrade history
227
- this.history = [];
228
-
229
- // Dependencies on other contracts
230
- this.dependencies = new Set();
231
-
232
- // Contracts that depend on us
233
- this.dependents = new Set();
234
-
235
- // Last compilation timestamp
236
- this.lastCompiled = null;
237
-
238
- // Compiler version used
239
- this.compilerVersion = null;
240
- }
241
-
242
- /**
243
- * Compile/recompile the contract
244
- */
245
- async compile(compiler) {
246
- console.log(`[DynamicContract] Compiling ${this.address.substring(0, 16)}...`);
247
-
248
- const startTime = Date.now();
249
-
250
- // Store old bytecode for rollback
251
- const oldBytecode = this.bytecode;
252
- const oldVersion = this.version;
253
-
254
- try {
255
- // Compile to unified AST
256
- const result = await compiler.compile([{
257
- name: this.address,
258
- code: this.source,
259
- language: this.language
260
- }]);
261
-
262
- this.ast = result.asts[0];
263
- this.bytecode = result.bytecode;
264
- this.version++;
265
- this.lastCompiled = Date.now();
266
- this.compilerVersion = '0.2.0';
267
-
268
- // Update interface
269
- this.updateInterface();
270
-
271
- // Record in history
272
- this.history.push({
273
- version: this.version,
274
- timestamp: this.lastCompiled,
275
- bytecodeHash: crypto.createHash('sha256').update(this.bytecode).digest('hex'),
276
- reason: 'compilation'
277
- });
278
-
279
- console.log(`[DynamicContract] Compiled v${this.version} in ${Date.now() - startTime}ms`);
280
-
281
- this.emit('compiled', { version: this.version });
282
-
283
- return true;
284
-
285
- } catch (error) {
286
- // Rollback
287
- this.bytecode = oldBytecode;
288
- this.version = oldVersion;
289
- console.error(`[DynamicContract] Compilation failed: ${error.message}`);
290
- throw error;
291
- }
292
- }
293
-
294
- /**
295
- * Update when VM specs change
296
- */
297
- async upgrade(compiler, reason = 'vm-upgrade') {
298
- console.log(`[DynamicContract] Upgrading due to: ${reason}`);
299
-
300
- // Snapshot state before upgrade
301
- const stateSnapshot = this.state.snapshot();
302
-
303
- try {
304
- // Recompile with new compiler
305
- await this.compile(compiler);
306
-
307
- // Record upgrade
308
- this.history[this.history.length - 1].reason = reason;
309
-
310
- this.emit('upgraded', { version: this.version, reason });
311
-
312
- // Notify dependents
313
- for (const dependent of this.dependents) {
314
- this.emit('dependentNeedsUpgrade', { dependent, reason });
315
- }
316
-
317
- return true;
318
-
319
- } catch (error) {
320
- // Rollback state
321
- this.state.rollback(stateSnapshot);
322
- throw error;
323
- }
324
- }
325
-
326
- /**
327
- * Update interface from AST
328
- */
329
- updateInterface() {
330
- this.interface.functions.clear();
331
- this.interface.events.clear();
332
-
333
- if (!this.ast) return;
334
-
335
- for (const contract of this.ast.contracts || []) {
336
- for (const func of contract.functions || []) {
337
- this.interface.functions.set(func.name, {
338
- name: func.name,
339
- selector: this.computeSelector(func.name, func.params),
340
- params: func.params,
341
- returns: func.returns,
342
- visibility: func.visibility,
343
- mutability: func.mutability
344
- });
345
- }
346
- }
347
- }
348
-
349
- computeSelector(name, params) {
350
- const signature = `${name}(${(params || []).map(p => p.type || 'uint256').join(',')})`;
351
- return crypto.createHash('sha256').update(signature).digest().slice(0, 4);
352
- }
353
-
354
- /**
355
- * Get contract ABI (compatible with all VMs!)
356
- */
357
- getABI() {
358
- const abi = [];
359
-
360
- for (const [name, func] of this.interface.functions) {
361
- abi.push({
362
- type: 'function',
363
- name: func.name,
364
- inputs: (func.params || []).map(p => ({
365
- name: p.name,
366
- type: this.toABIType(p.type)
367
- })),
368
- outputs: (func.returns || []).map(r => ({
369
- type: this.toABIType(r)
370
- })),
371
- stateMutability: func.mutability || 'nonpayable'
372
- });
373
- }
374
-
375
- return abi;
376
- }
377
-
378
- toABIType(unifiedType) {
379
- const typeMap = {
380
- 'U256': 'uint256',
381
- 'U128': 'uint128',
382
- 'U64': 'uint64',
383
- 'U32': 'uint32',
384
- 'U8': 'uint8',
385
- 'I256': 'int256',
386
- 'BOOL': 'bool',
387
- 'ADDRESS': 'address',
388
- 'BYTES32': 'bytes32',
389
- 'BYTES': 'bytes',
390
- 'STRING': 'string'
391
- };
392
- return typeMap[unifiedType] || 'uint256';
393
- }
394
- }
395
-
396
- /**
397
- * Dynamic Contract Manager
398
- *
399
- * Manages all dynamic contracts, handles upgrades,
400
- * and coordinates cross-contract updates.
401
- */
402
- class DynamicContractManager extends EventEmitter {
403
- constructor() {
404
- super();
405
-
406
- this.contracts = new Map();
407
- this.compiler = new UnifiedCompiler();
408
-
409
- // VM specification versions
410
- this.vmSpecs = {
411
- evm: '0.8.24', // Latest Solidity
412
- svm: '1.18.0', // Latest Solana
413
- move: '1.0.0', // Aptos Move
414
- tvm: '4.0.0', // TON
415
- cairo: '2.0.0', // Starknet Cairo
416
- wasm: '3.0.0' // WASM 3.0
417
- };
418
-
419
- // Upgrade queue
420
- this.upgradeQueue = [];
421
-
422
- // Auto-upgrade enabled
423
- this.autoUpgrade = true;
424
-
425
- console.log('[DynamicContractManager] Initialized');
426
- }
427
-
428
- /**
429
- * Deploy a new dynamic contract
430
- */
431
- async deploy(source, language, options = {}) {
432
- const address = options.address || this.generateAddress(source);
433
-
434
- console.log(`[DynamicContractManager] Deploying ${language} contract to ${address.substring(0, 16)}...`);
435
-
436
- const contract = new DynamicContract(address, source, language);
437
-
438
- // Initial compilation
439
- await contract.compile(this.compiler);
440
-
441
- // Register
442
- this.contracts.set(address, contract);
443
-
444
- // Setup event listeners
445
- contract.on('dependentNeedsUpgrade', ({ dependent, reason }) => {
446
- if (this.autoUpgrade) {
447
- this.queueUpgrade(dependent, reason);
448
- }
449
- });
450
-
451
- this.emit('deployed', { address, language, version: contract.version });
452
-
453
- return {
454
- address,
455
- contract,
456
- bytecode: contract.bytecode,
457
- abi: contract.getABI()
458
- };
459
- }
460
-
461
- /**
462
- * Update VM specs (triggers auto-upgrade)
463
- */
464
- async updateVMSpec(vm, newVersion) {
465
- const oldVersion = this.vmSpecs[vm];
466
- this.vmSpecs[vm] = newVersion;
467
-
468
- console.log(`[DynamicContractManager] VM spec update: ${vm} ${oldVersion} → ${newVersion}`);
469
-
470
- // Find all contracts using this VM
471
- const affectedContracts = [];
472
- for (const [address, contract] of this.contracts) {
473
- // Fixed: was triple comparison bug (a === b === c)
474
- if (this.languageToVM(contract.language) === vm) {
475
- affectedContracts.push(address);
476
- }
477
- }
478
-
479
- console.log(`[DynamicContractManager] ${affectedContracts.length} contracts affected`);
480
-
481
- if (this.autoUpgrade) {
482
- // Queue all for upgrade
483
- for (const address of affectedContracts) {
484
- this.queueUpgrade(address, `vm-upgrade:${vm}:${newVersion}`);
485
- }
486
-
487
- // Process queue
488
- await this.processUpgradeQueue();
489
- }
490
-
491
- return affectedContracts;
492
- }
493
-
494
- languageToVM(language) {
495
- const map = {
496
- 'solidity': 'evm',
497
- 'vyper': 'evm',
498
- 'rust': 'svm',
499
- 'move': 'move',
500
- 'func': 'tvm',
501
- 'cairo': 'cairo'
502
- };
503
- return map[language] || 'evm';
504
- }
505
-
506
- /**
507
- * Queue a contract for upgrade
508
- */
509
- queueUpgrade(address, reason) {
510
- if (!this.upgradeQueue.find(u => u.address === address)) {
511
- this.upgradeQueue.push({ address, reason, queuedAt: Date.now() });
512
- console.log(`[DynamicContractManager] Queued upgrade: ${address.substring(0, 16)}... (${reason})`);
513
- }
514
- }
515
-
516
- /**
517
- * Process upgrade queue
518
- */
519
- async processUpgradeQueue() {
520
- console.log(`[DynamicContractManager] Processing ${this.upgradeQueue.length} upgrades...`);
521
-
522
- const results = [];
523
-
524
- while (this.upgradeQueue.length > 0) {
525
- const { address, reason } = this.upgradeQueue.shift();
526
-
527
- const contract = this.contracts.get(address);
528
- if (!contract) continue;
529
-
530
- try {
531
- await contract.upgrade(this.compiler, reason);
532
- results.push({ address, success: true, version: contract.version });
533
- } catch (error) {
534
- results.push({ address, success: false, error: error.message });
535
- }
536
- }
537
-
538
- console.log(`[DynamicContractManager] Completed ${results.length} upgrades`);
539
- return results;
540
- }
541
-
542
- /**
543
- * Direct cross-contract call (NO BRIDGES!)
544
- */
545
- async crossContractCall(fromAddress, toAddress, functionName, args) {
546
- console.log(`[DynamicContractManager] Cross-call: ${fromAddress.substring(0, 10)}... → ${toAddress.substring(0, 10)}...::${functionName}`);
547
-
548
- const fromContract = this.contracts.get(fromAddress);
549
- const toContract = this.contracts.get(toAddress);
550
-
551
- if (!fromContract || !toContract) {
552
- throw new Error('Contract not found');
553
- }
554
-
555
- // Get function from target contract
556
- const func = toContract.interface.functions.get(functionName);
557
- if (!func) {
558
- throw new Error(`Function not found: ${functionName}`);
559
- }
560
-
561
- // Direct call - same memory space, no bridge!
562
- // The key insight: both contracts share the same state store
563
- // and can access each other's state directly
564
-
565
- // Record dependency
566
- fromContract.dependencies.add(toAddress);
567
- toContract.dependents.add(fromAddress);
568
-
569
- this.emit('crossCall', {
570
- from: fromAddress,
571
- to: toAddress,
572
- function: functionName,
573
- args
574
- });
575
-
576
- // Execute on target contract's bytecode
577
- const result = await this.executeFunction(toContract, func, args, {
578
- caller: fromAddress,
579
- origin: fromAddress,
580
- value: 0n
581
- });
582
-
583
- return result;
584
- }
585
-
586
- /**
587
- * Execute a function on a contract
588
- *
589
- * This is the actual bytecode execution engine
590
- */
591
- async executeFunction(contract, func, args, context = {}) {
592
- // JIR Opcodes
593
- const OP = {
594
- NOP: 0x00, BLOCK: 0x01, LOOP: 0x02, IF: 0x03, ELSE: 0x04, END: 0x05,
595
- BR: 0x06, BR_IF: 0x07, RETURN: 0x08, CALL: 0x09,
596
- DROP: 0x10, LOCAL_GET: 0x12, LOCAL_SET: 0x13,
597
- I32_LOAD: 0x20, I64_LOAD: 0x21, I32_STORE: 0x24, I64_STORE: 0x25,
598
- I32_CONST: 0x30, I64_CONST: 0x31,
599
- I32_ADD: 0x34, I32_SUB: 0x35, I32_MUL: 0x36, I32_DIV_S: 0x37,
600
- I64_ADD: 0x39, I64_SUB: 0x3A, I64_MUL: 0x3B, I64_DIV_S: 0x3C,
601
- I32_EQ: 0x40, I32_NE: 0x41, I32_LT_S: 0x42, I32_GT_S: 0x44,
602
- I32_AND: 0x50, I32_OR: 0x51, I32_XOR: 0x52,
603
- SLOAD: 0x80, SSTORE: 0x81, BALANCE: 0x84, TRANSFER: 0x85,
604
- CONTRACT_CALL: 0x87, CALLER: 0x90, CALLVALUE: 0x92,
605
- TIMESTAMP: 0xA2, BLOCKNUMBER: 0xA3,
606
- LOG0: 0xC0, LOG1: 0xC1, LOG2: 0xC2, LOG3: 0xC3, LOG4: 0xC4,
607
- CROSS_VM_CALL: 0xD0, REVERT: 0xFE, HALT: 0xFF
608
- };
609
-
610
- // Find function bytecode in contract
611
- let funcBytecode = null;
612
-
613
- // Search in compiled bytecode for the function
614
- if (contract.bytecode) {
615
- // Parse bytecode to find function by selector
616
- const selector = func.selector;
617
- const bytecode = contract.bytecode;
618
-
619
- // Simple bytecode structure: look for matching selector
620
- // Format: [magic][version][contracts...]
621
- // Contract: [nameLen][name][funcCount][functions...]
622
- // Function: [selector:4][bytecodeLen:2][bytecode...]
623
-
624
- let pos = 11; // Skip magic (8) + version (3)
625
- if (bytecode.length > pos) {
626
- const contractCount = bytecode[pos++];
627
- for (let c = 0; c < contractCount && !funcBytecode; c++) {
628
- const nameLen = bytecode[pos++];
629
- pos += nameLen; // Skip name
630
- const funcCount = bytecode[pos++];
631
- for (let f = 0; f < funcCount; f++) {
632
- const funcSelector = bytecode.slice(pos, pos + 4);
633
- pos += 4;
634
- const bytecodeLen = bytecode.readUInt16LE(pos);
635
- pos += 2;
636
- if (selector.equals(funcSelector)) {
637
- funcBytecode = bytecode.slice(pos, pos + bytecodeLen);
638
- break;
639
- }
640
- pos += bytecodeLen;
641
- }
642
- }
643
- }
644
- }
645
-
646
- if (!funcBytecode) {
647
- // No bytecode found, return default
648
- console.log(`[ExecuteFunction] No bytecode found for ${func.name}, using default`);
649
- return {
650
- success: true,
651
- returnValue: null,
652
- gasUsed: 0,
653
- logs: []
654
- };
655
- }
656
-
657
- // Execute bytecode
658
- const stack = [];
659
- const locals = new Map();
660
- const logs = [];
661
- let pc = 0; // Program counter
662
- let returnValue = null;
663
- let reverted = false;
664
-
665
- // Initialize locals with args
666
- for (let i = 0; i < args.length; i++) {
667
- locals.set(i, args[i]);
668
- }
669
-
670
- // Execution loop
671
- while (pc < funcBytecode.length && !reverted) {
672
- const opcode = funcBytecode[pc++];
673
-
674
- switch (opcode) {
675
- case OP.NOP:
676
- break;
677
-
678
- case OP.BLOCK:
679
- // Skip param/return counts
680
- pc += 2;
681
- break;
682
-
683
- case OP.END:
684
- // End of block
685
- break;
686
-
687
- case OP.RETURN:
688
- returnValue = stack.pop();
689
- pc = funcBytecode.length; // Exit loop
690
- break;
691
-
692
- case OP.I32_CONST:
693
- const i32 = funcBytecode.readInt32LE(pc);
694
- pc += 4;
695
- stack.push(i32);
696
- break;
697
-
698
- case OP.I64_CONST:
699
- const i64 = funcBytecode.readBigInt64LE(pc);
700
- pc += 8;
701
- stack.push(i64);
702
- break;
703
-
704
- case OP.LOCAL_GET:
705
- const getIdx = funcBytecode[pc++];
706
- stack.push(locals.get(getIdx) || 0n);
707
- break;
708
-
709
- case OP.LOCAL_SET:
710
- const setIdx = funcBytecode[pc++];
711
- locals.set(setIdx, stack.pop());
712
- break;
713
-
714
- case OP.I64_ADD:
715
- const addB = BigInt(stack.pop() || 0);
716
- const addA = BigInt(stack.pop() || 0);
717
- stack.push(addA + addB);
718
- break;
719
-
720
- case OP.I64_SUB:
721
- const subB = BigInt(stack.pop() || 0);
722
- const subA = BigInt(stack.pop() || 0);
723
- stack.push(subA - subB);
724
- break;
725
-
726
- case OP.I64_MUL:
727
- const mulB = BigInt(stack.pop() || 0);
728
- const mulA = BigInt(stack.pop() || 0);
729
- stack.push(mulA * mulB);
730
- break;
731
-
732
- case OP.I64_DIV_S:
733
- const divB = BigInt(stack.pop() || 1);
734
- const divA = BigInt(stack.pop() || 0);
735
- stack.push(divB !== 0n ? divA / divB : 0n);
736
- break;
737
-
738
- case OP.I32_EQ:
739
- const eqB = stack.pop();
740
- const eqA = stack.pop();
741
- stack.push(eqA === eqB ? 1 : 0);
742
- break;
743
-
744
- case OP.I32_NE:
745
- const neB = stack.pop();
746
- const neA = stack.pop();
747
- stack.push(neA !== neB ? 1 : 0);
748
- break;
749
-
750
- case OP.I32_LT_S:
751
- const ltB = stack.pop();
752
- const ltA = stack.pop();
753
- stack.push(ltA < ltB ? 1 : 0);
754
- break;
755
-
756
- case OP.I32_GT_S:
757
- const gtB = stack.pop();
758
- const gtA = stack.pop();
759
- stack.push(gtA > gtB ? 1 : 0);
760
- break;
761
-
762
- case OP.IF:
763
- const condition = stack.pop();
764
- if (!condition) {
765
- // Skip to ELSE or END
766
- let depth = 1;
767
- while (depth > 0 && pc < funcBytecode.length) {
768
- const op = funcBytecode[pc++];
769
- if (op === OP.IF || op === OP.BLOCK || op === OP.LOOP) depth++;
770
- else if (op === OP.END) depth--;
771
- else if (op === OP.ELSE && depth === 1) break;
772
- }
773
- }
774
- break;
775
-
776
- case OP.ELSE:
777
- // Skip to END (we executed the IF branch)
778
- let elseDepth = 1;
779
- while (elseDepth > 0 && pc < funcBytecode.length) {
780
- const op = funcBytecode[pc++];
781
- if (op === OP.IF || op === OP.BLOCK || op === OP.LOOP) elseDepth++;
782
- else if (op === OP.END) elseDepth--;
783
- }
784
- break;
785
-
786
- case OP.SLOAD:
787
- // Load from storage
788
- const loadSlot = stack.pop() || Buffer.alloc(32);
789
- const slotBuf = typeof loadSlot === 'string'
790
- ? Buffer.from(loadSlot.replace('0x', ''), 'hex')
791
- : Buffer.isBuffer(loadSlot) ? loadSlot : Buffer.alloc(32);
792
- const loadValue = contract.state.read(slotBuf);
793
- stack.push(loadValue.readBigUInt64LE(0));
794
- break;
795
-
796
- case OP.SSTORE:
797
- // Store to storage
798
- const storeValue = stack.pop();
799
- const storeSlot = stack.pop() || Buffer.alloc(32);
800
- const storeSlotBuf = typeof storeSlot === 'string'
801
- ? Buffer.from(storeSlot.replace('0x', ''), 'hex')
802
- : Buffer.isBuffer(storeSlot) ? storeSlot : Buffer.alloc(32);
803
- const valueBuf = Buffer.alloc(32);
804
- if (typeof storeValue === 'bigint') {
805
- for (let i = 0; i < 8; i++) {
806
- valueBuf[i] = Number((storeValue >> BigInt(i * 8)) & 0xFFn);
807
- }
808
- }
809
- contract.state.write(storeSlotBuf, valueBuf);
810
- break;
811
-
812
- case OP.CALLER:
813
- stack.push(context.caller || '0x0000000000000000000000000000000000000000');
814
- break;
815
-
816
- case OP.CALLVALUE:
817
- stack.push(context.value || 0n);
818
- break;
819
-
820
- case OP.TIMESTAMP:
821
- stack.push(BigInt(Math.floor(Date.now() / 1000)));
822
- break;
823
-
824
- case OP.BLOCKNUMBER:
825
- stack.push(BigInt(context.blockNumber || 0));
826
- break;
827
-
828
- case OP.LOG0:
829
- case OP.LOG1:
830
- case OP.LOG2:
831
- case OP.LOG3:
832
- case OP.LOG4:
833
- const topicCount = opcode - OP.LOG0;
834
- const topics = [];
835
- for (let i = 0; i < topicCount; i++) {
836
- topics.push(stack.pop());
837
- }
838
- const logData = stack.pop();
839
- logs.push({ topics, data: logData });
840
- break;
841
-
842
- case OP.DROP:
843
- stack.pop();
844
- break;
845
-
846
- case OP.REVERT:
847
- reverted = true;
848
- returnValue = stack.pop();
849
- break;
850
-
851
- case OP.HALT:
852
- pc = funcBytecode.length;
853
- break;
854
-
855
- default:
856
- // Skip unknown opcodes
857
- break;
858
- }
859
- }
860
-
861
- return {
862
- success: !reverted,
863
- returnValue: returnValue,
864
- gasUsed: 0, // ZERO FEES!
865
- logs: logs
866
- };
867
- }
868
-
869
- /**
870
- * Shared state access (between ANY contracts!)
871
- *
872
- * Access control rules:
873
- * 1. A contract can always read/write its own state
874
- * 2. Cross-contract state access requires explicit permission
875
- * 3. Immutable slots cannot be modified after initial write
876
- */
877
- async sharedStateRead(contractAddress, slot, callerAddress = null) {
878
- const contract = this.contracts.get(contractAddress);
879
- if (!contract) {
880
- throw new Error('Contract not found');
881
- }
882
-
883
- // Self-access is always allowed
884
- if (!callerAddress || callerAddress === contractAddress) {
885
- return contract.state.read(slot);
886
- }
887
-
888
- // Cross-contract read: check permissions
889
- const permissions = contract.statePermissions || new Map();
890
- const slotKey = slot.toString('hex');
891
- const slotPerms = permissions.get(slotKey) || { read: 'public', write: 'owner' };
892
-
893
- if (slotPerms.read === 'public') {
894
- return contract.state.read(slot);
895
- }
896
-
897
- if (slotPerms.read === 'allowlist') {
898
- const allowedReaders = slotPerms.readers || new Set();
899
- if (allowedReaders.has(callerAddress)) {
900
- return contract.state.read(slot);
901
- }
902
- }
903
-
904
- throw new Error(`Access denied: ${callerAddress} cannot read slot ${slotKey} from ${contractAddress}`);
905
- }
906
-
907
- async sharedStateWrite(contractAddress, slot, value, callerAddress) {
908
- const contract = this.contracts.get(contractAddress);
909
- if (!contract) {
910
- throw new Error('Contract not found');
911
- }
912
-
913
- // Initialize permissions map if not exists
914
- if (!contract.statePermissions) {
915
- contract.statePermissions = new Map();
916
- }
917
-
918
- const slotKey = slot.toString('hex');
919
- const slotPerms = contract.statePermissions.get(slotKey) || { read: 'public', write: 'owner' };
920
-
921
- // Check immutability
922
- if (slotPerms.immutable) {
923
- const existingValue = contract.state.read(slot);
924
- const isZero = existingValue.every(b => b === 0);
925
- if (!isZero) {
926
- throw new Error(`Access denied: slot ${slotKey} is immutable and already set`);
927
- }
928
- }
929
-
930
- // Self-access is always allowed
931
- if (!callerAddress || callerAddress === contractAddress) {
932
- return contract.state.write(slot, value);
933
- }
934
-
935
- // Cross-contract write: check permissions
936
- if (slotPerms.write === 'owner') {
937
- throw new Error(`Access denied: ${callerAddress} cannot write to slot ${slotKey} (owner-only)`);
938
- }
939
-
940
- if (slotPerms.write === 'allowlist') {
941
- const allowedWriters = slotPerms.writers || new Set();
942
- if (!allowedWriters.has(callerAddress)) {
943
- throw new Error(`Access denied: ${callerAddress} not in write allowlist for slot ${slotKey}`);
944
- }
945
- }
946
-
947
- // Write allowed
948
- console.log(`[StateAccess] Cross-contract write: ${callerAddress.substring(0, 10)}... → ${contractAddress.substring(0, 10)}...`);
949
- return contract.state.write(slot, value);
950
- }
951
-
952
- /**
953
- * Set state permissions for a slot
954
- *
955
- * @param {string} contractAddress - Contract address
956
- * @param {Buffer} slot - Storage slot
957
- * @param {object} permissions - { read: 'public'|'owner'|'allowlist', write: 'owner'|'allowlist', immutable: boolean }
958
- * @param {string} callerAddress - Caller must be contract owner
959
- */
960
- async setStatePermissions(contractAddress, slot, permissions, callerAddress) {
961
- const contract = this.contracts.get(contractAddress);
962
- if (!contract) {
963
- throw new Error('Contract not found');
964
- }
965
-
966
- // Only contract owner can set permissions
967
- if (callerAddress !== contractAddress) {
968
- throw new Error('Only contract owner can set state permissions');
969
- }
970
-
971
- if (!contract.statePermissions) {
972
- contract.statePermissions = new Map();
973
- }
974
-
975
- const slotKey = slot.toString('hex');
976
- const existing = contract.statePermissions.get(slotKey) || {};
977
-
978
- contract.statePermissions.set(slotKey, {
979
- read: permissions.read || existing.read || 'public',
980
- write: permissions.write || existing.write || 'owner',
981
- immutable: permissions.immutable || existing.immutable || false,
982
- readers: permissions.readers || existing.readers || new Set(),
983
- writers: permissions.writers || existing.writers || new Set()
984
- });
985
-
986
- console.log(`[StateAccess] Permissions updated for ${contractAddress.substring(0, 10)}...::${slotKey.substring(0, 16)}...`);
987
-
988
- return true;
989
- }
990
-
991
- /**
992
- * Grant state access to another contract
993
- */
994
- async grantStateAccess(contractAddress, slot, granteeAddress, accessType, callerAddress) {
995
- const contract = this.contracts.get(contractAddress);
996
- if (!contract) {
997
- throw new Error('Contract not found');
998
- }
999
-
1000
- if (callerAddress !== contractAddress) {
1001
- throw new Error('Only contract owner can grant state access');
1002
- }
1003
-
1004
- if (!contract.statePermissions) {
1005
- contract.statePermissions = new Map();
1006
- }
1007
-
1008
- const slotKey = slot.toString('hex');
1009
- const perms = contract.statePermissions.get(slotKey) || {
1010
- read: 'public',
1011
- write: 'owner',
1012
- readers: new Set(),
1013
- writers: new Set()
1014
- };
1015
-
1016
- if (accessType === 'read') {
1017
- perms.readers = perms.readers || new Set();
1018
- perms.readers.add(granteeAddress);
1019
- perms.read = 'allowlist';
1020
- } else if (accessType === 'write') {
1021
- perms.writers = perms.writers || new Set();
1022
- perms.writers.add(granteeAddress);
1023
- perms.write = 'allowlist';
1024
- }
1025
-
1026
- contract.statePermissions.set(slotKey, perms);
1027
-
1028
- console.log(`[StateAccess] Granted ${accessType} access to ${granteeAddress.substring(0, 10)}... for ${slotKey.substring(0, 16)}...`);
1029
-
1030
- return true;
1031
- }
1032
-
1033
- /**
1034
- * Revoke state access from another contract
1035
- */
1036
- async revokeStateAccess(contractAddress, slot, granteeAddress, accessType, callerAddress) {
1037
- const contract = this.contracts.get(contractAddress);
1038
- if (!contract) {
1039
- throw new Error('Contract not found');
1040
- }
1041
-
1042
- if (callerAddress !== contractAddress) {
1043
- throw new Error('Only contract owner can revoke state access');
1044
- }
1045
-
1046
- if (!contract.statePermissions) {
1047
- return false;
1048
- }
1049
-
1050
- const slotKey = slot.toString('hex');
1051
- const perms = contract.statePermissions.get(slotKey);
1052
- if (!perms) {
1053
- return false;
1054
- }
1055
-
1056
- if (accessType === 'read' && perms.readers) {
1057
- perms.readers.delete(granteeAddress);
1058
- } else if (accessType === 'write' && perms.writers) {
1059
- perms.writers.delete(granteeAddress);
1060
- }
1061
-
1062
- contract.statePermissions.set(slotKey, perms);
1063
-
1064
- console.log(`[StateAccess] Revoked ${accessType} access from ${granteeAddress.substring(0, 10)}... for ${slotKey.substring(0, 16)}...`);
1065
-
1066
- return true;
1067
- }
1068
-
1069
- /**
1070
- * Generate deterministic address
1071
- */
1072
- generateAddress(source) {
1073
- const hash = crypto.createHash('sha256')
1074
- .update(source + Date.now())
1075
- .digest('hex');
1076
- return '0x' + hash.substring(0, 40);
1077
- }
1078
-
1079
- /**
1080
- * Get all contracts
1081
- */
1082
- getAllContracts() {
1083
- return Array.from(this.contracts.entries()).map(([address, contract]) => ({
1084
- address,
1085
- language: contract.language,
1086
- version: contract.version,
1087
- lastCompiled: contract.lastCompiled,
1088
- functions: contract.interface.functions.size,
1089
- dependencies: contract.dependencies.size,
1090
- dependents: contract.dependents.size
1091
- }));
1092
- }
1093
-
1094
- /**
1095
- * Get contract dependency graph
1096
- */
1097
- getDependencyGraph() {
1098
- const graph = {
1099
- nodes: [],
1100
- edges: []
1101
- };
1102
-
1103
- for (const [address, contract] of this.contracts) {
1104
- graph.nodes.push({
1105
- id: address,
1106
- language: contract.language,
1107
- version: contract.version
1108
- });
1109
-
1110
- for (const dep of contract.dependencies) {
1111
- graph.edges.push({
1112
- from: address,
1113
- to: dep,
1114
- type: 'depends-on'
1115
- });
1116
- }
1117
- }
1118
-
1119
- return graph;
1120
- }
1121
- }
1122
-
1123
- module.exports = {
1124
- DynamicContract,
1125
- DynamicContractManager,
1126
- ContractStateStore
1127
- };