@alephium/web3 1.3.0 → 1.5.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.
- package/dist/alephium-web3.min.js +1 -1
- package/dist/alephium-web3.min.js.map +1 -1
- package/dist/src/address/address.js +11 -5
- package/dist/src/api/api-alephium.d.ts +2 -4
- package/dist/src/api/api-alephium.js +1 -1
- package/dist/src/codec/array-codec.d.ts +4 -12
- package/dist/src/codec/array-codec.js +15 -28
- package/dist/src/codec/asset-output-codec.d.ts +6 -11
- package/dist/src/codec/asset-output-codec.js +32 -71
- package/dist/src/codec/bigint-codec.d.ts +2 -1
- package/dist/src/codec/bigint-codec.js +14 -2
- package/dist/src/codec/bytestring-codec.d.ts +6 -11
- package/dist/src/codec/bytestring-codec.js +9 -23
- package/dist/src/codec/codec.d.ts +54 -5
- package/dist/src/codec/codec.js +112 -14
- package/dist/src/codec/compact-int-codec.d.ts +65 -44
- package/dist/src/codec/compact-int-codec.js +222 -204
- package/dist/src/codec/contract-codec.d.ts +5 -8
- package/dist/src/codec/contract-codec.js +15 -29
- package/dist/src/codec/contract-output-codec.d.ts +4 -10
- package/dist/src/codec/contract-output-codec.js +20 -40
- package/dist/src/codec/contract-output-ref-codec.d.ts +2 -8
- package/dist/src/codec/contract-output-ref-codec.js +7 -17
- package/dist/src/codec/either-codec.d.ts +8 -15
- package/dist/src/codec/either-codec.js +5 -46
- package/dist/src/codec/index.d.ts +4 -3
- package/dist/src/codec/index.js +7 -4
- package/dist/src/codec/input-codec.d.ts +4 -10
- package/dist/src/codec/input-codec.js +11 -46
- package/dist/src/codec/instr-codec.d.ts +633 -40
- package/dist/src/codec/instr-codec.js +1040 -434
- package/dist/src/codec/int-as-4bytes-codec.d.ts +7 -0
- package/dist/src/codec/{signed-int-codec.js → int-as-4bytes-codec.js} +6 -12
- package/dist/src/codec/lockup-script-codec.d.ts +23 -26
- package/dist/src/codec/lockup-script-codec.js +12 -58
- package/dist/src/codec/method-codec.d.ts +6 -18
- package/dist/src/codec/method-codec.js +20 -48
- package/dist/src/codec/option-codec.d.ts +8 -13
- package/dist/src/codec/option-codec.js +14 -32
- package/dist/src/codec/output-codec.d.ts +2 -2
- package/dist/src/codec/output-codec.js +1 -1
- package/dist/src/codec/reader.d.ts +8 -0
- package/dist/src/codec/reader.js +48 -0
- package/dist/src/codec/script-codec.d.ts +6 -14
- package/dist/src/codec/script-codec.js +6 -22
- package/dist/src/codec/signature-codec.d.ts +4 -12
- package/dist/src/codec/signature-codec.js +3 -15
- package/dist/src/codec/timestamp-codec.d.ts +8 -0
- package/dist/src/codec/timestamp-codec.js +39 -0
- package/dist/src/codec/token-codec.d.ts +3 -10
- package/dist/src/codec/token-codec.js +6 -24
- package/dist/src/codec/transaction-codec.d.ts +6 -11
- package/dist/src/codec/transaction-codec.js +24 -49
- package/dist/src/codec/unlock-script-codec.d.ts +25 -36
- package/dist/src/codec/unlock-script-codec.js +26 -147
- package/dist/src/codec/unsigned-tx-codec.d.ts +8 -14
- package/dist/src/codec/unsigned-tx-codec.js +24 -66
- package/dist/src/codec/val.d.ts +27 -0
- package/dist/src/codec/val.js +33 -0
- package/dist/src/contract/contract.d.ts +1 -0
- package/dist/src/contract/contract.js +20 -13
- package/dist/src/contract/index.d.ts +1 -0
- package/dist/src/contract/index.js +1 -0
- package/dist/src/contract/ralph.d.ts +0 -4
- package/dist/src/contract/ralph.js +50 -179
- package/dist/src/contract/script-simulator.d.ts +27 -0
- package/dist/src/contract/script-simulator.js +757 -0
- package/dist/src/exchange/exchange.js +1 -1
- package/package.json +3 -4
- package/src/address/address.ts +15 -9
- package/src/api/api-alephium.ts +2 -4
- package/src/codec/array-codec.ts +16 -34
- package/src/codec/asset-output-codec.ts +38 -83
- package/src/codec/bigint-codec.ts +16 -2
- package/src/codec/bytestring-codec.ts +10 -28
- package/src/codec/codec.ts +121 -15
- package/src/codec/compact-int-codec.ts +230 -207
- package/src/codec/contract-codec.ts +20 -33
- package/src/codec/contract-output-codec.ts +22 -48
- package/src/codec/contract-output-ref-codec.ts +6 -17
- package/src/codec/either-codec.ts +4 -53
- package/src/codec/index.ts +4 -3
- package/src/codec/input-codec.ts +14 -36
- package/src/codec/instr-codec.ts +1229 -455
- package/src/codec/{signed-int-codec.ts → int-as-4bytes-codec.ts} +6 -10
- package/src/codec/lockup-script-codec.ts +28 -76
- package/src/codec/method-codec.ts +23 -61
- package/src/codec/option-codec.ts +13 -36
- package/src/codec/output-codec.ts +2 -2
- package/src/codec/reader.ts +56 -0
- package/src/codec/script-codec.ts +9 -31
- package/src/codec/signature-codec.ts +3 -18
- package/src/codec/timestamp-codec.ts +42 -0
- package/src/codec/token-codec.ts +7 -26
- package/src/codec/transaction-codec.ts +29 -58
- package/src/codec/unlock-script-codec.ts +44 -171
- package/src/codec/unsigned-tx-codec.ts +34 -63
- package/src/codec/val.ts +40 -0
- package/src/contract/contract.ts +24 -20
- package/src/contract/index.ts +1 -0
- package/src/contract/ralph.ts +76 -172
- package/src/contract/script-simulator.ts +838 -0
- package/src/exchange/exchange.ts +1 -1
- package/dist/src/codec/long-codec.d.ts +0 -8
- package/dist/src/codec/long-codec.js +0 -55
- package/dist/src/codec/signed-int-codec.d.ts +0 -8
- package/src/codec/long-codec.ts +0 -58
|
@@ -15,75 +15,67 @@ GNU Lesser General Public License for more details.
|
|
|
15
15
|
You should have received a copy of the GNU Lesser General Public License
|
|
16
16
|
along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
|
-
import { Parser } from 'binary-parser'
|
|
19
18
|
import { Codec, assert } from './codec'
|
|
20
19
|
import { BigIntCodec } from './bigint-codec'
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
export class CompactInt {
|
|
24
|
-
static readonly oneBytePrefix = 0x00
|
|
25
|
-
static readonly oneByteNegPrefix = 0xc0
|
|
26
|
-
static readonly twoBytePrefix = 0x40
|
|
27
|
-
static readonly twoByteNegPrefix = 0x80
|
|
28
|
-
static readonly fourBytePrefix = 0x80
|
|
29
|
-
static readonly fourByteNegPrefix = 0x40
|
|
30
|
-
static readonly multiBytePrefix = 0xc0
|
|
31
|
-
}
|
|
20
|
+
import { Reader } from './reader'
|
|
32
21
|
|
|
33
22
|
const maskRest = 0xc0
|
|
34
23
|
const maskMode = 0x3f
|
|
35
24
|
const maskModeNeg = 0xffffffc0
|
|
36
|
-
const signFlag = 0x20 // 0b00100000
|
|
37
25
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
26
|
+
type FixedWidthMode = {
|
|
27
|
+
type: 'SingleByte' | 'TwoByte' | 'FourByte'
|
|
28
|
+
prefix: number
|
|
29
|
+
negPrefix: number
|
|
41
30
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
31
|
+
type MultiByteMode = { type: 'MultiByte'; prefix: number }
|
|
32
|
+
type Mode = FixedWidthMode | MultiByteMode
|
|
33
|
+
|
|
34
|
+
const SingleByteMode: FixedWidthMode = { type: 'SingleByte', prefix: 0x00, negPrefix: 0xc0 }
|
|
35
|
+
const TwoByteMode: FixedWidthMode = { type: 'TwoByte', prefix: 0x40, negPrefix: 0x80 }
|
|
36
|
+
const FourByteMode: FixedWidthMode = { type: 'FourByte', prefix: 0x80, negPrefix: 0x40 }
|
|
37
|
+
const MultiByte: MultiByteMode = { type: 'MultiByte', prefix: 0xc0 }
|
|
38
|
+
|
|
39
|
+
function decodeMode(input: Reader): { mode: Mode; body: Uint8Array } {
|
|
40
|
+
const byte = input.consumeByte()
|
|
41
|
+
switch (byte & maskRest) {
|
|
42
|
+
case SingleByteMode.prefix:
|
|
43
|
+
return { mode: SingleByteMode, body: new Uint8Array([byte]) }
|
|
44
|
+
case TwoByteMode.prefix:
|
|
45
|
+
return { mode: TwoByteMode, body: new Uint8Array([byte, ...input.consumeBytes(1)]) }
|
|
46
|
+
case FourByteMode.prefix:
|
|
47
|
+
return { mode: FourByteMode, body: new Uint8Array([byte, ...input.consumeBytes(3)]) }
|
|
48
|
+
default: {
|
|
49
|
+
const length = (byte & maskMode) + 4
|
|
50
|
+
return { mode: MultiByte, body: new Uint8Array([byte, ...input.consumeBytes(length)]) }
|
|
57
51
|
}
|
|
58
52
|
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export class CompactUnsignedIntCodec implements Codec<DecodedCompactInt> {
|
|
62
|
-
private oneByteBound = 0x40
|
|
63
|
-
private twoByteBound = this.oneByteBound << 8
|
|
64
|
-
private fourByteBound = this.oneByteBound << (8 * 3)
|
|
65
|
-
|
|
66
|
-
parser = compactIntParser
|
|
67
|
-
|
|
68
|
-
encode(input: DecodedCompactInt): Uint8Array {
|
|
69
|
-
return new Uint8Array([input.mode, ...input.rest])
|
|
70
|
-
}
|
|
53
|
+
}
|
|
71
54
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
55
|
+
export class UnSigned {
|
|
56
|
+
static readonly oneByteBound = BigInt(0x40)
|
|
57
|
+
static readonly twoByteBound = UnSigned.oneByteBound << BigInt(8)
|
|
58
|
+
static readonly fourByteBound = UnSigned.oneByteBound << BigInt(8 * 3)
|
|
59
|
+
static readonly u256UpperBound = BigInt(1) << BigInt(256)
|
|
60
|
+
static readonly u32UpperBound = 2 ** 32
|
|
61
|
+
|
|
62
|
+
static encodeU32(value: number): Uint8Array {
|
|
63
|
+
assert(value >= 0 && value < UnSigned.u32UpperBound, `Invalid u32 value: ${value}`)
|
|
64
|
+
|
|
65
|
+
if (value < UnSigned.oneByteBound) {
|
|
66
|
+
return new Uint8Array([(SingleByteMode.prefix + value) & 0xff])
|
|
67
|
+
} else if (value < UnSigned.twoByteBound) {
|
|
68
|
+
return new Uint8Array([(TwoByteMode.prefix + (value >> 8)) & 0xff, value & 0xff])
|
|
69
|
+
} else if (value < UnSigned.fourByteBound) {
|
|
78
70
|
return new Uint8Array([
|
|
79
|
-
(
|
|
71
|
+
(FourByteMode.prefix + (value >> 24)) & 0xff,
|
|
80
72
|
(value >> 16) & 0xff,
|
|
81
73
|
(value >> 8) & 0xff,
|
|
82
74
|
value & 0xff
|
|
83
75
|
])
|
|
84
76
|
} else {
|
|
85
77
|
return new Uint8Array([
|
|
86
|
-
|
|
78
|
+
MultiByte.prefix,
|
|
87
79
|
(value >> 24) & 0xff,
|
|
88
80
|
(value >> 16) & 0xff,
|
|
89
81
|
(value >> 8) & 0xff,
|
|
@@ -92,211 +84,242 @@ export class CompactUnsignedIntCodec implements Codec<DecodedCompactInt> {
|
|
|
92
84
|
}
|
|
93
85
|
}
|
|
94
86
|
|
|
95
|
-
encodeU256(value: bigint): Uint8Array {
|
|
96
|
-
assert(value >= 0n,
|
|
87
|
+
static encodeU256(value: bigint): Uint8Array {
|
|
88
|
+
assert(value >= 0n && value < UnSigned.u256UpperBound, `Invalid u256 value: ${value}`)
|
|
97
89
|
|
|
98
|
-
if (value <
|
|
99
|
-
return
|
|
90
|
+
if (value < UnSigned.fourByteBound) {
|
|
91
|
+
return UnSigned.encodeU32(Number(value))
|
|
100
92
|
} else {
|
|
101
93
|
let bytes = BigIntCodec.encode(value)
|
|
102
94
|
if (bytes[0] === 0) {
|
|
103
95
|
bytes = bytes.slice(1)
|
|
104
96
|
}
|
|
105
97
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const header = (bytes.length - 4 + CompactInt.multiBytePrefix) & 0xff
|
|
98
|
+
const header = (bytes.length - 4 + MultiByte.prefix) & 0xff
|
|
109
99
|
return new Uint8Array([header, ...bytes])
|
|
110
100
|
}
|
|
111
101
|
}
|
|
112
102
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
103
|
+
static decodeInt(mode: FixedWidthMode, body: Uint8Array): number {
|
|
104
|
+
switch (mode.type) {
|
|
105
|
+
case 'SingleByte':
|
|
106
|
+
assert(body.length === 1, 'Length should be 2')
|
|
107
|
+
return body[0]
|
|
108
|
+
case 'TwoByte':
|
|
109
|
+
assert(body.length === 2, 'Length should be 2')
|
|
110
|
+
return ((body[0] & maskMode) << 8) | (body[1] & 0xff)
|
|
111
|
+
case 'FourByte':
|
|
112
|
+
assert(body.length === 4, 'Length should be 4')
|
|
113
|
+
return (
|
|
114
|
+
(((body[0] & maskMode) << 24) | ((body[1] & 0xff) << 16) | ((body[2] & 0xff) << 8) | (body[3] & 0xff)) >>> 0
|
|
115
|
+
)
|
|
116
|
+
}
|
|
120
117
|
}
|
|
121
118
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
119
|
+
static decodeU32(mode: Mode, body: Uint8Array): number {
|
|
120
|
+
switch (mode.type) {
|
|
121
|
+
case 'SingleByte':
|
|
122
|
+
case 'TwoByte':
|
|
123
|
+
case 'FourByte':
|
|
124
|
+
return UnSigned.decodeInt(mode, body)
|
|
125
|
+
case 'MultiByte':
|
|
126
|
+
assert(body.length >= 5, 'Length should be greater than 5')
|
|
127
|
+
if (body.length === 5) {
|
|
128
|
+
return ((body[1] << 24) | ((body[2] & 0xff) << 16) | ((body[3] & 0xff) << 8) | (body[4] & 0xff)) >>> 0
|
|
129
|
+
} else {
|
|
130
|
+
throw new Error(`Expect 4 bytes int, but get ${body.length - 1} bytes int`)
|
|
131
|
+
}
|
|
130
132
|
}
|
|
131
133
|
}
|
|
132
134
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
+
static decodeU256(mode: Mode, body: Uint8Array): bigint {
|
|
136
|
+
switch (mode.type) {
|
|
137
|
+
case 'SingleByte':
|
|
138
|
+
case 'TwoByte':
|
|
139
|
+
case 'FourByte':
|
|
140
|
+
return BigInt(UnSigned.decodeInt(mode, body))
|
|
141
|
+
case 'MultiByte':
|
|
142
|
+
return BigIntCodec.decodeUnsigned(body.slice(1, body.length))
|
|
143
|
+
}
|
|
135
144
|
}
|
|
136
145
|
}
|
|
137
146
|
|
|
138
|
-
export const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
parser = compactIntParser
|
|
147
|
-
|
|
148
|
-
encode(input: DecodedCompactInt): Uint8Array {
|
|
149
|
-
return new Uint8Array([input.mode, ...input.rest])
|
|
147
|
+
export const u256Codec = new (class extends Codec<bigint> {
|
|
148
|
+
encode(input: bigint): Uint8Array {
|
|
149
|
+
return UnSigned.encodeU256(input)
|
|
150
|
+
}
|
|
151
|
+
_decode(input: Reader): bigint {
|
|
152
|
+
const { mode, body } = decodeMode(input)
|
|
153
|
+
return UnSigned.decodeU256(mode, body)
|
|
150
154
|
}
|
|
155
|
+
})()
|
|
151
156
|
|
|
152
|
-
|
|
153
|
-
|
|
157
|
+
export const u32Codec = new (class extends Codec<number> {
|
|
158
|
+
encode(input: number): Uint8Array {
|
|
159
|
+
return UnSigned.encodeU32(input)
|
|
160
|
+
}
|
|
161
|
+
_decode(input: Reader): number {
|
|
162
|
+
const { mode, body } = decodeMode(input)
|
|
163
|
+
return UnSigned.decodeU32(mode, body)
|
|
164
|
+
}
|
|
165
|
+
})()
|
|
166
|
+
|
|
167
|
+
export class Signed {
|
|
168
|
+
static readonly signFlag = 0x20 // 0b00100000
|
|
169
|
+
static readonly oneByteBound = BigInt(0x20)
|
|
170
|
+
static readonly twoByteBound = Signed.oneByteBound << BigInt(8)
|
|
171
|
+
static readonly fourByteBound = Signed.oneByteBound << BigInt(8 * 3)
|
|
172
|
+
static readonly i256UpperBound = BigInt(1) << BigInt(255)
|
|
173
|
+
static readonly i256LowerBound = -Signed.i256UpperBound
|
|
174
|
+
static readonly i32UpperBound = 2 ** 31
|
|
175
|
+
static readonly i32LowerBound = -Signed.i32UpperBound
|
|
176
|
+
|
|
177
|
+
static encodeI32(value: number): Uint8Array {
|
|
178
|
+
assert(value >= Signed.i32LowerBound && value < Signed.i32UpperBound, `Invalid i32 value: ${value}`)
|
|
179
|
+
if (value >= 0) {
|
|
180
|
+
return Signed.encodePositiveI32(value)
|
|
181
|
+
} else {
|
|
182
|
+
return Signed.encodeNegativeI32(value)
|
|
183
|
+
}
|
|
154
184
|
}
|
|
155
185
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
186
|
+
static encodePositiveI32(value: number): Uint8Array {
|
|
187
|
+
if (value < this.oneByteBound) {
|
|
188
|
+
return new Uint8Array([(SingleByteMode.prefix + value) & 0xff])
|
|
189
|
+
} else if (value < this.twoByteBound) {
|
|
190
|
+
return new Uint8Array([(TwoByteMode.prefix + (value >> 8)) & 0xff, value & 0xff])
|
|
191
|
+
} else if (value < this.fourByteBound) {
|
|
192
|
+
return new Uint8Array([
|
|
193
|
+
(FourByteMode.prefix + (value >> 24)) & 0xff,
|
|
194
|
+
(value >> 16) & 0xff,
|
|
195
|
+
(value >> 8) & 0xff,
|
|
196
|
+
value & 0xff
|
|
197
|
+
])
|
|
198
|
+
} else {
|
|
199
|
+
return new Uint8Array([
|
|
200
|
+
MultiByte.prefix,
|
|
201
|
+
(value >> 24) & 0xff,
|
|
202
|
+
(value >> 16) & 0xff,
|
|
203
|
+
(value >> 8) & 0xff,
|
|
204
|
+
value & 0xff
|
|
205
|
+
])
|
|
206
|
+
}
|
|
159
207
|
}
|
|
160
208
|
|
|
161
|
-
|
|
162
|
-
if (value >=
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
])
|
|
174
|
-
} else {
|
|
175
|
-
return new Uint8Array([
|
|
176
|
-
CompactInt.multiBytePrefix,
|
|
177
|
-
(value >> 24) & 0xff,
|
|
178
|
-
(value >> 16) & 0xff,
|
|
179
|
-
(value >> 8) & 0xff,
|
|
180
|
-
value & 0xff
|
|
181
|
-
])
|
|
182
|
-
}
|
|
209
|
+
static encodeNegativeI32(value: number): Uint8Array {
|
|
210
|
+
if (value >= -this.oneByteBound) {
|
|
211
|
+
return new Uint8Array([(value ^ SingleByteMode.negPrefix) & 0xff])
|
|
212
|
+
} else if (value >= -this.twoByteBound) {
|
|
213
|
+
return new Uint8Array([((value >> 8) ^ TwoByteMode.negPrefix) & 0xff, value & 0xff])
|
|
214
|
+
} else if (value >= -this.fourByteBound) {
|
|
215
|
+
return new Uint8Array([
|
|
216
|
+
((value >> 24) ^ FourByteMode.negPrefix) & 0xff,
|
|
217
|
+
(value >> 16) & 0xff,
|
|
218
|
+
(value >> 8) & 0xff,
|
|
219
|
+
value & 0xff
|
|
220
|
+
])
|
|
183
221
|
} else {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
(value >> 16) & 0xff,
|
|
192
|
-
(value >> 8) & 0xff,
|
|
193
|
-
value & 0xff
|
|
194
|
-
])
|
|
195
|
-
} else {
|
|
196
|
-
return new Uint8Array([
|
|
197
|
-
CompactInt.multiBytePrefix,
|
|
198
|
-
(value >> 24) & 0xff,
|
|
199
|
-
(value >> 16) & 0xff,
|
|
200
|
-
(value >> 8) & 0xff,
|
|
201
|
-
value & 0xff
|
|
202
|
-
])
|
|
203
|
-
}
|
|
222
|
+
return new Uint8Array([
|
|
223
|
+
MultiByte.prefix,
|
|
224
|
+
(value >> 24) & 0xff,
|
|
225
|
+
(value >> 16) & 0xff,
|
|
226
|
+
(value >> 8) & 0xff,
|
|
227
|
+
value & 0xff
|
|
228
|
+
])
|
|
204
229
|
}
|
|
205
230
|
}
|
|
206
231
|
|
|
207
|
-
encodeI256(value: bigint): Uint8Array {
|
|
232
|
+
static encodeI256(value: bigint): Uint8Array {
|
|
233
|
+
assert(value >= Signed.i256LowerBound && value < Signed.i256UpperBound, `Invalid i256 value: ${value}`)
|
|
234
|
+
|
|
208
235
|
if (value >= -0x20000000 && value < 0x20000000) {
|
|
209
236
|
return this.encodeI32(Number(value))
|
|
210
237
|
} else {
|
|
211
238
|
const bytes = BigIntCodec.encode(value)
|
|
212
|
-
const header = (bytes.length - 4 +
|
|
239
|
+
const header = (bytes.length - 4 + MultiByte.prefix) & 0xff
|
|
213
240
|
return new Uint8Array([header, ...bytes])
|
|
214
241
|
}
|
|
215
242
|
}
|
|
216
243
|
|
|
217
|
-
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
toI32(value: DecodedCompactInt): number {
|
|
223
|
-
const body = new Uint8Array([value.mode, ...value.rest])
|
|
224
|
-
const mode = value.mode & maskRest
|
|
225
|
-
if (fixedSize(mode)) {
|
|
226
|
-
const isPositive = (value.mode & signFlag) == 0
|
|
227
|
-
if (isPositive) {
|
|
228
|
-
return decodePositiveInt(value.mode, body)
|
|
229
|
-
} else {
|
|
230
|
-
return decodeNegativeInt(value.mode, body)
|
|
231
|
-
}
|
|
244
|
+
static decodeInt(mode: FixedWidthMode, body: Uint8Array): number {
|
|
245
|
+
const isPositive = (body[0] & Signed.signFlag) === 0
|
|
246
|
+
if (isPositive) {
|
|
247
|
+
return Signed.decodePositiveInt(mode, body)
|
|
232
248
|
} else {
|
|
233
|
-
|
|
234
|
-
return ((body[1] & 0xff) << 24) | ((body[2] & 0xff) << 16) | ((body[3] & 0xff) << 8) | (body[4] & 0xff)
|
|
235
|
-
} else {
|
|
236
|
-
throw new Error(`Expect 4 bytes int, but get ${body.length - 1} bytes int`)
|
|
237
|
-
}
|
|
249
|
+
return Signed.decodeNegativeInt(mode, body)
|
|
238
250
|
}
|
|
239
251
|
}
|
|
240
252
|
|
|
241
|
-
|
|
242
|
-
|
|
253
|
+
static decodePositiveInt(mode: FixedWidthMode, body: Uint8Array): number {
|
|
254
|
+
switch (mode.type) {
|
|
255
|
+
case 'SingleByte':
|
|
256
|
+
return body[0]
|
|
257
|
+
case 'TwoByte':
|
|
258
|
+
assert(body.length === 2, 'Length should be 2')
|
|
259
|
+
return ((body[0] & maskMode) << 8) | (body[1] & 0xff)
|
|
260
|
+
case 'FourByte':
|
|
261
|
+
assert(body.length === 4, 'Length should be 4')
|
|
262
|
+
return ((body[0] & maskMode) << 24) | ((body[1] & 0xff) << 16) | ((body[2] & 0xff) << 8) | (body[3] & 0xff)
|
|
263
|
+
}
|
|
243
264
|
}
|
|
244
265
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
266
|
+
static decodeNegativeInt(mode: FixedWidthMode, body: Uint8Array) {
|
|
267
|
+
switch (mode.type) {
|
|
268
|
+
case 'SingleByte':
|
|
269
|
+
return body[0] | maskModeNeg
|
|
270
|
+
case 'TwoByte':
|
|
271
|
+
assert(body.length === 2, 'Length should be 2')
|
|
272
|
+
return ((body[0] | maskModeNeg) << 8) | (body[1] & 0xff)
|
|
273
|
+
case 'FourByte':
|
|
274
|
+
assert(body.length === 4, 'Length should be 4')
|
|
275
|
+
return ((body[0] | maskModeNeg) << 24) | ((body[1] & 0xff) << 16) | ((body[2] & 0xff) << 8) | (body[3] & 0xff)
|
|
253
276
|
}
|
|
254
277
|
}
|
|
255
278
|
|
|
256
|
-
|
|
257
|
-
|
|
279
|
+
static decodeI32(mode: Mode, body: Uint8Array): number {
|
|
280
|
+
switch (mode.type) {
|
|
281
|
+
case 'SingleByte':
|
|
282
|
+
case 'TwoByte':
|
|
283
|
+
case 'FourByte':
|
|
284
|
+
return Signed.decodeInt(mode, body)
|
|
285
|
+
case 'MultiByte':
|
|
286
|
+
if (body.length === 5) {
|
|
287
|
+
return (body[1] << 24) | ((body[2] & 0xff) << 16) | ((body[3] & 0xff) << 8) | (body[4] & 0xff)
|
|
288
|
+
} else {
|
|
289
|
+
throw new Error(`Expect 4 bytes int, but get ${body.length - 1} bytes int`)
|
|
290
|
+
}
|
|
291
|
+
}
|
|
258
292
|
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
export const compactSignedIntCodec = new CompactSignedIntCodec()
|
|
262
293
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
return ((body[0] & maskMode) << 24) | ((body[1] & 0xff) << 16) | ((body[2] & 0xff) << 8) | (body[3] & 0xff)
|
|
275
|
-
default:
|
|
276
|
-
if (body.length === 5) {
|
|
277
|
-
return Number(BigInt('0x' + binToHex(body.slice(1))))
|
|
278
|
-
} else {
|
|
279
|
-
throw new Error(`decodePositiveInt: Expect 4 bytes int, but get ${body.length - 1} bytes int`)
|
|
280
|
-
}
|
|
294
|
+
static decodeI256(mode: Mode, body: Uint8Array): bigint {
|
|
295
|
+
switch (mode.type) {
|
|
296
|
+
case 'SingleByte':
|
|
297
|
+
case 'TwoByte':
|
|
298
|
+
case 'FourByte':
|
|
299
|
+
return BigInt(Signed.decodeInt(mode, body))
|
|
300
|
+
case 'MultiByte':
|
|
301
|
+
const bytes = body.slice(1, body.length)
|
|
302
|
+
assert(bytes.length <= 32, 'Expect <= 32 bytes for I256')
|
|
303
|
+
return BigIntCodec.decodeSigned(bytes)
|
|
304
|
+
}
|
|
281
305
|
}
|
|
282
306
|
}
|
|
283
307
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
case CompactInt.oneBytePrefix:
|
|
288
|
-
return rawMode | maskModeNeg
|
|
289
|
-
case CompactInt.twoBytePrefix:
|
|
290
|
-
assert(body.length === 2, 'Length should be 2')
|
|
291
|
-
return ((body[0] | maskModeNeg) << 8) | (body[1] & 0xff)
|
|
292
|
-
case CompactInt.fourBytePrefix:
|
|
293
|
-
assert(body.length === 4, 'Length should be 4')
|
|
294
|
-
return ((body[0] | maskModeNeg) << 24) | ((body[1] & 0xff) << 16) | ((body[2] & 0xff) << 8) | (body[3] & 0xff)
|
|
295
|
-
default:
|
|
296
|
-
throw new Error(`decodeNegativeInt: Expect 4 bytes int, but get ${body.length - 1} bytes int`)
|
|
308
|
+
export const i256Codec = new (class extends Codec<bigint> {
|
|
309
|
+
encode(input: bigint): Uint8Array {
|
|
310
|
+
return Signed.encodeI256(input)
|
|
297
311
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
}
|
|
312
|
+
_decode(input: Reader): bigint {
|
|
313
|
+
const { mode, body } = decodeMode(input)
|
|
314
|
+
return Signed.decodeI256(mode, body)
|
|
315
|
+
}
|
|
316
|
+
})()
|
|
317
|
+
export const i32Codec = new (class extends Codec<number> {
|
|
318
|
+
encode(input: number): Uint8Array {
|
|
319
|
+
return Signed.encodeI32(input)
|
|
320
|
+
}
|
|
321
|
+
_decode(input: Reader): number {
|
|
322
|
+
const { mode, body } = decodeMode(input)
|
|
323
|
+
return Signed.decodeI32(mode, body)
|
|
324
|
+
}
|
|
325
|
+
})()
|
|
@@ -16,18 +16,18 @@ You should have received a copy of the GNU Lesser General Public License
|
|
|
16
16
|
along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import {
|
|
20
|
-
import { ArrayCodec, DecodedArray } from './array-codec'
|
|
19
|
+
import { ArrayCodec } from './array-codec'
|
|
21
20
|
import { Codec } from './codec'
|
|
22
|
-
import {
|
|
23
|
-
import { Method,
|
|
21
|
+
import { i32Codec } from './compact-int-codec'
|
|
22
|
+
import { Method, methodCodec } from './method-codec'
|
|
24
23
|
import { concatBytes } from '../utils'
|
|
24
|
+
import { Reader } from './reader'
|
|
25
25
|
|
|
26
|
-
const
|
|
26
|
+
const i32sCodec = new ArrayCodec(i32Codec)
|
|
27
27
|
|
|
28
28
|
export interface HalfDecodedContract {
|
|
29
|
-
fieldLength:
|
|
30
|
-
methodIndexes:
|
|
29
|
+
fieldLength: number
|
|
30
|
+
methodIndexes: number[]
|
|
31
31
|
methods: Uint8Array
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -36,36 +36,26 @@ export interface Contract {
|
|
|
36
36
|
methods: Method[]
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
export class ContractCodec
|
|
40
|
-
parser = Parser.start()
|
|
41
|
-
.nest('fieldLength', {
|
|
42
|
-
type: compactSignedIntCodec.parser
|
|
43
|
-
})
|
|
44
|
-
.nest('methodIndexes', {
|
|
45
|
-
type: compactSignedIntsCodec.parser
|
|
46
|
-
})
|
|
47
|
-
.buffer('methods', { readUntil: 'eof' })
|
|
48
|
-
|
|
39
|
+
export class ContractCodec extends Codec<HalfDecodedContract> {
|
|
49
40
|
encode(input: HalfDecodedContract): Uint8Array {
|
|
50
|
-
return concatBytes([
|
|
51
|
-
compactSignedIntCodec.encode(input.fieldLength),
|
|
52
|
-
compactSignedIntsCodec.encode(input.methodIndexes.value),
|
|
53
|
-
input.methods
|
|
54
|
-
])
|
|
41
|
+
return concatBytes([i32Codec.encode(input.fieldLength), i32sCodec.encode(input.methodIndexes), input.methods])
|
|
55
42
|
}
|
|
56
43
|
|
|
57
|
-
|
|
58
|
-
|
|
44
|
+
_decode(input: Reader): HalfDecodedContract {
|
|
45
|
+
const fieldLength = i32Codec._decode(input)
|
|
46
|
+
const methodIndexes = i32sCodec._decode(input)
|
|
47
|
+
const methods = input.consumeAll()
|
|
48
|
+
return { fieldLength, methodIndexes, methods }
|
|
59
49
|
}
|
|
60
50
|
|
|
61
51
|
decodeContract(input: Uint8Array): Contract {
|
|
62
52
|
const halfDecoded = this.decode(input)
|
|
63
|
-
const fieldLength =
|
|
64
|
-
const methodIndexes = halfDecoded.methodIndexes
|
|
53
|
+
const fieldLength = halfDecoded.fieldLength
|
|
54
|
+
const methodIndexes = halfDecoded.methodIndexes
|
|
65
55
|
const methods: Method[] = []
|
|
66
56
|
for (let i = 0, start = 0; i < methodIndexes.length; i++) {
|
|
67
57
|
const end = methodIndexes[i]
|
|
68
|
-
const method =
|
|
58
|
+
const method = methodCodec.decode(halfDecoded.methods.slice(start, end))
|
|
69
59
|
methods.push(method)
|
|
70
60
|
start = end
|
|
71
61
|
}
|
|
@@ -74,8 +64,8 @@ export class ContractCodec implements Codec<HalfDecodedContract> {
|
|
|
74
64
|
}
|
|
75
65
|
|
|
76
66
|
encodeContract(contract: Contract): Uint8Array {
|
|
77
|
-
const fieldLength =
|
|
78
|
-
const methods = contract.methods.map((m) => methodCodec.encode(
|
|
67
|
+
const fieldLength = contract.fieldLength
|
|
68
|
+
const methods = contract.methods.map((m) => methodCodec.encode(m))
|
|
79
69
|
let count = 0
|
|
80
70
|
const methodIndexes = Array.from(Array(methods.length).keys()).map((index) => {
|
|
81
71
|
count += methods[`${index}`].length
|
|
@@ -83,10 +73,7 @@ export class ContractCodec implements Codec<HalfDecodedContract> {
|
|
|
83
73
|
})
|
|
84
74
|
const halfDecoded = {
|
|
85
75
|
fieldLength,
|
|
86
|
-
methodIndexes:
|
|
87
|
-
length: compactSignedIntCodec.fromI32(methodIndexes.length),
|
|
88
|
-
value: methodIndexes.map((value) => compactSignedIntCodec.fromI32(value))
|
|
89
|
-
},
|
|
76
|
+
methodIndexes: methodIndexes,
|
|
90
77
|
methods: concatBytes(methods)
|
|
91
78
|
}
|
|
92
79
|
return this.encode(halfDecoded)
|