@alephium/web3 1.6.0 → 1.7.1
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.
|
@@ -2,7 +2,7 @@ import { NamedVals, node, NodeProvider, Number256, Token, Val } from '../api';
|
|
|
2
2
|
import { SignDeployContractTxParams, SignDeployContractTxResult, SignExecuteScriptTxParams, SignerProvider, Address, SignExecuteScriptTxResult } from '../signer';
|
|
3
3
|
import { Optional, HexString } from '../utils';
|
|
4
4
|
import { EventSubscribeOptions, EventSubscription } from './events';
|
|
5
|
-
import { Method } from '../codec';
|
|
5
|
+
import { contract, Method } from '../codec';
|
|
6
6
|
export type FieldsSig = node.FieldsSig;
|
|
7
7
|
export type MapsSig = node.MapsSig;
|
|
8
8
|
export type EventSig = node.EventSig;
|
|
@@ -32,7 +32,7 @@ export declare abstract class Artifact {
|
|
|
32
32
|
readonly name: string;
|
|
33
33
|
readonly functions: FunctionSig[];
|
|
34
34
|
constructor(version: string, name: string, functions: FunctionSig[]);
|
|
35
|
-
abstract buildByteCodeToDeploy(initialFields: Fields, isDevnet: boolean): string;
|
|
35
|
+
abstract buildByteCodeToDeploy(initialFields: Fields, isDevnet: boolean, exposePrivateFunctions: boolean): string;
|
|
36
36
|
isDevnet(signer: SignerProvider): Promise<boolean>;
|
|
37
37
|
}
|
|
38
38
|
export declare class Contract extends Artifact {
|
|
@@ -48,11 +48,17 @@ export declare class Contract extends Artifact {
|
|
|
48
48
|
readonly stdInterfaceId?: HexString;
|
|
49
49
|
readonly bytecodeDebug: string;
|
|
50
50
|
readonly codeHashDebug: string;
|
|
51
|
-
readonly
|
|
51
|
+
readonly decodedContract: contract.Contract;
|
|
52
|
+
private bytecodeForTesting;
|
|
53
|
+
private codeHashForTesting;
|
|
52
54
|
constructor(version: string, name: string, bytecode: string, bytecodeDebugPatch: string, codeHash: string, codeHashDebug: string, fieldsSig: FieldsSig, eventsSig: EventSig[], functions: FunctionSig[], constants: Constant[], enums: Enum[], structs: Struct[], mapsSig?: MapsSig, stdInterfaceId?: HexString);
|
|
55
|
+
getByteCodeForTesting(): string;
|
|
56
|
+
hasCodeHash(hash: string): boolean;
|
|
57
|
+
getDecodedMethod(methodIndex: number): Method;
|
|
53
58
|
publicFunctions(): FunctionSig[];
|
|
54
59
|
usingPreapprovedAssetsFunctions(): FunctionSig[];
|
|
55
60
|
usingAssetsInContractFunctions(): FunctionSig[];
|
|
61
|
+
isMethodUsePreapprovedAssets(methodIndex: number): boolean;
|
|
56
62
|
static fromJson(artifact: any, bytecodeDebugPatch?: string, codeHashDebug?: string, structs?: Struct[]): Contract;
|
|
57
63
|
static fromCompileResult(result: node.CompileContractResult, structs?: Struct[]): Contract;
|
|
58
64
|
static fromArtifactFile(path: string, bytecodeDebugPatch: string, codeHashDebug: string, structs?: Struct[]): Promise<Contract>;
|
|
@@ -75,7 +81,7 @@ export declare class Contract extends Artifact {
|
|
|
75
81
|
static fromApiEvent(event: node.ContractEventByTxId, codeHash: string | undefined, txId: string, getContractByCodeHash: (codeHash: string) => Contract): ContractEvent;
|
|
76
82
|
fromApiTestContractResult(methodName: string, result: node.TestContractResult, txId: string, getContractByCodeHash: (codeHash: string) => Contract): TestContractResult<unknown>;
|
|
77
83
|
txParamsForDeployment<P extends Fields>(signer: SignerProvider, params: DeployContractParams<P>): Promise<SignDeployContractTxParams>;
|
|
78
|
-
buildByteCodeToDeploy(initialFields: Fields, isDevnet: boolean): string;
|
|
84
|
+
buildByteCodeToDeploy(initialFields: Fields, isDevnet: boolean, exposePrivateFunctions?: boolean): string;
|
|
79
85
|
static fromApiEvents(events: node.ContractEventByTxId[], addressToCodeHash: Map<string, string>, txId: string, getContractByCodeHash: (codeHash: string) => Contract): ContractEvent[];
|
|
80
86
|
toApiCallContract<T extends Arguments>(params: CallContractParams<T>, groupIndex: number, contractAddress: string, methodIndex: number): node.CallContract;
|
|
81
87
|
fromApiCallContractResult(result: node.CallContractResult, txId: string, methodIndex: number, getContractByCodeHash: (codeHash: string) => Contract): CallContractResult<unknown>;
|
|
@@ -173,6 +179,7 @@ export interface DeployContractParams<P extends Fields = Fields> {
|
|
|
173
179
|
issueTokenTo?: string;
|
|
174
180
|
gasAmount?: number;
|
|
175
181
|
gasPrice?: Number256;
|
|
182
|
+
exposePrivateFunctions?: boolean;
|
|
176
183
|
}
|
|
177
184
|
export type DeployContractResult<T extends ContractInstance> = Omit<SignDeployContractTxResult, 'contractId' | 'contractAddress' | 'groupIndex'> & {
|
|
178
185
|
contractInstance: T;
|
|
@@ -129,16 +129,46 @@ class Contract extends Artifact {
|
|
|
129
129
|
this.stdInterfaceId = stdInterfaceId;
|
|
130
130
|
this.bytecodeDebug = ralph.buildDebugBytecode(this.bytecode, this.bytecodeDebugPatch);
|
|
131
131
|
this.codeHashDebug = codeHashDebug;
|
|
132
|
-
this.
|
|
132
|
+
this.decodedContract = codec_1.contract.contractCodec.decodeContract((0, utils_1.hexToBinUnsafe)(this.bytecode));
|
|
133
|
+
this.bytecodeForTesting = undefined;
|
|
134
|
+
this.codeHashForTesting = undefined;
|
|
135
|
+
}
|
|
136
|
+
getByteCodeForTesting() {
|
|
137
|
+
if (this.bytecodeForTesting !== undefined)
|
|
138
|
+
return this.bytecodeForTesting;
|
|
139
|
+
if (this.publicFunctions().length == this.functions.length) {
|
|
140
|
+
this.bytecodeForTesting = this.bytecodeDebug;
|
|
141
|
+
this.codeHashForTesting = this.codeHashDebug;
|
|
142
|
+
return this.bytecodeForTesting;
|
|
143
|
+
}
|
|
144
|
+
const decodedDebugContract = codec_1.contract.contractCodec.decodeContract((0, utils_1.hexToBinUnsafe)(this.bytecodeDebug));
|
|
145
|
+
const methods = decodedDebugContract.methods.map((method) => ({ ...method, isPublic: true }));
|
|
146
|
+
const bytecodeForTesting = codec_1.contract.contractCodec.encodeContract({
|
|
147
|
+
fieldLength: decodedDebugContract.fieldLength,
|
|
148
|
+
methods: methods
|
|
149
|
+
});
|
|
150
|
+
const codeHashForTesting = blake.blake2b(bytecodeForTesting, undefined, 32);
|
|
151
|
+
this.bytecodeForTesting = (0, utils_1.binToHex)(bytecodeForTesting);
|
|
152
|
+
this.codeHashForTesting = (0, utils_1.binToHex)(codeHashForTesting);
|
|
153
|
+
return this.bytecodeForTesting;
|
|
154
|
+
}
|
|
155
|
+
hasCodeHash(hash) {
|
|
156
|
+
return this.codeHash === hash || this.codeHashDebug === hash || this.codeHashForTesting === hash;
|
|
157
|
+
}
|
|
158
|
+
getDecodedMethod(methodIndex) {
|
|
159
|
+
return this.decodedContract.methods[`${methodIndex}`];
|
|
133
160
|
}
|
|
134
161
|
publicFunctions() {
|
|
135
|
-
return this.functions.filter((_, index) => this.
|
|
162
|
+
return this.functions.filter((_, index) => this.getDecodedMethod(index).isPublic);
|
|
136
163
|
}
|
|
137
164
|
usingPreapprovedAssetsFunctions() {
|
|
138
|
-
return this.functions.filter((_, index) => this.
|
|
165
|
+
return this.functions.filter((_, index) => this.getDecodedMethod(index).usePreapprovedAssets);
|
|
139
166
|
}
|
|
140
167
|
usingAssetsInContractFunctions() {
|
|
141
|
-
return this.functions.filter((_, index) => this.
|
|
168
|
+
return this.functions.filter((_, index) => this.getDecodedMethod(index).useContractAssets);
|
|
169
|
+
}
|
|
170
|
+
isMethodUsePreapprovedAssets(methodIndex) {
|
|
171
|
+
return this.getDecodedMethod(methodIndex).usePreapprovedAssets;
|
|
142
172
|
}
|
|
143
173
|
// TODO: safely parse json
|
|
144
174
|
static fromJson(artifact, bytecodeDebugPatch = '', codeHashDebug = '', structs = []) {
|
|
@@ -333,7 +363,7 @@ class Contract extends Artifact {
|
|
|
333
363
|
async txParamsForDeployment(signer, params) {
|
|
334
364
|
const isDevnet = await this.isDevnet(signer);
|
|
335
365
|
const initialFields = params.initialFields ?? {};
|
|
336
|
-
const bytecode = this.buildByteCodeToDeploy(addStdIdToFields(this, initialFields), isDevnet);
|
|
366
|
+
const bytecode = this.buildByteCodeToDeploy(addStdIdToFields(this, initialFields), isDevnet, params.exposePrivateFunctions ?? false);
|
|
337
367
|
const selectedAccount = await signer.getSelectedAccount();
|
|
338
368
|
const signerParams = {
|
|
339
369
|
signerAddress: selectedAccount.address,
|
|
@@ -348,9 +378,17 @@ class Contract extends Artifact {
|
|
|
348
378
|
};
|
|
349
379
|
return signerParams;
|
|
350
380
|
}
|
|
351
|
-
buildByteCodeToDeploy(initialFields, isDevnet) {
|
|
381
|
+
buildByteCodeToDeploy(initialFields, isDevnet, exposePrivateFunctions = false) {
|
|
382
|
+
if (exposePrivateFunctions && !isDevnet) {
|
|
383
|
+
throw new Error('Cannot expose private functions in non-devnet environment');
|
|
384
|
+
}
|
|
352
385
|
try {
|
|
353
|
-
|
|
386
|
+
const bytecode = exposePrivateFunctions && isDevnet
|
|
387
|
+
? this.getByteCodeForTesting()
|
|
388
|
+
: isDevnet
|
|
389
|
+
? this.bytecodeDebug
|
|
390
|
+
: this.bytecode;
|
|
391
|
+
return ralph.buildContractByteCode(bytecode, initialFields, this.fieldsSig, this.structs);
|
|
354
392
|
}
|
|
355
393
|
catch (error) {
|
|
356
394
|
throw new Error(`Failed to build bytecode for contract ${this.name}, error: ${error}`);
|
|
@@ -1074,7 +1112,7 @@ exports.callMethod = callMethod;
|
|
|
1074
1112
|
async function signExecuteMethod(contract, instance, methodName, params) {
|
|
1075
1113
|
const methodIndex = contract.contract.getMethodIndex(methodName);
|
|
1076
1114
|
const functionSig = contract.contract.functions[methodIndex];
|
|
1077
|
-
const methodUsePreapprovedAssets = contract.contract.
|
|
1115
|
+
const methodUsePreapprovedAssets = contract.contract.isMethodUsePreapprovedAssets(methodIndex);
|
|
1078
1116
|
const bytecodeTemplate = getBytecodeTemplate(methodIndex, methodUsePreapprovedAssets, functionSig, contract.contract.structs, params.attoAlphAmount, params.tokens);
|
|
1079
1117
|
const fieldsSig = toFieldsSig(contract.contract.name, functionSig);
|
|
1080
1118
|
const bytecode = ralph.buildScriptByteCode(bytecodeTemplate, { __contract__: instance.contractId, ...params.args }, fieldsSig, contract.contract.structs);
|
package/package.json
CHANGED
package/src/contract/contract.ts
CHANGED
|
@@ -162,7 +162,7 @@ export abstract class Artifact {
|
|
|
162
162
|
this.functions = functions
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
abstract buildByteCodeToDeploy(initialFields: Fields, isDevnet: boolean): string
|
|
165
|
+
abstract buildByteCodeToDeploy(initialFields: Fields, isDevnet: boolean, exposePrivateFunctions: boolean): string
|
|
166
166
|
|
|
167
167
|
async isDevnet(signer: SignerProvider): Promise<boolean> {
|
|
168
168
|
if (!signer.nodeProvider) {
|
|
@@ -197,7 +197,10 @@ export class Contract extends Artifact {
|
|
|
197
197
|
|
|
198
198
|
readonly bytecodeDebug: string
|
|
199
199
|
readonly codeHashDebug: string
|
|
200
|
-
readonly
|
|
200
|
+
readonly decodedContract: contract.Contract
|
|
201
|
+
|
|
202
|
+
private bytecodeForTesting: string | undefined
|
|
203
|
+
private codeHashForTesting: string | undefined
|
|
201
204
|
|
|
202
205
|
constructor(
|
|
203
206
|
version: string,
|
|
@@ -230,19 +233,54 @@ export class Contract extends Artifact {
|
|
|
230
233
|
this.bytecodeDebug = ralph.buildDebugBytecode(this.bytecode, this.bytecodeDebugPatch)
|
|
231
234
|
this.codeHashDebug = codeHashDebug
|
|
232
235
|
|
|
233
|
-
this.
|
|
236
|
+
this.decodedContract = contract.contractCodec.decodeContract(hexToBinUnsafe(this.bytecode))
|
|
237
|
+
this.bytecodeForTesting = undefined
|
|
238
|
+
this.codeHashForTesting = undefined
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
getByteCodeForTesting(): string {
|
|
242
|
+
if (this.bytecodeForTesting !== undefined) return this.bytecodeForTesting
|
|
243
|
+
|
|
244
|
+
if (this.publicFunctions().length == this.functions.length) {
|
|
245
|
+
this.bytecodeForTesting = this.bytecodeDebug
|
|
246
|
+
this.codeHashForTesting = this.codeHashDebug
|
|
247
|
+
return this.bytecodeForTesting
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const decodedDebugContract = contract.contractCodec.decodeContract(hexToBinUnsafe(this.bytecodeDebug))
|
|
251
|
+
const methods = decodedDebugContract.methods.map((method) => ({ ...method, isPublic: true }))
|
|
252
|
+
const bytecodeForTesting = contract.contractCodec.encodeContract({
|
|
253
|
+
fieldLength: decodedDebugContract.fieldLength,
|
|
254
|
+
methods: methods
|
|
255
|
+
})
|
|
256
|
+
const codeHashForTesting = blake.blake2b(bytecodeForTesting, undefined, 32)
|
|
257
|
+
this.bytecodeForTesting = binToHex(bytecodeForTesting)
|
|
258
|
+
this.codeHashForTesting = binToHex(codeHashForTesting)
|
|
259
|
+
return this.bytecodeForTesting
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
hasCodeHash(hash: string): boolean {
|
|
263
|
+
return this.codeHash === hash || this.codeHashDebug === hash || this.codeHashForTesting === hash
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
getDecodedMethod(methodIndex: number): Method {
|
|
267
|
+
return this.decodedContract.methods[`${methodIndex}`]
|
|
234
268
|
}
|
|
235
269
|
|
|
236
270
|
publicFunctions(): FunctionSig[] {
|
|
237
|
-
return this.functions.filter((_, index) => this.
|
|
271
|
+
return this.functions.filter((_, index) => this.getDecodedMethod(index).isPublic)
|
|
238
272
|
}
|
|
239
273
|
|
|
240
274
|
usingPreapprovedAssetsFunctions(): FunctionSig[] {
|
|
241
|
-
return this.functions.filter((_, index) => this.
|
|
275
|
+
return this.functions.filter((_, index) => this.getDecodedMethod(index).usePreapprovedAssets)
|
|
242
276
|
}
|
|
243
277
|
|
|
244
278
|
usingAssetsInContractFunctions(): FunctionSig[] {
|
|
245
|
-
return this.functions.filter((_, index) => this.
|
|
279
|
+
return this.functions.filter((_, index) => this.getDecodedMethod(index).useContractAssets)
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
isMethodUsePreapprovedAssets(methodIndex: number): boolean {
|
|
283
|
+
return this.getDecodedMethod(methodIndex).usePreapprovedAssets
|
|
246
284
|
}
|
|
247
285
|
|
|
248
286
|
// TODO: safely parse json
|
|
@@ -530,7 +568,11 @@ export class Contract extends Artifact {
|
|
|
530
568
|
): Promise<SignDeployContractTxParams> {
|
|
531
569
|
const isDevnet = await this.isDevnet(signer)
|
|
532
570
|
const initialFields: Fields = params.initialFields ?? {}
|
|
533
|
-
const bytecode = this.buildByteCodeToDeploy(
|
|
571
|
+
const bytecode = this.buildByteCodeToDeploy(
|
|
572
|
+
addStdIdToFields(this, initialFields),
|
|
573
|
+
isDevnet,
|
|
574
|
+
params.exposePrivateFunctions ?? false
|
|
575
|
+
)
|
|
534
576
|
const selectedAccount = await signer.getSelectedAccount()
|
|
535
577
|
const signerParams: SignDeployContractTxParams = {
|
|
536
578
|
signerAddress: selectedAccount.address,
|
|
@@ -546,14 +588,19 @@ export class Contract extends Artifact {
|
|
|
546
588
|
return signerParams
|
|
547
589
|
}
|
|
548
590
|
|
|
549
|
-
buildByteCodeToDeploy(initialFields: Fields, isDevnet: boolean): string {
|
|
591
|
+
buildByteCodeToDeploy(initialFields: Fields, isDevnet: boolean, exposePrivateFunctions = false): string {
|
|
592
|
+
if (exposePrivateFunctions && !isDevnet) {
|
|
593
|
+
throw new Error('Cannot expose private functions in non-devnet environment')
|
|
594
|
+
}
|
|
595
|
+
|
|
550
596
|
try {
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
597
|
+
const bytecode =
|
|
598
|
+
exposePrivateFunctions && isDevnet
|
|
599
|
+
? this.getByteCodeForTesting()
|
|
600
|
+
: isDevnet
|
|
601
|
+
? this.bytecodeDebug
|
|
602
|
+
: this.bytecode
|
|
603
|
+
return ralph.buildContractByteCode(bytecode, initialFields, this.fieldsSig, this.structs)
|
|
557
604
|
} catch (error) {
|
|
558
605
|
throw new Error(`Failed to build bytecode for contract ${this.name}, error: ${error}`)
|
|
559
606
|
}
|
|
@@ -975,10 +1022,11 @@ export interface DeployContractParams<P extends Fields = Fields> {
|
|
|
975
1022
|
issueTokenTo?: string
|
|
976
1023
|
gasAmount?: number
|
|
977
1024
|
gasPrice?: Number256
|
|
1025
|
+
exposePrivateFunctions?: boolean
|
|
978
1026
|
}
|
|
979
1027
|
assertType<
|
|
980
1028
|
Eq<
|
|
981
|
-
Omit<DeployContractParams<undefined>, 'initialFields'>,
|
|
1029
|
+
Omit<DeployContractParams<undefined>, 'initialFields' | 'exposePrivateFunctions'>,
|
|
982
1030
|
Omit<SignDeployContractTxParams, 'signerAddress' | 'signerKeyType' | 'bytecode'>
|
|
983
1031
|
>
|
|
984
1032
|
>
|
|
@@ -1687,7 +1735,7 @@ export async function signExecuteMethod<I extends ContractInstance, F extends Fi
|
|
|
1687
1735
|
): Promise<SignExecuteScriptTxResult> {
|
|
1688
1736
|
const methodIndex = contract.contract.getMethodIndex(methodName)
|
|
1689
1737
|
const functionSig = contract.contract.functions[methodIndex]
|
|
1690
|
-
const methodUsePreapprovedAssets = contract.contract.
|
|
1738
|
+
const methodUsePreapprovedAssets = contract.contract.isMethodUsePreapprovedAssets(methodIndex)
|
|
1691
1739
|
const bytecodeTemplate = getBytecodeTemplate(
|
|
1692
1740
|
methodIndex,
|
|
1693
1741
|
methodUsePreapprovedAssets,
|