@btc-vision/btc-runtime 1.0.29 → 1.0.31
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.
- package/package.json +1 -1
- package/runtime/env/BTCEnvironment.ts +319 -314
- package/runtime/index.ts +54 -52
- package/runtime/shared-libraries/OP20Utils.ts +21 -0
- package/runtime/storage/Serializable.ts +79 -0
package/package.json
CHANGED
|
@@ -1,314 +1,319 @@
|
|
|
1
|
-
import { Address, PotentialAddress } from '../types/Address';
|
|
2
|
-
import { MemorySlotPointer } from '../memory/MemorySlotPointer';
|
|
3
|
-
import { MemorySlotData } from '../memory/MemorySlot';
|
|
4
|
-
import { u256 } from 'as-bignum/assembly';
|
|
5
|
-
import { ABIRegistry } from '../universal/ABIRegistry';
|
|
6
|
-
import { BytesReader } from '../buffer/BytesReader';
|
|
7
|
-
import { encodePointerHash } from '../math/abi';
|
|
8
|
-
import { BytesWriter } from '../buffer/BytesWriter';
|
|
9
|
-
import { MAX_EVENTS, NetEvent } from '../events/NetEvent';
|
|
10
|
-
import { Potential } from '../lang/Definitions';
|
|
11
|
-
import { OP_NET } from '../contracts/OP_NET';
|
|
12
|
-
import { PointerStorage } from '../types';
|
|
13
|
-
import {
|
|
14
|
-
callContract,
|
|
15
|
-
deploy,
|
|
16
|
-
deployFromAddress,
|
|
17
|
-
encodeAddress,
|
|
18
|
-
loadPointer,
|
|
19
|
-
log,
|
|
20
|
-
storePointer,
|
|
21
|
-
} from './global';
|
|
22
|
-
import { DeployContractResponse } from '../interfaces/DeployContractResponse';
|
|
23
|
-
import { MapU256 } from '../generic/MapU256';
|
|
24
|
-
|
|
25
|
-
export * from '../env/global';
|
|
26
|
-
|
|
27
|
-
@final
|
|
28
|
-
export class BlockchainEnvironment {
|
|
29
|
-
private static readonly
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
private
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
private
|
|
36
|
-
private
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
this.
|
|
121
|
-
|
|
122
|
-
this.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
}
|
|
1
|
+
import { Address, PotentialAddress } from '../types/Address';
|
|
2
|
+
import { MemorySlotPointer } from '../memory/MemorySlotPointer';
|
|
3
|
+
import { MemorySlotData } from '../memory/MemorySlot';
|
|
4
|
+
import { u256 } from 'as-bignum/assembly';
|
|
5
|
+
import { ABIRegistry } from '../universal/ABIRegistry';
|
|
6
|
+
import { BytesReader } from '../buffer/BytesReader';
|
|
7
|
+
import { encodePointerHash } from '../math/abi';
|
|
8
|
+
import { BytesWriter } from '../buffer/BytesWriter';
|
|
9
|
+
import { MAX_EVENTS, NetEvent } from '../events/NetEvent';
|
|
10
|
+
import { Potential } from '../lang/Definitions';
|
|
11
|
+
import { OP_NET } from '../contracts/OP_NET';
|
|
12
|
+
import { PointerStorage } from '../types';
|
|
13
|
+
import {
|
|
14
|
+
callContract,
|
|
15
|
+
deploy,
|
|
16
|
+
deployFromAddress,
|
|
17
|
+
encodeAddress,
|
|
18
|
+
loadPointer,
|
|
19
|
+
log,
|
|
20
|
+
storePointer,
|
|
21
|
+
} from './global';
|
|
22
|
+
import { DeployContractResponse } from '../interfaces/DeployContractResponse';
|
|
23
|
+
import { MapU256 } from '../generic/MapU256';
|
|
24
|
+
|
|
25
|
+
export * from '../env/global';
|
|
26
|
+
|
|
27
|
+
@final
|
|
28
|
+
export class BlockchainEnvironment {
|
|
29
|
+
private static readonly MAX_U16: u16 = 65535;
|
|
30
|
+
private static readonly runtimeException: string = 'RuntimeException';
|
|
31
|
+
|
|
32
|
+
private storage: PointerStorage = new MapU256();
|
|
33
|
+
private events: NetEvent[] = [];
|
|
34
|
+
|
|
35
|
+
private _callee: PotentialAddress = null;
|
|
36
|
+
private _caller: PotentialAddress = null;
|
|
37
|
+
private currentBlock: u256 = u256.Zero;
|
|
38
|
+
|
|
39
|
+
constructor() {}
|
|
40
|
+
|
|
41
|
+
private _timestamp: u64 = 0;
|
|
42
|
+
|
|
43
|
+
public get timestamp(): u64 {
|
|
44
|
+
return this._timestamp;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private _contract: Potential<() => OP_NET> = null;
|
|
48
|
+
|
|
49
|
+
public get contract(): OP_NET {
|
|
50
|
+
if (!this._contract) {
|
|
51
|
+
throw this.error('Contract is required');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return this._contract();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public set contract(contract: () => OP_NET) {
|
|
58
|
+
this._contract = contract;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private _nextPointer: u16 = 0;
|
|
62
|
+
|
|
63
|
+
public get nextPointer(): u16 {
|
|
64
|
+
if(this._nextPointer === BlockchainEnvironment.MAX_U16) {
|
|
65
|
+
throw this.error(`Out of storage pointer.`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
this._nextPointer += 1;
|
|
69
|
+
|
|
70
|
+
return this._nextPointer;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public _owner: Potential<Address> = null;
|
|
74
|
+
|
|
75
|
+
public get owner(): Address {
|
|
76
|
+
if (!this._owner) {
|
|
77
|
+
throw this.error('Owner is required');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return this._owner as Address;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public _contractAddress: Potential<Address> = null;
|
|
84
|
+
|
|
85
|
+
public get contractAddress(): Address {
|
|
86
|
+
if (!this._contractAddress) {
|
|
87
|
+
throw this.error('Contract address is required');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return this._contractAddress as Address;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public get blockNumber(): u256 {
|
|
94
|
+
return this.currentBlock;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public get blockNumberU64(): u64 {
|
|
98
|
+
return this.currentBlock.toU64();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public callee(): Address {
|
|
102
|
+
if (!this._callee) {
|
|
103
|
+
throw this.error('Callee is required');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return this._callee as Address;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
public caller(): Address {
|
|
110
|
+
if (!this._caller) {
|
|
111
|
+
throw this.error('Caller is required');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return this._caller as Address;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
public setEnvironment(data: Uint8Array): void {
|
|
118
|
+
const reader: BytesReader = new BytesReader(data);
|
|
119
|
+
|
|
120
|
+
this._caller = reader.readAddress();
|
|
121
|
+
this._callee = reader.readAddress();
|
|
122
|
+
this.currentBlock = reader.readU256();
|
|
123
|
+
|
|
124
|
+
this._owner = reader.readAddress();
|
|
125
|
+
this._contractAddress = reader.readAddress();
|
|
126
|
+
|
|
127
|
+
this._timestamp = reader.readU64();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
public call(destinationContract: Address, calldata: BytesWriter): BytesReader {
|
|
131
|
+
if (destinationContract === this._callee) {
|
|
132
|
+
throw this.error('Cannot call self');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (!destinationContract) {
|
|
136
|
+
throw this.error('Destination contract is required');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const call = new BytesWriter();
|
|
140
|
+
call.writeAddress(destinationContract);
|
|
141
|
+
call.writeBytesWithLength(calldata.getBuffer());
|
|
142
|
+
|
|
143
|
+
const response: Uint8Array = callContract(call.getBuffer());
|
|
144
|
+
|
|
145
|
+
return new BytesReader(response);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
public log(data: string): void {
|
|
149
|
+
const writer = new BytesWriter();
|
|
150
|
+
writer.writeStringWithLength(data);
|
|
151
|
+
|
|
152
|
+
const buffer = writer.getBuffer();
|
|
153
|
+
log(buffer);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
public addEvent(event: NetEvent): void {
|
|
157
|
+
if (this.events.length >= i32(MAX_EVENTS)) {
|
|
158
|
+
throw this.error(`Too many events in the same transaction.`);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
this.events.push(event);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
public getEvents(): Uint8Array {
|
|
165
|
+
const eventLength: u16 = u16(this.events.length);
|
|
166
|
+
if (eventLength > MAX_EVENTS) {
|
|
167
|
+
throw this.error('Too many events');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const buffer: BytesWriter = new BytesWriter();
|
|
171
|
+
buffer.writeU16(eventLength);
|
|
172
|
+
|
|
173
|
+
for (let i: u8 = 0; i < eventLength; i++) {
|
|
174
|
+
const event: NetEvent = this.events[i];
|
|
175
|
+
|
|
176
|
+
buffer.writeStringWithLength(event.eventType);
|
|
177
|
+
buffer.writeU64(event.getEventDataSelector());
|
|
178
|
+
buffer.writeBytesWithLength(event.getEventData());
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return buffer.getBuffer();
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
public encodeVirtualAddress(virtualAddress: Uint8Array): Address {
|
|
185
|
+
const writer: BytesWriter = new BytesWriter();
|
|
186
|
+
writer.writeBytesWithLength(virtualAddress);
|
|
187
|
+
|
|
188
|
+
const buffer: Uint8Array = writer.getBuffer();
|
|
189
|
+
const cb: Potential<Uint8Array> = encodeAddress(buffer);
|
|
190
|
+
if (!cb) throw this.error('Failed to encode virtual address');
|
|
191
|
+
|
|
192
|
+
const reader: BytesReader = new BytesReader(cb as Uint8Array);
|
|
193
|
+
return reader.readAddress();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
public deployContract(hash: u256, bytecode: Uint8Array): DeployContractResponse {
|
|
197
|
+
const writer = new BytesWriter();
|
|
198
|
+
writer.writeU256(hash);
|
|
199
|
+
writer.writeBytes(bytecode);
|
|
200
|
+
|
|
201
|
+
const cb: Potential<Uint8Array> = deploy(writer.getBuffer());
|
|
202
|
+
if (!cb) throw this.error('Failed to deploy contract');
|
|
203
|
+
|
|
204
|
+
const reader: BytesReader = new BytesReader(cb as Uint8Array);
|
|
205
|
+
const virtualAddress: u256 = reader.readU256();
|
|
206
|
+
const contractAddress: Address = reader.readAddress();
|
|
207
|
+
|
|
208
|
+
return new DeployContractResponse(virtualAddress, contractAddress);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
public deployContractFromExisting(
|
|
212
|
+
existingAddress: Address,
|
|
213
|
+
salt: u256,
|
|
214
|
+
): DeployContractResponse {
|
|
215
|
+
const writer = new BytesWriter();
|
|
216
|
+
writer.writeAddress(existingAddress);
|
|
217
|
+
writer.writeU256(salt);
|
|
218
|
+
|
|
219
|
+
const buffer: Uint8Array = writer.getBuffer();
|
|
220
|
+
const cb: Potential<Uint8Array> = deployFromAddress(buffer);
|
|
221
|
+
if (!cb) throw this.error('Failed to deploy contract');
|
|
222
|
+
|
|
223
|
+
const reader: BytesReader = new BytesReader(cb as Uint8Array);
|
|
224
|
+
const virtualAddress: u256 = reader.readU256();
|
|
225
|
+
const contractAddress: Address = reader.readAddress();
|
|
226
|
+
|
|
227
|
+
return new DeployContractResponse(virtualAddress, contractAddress);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
public getStorageAt(
|
|
231
|
+
pointer: u16,
|
|
232
|
+
subPointer: MemorySlotPointer,
|
|
233
|
+
defaultValue: MemorySlotData<u256>,
|
|
234
|
+
): MemorySlotData<u256> {
|
|
235
|
+
const pointerHash: MemorySlotPointer = encodePointerHash(pointer, subPointer);
|
|
236
|
+
this.ensureStorageAtPointer(pointerHash, defaultValue);
|
|
237
|
+
|
|
238
|
+
if (this.storage.has(pointerHash)) {
|
|
239
|
+
return this.storage.get(pointerHash);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return defaultValue;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
public hasStorageAt(pointer: u16, subPointer: MemorySlotPointer): bool {
|
|
246
|
+
// We mark zero as the default value for the storage, if something is 0, the storage slot get deleted or is non-existent
|
|
247
|
+
const val: u256 = this.getStorageAt(pointer, subPointer, u256.Zero);
|
|
248
|
+
|
|
249
|
+
return u256.ne(val, u256.Zero);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
public setStorageAt(
|
|
253
|
+
pointer: u16,
|
|
254
|
+
keyPointer: MemorySlotPointer,
|
|
255
|
+
value: MemorySlotData<u256>,
|
|
256
|
+
): void {
|
|
257
|
+
const pointerHash: u256 = encodePointerHash(pointer, keyPointer);
|
|
258
|
+
|
|
259
|
+
this._internalSetStorageAt(pointerHash, value);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
public getViewSelectors(): Uint8Array {
|
|
263
|
+
return ABIRegistry.getViewSelectors();
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
public getMethodSelectors(): Uint8Array {
|
|
267
|
+
return ABIRegistry.getMethodSelectors();
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
public getWriteMethods(): Uint8Array {
|
|
271
|
+
return ABIRegistry.getWriteMethods();
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
private error(msg: string): Error {
|
|
275
|
+
return new Error(`${BlockchainEnvironment.runtimeException}: ${msg}`);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
private _internalSetStorageAt(pointerHash: u256, value: MemorySlotData<u256>): void {
|
|
279
|
+
this.storage.set(pointerHash, value);
|
|
280
|
+
|
|
281
|
+
const writer: BytesWriter = new BytesWriter();
|
|
282
|
+
writer.writeU256(pointerHash);
|
|
283
|
+
writer.writeU256(value);
|
|
284
|
+
|
|
285
|
+
const buffer: Uint8Array = writer.getBuffer();
|
|
286
|
+
storePointer(buffer);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
private hasPointerStorageHash(pointer: MemorySlotPointer): bool {
|
|
290
|
+
if (this.storage.has(pointer)) {
|
|
291
|
+
return true;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// we attempt to load the requested pointer.
|
|
295
|
+
const writer = new BytesWriter();
|
|
296
|
+
writer.writeU256(pointer);
|
|
297
|
+
|
|
298
|
+
const result: Uint8Array = loadPointer(writer.getBuffer());
|
|
299
|
+
const reader: BytesReader = new BytesReader(result);
|
|
300
|
+
|
|
301
|
+
const value: u256 = reader.readU256();
|
|
302
|
+
this.storage.set(pointer, value); // cache the value
|
|
303
|
+
|
|
304
|
+
return !u256.eq(value, u256.Zero);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
private ensureStorageAtPointer(
|
|
308
|
+
pointerHash: MemorySlotPointer,
|
|
309
|
+
defaultValue: MemorySlotData<u256>,
|
|
310
|
+
): void {
|
|
311
|
+
if (!this.hasPointerStorageHash(pointerHash)) {
|
|
312
|
+
if (u256.eq(defaultValue, u256.Zero)) {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
this._internalSetStorageAt(pointerHash, defaultValue);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
package/runtime/index.ts
CHANGED
|
@@ -1,52 +1,54 @@
|
|
|
1
|
-
/** Environment */
|
|
2
|
-
export * from './env';
|
|
3
|
-
|
|
4
|
-
/** Contracts */
|
|
5
|
-
export * from './contracts/interfaces/IOP_20';
|
|
6
|
-
export * from './contracts/OP_20';
|
|
7
|
-
export * from './contracts/OP_NET';
|
|
8
|
-
|
|
9
|
-
/** Buffer */
|
|
10
|
-
export * from './buffer/BytesReader';
|
|
11
|
-
export * from './buffer/BytesWriter';
|
|
12
|
-
|
|
13
|
-
/** Interfaces */
|
|
14
|
-
export * from './interfaces/DeployContractResponse';
|
|
15
|
-
|
|
16
|
-
/** Events */
|
|
17
|
-
export * from './events/NetEvent';
|
|
18
|
-
export * from './events/predefined';
|
|
19
|
-
|
|
20
|
-
/** Types */
|
|
21
|
-
export * from './generic/Map';
|
|
22
|
-
export * from './interfaces/IBTC';
|
|
23
|
-
|
|
24
|
-
/** Definitions */
|
|
25
|
-
export * from './lang/Definitions';
|
|
26
|
-
export * from './types/Address';
|
|
27
|
-
export * from './types/Revert';
|
|
28
|
-
export * from './types/SafeMath';
|
|
29
|
-
|
|
30
|
-
/** Math */
|
|
31
|
-
export * from './math/abi';
|
|
32
|
-
export * from './math/bytes';
|
|
33
|
-
export * from './math/cyrb53';
|
|
34
|
-
export * from './math/sha256';
|
|
35
|
-
export * from './math/rnd';
|
|
36
|
-
|
|
37
|
-
/** Memory */
|
|
38
|
-
export * from './memory/AddressMemoryMap';
|
|
39
|
-
export * from './memory/MemorySlot';
|
|
40
|
-
export * from './memory/MemorySlotPointer';
|
|
41
|
-
export * from './memory/KeyMerger';
|
|
42
|
-
export * from './memory/MultiAddressMemoryMap';
|
|
43
|
-
|
|
44
|
-
/** Storage */
|
|
45
|
-
export * from './storage/StoredU256';
|
|
46
|
-
export * from './storage/StoredString';
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
1
|
+
/** Environment */
|
|
2
|
+
export * from './env';
|
|
3
|
+
|
|
4
|
+
/** Contracts */
|
|
5
|
+
export * from './contracts/interfaces/IOP_20';
|
|
6
|
+
export * from './contracts/OP_20';
|
|
7
|
+
export * from './contracts/OP_NET';
|
|
8
|
+
|
|
9
|
+
/** Buffer */
|
|
10
|
+
export * from './buffer/BytesReader';
|
|
11
|
+
export * from './buffer/BytesWriter';
|
|
12
|
+
|
|
13
|
+
/** Interfaces */
|
|
14
|
+
export * from './interfaces/DeployContractResponse';
|
|
15
|
+
|
|
16
|
+
/** Events */
|
|
17
|
+
export * from './events/NetEvent';
|
|
18
|
+
export * from './events/predefined';
|
|
19
|
+
|
|
20
|
+
/** Types */
|
|
21
|
+
export * from './generic/Map';
|
|
22
|
+
export * from './interfaces/IBTC';
|
|
23
|
+
|
|
24
|
+
/** Definitions */
|
|
25
|
+
export * from './lang/Definitions';
|
|
26
|
+
export * from './types/Address';
|
|
27
|
+
export * from './types/Revert';
|
|
28
|
+
export * from './types/SafeMath';
|
|
29
|
+
|
|
30
|
+
/** Math */
|
|
31
|
+
export * from './math/abi';
|
|
32
|
+
export * from './math/bytes';
|
|
33
|
+
export * from './math/cyrb53';
|
|
34
|
+
export * from './math/sha256';
|
|
35
|
+
export * from './math/rnd';
|
|
36
|
+
|
|
37
|
+
/** Memory */
|
|
38
|
+
export * from './memory/AddressMemoryMap';
|
|
39
|
+
export * from './memory/MemorySlot';
|
|
40
|
+
export * from './memory/MemorySlotPointer';
|
|
41
|
+
export * from './memory/KeyMerger';
|
|
42
|
+
export * from './memory/MultiAddressMemoryMap';
|
|
43
|
+
|
|
44
|
+
/** Storage */
|
|
45
|
+
export * from './storage/StoredU256';
|
|
46
|
+
export * from './storage/StoredString';
|
|
47
|
+
export * from './storage/Serializable';
|
|
48
|
+
|
|
49
|
+
/** Universal */
|
|
50
|
+
export * from './universal/ABIRegistry';
|
|
51
|
+
|
|
52
|
+
/** Shared libraries */
|
|
53
|
+
export * from './shared-libraries/TransferHelper';
|
|
54
|
+
export * from './shared-libraries/OP20Utils';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Address } from '../types/Address';
|
|
2
|
+
import { u256 } from 'as-bignum/assembly';
|
|
3
|
+
import { BytesWriter } from '../buffer/BytesWriter';
|
|
4
|
+
import { Blockchain } from '../env';
|
|
5
|
+
import { encodeSelector, Selector } from '../math/abi';
|
|
6
|
+
|
|
7
|
+
export class OP20Utils {
|
|
8
|
+
public static get BALANCE_OF_SELECTOR(): Selector {
|
|
9
|
+
return encodeSelector('balanceOf');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
public static balanceOf(token: Address, owner: Address): u256 {
|
|
13
|
+
const calldata: BytesWriter = new BytesWriter();
|
|
14
|
+
calldata.writeSelector(OP20Utils.BALANCE_OF_SELECTOR);
|
|
15
|
+
calldata.writeAddress(owner);
|
|
16
|
+
|
|
17
|
+
const response = Blockchain.call(token, calldata);
|
|
18
|
+
|
|
19
|
+
return response.readU256();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { u256 } from 'as-bignum/assembly';
|
|
2
|
+
import { Blockchain } from '../env';
|
|
3
|
+
import { MemorySlotPointer } from '../memory/MemorySlotPointer';
|
|
4
|
+
import { BytesWriter } from '../buffer/BytesWriter';
|
|
5
|
+
import { BytesReader } from '../buffer/BytesReader';
|
|
6
|
+
import { Revert } from '../types/Revert';
|
|
7
|
+
|
|
8
|
+
export abstract class Serializable {
|
|
9
|
+
protected pointer: u16;
|
|
10
|
+
protected subPointer:MemorySlotPointer;
|
|
11
|
+
|
|
12
|
+
protected constructor(pointer: u16,
|
|
13
|
+
subPointer:MemorySlotPointer) {
|
|
14
|
+
this.pointer = pointer;
|
|
15
|
+
this.subPointer = subPointer;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public abstract get chunkCount(): i32;
|
|
19
|
+
public abstract writeToBuffer(): BytesWriter;
|
|
20
|
+
public abstract readFromBuffer(reader: BytesReader): void;
|
|
21
|
+
|
|
22
|
+
public load() :void {
|
|
23
|
+
const chunks: u256[] = [];
|
|
24
|
+
|
|
25
|
+
for(let index:i32 = 0; index < this.chunkCount; index++){
|
|
26
|
+
const chunk: u256 = Blockchain.getStorageAt(this.pointer, u256.add(this.subPointer, u256.fromU32(index)), u256.Zero);
|
|
27
|
+
chunks.push(chunk);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const reader = this.chunksToBytes(chunks);
|
|
31
|
+
|
|
32
|
+
this.readFromBuffer(reader);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public save(): void {
|
|
36
|
+
const writer: BytesWriter = this.writeToBuffer();
|
|
37
|
+
|
|
38
|
+
const buffer = writer.getBuffer();
|
|
39
|
+
|
|
40
|
+
const chunks: u256[] = this.bytesToChunks(buffer);
|
|
41
|
+
|
|
42
|
+
for (let index: i32 = 0; index < chunks.length; index++) {
|
|
43
|
+
Blockchain.setStorageAt(
|
|
44
|
+
this.pointer,
|
|
45
|
+
u256.add(this.subPointer, u256.fromU32(index)),
|
|
46
|
+
chunks[index],
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
protected bytesToChunks(buffer: Uint8Array): u256[] {
|
|
52
|
+
const chunks: u256[] = [];
|
|
53
|
+
|
|
54
|
+
for (let index: i32 = 0; index < buffer.byteLength; index += 32) {
|
|
55
|
+
const chunk = buffer.slice(index, index + 32);
|
|
56
|
+
chunks.push(u256.fromBytes(chunk, true));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return chunks;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
protected chunksToBytes(chunks: u256[]): BytesReader {
|
|
63
|
+
if(this.chunkCount >= 67108863) {
|
|
64
|
+
throw new Revert('Too many chunks received');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const buffer: Uint8Array = new Uint8Array(this.chunkCount * 32);
|
|
68
|
+
let offset: i32 = 0;
|
|
69
|
+
|
|
70
|
+
for (let indexChunk: i32 = 0; indexChunk < chunks.length; indexChunk++) {
|
|
71
|
+
const bytes: u8[] = chunks[indexChunk].toBytes(true);
|
|
72
|
+
for (let indexByte: i32 = 0; indexByte < bytes.length; indexByte++) {
|
|
73
|
+
buffer[offset++] = bytes[indexByte];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return new BytesReader(buffer);
|
|
78
|
+
}
|
|
79
|
+
}
|