From 4bc2c24aca06cc541c1993852b0105e083ee0d3d Mon Sep 17 00:00:00 2001 From: lbqds Date: Thu, 21 Mar 2024 08:58:07 +0800 Subject: [PATCH 01/24] Fix buffer --- packages/web3/src/codec/array-codec.ts | 1 + packages/web3/src/codec/asset-output-codec.ts | 1 + packages/web3/src/codec/bigint-codec.ts | 1 + packages/web3/src/codec/bytestring-codec.test.ts | 1 + packages/web3/src/codec/bytestring-codec.ts | 1 + packages/web3/src/codec/codec.ts | 1 + packages/web3/src/codec/compact-int-codec.test.ts | 1 + packages/web3/src/codec/compact-int-codec.ts | 1 + packages/web3/src/codec/contract-codec.test.ts | 1 + packages/web3/src/codec/contract-codec.ts | 1 + packages/web3/src/codec/contract-output-codec.ts | 1 + packages/web3/src/codec/contract-output-ref-codec.ts | 1 + packages/web3/src/codec/either-codec.ts | 1 + packages/web3/src/codec/hash.ts | 1 + packages/web3/src/codec/input-codec.ts | 1 + packages/web3/src/codec/instr-codec.ts | 1 + packages/web3/src/codec/lockup-script-codec.ts | 1 + packages/web3/src/codec/long-codec.ts | 1 + packages/web3/src/codec/method-codec.ts | 1 + packages/web3/src/codec/option-codec.ts | 1 + packages/web3/src/codec/script-codec.test.ts | 1 + packages/web3/src/codec/script-codec.ts | 1 + packages/web3/src/codec/signature-codec.ts | 1 + packages/web3/src/codec/signed-int-codec.ts | 1 + packages/web3/src/codec/token-codec.ts | 1 + packages/web3/src/codec/transaction-codec.test.ts | 1 + packages/web3/src/codec/transaction-codec.ts | 1 + packages/web3/src/codec/unlock-script-codec.ts | 1 + packages/web3/src/codec/unsigned-tx-codec.test.ts | 1 + packages/web3/src/codec/unsigned-tx-codec.ts | 1 + 30 files changed, 30 insertions(+) diff --git a/packages/web3/src/codec/array-codec.ts b/packages/web3/src/codec/array-codec.ts index ab4b85380..07ae7b889 100644 --- a/packages/web3/src/codec/array-codec.ts +++ b/packages/web3/src/codec/array-codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { compactSignedIntCodec, compactUnsignedIntCodec, DecodedCompactInt } from './compact-int-codec' import { Codec } from './codec' diff --git a/packages/web3/src/codec/asset-output-codec.ts b/packages/web3/src/codec/asset-output-codec.ts index e0450b21e..bf02da3ee 100644 --- a/packages/web3/src/codec/asset-output-codec.ts +++ b/packages/web3/src/codec/asset-output-codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { ArrayCodec, DecodedArray } from './array-codec' import { DecodedCompactInt, compactUnsignedIntCodec } from './compact-int-codec' diff --git a/packages/web3/src/codec/bigint-codec.ts b/packages/web3/src/codec/bigint-codec.ts index bd68946be..4254ad644 100644 --- a/packages/web3/src/codec/bigint-codec.ts +++ b/packages/web3/src/codec/bigint-codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' export class BigIntCodec { static encode(value: bigint): Buffer { // Special case for zero. diff --git a/packages/web3/src/codec/bytestring-codec.test.ts b/packages/web3/src/codec/bytestring-codec.test.ts index 29bc508a7..e1cd23319 100644 --- a/packages/web3/src/codec/bytestring-codec.test.ts +++ b/packages/web3/src/codec/bytestring-codec.test.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { byteStringCodec } from './bytestring-codec' import { compactUnsignedIntCodec } from './compact-int-codec' diff --git a/packages/web3/src/codec/bytestring-codec.ts b/packages/web3/src/codec/bytestring-codec.ts index 8614d6cb4..45b9b7be6 100644 --- a/packages/web3/src/codec/bytestring-codec.ts +++ b/packages/web3/src/codec/bytestring-codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { DecodedCompactInt, compactUnsignedIntCodec } from './compact-int-codec' import { Codec } from './codec' diff --git a/packages/web3/src/codec/codec.ts b/packages/web3/src/codec/codec.ts index 157cc5ded..74e3bb58f 100644 --- a/packages/web3/src/codec/codec.ts +++ b/packages/web3/src/codec/codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' export interface Codec { diff --git a/packages/web3/src/codec/compact-int-codec.test.ts b/packages/web3/src/codec/compact-int-codec.test.ts index 12b8bf91c..1f61cddc1 100644 --- a/packages/web3/src/codec/compact-int-codec.test.ts +++ b/packages/web3/src/codec/compact-int-codec.test.ts @@ -16,6 +16,7 @@ You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { compactSignedIntCodec, compactUnsignedIntCodec } from './compact-int-codec' import { randomBytes } from 'crypto' diff --git a/packages/web3/src/codec/compact-int-codec.ts b/packages/web3/src/codec/compact-int-codec.ts index d4cb00c9d..f51c6b8cb 100644 --- a/packages/web3/src/codec/compact-int-codec.ts +++ b/packages/web3/src/codec/compact-int-codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { Codec, assert } from './codec' import { BigIntCodec } from './bigint-codec' diff --git a/packages/web3/src/codec/contract-codec.test.ts b/packages/web3/src/codec/contract-codec.test.ts index 2c6760399..c0e04b73c 100644 --- a/packages/web3/src/codec/contract-codec.test.ts +++ b/packages/web3/src/codec/contract-codec.test.ts @@ -16,6 +16,7 @@ You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { web3 } from '@alephium/web3' import { Method } from './method-codec' import { contractCodec } from './contract-codec' diff --git a/packages/web3/src/codec/contract-codec.ts b/packages/web3/src/codec/contract-codec.ts index eb7653f48..132c0968e 100644 --- a/packages/web3/src/codec/contract-codec.ts +++ b/packages/web3/src/codec/contract-codec.ts @@ -16,6 +16,7 @@ You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { ArrayCodec, DecodedArray } from './array-codec' import { Codec } from './codec' diff --git a/packages/web3/src/codec/contract-output-codec.ts b/packages/web3/src/codec/contract-output-codec.ts index e88a7b414..85757d283 100644 --- a/packages/web3/src/codec/contract-output-codec.ts +++ b/packages/web3/src/codec/contract-output-codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { DecodedArray } from './array-codec' import { DecodedCompactInt, compactUnsignedIntCodec } from './compact-int-codec' diff --git a/packages/web3/src/codec/contract-output-ref-codec.ts b/packages/web3/src/codec/contract-output-ref-codec.ts index 4f4d44b41..782e16678 100644 --- a/packages/web3/src/codec/contract-output-ref-codec.ts +++ b/packages/web3/src/codec/contract-output-ref-codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { ArrayCodec } from './array-codec' import { Codec } from './codec' diff --git a/packages/web3/src/codec/either-codec.ts b/packages/web3/src/codec/either-codec.ts index 6a29caefc..84af08a26 100644 --- a/packages/web3/src/codec/either-codec.ts +++ b/packages/web3/src/codec/either-codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { Codec } from './codec' diff --git a/packages/web3/src/codec/hash.ts b/packages/web3/src/codec/hash.ts index 62286f383..c63dababa 100644 --- a/packages/web3/src/codec/hash.ts +++ b/packages/web3/src/codec/hash.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import blake from 'blakejs' export function blakeHash(raw: Uint8Array) { diff --git a/packages/web3/src/codec/input-codec.ts b/packages/web3/src/codec/input-codec.ts index ee571e505..865e73689 100644 --- a/packages/web3/src/codec/input-codec.ts +++ b/packages/web3/src/codec/input-codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { AssetInput } from '../api/api-alephium' import { binToHex } from '../utils' diff --git a/packages/web3/src/codec/instr-codec.ts b/packages/web3/src/codec/instr-codec.ts index 98fdb2f9b..bae3dba9d 100644 --- a/packages/web3/src/codec/instr-codec.ts +++ b/packages/web3/src/codec/instr-codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { ArrayCodec, DecodedArray } from './array-codec' import { compactUnsignedIntCodec, compactSignedIntCodec, DecodedCompactInt } from './compact-int-codec' diff --git a/packages/web3/src/codec/lockup-script-codec.ts b/packages/web3/src/codec/lockup-script-codec.ts index 0473547ca..c98cfddfd 100644 --- a/packages/web3/src/codec/lockup-script-codec.ts +++ b/packages/web3/src/codec/lockup-script-codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { DecodedCompactInt, compactUnsignedIntCodec } from './compact-int-codec' import { Codec } from './codec' diff --git a/packages/web3/src/codec/long-codec.ts b/packages/web3/src/codec/long-codec.ts index 748c73f55..36ef36544 100644 --- a/packages/web3/src/codec/long-codec.ts +++ b/packages/web3/src/codec/long-codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { Codec, assert } from './codec' diff --git a/packages/web3/src/codec/method-codec.ts b/packages/web3/src/codec/method-codec.ts index 0a6cf43f5..4353409ba 100644 --- a/packages/web3/src/codec/method-codec.ts +++ b/packages/web3/src/codec/method-codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { ArrayCodec, DecodedArray } from './array-codec' import { DecodedCompactInt, compactUnsignedIntCodec } from './compact-int-codec' diff --git a/packages/web3/src/codec/option-codec.ts b/packages/web3/src/codec/option-codec.ts index e819a3a60..518ed7fae 100644 --- a/packages/web3/src/codec/option-codec.ts +++ b/packages/web3/src/codec/option-codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { Codec } from './codec' diff --git a/packages/web3/src/codec/script-codec.test.ts b/packages/web3/src/codec/script-codec.test.ts index 1ef38be57..f05ffa9f3 100644 --- a/packages/web3/src/codec/script-codec.test.ts +++ b/packages/web3/src/codec/script-codec.test.ts @@ -16,6 +16,7 @@ You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { web3, Fields, FieldsSig, buildScriptByteCode } from '@alephium/web3' import { randomContractId } from '@alephium/web3-test' import { scriptCodec } from './script-codec' diff --git a/packages/web3/src/codec/script-codec.ts b/packages/web3/src/codec/script-codec.ts index 53eb8fc9c..47e3d693c 100644 --- a/packages/web3/src/codec/script-codec.ts +++ b/packages/web3/src/codec/script-codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { DecodedArray } from './array-codec' import { Codec } from './codec' diff --git a/packages/web3/src/codec/signature-codec.ts b/packages/web3/src/codec/signature-codec.ts index 3eca490ba..2a371aa27 100644 --- a/packages/web3/src/codec/signature-codec.ts +++ b/packages/web3/src/codec/signature-codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { ArrayCodec } from './array-codec' import { Codec } from './codec' diff --git a/packages/web3/src/codec/signed-int-codec.ts b/packages/web3/src/codec/signed-int-codec.ts index 0da8ee7ea..d419a0e90 100644 --- a/packages/web3/src/codec/signed-int-codec.ts +++ b/packages/web3/src/codec/signed-int-codec.ts @@ -18,6 +18,7 @@ along with the library. If not, see . import { Parser } from 'binary-parser' import { Codec, assert } from './codec' +import { Buffer } from 'buffer/' export class SignedIntCodec implements Codec { parser = Parser.start().buffer('value', { length: 4 diff --git a/packages/web3/src/codec/token-codec.ts b/packages/web3/src/codec/token-codec.ts index b8c3731e1..74f9e3f79 100644 --- a/packages/web3/src/codec/token-codec.ts +++ b/packages/web3/src/codec/token-codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { DecodedCompactInt, compactUnsignedIntCodec } from './compact-int-codec' import { Codec } from './codec' diff --git a/packages/web3/src/codec/transaction-codec.test.ts b/packages/web3/src/codec/transaction-codec.test.ts index ab4b313d6..ace940bf0 100644 --- a/packages/web3/src/codec/transaction-codec.test.ts +++ b/packages/web3/src/codec/transaction-codec.test.ts @@ -16,6 +16,7 @@ You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { TransactionCodec, transactionCodec } from './transaction-codec' describe('Encode & decode transactions', function () { diff --git a/packages/web3/src/codec/transaction-codec.ts b/packages/web3/src/codec/transaction-codec.ts index 7cc6fe5d8..d48790a0f 100644 --- a/packages/web3/src/codec/transaction-codec.ts +++ b/packages/web3/src/codec/transaction-codec.ts @@ -16,6 +16,7 @@ You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { DecodedArray } from './array-codec' diff --git a/packages/web3/src/codec/unlock-script-codec.ts b/packages/web3/src/codec/unlock-script-codec.ts index bae8a6563..fad627712 100644 --- a/packages/web3/src/codec/unlock-script-codec.ts +++ b/packages/web3/src/codec/unlock-script-codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { ArrayCodec, DecodedArray } from './array-codec' import { compactUnsignedIntCodec, compactSignedIntCodec, DecodedCompactInt } from './compact-int-codec' diff --git a/packages/web3/src/codec/unsigned-tx-codec.test.ts b/packages/web3/src/codec/unsigned-tx-codec.test.ts index 797483683..87c814222 100644 --- a/packages/web3/src/codec/unsigned-tx-codec.test.ts +++ b/packages/web3/src/codec/unsigned-tx-codec.test.ts @@ -16,6 +16,7 @@ You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { web3, ONE_ALPH, buildScriptByteCode, buildContractByteCode } from '@alephium/web3' import { getSigners } from '@alephium/web3-test' import { unsignedTxCodec } from './index' diff --git a/packages/web3/src/codec/unsigned-tx-codec.ts b/packages/web3/src/codec/unsigned-tx-codec.ts index 140d4179c..81d02f778 100644 --- a/packages/web3/src/codec/unsigned-tx-codec.ts +++ b/packages/web3/src/codec/unsigned-tx-codec.ts @@ -15,6 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ +import { Buffer } from 'buffer/' import { Parser } from 'binary-parser' import { UnsignedTx as ApiUnsignedTx } from '../api/api-alephium' import { binToHex, hexToBinUnsafe } from '../utils' From 1af86d71c721b904e2bf0fbd7777c8b96ff952a2 Mon Sep 17 00:00:00 2001 From: lbqds Date: Wed, 20 Mar 2024 12:03:16 +0800 Subject: [PATCH 02/24] Fix encode fields --- contracts/add/add.ral | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/add/add.ral b/contracts/add/add.ral index 230be7b50..d167a344b 100644 --- a/contracts/add/add.ral +++ b/contracts/add/add.ral @@ -17,7 +17,8 @@ Contract Add(sub: Sub, mut result : U256) { @using(preapprovedAssets = true) pub fn createSubContract(a: U256, path: ByteVec, subContractId: ByteVec, payer: Address) -> () { - copyCreateSubContract!{payer -> ALPH: 1 alph}(path, subContractId, #00, Sub.encodeMutFields!(a)) + let (immFields, mutFields) = Sub.encodeFields!(a) + copyCreateSubContract!{payer -> ALPH: 1 alph}(path, subContractId, immFields, mutFields) } @using(checkExternalCaller = false, assetsInContract = true) From 10a56270b79385aaa6c496150d6ef40a81d88b3e Mon Sep 17 00:00:00 2001 From: lbqds Date: Wed, 20 Mar 2024 13:50:26 +0800 Subject: [PATCH 03/24] Ignore map contract fields --- packages/cli/src/codegen.ts | 14 ++++++------- packages/web3/src/contract/contract.ts | 26 +++++++++++++----------- packages/web3/src/contract/ralph.test.ts | 23 +++++++++++++++++++++ packages/web3/src/contract/ralph.ts | 15 ++++++++++++++ 4 files changed, 59 insertions(+), 19 deletions(-) diff --git a/packages/cli/src/codegen.ts b/packages/cli/src/codegen.ts index 53e7da9c5..e49348ce5 100644 --- a/packages/cli/src/codegen.ts +++ b/packages/cli/src/codegen.ts @@ -253,12 +253,12 @@ function genGetInitialFieldsWithDefaultValues(contract: Contract): string { } function genContractStateType(contract: Contract): string { - if (contract.fieldsSig.names.length === 0) { + if (contract.fieldsExceptMaps.names.length === 0) { return `export type State = Omit, 'fields'>` } return ` export type Fields = { - ${formatParameters(contract.fieldsSig)} + ${formatParameters(contract.fieldsExceptMaps)} } export type State = ContractState @@ -361,14 +361,14 @@ function toUnixPath(p: string): string { } function getContractFields(contract: Contract): node.FieldsSig { - const stdIdFieldIndex = contract.fieldsSig.names.findIndex((name) => name === StdIdFieldName) + const stdIdFieldIndex = contract.fieldsExceptMaps.names.findIndex((name) => name === StdIdFieldName) if (stdIdFieldIndex === -1) { - return contract.fieldsSig + return contract.fieldsExceptMaps } return { - names: contract.fieldsSig.names.filter((_, index) => index !== stdIdFieldIndex), - types: contract.fieldsSig.types.filter((_, index) => index !== stdIdFieldIndex), - isMutable: contract.fieldsSig.isMutable.filter((_, index) => index !== stdIdFieldIndex) + names: contract.fieldsExceptMaps.names.filter((_, index) => index !== stdIdFieldIndex), + types: contract.fieldsExceptMaps.types.filter((_, index) => index !== stdIdFieldIndex), + isMutable: contract.fieldsExceptMaps.isMutable.filter((_, index) => index !== stdIdFieldIndex) } } diff --git a/packages/web3/src/contract/contract.ts b/packages/web3/src/contract/contract.ts index 31786f6d0..484eef12d 100644 --- a/packages/web3/src/contract/contract.ts +++ b/packages/web3/src/contract/contract.ts @@ -886,6 +886,7 @@ export class Contract extends Artifact { readonly bytecodeDebugPatch: string readonly codeHash: string readonly fieldsSig: FieldsSig + readonly fieldsExceptMaps: FieldsSig readonly eventsSig: EventSig[] readonly constants: Constant[] readonly enums: Enum[] @@ -915,6 +916,7 @@ export class Contract extends Artifact { this.bytecodeDebugPatch = bytecodeDebugPatch this.codeHash = codeHash this.fieldsSig = fieldsSig + this.fieldsExceptMaps = ralph.fieldsExceptMaps(fieldsSig) this.eventsSig = eventsSig this.constants = constants this.enums = enums @@ -1009,11 +1011,11 @@ export class Contract extends Artifact { getInitialFieldsWithDefaultValues(): Fields { const fields = this.stdInterfaceId === undefined - ? this.fieldsSig + ? this.fieldsExceptMaps : { - names: this.fieldsSig.names.slice(0, -1), - types: this.fieldsSig.types.slice(0, -1), - isMutable: this.fieldsSig.isMutable.slice(0, -1) + names: this.fieldsExceptMaps.names.slice(0, -1), + types: this.fieldsExceptMaps.types.slice(0, -1), + isMutable: this.fieldsExceptMaps.isMutable.slice(0, -1) } return getDefaultValue(fields, this.structs) } @@ -1026,7 +1028,7 @@ export class Contract extends Artifact { bytecode: this.bytecode, codeHash: this.codeHash, fields: fields, - fieldsSig: this.fieldsSig, + fieldsSig: this.fieldsExceptMaps, asset: asset } } @@ -1050,7 +1052,7 @@ export class Contract extends Artifact { if (typeof fields === 'undefined') { return [] } else { - return toApiFields(fields, this.fieldsSig, this.structs) + return toApiFields(fields, this.fieldsExceptMaps, this.structs) } } @@ -1081,9 +1083,9 @@ export class Contract extends Artifact { ? [] : ralph.flattenFields( params.initialFields, - this.fieldsSig.names, - this.fieldsSig.types, - this.fieldsSig.isMutable, + this.fieldsExceptMaps.names, + this.fieldsExceptMaps.types, + this.fieldsExceptMaps.isMutable, this.structs ) const immFields = allFields.filter((f) => !f.isMutable).map((f) => toApiVal(f.value, f.type)) @@ -1113,8 +1115,8 @@ export class Contract extends Artifact { bytecode: state.bytecode, initialStateHash: state.initialStateHash, codeHash: state.codeHash, - fields: fromApiFields(state.immFields, state.mutFields, this.fieldsSig, this.structs), - fieldsSig: this.fieldsSig, + fields: fromApiFields(state.immFields, state.mutFields, this.fieldsExceptMaps, this.structs), + fieldsSig: this.fieldsExceptMaps, asset: fromApiAsset(state.asset) } } @@ -1229,7 +1231,7 @@ export class Contract extends Artifact { return ralph.buildContractByteCode( isDevnet ? this.bytecodeDebug : this.bytecode, initialFields, - this.fieldsSig, + this.fieldsExceptMaps, this.structs ) } catch (error) { diff --git a/packages/web3/src/contract/ralph.test.ts b/packages/web3/src/contract/ralph.test.ts index b341da0c1..9156c2041 100644 --- a/packages/web3/src/contract/ralph.test.ts +++ b/packages/web3/src/contract/ralph.test.ts @@ -290,6 +290,29 @@ describe('contract', function () { }) }) + it('should filter out map fields', () => { + const fieldsSig0: node.FieldsSig = { + names: ['foo', 'number', 'map'], + types: ['Foo', 'U256', 'Map[U256, Foo]'], + isMutable: [false, true, true] + } + expect(ralph.fieldsExceptMaps(fieldsSig0)).toEqual({ + names: ['foo', 'number'], + types: ['Foo', 'U256'], + isMutable: [false, true] + }) + const fieldsSig1: node.FieldsSig = { + names: ['foo', 'number'], + types: ['Foo', 'U256'], + isMutable: [false, true] + } + expect(ralph.fieldsExceptMaps(fieldsSig1)).toEqual({ + names: ['foo', 'number'], + types: ['Foo', 'U256'], + isMutable: [false, true] + }) + }) + it('should test buildScriptByteCode', () => { const variables = { x: true, y: 0x05n, z: 'ff', a: '1C2RAVWSuaXw8xtUxqVERR7ChKBE1XgscNFw73NSHE1v3' } const fieldsSig: FieldsSig = { diff --git a/packages/web3/src/contract/ralph.ts b/packages/web3/src/contract/ralph.ts index 1ed57dfaf..b8b6df354 100644 --- a/packages/web3/src/contract/ralph.ts +++ b/packages/web3/src/contract/ralph.ts @@ -247,6 +247,21 @@ export function encodeScriptField(tpe: string, value: Val): Uint8Array { throw invalidScriptField(tpe, value) } +export function fieldsExceptMaps(fieldsSig: FieldsSig): FieldsSig { + return fieldsSig.types.reduce( + (acc, type, index) => { + if (type.startsWith('Map[')) { + return acc + } + acc.names.push(fieldsSig.names[`${index}`]) + acc.types.push(type) + acc.isMutable.push(fieldsSig.isMutable[`${index}`]) + return acc + }, + { names: [], types: [], isMutable: [] } + ) +} + export function flattenFields( fields: Fields, names: string[], From 666336ad515db1e5bb5195c12f7bea8a78bd7516 Mon Sep 17 00:00:00 2001 From: lbqds Date: Wed, 20 Mar 2024 20:28:23 +0800 Subject: [PATCH 04/24] Save generated contracts --- packages/cli/src/codegen.ts | 44 +++++++++++----- packages/web3/src/contract/contract.ts | 70 ++++++++++++++++++++++---- 2 files changed, 91 insertions(+), 23 deletions(-) diff --git a/packages/cli/src/codegen.ts b/packages/cli/src/codegen.ts index e49348ce5..03eb9b868 100644 --- a/packages/cli/src/codegen.ts +++ b/packages/cli/src/codegen.ts @@ -372,15 +372,20 @@ function getContractFields(contract: Contract): node.FieldsSig { } } -function importStructs(): string { +function importTypes(): string { + const hasGeneratedContracts = Project.currentProject.generatedContracts.length > 0 const structs = Project.currentProject.structs.map((s) => s.name) - if (structs.length === 0) return '' - return `import { ${structs.join(',')}, AllStructs } from './types'` + if (structs.length === 0 && !hasGeneratedContracts) return '' + return ` + ${structs.length === 0 ? '' : `import { ${structs.join(',')}, AllStructs } from './types'`} + ${hasGeneratedContracts ? `import { AllGeneratedContracts } from './types'` : ''} + ` } function genContract(contract: Contract, artifactRelativePath: string): string { const fieldsSig = getContractFields(contract) const hasStruct = Project.currentProject.structs.length > 0 + const hasGeneratedContracts = Project.currentProject.generatedContracts.length > 0 const projectArtifact = Project.currentProject.projectArtifact const contractInfo = projectArtifact.infos.get(contract.name) if (contractInfo === undefined) { @@ -398,7 +403,7 @@ function genContract(contract: Contract, artifactRelativePath: string): string { } from '@alephium/web3' import { default as ${contract.name}ContractJson } from '../${toUnixPath(artifactRelativePath)}' import { getContractByCodeHash } from './contracts' - ${importStructs()} + ${importTypes()} // Custom types for the contract export namespace ${contract.name}Types { @@ -420,7 +425,8 @@ function genContract(contract: Contract, artifactRelativePath: string): string { ${contract.name}ContractJson, '${contractInfo.bytecodeDebugPatch}', '${contractInfo.codeHashDebug}', - ${hasStruct ? 'AllStructs' : []} + ${hasStruct ? 'AllStructs' : []}, + ${hasGeneratedContracts ? 'AllGeneratedContracts' : []} )) // Use this class to interact with the blockchain @@ -479,7 +485,7 @@ function genScripts(outDir: string, artifactDir: string, exports: string[]) { HexString } from '@alephium/web3' ${importArtifacts} - ${importStructs()} + ${importTypes()} ${scriptsSource} ` @@ -722,9 +728,11 @@ function cleanCode(outDir: string) { }) } -function genStructTypes(outDir: string) { +function genTypes(outDir: string) { + const generatedContracts = Project.currentProject.generatedContracts const structs = Project.currentProject.structs - if (structs.length === 0) return + if (generatedContracts.length === 0 && structs.length === 0) return + const sorted = structs.sort((a, b) => (a.name > b.name ? 1 : -1)) const interfaces = sorted.map((struct) => { const fields = struct.fieldNames @@ -734,9 +742,21 @@ function genStructTypes(outDir: string) { }) const sourceCode = ` ${header} - import { Address, HexString, Val, Struct } from '@alephium/web3' - import { default as allStructsJson } from '../structs.ral.json' - export const AllStructs = allStructsJson.map((json) => Struct.fromJson(json)) + import { Address, HexString, Val, Struct, Contract } from '@alephium/web3' + ${ + generatedContracts.length === 0 + ? '' + : `import { default as allGeneratedContractsJson } from '../generated_contracts.ral.json'` + } + ${interfaces.length === 0 ? '' : `import { default as allStructsJson } from '../structs.ral.json'`} + ${interfaces.length === 0 ? '' : `export const AllStructs = allStructsJson.map((json) => Struct.fromJson(json))`} + ${ + generatedContracts.length === 0 + ? '' + : interfaces.length !== 0 + ? `export const AllGeneratedContracts = allGeneratedContractsJson.map((json) => Contract.fromJson(json, '', '', AllStructs))` + : `export const AllGeneratedContracts = allGeneratedContractsJson.map((json) => Contract.fromJson(json, '', ''))` + } ${interfaces.join('\n')} ` const sourcePath = path.join(outDir, 'types.ts') @@ -753,7 +773,7 @@ export function codegen(artifactDir: string) { const exports: string[] = [] try { - genStructTypes(outDir) + genTypes(outDir) genContracts(outDir, artifactDir, exports) const contractNames = exports.map((p) => p.slice(2)) genContractByCodeHash(outDir, contractNames) diff --git a/packages/web3/src/contract/contract.ts b/packages/web3/src/contract/contract.ts index 484eef12d..114983280 100644 --- a/packages/web3/src/contract/contract.ts +++ b/packages/web3/src/contract/contract.ts @@ -367,6 +367,7 @@ export class Project { contracts: Map> scripts: Map> structs: Struct[] + generatedContracts: Contract[] projectArtifact: ProjectArtifact readonly contractsRootDir: string @@ -437,6 +438,7 @@ export class Project { contracts: Map>, scripts: Map>, structs: Struct[], + generatedContracts: Contract[], errorOnWarnings: boolean, projectArtifact: ProjectArtifact ) { @@ -446,6 +448,7 @@ export class Project { this.contracts = contracts this.scripts = scripts this.structs = structs + this.generatedContracts = generatedContracts this.projectArtifact = projectArtifact if (errorOnWarnings) { @@ -506,6 +509,24 @@ export class Project { return fsPromises.writeFile(filePath, JSON.stringify(structs, null, 2)) } + private static async loadGeneratedContracts(artifactsRootDir: string, structs: Struct[]): Promise { + const filePath = path.join(artifactsRootDir, 'generated_contracts.ral.json') + if (!fs.existsSync(filePath)) return [] + const content = await fsPromises.readFile(filePath) + const json = JSON.parse(content.toString()) + if (!Array.isArray(json)) { + throw Error(`Invalid contract JSON: ${content}`) + } + return Array.from(json).map((item) => Contract.fromJson(item, '', '', structs)) + } + + private async saveGeneratedContractsToFile(): Promise { + if (this.generatedContracts.length === 0) return + const contracts = this.generatedContracts.map((c) => c.toJson()) + const filePath = path.join(this.artifactsRootDir, 'generated_contracts.ral.json') + return fsPromises.writeFile(filePath, JSON.stringify(contracts, null, 2)) + } + private async saveArtifactsToFile(projectRootDir: string): Promise { const artifactsRootDir = this.artifactsRootDir const saveToFile = async function (compiled: Compiled): Promise { @@ -519,6 +540,7 @@ export class Project { this.contracts.forEach((contract) => saveToFile(contract)) this.scripts.forEach((script) => saveToFile(script)) this.saveStructsToFile() + this.saveGeneratedContractsToFile() await this.projectArtifact.saveToFile(projectRootDir) } @@ -585,16 +607,17 @@ export class Project { const contracts = new Map>() const scripts = new Map>() const structs = result.structs === undefined ? [] : result.structs.map((item) => Struct.fromStructSig(item)) + const generatedContracts = result.contracts + .filter((c) => sourceInfos.find((s) => s.type === SourceKind.Contract && s.name === c.name) === undefined) + .map((c) => Contract.fromCompileResult(c, structs)) result.contracts.forEach((contractResult) => { const sourceInfo = sourceInfos.find( (sourceInfo) => sourceInfo.type === SourceKind.Contract && sourceInfo.name === contractResult.name ) - if (sourceInfo === undefined) { - // this should never happen - throw new Error(`SourceInfo does not exist for contract ${contractResult.name}`) + if (sourceInfo !== undefined) { + const contract = Contract.fromCompileResult(contractResult, structs, generatedContracts) + contracts.set(contract.name, new Compiled(sourceInfo, contract, contractResult.warnings)) } - const contract = Contract.fromCompileResult(contractResult, structs) - contracts.set(contract.name, new Compiled(sourceInfo, contract, contractResult.warnings)) }) result.scripts.forEach((scriptResult) => { const sourceInfo = sourceInfos.find( @@ -621,6 +644,7 @@ export class Project { contracts, scripts, structs, + generatedContracts, errorOnWarnings, projectArtifact ) @@ -642,6 +666,7 @@ export class Project { const contracts = new Map>() const scripts = new Map>() const structs = await Project.loadStructs(artifactsRootDir) + const generatedContracts = await Project.loadGeneratedContracts(artifactsRootDir, structs) for (const sourceInfo of sourceInfos) { const info = projectArtifact.infos.get(sourceInfo.name) if (typeof info === 'undefined') { @@ -654,7 +679,8 @@ export class Project { artifactDir, info.bytecodeDebugPatch, info.codeHashDebug, - structs + structs, + generatedContracts ) contracts.set(artifact.name, new Compiled(sourceInfo, artifact, warnings)) } else if (sourceInfo.type === SourceKind.Script) { @@ -670,6 +696,7 @@ export class Project { contracts, scripts, structs, + generatedContracts, errorOnWarnings, projectArtifact ) @@ -891,6 +918,7 @@ export class Contract extends Artifact { readonly constants: Constant[] readonly enums: Enum[] readonly structs: Struct[] + readonly generatedContracts: Contract[] readonly stdInterfaceId?: HexString readonly bytecodeDebug: string @@ -909,6 +937,7 @@ export class Contract extends Artifact { constants: Constant[], enums: Enum[], structs: Struct[], + generatedContracts: Contract[], stdInterfaceId?: HexString ) { super(version, name, functions) @@ -921,6 +950,7 @@ export class Contract extends Artifact { this.constants = constants this.enums = enums this.structs = structs + this.generatedContracts = generatedContracts this.stdInterfaceId = stdInterfaceId this.bytecodeDebug = ralph.buildDebugBytecode(this.bytecode, this.bytecodeDebugPatch) @@ -928,7 +958,13 @@ export class Contract extends Artifact { } // TODO: safely parse json - static fromJson(artifact: any, bytecodeDebugPatch = '', codeHashDebug = '', structs: Struct[] = []): Contract { + static fromJson( + artifact: any, + bytecodeDebugPatch = '', + codeHashDebug = '', + structs: Struct[] = [], + generatedContracts: Contract[] = [] + ): Contract { if ( artifact.version == null || artifact.name == null || @@ -955,12 +991,17 @@ export class Contract extends Artifact { artifact.constants, artifact.enums, structs, + generatedContracts, artifact.stdInterfaceId === null ? undefined : artifact.stdInterfaceId ) return contract } - static fromCompileResult(result: node.CompileContractResult, structs: Struct[] = []): Contract { + static fromCompileResult( + result: node.CompileContractResult, + structs: Struct[] = [], + generatedContracts: Contract[] = [] + ): Contract { return new Contract( result.version, result.name, @@ -974,6 +1015,7 @@ export class Contract extends Artifact { result.constants, result.enums, structs, + generatedContracts, result.stdInterfaceId ) } @@ -983,14 +1025,15 @@ export class Contract extends Artifact { path: string, bytecodeDebugPatch: string, codeHashDebug: string, - structs: Struct[] = [] + structs: Struct[] = [], + generatedContracts: Contract[] = [] ): Promise { const content = await fsPromises.readFile(path) const artifact = JSON.parse(content.toString()) - return Contract.fromJson(artifact, bytecodeDebugPatch, codeHashDebug, structs) + return Contract.fromJson(artifact, bytecodeDebugPatch, codeHashDebug, structs, generatedContracts) } - override toString(): string { + toJson(): any { const object: any = { version: this.version, name: this.name, @@ -1005,6 +1048,11 @@ export class Contract extends Artifact { if (this.stdInterfaceId !== undefined) { object.stdInterfaceId = this.stdInterfaceId } + return object + } + + override toString(): string { + const object = this.toJson() return JSON.stringify(object, null, 2) } From 236ff5d7a96fae3c2e600cb04df9ee2968f33617 Mon Sep 17 00:00:00 2001 From: lbqds Date: Thu, 21 Mar 2024 08:28:20 +0800 Subject: [PATCH 05/24] Generate code for map --- packages/cli/src/codegen.ts | 51 ++++-- packages/web3/src/api/types.ts | 2 +- packages/web3/src/contract/contract.ts | 199 +++++++++++++++++++++-- packages/web3/src/contract/ralph.test.ts | 65 ++++++-- packages/web3/src/contract/ralph.ts | 122 ++++++++++++-- 5 files changed, 384 insertions(+), 55 deletions(-) diff --git a/packages/cli/src/codegen.ts b/packages/cli/src/codegen.ts index 03eb9b868..bbb1d277e 100644 --- a/packages/cli/src/codegen.ts +++ b/packages/cli/src/codegen.ts @@ -28,7 +28,8 @@ import { NetworkId, networkIds, fromApiPrimitiveVal, - Val + Val, + parseMapType } from '@alephium/web3' import * as prettier from 'prettier' import path from 'path' @@ -257,7 +258,7 @@ function genContractStateType(contract: Contract): string { return `export type State = Omit, 'fields'>` } return ` - export type Fields = { + export interface Fields extends Record { ${formatParameters(contract.fieldsExceptMaps)} } @@ -265,13 +266,28 @@ function genContractStateType(contract: Contract): string { ` } -function genTestMethod(contractName: string, fieldsSig: node.FieldsSig, functionSig: node.FunctionSig): string { +function genMapFields(contract: Contract): string { + const mapFields = contract.mapFields.names.map((name, index) => { + const type = contract.mapFields.types[`${index}`] + const [key, value] = parseMapType(type) + return `${name}?: Map<${toTsType(key)}, ${toTsType(value)}>` + }) + return `{ ${mapFields.join(', ')} }` +} + +function genTestMethod(contract: Contract, functionSig: node.FunctionSig): string { const funcHasArgs = functionSig.paramNames.length > 0 + const fieldsSig = contract.fieldsExceptMaps const contractHasFields = fieldsSig.names.length > 0 const argsType = funcHasArgs ? `{${formatParameters({ names: functionSig.paramNames, types: functionSig.paramTypes })}}` : 'never' - const fieldsType = contractHasFields ? `${contractFieldType(contractName, fieldsSig)}` : 'never' + const fieldsType = + contractHasFields && contract.hasMapFields() + ? `${contractFieldType(contract.name, fieldsSig)} & ${genMapFields(contract)}` + : contractHasFields + ? `${contractFieldType(contract.name, fieldsSig)}` + : 'never' const params = funcHasArgs && contractHasFields ? `params: TestContractParams<${fieldsType}, ${argsType}>` @@ -281,12 +297,13 @@ function genTestMethod(contractName: string, fieldsSig: node.FieldsSig, function ? `params: Omit, 'testArgs'>` : `params?: Omit, 'testArgs' | 'initialFields'>` const tsReturnTypes = functionSig.returnTypes.map((tpe) => toTsType(tpe)) + const mapFields = genMapFields(contract) const retType = tsReturnTypes.length === 0 - ? `TestContractResult` + ? `TestContractResult` : tsReturnTypes.length === 1 - ? `TestContractResult<${tsReturnTypes[0]}>` - : `TestContractResult<[${tsReturnTypes.join(', ')}]>` + ? `TestContractResult<${tsReturnTypes[0]}, ${mapFields}>` + : `TestContractResult<[${tsReturnTypes.join(', ')}], ${mapFields}>` const callParams = funcHasArgs || contractHasFields ? 'params' : 'params === undefined ? {} : params' return ` ${functionSig.name}: async (${params}): Promise<${retType}> => { @@ -295,10 +312,10 @@ function genTestMethod(contractName: string, fieldsSig: node.FieldsSig, function ` } -function genTestMethods(contract: Contract, fieldsSig: node.FieldsSig): string { +function genTestMethods(contract: Contract): string { return ` tests = { - ${contract.functions.map((f) => genTestMethod(contract.name, fieldsSig, f)).join(',')} + ${contract.functions.map((f) => genTestMethod(contract, f)).join(',')} } ` } @@ -399,7 +416,7 @@ function genContract(contract: Contract, artifactRelativePath: string): string { EventSubscribeOptions, EventSubscription, CallContractParams, CallContractResult, TestContractParams, ContractEvent, subscribeContractEvent, subscribeContractEvents, testMethod, callMethod, multicallMethods, fetchContractState, - ContractInstance, getContractEventsCurrentCount + ContractInstance, getContractEventsCurrentCount, Val } from '@alephium/web3' import { default as ${contract.name}ContractJson } from '../${toUnixPath(artifactRelativePath)}' import { getContractByCodeHash } from './contracts' @@ -417,7 +434,7 @@ function genContract(contract: Contract, artifactRelativePath: string): string { ${genEventIndex(contract)} ${genConsts(contract)} ${genAttach(getInstanceName(contract))} - ${genTestMethods(contract, fieldsSig)} + ${genTestMethods(contract)} } // Use this object to test and deploy the contract @@ -499,23 +516,27 @@ function genIndexTs(outDir: string, exports: string[]) { } function genContractByCodeHash(outDir: string, contractNames: string[]) { + const hasGeneratedContracts = Project.currentProject.generatedContracts.length > 0 const contracts = contractNames.join(',') const source = ` ${header} import { Contract, ContractFactory } from '@alephium/web3' + ${hasGeneratedContracts ? `import { AllGeneratedContracts } from './types'` : ''} ${contracts.length === 0 ? '' : `import { ${contracts} } from '.'`} - let contracts: ContractFactory[] | undefined = undefined + let contracts: Contract[] | undefined = undefined export function getContractByCodeHash(codeHash: string): Contract { if (contracts === undefined) { - contracts = [${contracts}] + const factories: ContractFactory[] = [${contracts}] + contracts = factories.map((f) => f.contract) } - const c = contracts.find((c) => c.contract.codeHash === codeHash || c.contract.codeHashDebug === codeHash) + const allContracts = ${hasGeneratedContracts ? 'contracts.concat(AllGeneratedContracts)' : 'contracts'} + const c = allContracts.find((c) => c.codeHash === codeHash || c.codeHashDebug === codeHash) if (c === undefined) { throw new Error("Unknown code with code hash: " + codeHash) } - return c.contract + return c } ` const filename = 'contracts.ts' diff --git a/packages/web3/src/api/types.ts b/packages/web3/src/api/types.ts index 5515d1697..106e7fe59 100644 --- a/packages/web3/src/api/types.ts +++ b/packages/web3/src/api/types.ts @@ -22,7 +22,7 @@ import { assertType, bs58, Eq, isBase58, isHexString } from '../utils' import * as node from './api-alephium' export type Number256 = bigint | string -export type Val = Number256 | boolean | string | Val[] | ValObject +export type Val = Number256 | boolean | string | Val[] | ValObject | Map // eslint-disable-next-line export interface ValObject extends Record {} // bypassing typescript recursive type limitations export type NamedVals = Record diff --git a/packages/web3/src/contract/contract.ts b/packages/web3/src/contract/contract.ts index 114983280..94eaf42cc 100644 --- a/packages/web3/src/contract/contract.ts +++ b/packages/web3/src/contract/contract.ts @@ -57,7 +57,8 @@ import { WebCrypto, hexToBinUnsafe, isDevnet, - addressFromContractId + addressFromContractId, + subContractId } from '../utils' import { getCurrentNodeProvider } from '../global' import * as path from 'path' @@ -545,13 +546,14 @@ export class Project { } contractByCodeHash(codeHash: string): Contract { - const contract = [...this.contracts.values()].find( - (c) => c.artifact.codeHash === codeHash || c.artifact.codeHashDebug == codeHash - ) + const allContracts = Array.from(this.contracts.values()) + .map((c) => c.artifact) + .concat(this.generatedContracts) + const contract = allContracts.find((c) => c.codeHash === codeHash || c.codeHashDebug == codeHash) if (typeof contract === 'undefined') { throw new Error(`Unknown code with code hash: ${codeHash}`) } - return contract.artifact + return contract } private static async getCompileResult( @@ -914,6 +916,7 @@ export class Contract extends Artifact { readonly codeHash: string readonly fieldsSig: FieldsSig readonly fieldsExceptMaps: FieldsSig + readonly mapFields: FieldsSig readonly eventsSig: EventSig[] readonly constants: Constant[] readonly enums: Enum[] @@ -945,7 +948,7 @@ export class Contract extends Artifact { this.bytecodeDebugPatch = bytecodeDebugPatch this.codeHash = codeHash this.fieldsSig = fieldsSig - this.fieldsExceptMaps = ralph.fieldsExceptMaps(fieldsSig) + ;[this.mapFields, this.fieldsExceptMaps] = ralph.splitFields(fieldsSig) this.eventsSig = eventsSig this.constants = constants this.enums = enums @@ -1056,6 +1059,22 @@ export class Contract extends Artifact { return JSON.stringify(object, null, 2) } + hasMapFields(): boolean { + return this.fieldsExceptMaps.names.length !== this.fieldsSig.names.length + } + + getGeneratedContract(type: string): Contract | undefined { + const struct = this.structs.find((s) => s.name === type) + if (struct !== undefined) { + const name = `StructWrapper${struct.name}` + return this.generatedContracts.find((c) => c.name === name) + } + const suffix = Array.from(type) + .filter((c) => !'[;]'.includes(c)) + .join('') + return this.generatedContracts.find((c) => c.name === `SimpleWrapper${suffix}`) + } + getInitialFieldsWithDefaultValues(): Fields { const fields = this.stdInterfaceId === undefined @@ -1617,11 +1636,12 @@ export interface ContractEvent { export type DebugMessage = node.DebugMessage -export interface TestContractResult { +export interface TestContractResult> = Record>> { contractId: string contractAddress: string returns: R gasUsed: number + maps?: M contracts: ContractState[] txOutputs: Output[] events: ContractEvent[] @@ -1874,23 +1894,170 @@ export function addStdIdToFields( : { ...fields, __stdInterfaceId: stdInterfaceIdPrefix + contract.stdInterfaceId } } -export async function testMethod( - contract: ContractFactory, +function calcWrapperContractId( + parentContractId: string, + mapIndex: number, + key: Val, + keyType: string, + group: number +): string { + const prefix = ralph.encodeMapPrefix(mapIndex) + const encodedKey = ralph.primitiveToByteVec(key, keyType) + const path = binToHex(prefix) + binToHex(encodedKey) + return subContractId(parentContractId, path, group) +} + +function mapToExistingContracts( + contract: Contract, + parentContractId: string, + group: number, + map: Map, + mapIndex: number, + type: string +): ContractState[] { + const [keyType, valueType] = ralph.parseMapType(type) + const generatedContract = contract.getGeneratedContract(valueType) + if (generatedContract === undefined) { + throw new Error(`Contract for type ${valueType} does not exist`) + } + return Array.from(map.entries()).map(([key, value]) => { + const fields = + generatedContract.fieldsSig.names.length === 2 + ? { value } // simple wrapper + : { ...(value as Fields) } // struct wrapper + const parentContractIdName = generatedContract.fieldsSig.names[`${generatedContract.fieldsSig.names.length - 1}`] + fields[`${parentContractIdName}`] = parentContractId + const contractId = calcWrapperContractId(parentContractId, mapIndex, key, keyType, group) + return { + address: addressFromContractId(contractId), + contractId: contractId, + bytecode: generatedContract.bytecode, + codeHash: generatedContract.codeHash, + fieldsSig: generatedContract.fieldsSig, + fields, + asset: { alphAmount: ONE_ALPH } + } + }) +} + +function mapsToExistingContracts(contract: Contract, parentContractId: string, group: number, fields: Fields) { + const fieldsExceptMaps: Fields = {} + const contractStates: ContractState[] = [] + let mapIndex = 0 + Object.keys(fields).forEach((name) => { + const index = contract.fieldsSig.names.indexOf(name) + const type = contract.fieldsSig.types[`${index}`] + const field = fields[`${name}`] + if (type.startsWith('Map[')) { + const states = mapToExistingContracts(contract, parentContractId, group, field as Map, mapIndex, type) + contractStates.push(...states) + mapIndex += 1 + } else { + fieldsExceptMaps[`${name}`] = field + } + }) + return { fieldsExceptMaps, contractStates } +} + +export async function testMethod< + I extends ContractInstance, + F extends Fields, + A extends Arguments, + R, + M extends Record> = Record> +>( + factory: ContractFactory, methodName: string, params: Optional, 'testArgs' | 'initialFields'> -): Promise> { +): Promise> { const txId = params?.txId ?? randomTxId() const initialFields = params.initialFields === undefined ? {} : params.initialFields - const apiParams = contract.contract.toApiTestContractParams(methodName, { + const contract = factory.contract + const address = params.address ?? addressFromContractId(binToHex(crypto.getRandomValues(new Uint8Array(32)))) + const contractId = binToHex(contractIdFromAddress(address)) + const group = params.group ?? 0 + const { fieldsExceptMaps, contractStates } = mapsToExistingContracts(contract, contractId, group, initialFields) + const apiParams = contract.toApiTestContractParams(methodName, { ...params, + address, txId: txId, - initialFields: addStdIdToFields(contract.contract, initialFields), - testArgs: params.testArgs === undefined ? {} : params.testArgs + initialFields: addStdIdToFields(contract, fieldsExceptMaps), + testArgs: params.testArgs === undefined ? {} : params.testArgs, + existingContracts: (params.existingContracts ?? []).concat(contractStates) }) const apiResult = await getCurrentNodeProvider().contracts.postContractsTestContract(apiParams) - const testResult = contract.contract.fromApiTestContractResult(methodName, apiResult, txId) - contract.contract.printDebugMessages(methodName, testResult.debugMessages) - return testResult as TestContractResult + const testResult = contract.fromApiTestContractResult(methodName, apiResult, txId) + const maps = existingContractsToMaps( + contract, + address, + group, + testResult.contracts, + testResult.debugMessages, + initialFields + ) + contract.printDebugMessages(methodName, testResult.debugMessages) + return { + ...testResult, + maps + } as TestContractResult +} + +function existingContractsToMaps( + contract: Contract, + address: Address, + group: number, + states: ContractState[], + messages: DebugMessage[], + fields: Fields +): Record> { + const allMaps = contract.mapFields.types.map((type, index) => { + const name = contract.mapFields.names[`${index}`] + const map = (fields[`${name}`] ?? new Map()) as Map + const [keyType, valueType] = ralph.parseMapType(type) + return { name, map, keyType, valueType, mapIndex: index } + }) + const parentContractId = binToHex(contractIdFromAddress(address)) + const newInserted: string[] = [] + messages.forEach((message) => { + if (message.contractAddress !== address) return + const decoded = ralph.tryDecodeMapDebugLog(message.message) + if (decoded === undefined) return + const map = allMaps[`${decoded.mapIndex}`] + const decodedKey = ralph.decodePrimitive(decoded.encodedKey, map.keyType) + const contractId = subContractId(parentContractId, decoded.path, group) + if (!decoded.isInsert) { + map.map.delete(decodedKey) + return + } + const state = states.find((s) => s.contractId === contractId) + if (state === undefined) { + throw new Error(`Cannot find contract state for map value, map field: ${map.name}, value type: ${map.valueType}`) + } + newInserted.push(contractId) + map.map.set(decodedKey, decodeWrapperFields(state.fields)) + }) + return allMaps.reduce((acc, map) => { + Array.from(map.map.keys()).forEach((key) => { + const contractId = calcWrapperContractId(parentContractId, map.mapIndex, key, map.keyType, group) + if (newInserted.includes(contractId)) return + const updatedState = states.find((s) => s.contractId === contractId) + if (updatedState !== undefined) map.map.set(key, decodeWrapperFields(updatedState.fields)) + }) + acc[`${map.name}`] = map.map + return acc + }, {}) +} + +function decodeWrapperFields(fields: Fields): Val { + const allFields = Object.entries(fields).map(([name]) => name) + delete fields[allFields[`${allFields.length - 1}`]] // remove the `parentContractId` field + if (allFields.length === 2) { + // simple wrapper + return fields[allFields[0]] + } else { + // struct wrapper + return fields + } } export abstract class ContractInstance { diff --git a/packages/web3/src/contract/ralph.test.ts b/packages/web3/src/contract/ralph.test.ts index 9156c2041..676b01978 100644 --- a/packages/web3/src/contract/ralph.test.ts +++ b/packages/web3/src/contract/ralph.test.ts @@ -296,21 +296,66 @@ describe('contract', function () { types: ['Foo', 'U256', 'Map[U256, Foo]'], isMutable: [false, true, true] } - expect(ralph.fieldsExceptMaps(fieldsSig0)).toEqual({ - names: ['foo', 'number'], - types: ['Foo', 'U256'], - isMutable: [false, true] - }) + expect(ralph.splitFields(fieldsSig0)).toEqual([ + { + names: ['map'], + types: ['Map[U256, Foo]'], + isMutable: [true] + }, + { + names: ['foo', 'number'], + types: ['Foo', 'U256'], + isMutable: [false, true] + } + ]) const fieldsSig1: node.FieldsSig = { names: ['foo', 'number'], types: ['Foo', 'U256'], isMutable: [false, true] } - expect(ralph.fieldsExceptMaps(fieldsSig1)).toEqual({ - names: ['foo', 'number'], - types: ['Foo', 'U256'], - isMutable: [false, true] - }) + expect(ralph.splitFields(fieldsSig1)).toEqual([ + { + names: [], + types: [], + isMutable: [] + }, + { + names: ['foo', 'number'], + types: ['Foo', 'U256'], + isMutable: [false, true] + } + ]) + const fieldsSig2: node.FieldsSig = { + names: ['map'], + types: ['Map[U256, Foo]'], + isMutable: [true] + } + expect(ralph.splitFields(fieldsSig2)).toEqual([ + { + names: ['map'], + types: ['Map[U256, Foo]'], + isMutable: [true] + }, + { + names: [], + types: [], + isMutable: [] + } + ]) + }) + + it('should parse map type', () => { + expect(ralph.parseMapType('Map[U256,U256]')).toEqual(['U256', 'U256']) + expect(ralph.parseMapType('Map[ByteVec,Foo]')).toEqual(['ByteVec', 'Foo']) + expect(() => ralph.parseMapType('[Foo;2]')).toThrow() + expect(() => ralph.parseMapType('U256')).toThrow() + }) + + it('should decode map debug message', () => { + const result = ralph.tryDecodeMapDebugLog( + '5f5f6d61705f5f305f5f00066fb0c875e171612b2da9135756faed416696b184d06d93a32f894e84f9e28a,true' + ) + console.log(result) }) it('should test buildScriptByteCode', () => { diff --git a/packages/web3/src/contract/ralph.ts b/packages/web3/src/contract/ralph.ts index b8b6df354..24790dff5 100644 --- a/packages/web3/src/contract/ralph.ts +++ b/packages/web3/src/contract/ralph.ts @@ -17,9 +17,11 @@ along with the library. If not, see . */ import { Buffer } from 'buffer/' -import { PrimitiveTypes, Val, decodeArrayType, toApiAddress, toApiBoolean, toApiByteVec, toApiNumber256 } from '../api' -import { binToHex, bs58, isHexString } from '../utils' +import { Val, decodeArrayType, toApiAddress, toApiBoolean, toApiByteVec, toApiNumber256 } from '../api' +import { binToHex, bs58, hexToBinUnsafe, isHexString } from '../utils' import { Fields, FieldsSig, Struct } from './contract' +import { compactSignedIntCodec, compactUnsignedIntCodec } from '../codec' +import { lockupScriptCodec } from '../codec/lockup-script-codec' const bigIntZero = BigInt(0) @@ -52,6 +54,13 @@ export function encodeBool(bool: boolean): Uint8Array { return bool ? Uint8Array.from([1]) : Uint8Array.from([0]) } +export function decodeBool(bytes: Uint8Array): boolean { + if (bytes.length !== 1) { + throw new Error(`Expected one byte for encoded bool, got ${bytes.length}`) + } + return bytes[0] === 1 ? true : false +} + export function encodeI256(i256: bigint): Uint8Array { if (i256 >= bigIntZero) { return encodeI256Positive(i256) @@ -247,21 +256,108 @@ export function encodeScriptField(tpe: string, value: Val): Uint8Array { throw invalidScriptField(tpe, value) } -export function fieldsExceptMaps(fieldsSig: FieldsSig): FieldsSig { - return fieldsSig.types.reduce( - (acc, type, index) => { - if (type.startsWith('Map[')) { - return acc - } - acc.names.push(fieldsSig.names[`${index}`]) - acc.types.push(type) - acc.isMutable.push(fieldsSig.isMutable[`${index}`]) - return acc +export function splitFields(fieldsSig: FieldsSig): [FieldsSig, FieldsSig] { + return fieldsSig.types.reduce<[FieldsSig, FieldsSig]>( + ([mapFields, fieldsExceptMaps], type, index) => { + const fieldSig = type.startsWith('Map[') ? mapFields : fieldsExceptMaps + fieldSig.names.push(fieldsSig.names[`${index}`]) + fieldSig.types.push(type) + fieldSig.isMutable.push(fieldsSig.isMutable[`${index}`]) + return [mapFields, fieldsExceptMaps] }, - { names: [], types: [], isMutable: [] } + [ + { names: [], types: [], isMutable: [] }, + { names: [], types: [], isMutable: [] } + ] ) } +export function parseMapType(type: string): [string, string] { + if (!type.startsWith('Map[')) { + throw new Error(`Expected map type, got ${type}`) + } + const keyStartIndex = type.indexOf('[') + const keyEndIndex = type.indexOf(',') + return [type.slice(keyStartIndex + 1, keyEndIndex), type.slice(keyEndIndex + 1, type.length - 1)] +} + +export function encodeMapPrefix(mapIndex: number): Uint8Array { + const str = `__map__${mapIndex}__` + const bytes = new Uint8Array(str.length) + for (let i = 0; i < str.length; i += 1) { + bytes[i] = str.charCodeAt(i) + } + return bytes +} + +function fromAscii(str: string): string { + let result = '' + for (let i = 0; i < str.length; i += 2) { + const ascii = parseInt(str.slice(i, i + 2), 16) + result += String.fromCharCode(ascii) + } + return result +} + +export function tryDecodeMapDebugLog( + message: string +): { path: string; mapIndex: number; encodedKey: Uint8Array; isInsert: boolean } | undefined { + const prefix = '5f5f6d61705f5f' // __map__ + const parts = message.split(',') + if (!message.startsWith(prefix) || parts.length !== 2) return undefined + if (parts[1] !== 'true' && parts[1] !== 'false') return undefined + + if (!isHexString(parts[0])) return undefined + const remain = parts[0].slice(prefix.length) + const suffixIndex = remain.indexOf('5f5f') // __ + if (suffixIndex === -1) return undefined + + const encodedMapIndex = remain.slice(0, suffixIndex) + const mapIndex = parseInt(fromAscii(encodedMapIndex)) + const encodedKey = hexToBinUnsafe(remain.slice(suffixIndex + 4)) + const isInsert = parts[1] === 'true' ? true : false + return { path: parts[0], mapIndex, encodedKey, isInsert } +} + +export function decodePrimitive(value: Uint8Array, type: string): Val { + switch (type) { + case 'Bool': + return decodeBool(value) + case 'I256': + return compactSignedIntCodec.decodeI256(Buffer.from(value)) + case 'U256': + return compactUnsignedIntCodec.decodeU256(Buffer.from(value)) + case 'ByteVec': + return binToHex(value) + case 'Address': + return bs58.encode(value) + default: + throw Error(`Expected primitive type, got ${type}`) + } +} + +export function primitiveToByteVec(value: Val, type: string): Uint8Array { + switch (type) { + case 'Bool': + const byte = toApiBoolean(value) ? 1 : 0 + return new Uint8Array([byte]) + case 'I256': + const i256 = toApiNumber256(value) + return encodeI256(BigInt(i256)) + case 'U256': + const u256 = toApiNumber256(value) + return encodeU256(BigInt(u256)) + case 'ByteVec': + const hexStr = toApiByteVec(value) + return encodeByteVec(hexStr) + case 'Address': + const address = toApiAddress(value) + return encodeAddress(address) + default: + throw Error(`Expected primitive type, got ${type}`) + } +} + export function flattenFields( fields: Fields, names: string[], From a771d509114310c63dd955440e805e0b710d6ff6 Mon Sep 17 00:00:00 2001 From: lbqds Date: Thu, 21 Mar 2024 10:18:08 +0800 Subject: [PATCH 06/24] Add map tests --- .project.json | 45 +++- artifacts/add/Add.ral.json | 4 +- artifacts/generated_contracts.ral.json | 199 ++++++++++++++++++ artifacts/structs.ral.json | 15 ++ artifacts/test/InsertIntoMap.ral.json | 34 +++ artifacts/test/MapTest.ral.json | 118 +++++++++++ artifacts/test/RemoveFromMap.ral.json | 31 +++ artifacts/test/UpdateMapValue.ral.json | 31 +++ artifacts/ts/Add.ts | 24 ++- artifacts/ts/Assert.ts | 10 +- artifacts/ts/Debug.ts | 10 +- artifacts/ts/DeprecatedNFTTest1.ts | 14 +- artifacts/ts/DeprecatedNFTTest2.ts | 16 +- artifacts/ts/DeprecatedNFTTest3.ts | 16 +- artifacts/ts/DeprecatedNFTTest4.ts | 16 +- artifacts/ts/DeprecatedNFTTest5.ts | 16 +- artifacts/ts/DeprecatedNFTTest6.ts | 16 +- artifacts/ts/DeprecatedNFTTest7.ts | 16 +- artifacts/ts/FakeTokenTest.ts | 22 +- artifacts/ts/Greeter.ts | 14 +- artifacts/ts/MapTest.ts | 210 +++++++++++++++++++ artifacts/ts/MetaData.ts | 14 +- artifacts/ts/NFTCollectionTest.ts | 22 +- artifacts/ts/NFTCollectionWithRoyaltyTest.ts | 28 +-- artifacts/ts/NFTTest.ts | 16 +- artifacts/ts/OwnerOnly.ts | 14 +- artifacts/ts/Sub.ts | 14 +- artifacts/ts/TokenTest.ts | 20 +- artifacts/ts/UserAccount.ts | 18 +- artifacts/ts/Warnings.ts | 14 +- artifacts/ts/WrongNFTTest.ts | 16 +- artifacts/ts/contracts.ts | 16 +- artifacts/ts/index.ts | 1 + artifacts/ts/scripts.ts | 23 +- artifacts/ts/types.ts | 10 +- contracts/test/map.ral | 43 ++++ test/contract.test.ts | 81 ++++++- 37 files changed, 1072 insertions(+), 155 deletions(-) create mode 100644 artifacts/generated_contracts.ral.json create mode 100644 artifacts/test/InsertIntoMap.ral.json create mode 100644 artifacts/test/MapTest.ral.json create mode 100644 artifacts/test/RemoveFromMap.ral.json create mode 100644 artifacts/test/UpdateMapValue.ral.json create mode 100644 artifacts/ts/MapTest.ts create mode 100644 contracts/test/map.ral diff --git a/.project.json b/.project.json index c2add9ce9..086a5654e 100644 --- a/.project.json +++ b/.project.json @@ -11,9 +11,9 @@ "infos": { "Add": { "sourceFile": "add/add.ral", - "sourceCodeHash": "f7d27ecff8f7da7afcfee957842d8629930c9980f87a1c6d17561bb1fbe6dab6", - "bytecodeDebugPatch": "=8+4=1-1=2-2+64=3-1+d=37+77e010a=1+1646450726976617465=154", - "codeHashDebug": "a49f0624ccbec8df1bf3ad7f628fb47a42cc448fe7369fc0da02071df6787b69", + "sourceCodeHash": "65456a08b5d277114f65beda04224055eda3df8ad61d6fe5894a00af1df986c1", + "bytecodeDebugPatch": "=8+4=1-1=2-2+6c=2-2+75=37+77e010a=1+1646450726976617465=170", + "codeHashDebug": "da908c46aa94ebe533cdb16d1f5f2ba771def332ae09dda36218bba7efc2de0a", "warnings": [ "The return values of the function \"Add.copyCreateSubContract\" are not used. If this is intentional, consider using anonymous variables to suppress this warning.", "No external caller check for function \"Add.createSubContract\". Please use \"checkCaller!(...)\" in the function or its callees, or disable it with \"@using(checkExternalCaller = false)\".", @@ -164,15 +164,38 @@ "codeHashDebug": "", "warnings": [] }, + "InsertIntoMap": { + "sourceFile": "test/map.ral", + "sourceCodeHash": "79c5f8ba94a478a18b76f9ebb5f450632e557330cccb3de67ac2e2d4833aa567", + "bytecodeDebugPatch": "", + "codeHashDebug": "", + "warnings": [] + }, "Main": { "sourceFile": "add/add.ral", - "sourceCodeHash": "f7d27ecff8f7da7afcfee957842d8629930c9980f87a1c6d17561bb1fbe6dab6", + "sourceCodeHash": "65456a08b5d277114f65beda04224055eda3df8ad61d6fe5894a00af1df986c1", "bytecodeDebugPatch": "", "codeHashDebug": "", "warnings": [ "The return values of the function \"Add.add\" are not used. If this is intentional, consider using anonymous variables to suppress this warning." ] }, + "MapTest": { + "sourceFile": "test/map.ral", + "sourceCodeHash": "79c5f8ba94a478a18b76f9ebb5f450632e557330cccb3de67ac2e2d4833aa567", + "bytecodeDebugPatch": "=6-1+d=3-1+3=3-2+8f=2-1=1+b=2-2+c4=13-1+7=40+7a037e0300012c00=226+7a037e0300012c00=308-2+4022=90+7a047e0300012c00=46+7a047e0300012c00=112", + "codeHashDebug": "d012c5bf0e7658ee640d58506c576e5fdbcc5c2c7515b1ad9dcf3076f85af881", + "warnings": [ + "No external caller check for function \"MapTest.insert\". Please use \"checkCaller!(...)\" in the function or its callees, or disable it with \"@using(checkExternalCaller = false)\"." + ] + }, + "MapValue": { + "sourceFile": "test/map.ral", + "sourceCodeHash": "79c5f8ba94a478a18b76f9ebb5f450632e557330cccb3de67ac2e2d4833aa567", + "bytecodeDebugPatch": "", + "codeHashDebug": "", + "warnings": [] + }, "MetaData": { "sourceFile": "test/metadata.ral", "sourceCodeHash": "79099ed139ae980aeb7010a648998ebeaf4ee4102cb76c40addb1a0d5dd9c684", @@ -233,6 +256,13 @@ "codeHashDebug": "c21e66486f3fa9f78555b71d30ba1ffd2f5a4bf8624647b97ed3748db20e295a", "warnings": [] }, + "RemoveFromMap": { + "sourceFile": "test/map.ral", + "sourceCodeHash": "79c5f8ba94a478a18b76f9ebb5f450632e557330cccb3de67ac2e2d4833aa567", + "bytecodeDebugPatch": "", + "codeHashDebug": "", + "warnings": [] + }, "Sub": { "sourceFile": "sub/sub.ral", "sourceCodeHash": "c8b669babea2f36bdb8f92afb17747bfb9eecb13ac17c5a02388426c91a4434e", @@ -261,6 +291,13 @@ "codeHashDebug": "a2800413eb2c5c23d48068db23df5f8eeaba04653e12c8ed59d589720d96dadd", "warnings": [] }, + "UpdateMapValue": { + "sourceFile": "test/map.ral", + "sourceCodeHash": "79c5f8ba94a478a18b76f9ebb5f450632e557330cccb3de67ac2e2d4833aa567", + "bytecodeDebugPatch": "", + "codeHashDebug": "", + "warnings": [] + }, "UpdateUserAccount": { "sourceFile": "test/struct.ral", "sourceCodeHash": "7690ad7d8b8c4b952fc6f439eb75648164532e055e6a47881882097c0600bb6a", diff --git a/artifacts/add/Add.ral.json b/artifacts/add/Add.ral.json index 2ed2da683..8f1a4d730 100644 --- a/artifacts/add/Add.ral.json +++ b/artifacts/add/Add.ral.json @@ -1,8 +1,8 @@ { "version": "v2.11.0", "name": "Add", - "bytecode": "02040d4036405740600100020402041600160100010200000202021605160016015f06160016015fa00016002a16012aa100a000160016010e0dce0001000201030404000b160313c40de0b6b3a7640000a2160116021401001600130164c1180102010100021600b0", - "codeHash": "2b9e382c20b4facf21eb745a46a72447dae221c274518e19c60b5ddfe478cc9c", + "bytecode": "02040d4036405f40680100020402041600160100010200000202021605160016015f06160016015fa00016002a16012aa100a000160016010e0dce00010002010304060010130064160013016417051704160313c40de0b6b3a7640000a21601160216041605c1180102010100021600b0", + "codeHash": "733064f0cc76f1e6a9451e701d01595c78e4972c21a25323f7c5e0199fb68d8d", "fieldsSig": { "names": [ "sub", diff --git a/artifacts/generated_contracts.ral.json b/artifacts/generated_contracts.ral.json new file mode 100644 index 000000000..4692db292 --- /dev/null +++ b/artifacts/generated_contracts.ral.json @@ -0,0 +1,199 @@ +[ + { + "version": "v2.11.0", + "name": "StructWrapperMapValue", + "bytecode": "03060d184021402a403740430000010100051600ce01410c7b010000000203ce00a00002010000000102ce0002010000000102a00002010001010004b300001600a100010201010004b300001600b0", + "codeHash": "3c92b960989b8044ebc882c2e4fed45f75a50b5936e92baef1c2dfdd820d9a7a", + "fieldsSig": { + "names": [ + "id", + "balance", + "parentContractId" + ], + "types": [ + "U256", + "U256", + "ByteVec" + ], + "isMutable": [ + false, + true, + false + ] + }, + "eventsSig": [], + "functions": [ + { + "name": "f0", + "usePreapprovedAssets": false, + "useAssetsInContract": false, + "isPublic": false, + "paramNames": [ + "callerContractId" + ], + "paramTypes": [ + "ByteVec" + ], + "paramIsMutable": [ + false + ], + "returnTypes": [] + }, + { + "name": "f1", + "usePreapprovedAssets": false, + "useAssetsInContract": false, + "isPublic": true, + "paramNames": [], + "paramTypes": [], + "paramIsMutable": [], + "returnTypes": [ + "MapValue" + ] + }, + { + "name": "f2", + "usePreapprovedAssets": false, + "useAssetsInContract": false, + "isPublic": true, + "paramNames": [], + "paramTypes": [], + "paramIsMutable": [], + "returnTypes": [ + "U256" + ] + }, + { + "name": "f3", + "usePreapprovedAssets": false, + "useAssetsInContract": false, + "isPublic": true, + "paramNames": [], + "paramTypes": [], + "paramIsMutable": [], + "returnTypes": [ + "U256" + ] + }, + { + "name": "f4", + "usePreapprovedAssets": false, + "useAssetsInContract": false, + "isPublic": true, + "paramNames": [ + "newValue" + ], + "paramTypes": [ + "U256" + ], + "paramIsMutable": [ + false + ], + "returnTypes": [] + }, + { + "name": "destroy", + "usePreapprovedAssets": false, + "useAssetsInContract": true, + "isPublic": true, + "paramNames": [ + "address" + ], + "paramTypes": [ + "Address" + ], + "paramIsMutable": [ + false + ], + "returnTypes": [] + } + ], + "constants": [], + "enums": [] + }, + { + "version": "v2.11.0", + "name": "SimpleWrapperU256", + "bytecode": "02040d164023402f0000010100051600ce00410c7b010000000102a00002010001010004b300001600a100010201010004b300001600b0", + "codeHash": "b8745b5749f063d70978956e10d267e6480b8e94469963042d9c326794f59449", + "fieldsSig": { + "names": [ + "value", + "parentContractId" + ], + "types": [ + "U256", + "ByteVec" + ], + "isMutable": [ + true, + false + ] + }, + "eventsSig": [], + "functions": [ + { + "name": "f0", + "usePreapprovedAssets": false, + "useAssetsInContract": false, + "isPublic": false, + "paramNames": [ + "callerContractId" + ], + "paramTypes": [ + "ByteVec" + ], + "paramIsMutable": [ + false + ], + "returnTypes": [] + }, + { + "name": "f1", + "usePreapprovedAssets": false, + "useAssetsInContract": false, + "isPublic": true, + "paramNames": [], + "paramTypes": [], + "paramIsMutable": [], + "returnTypes": [ + "U256" + ] + }, + { + "name": "f2", + "usePreapprovedAssets": false, + "useAssetsInContract": false, + "isPublic": true, + "paramNames": [ + "newValue" + ], + "paramTypes": [ + "U256" + ], + "paramIsMutable": [ + false + ], + "returnTypes": [] + }, + { + "name": "destroy", + "usePreapprovedAssets": false, + "useAssetsInContract": true, + "isPublic": true, + "paramNames": [ + "address" + ], + "paramTypes": [ + "Address" + ], + "paramIsMutable": [ + false + ], + "returnTypes": [] + } + ], + "constants": [], + "enums": [] + } +] \ No newline at end of file diff --git a/artifacts/structs.ral.json b/artifacts/structs.ral.json index ce99b765f..28d68d54d 100644 --- a/artifacts/structs.ral.json +++ b/artifacts/structs.ral.json @@ -1,4 +1,19 @@ [ + { + "name": "MapValue", + "fieldNames": [ + "id", + "balance" + ], + "fieldTypes": [ + "U256", + "U256" + ], + "isMutable": [ + false, + true + ] + }, { "name": "TokenBalance", "fieldNames": [ diff --git a/artifacts/test/InsertIntoMap.ral.json b/artifacts/test/InsertIntoMap.ral.json new file mode 100644 index 000000000..215198022 --- /dev/null +++ b/artifacts/test/InsertIntoMap.ral.json @@ -0,0 +1,34 @@ +{ + "version": "v2.11.0", + "name": "InsertIntoMap", + "bytecodeTemplate": "01010300020010{2}{3}17011700{1}d10e2ca2{1}160016010f0c{0}0100", + "fieldsSig": { + "names": [ + "mapTest", + "from", + "value" + ], + "types": [ + "MapTest", + "Address", + "MapValue" + ], + "isMutable": [ + false, + false, + false + ] + }, + "functions": [ + { + "name": "main", + "usePreapprovedAssets": true, + "useAssetsInContract": false, + "isPublic": true, + "paramNames": [], + "paramTypes": [], + "paramIsMutable": [], + "returnTypes": [] + } + ] +} \ No newline at end of file diff --git a/artifacts/test/MapTest.ral.json b/artifacts/test/MapTest.ral.json new file mode 100644 index 000000000..64ee890ec --- /dev/null +++ b/artifacts/test/MapTest.ral.json @@ -0,0 +1,118 @@ +{ + "version": "v2.11.0", + "name": "MapTest", + "bytecode": "020540cf4121416e418a41a3010303030040211600d1a2140a5f5f6d61705f5f305f5f1600474414404f03060d184021402a403740430000010100051600ce01410c7b010000000203ce00a00002010000000102ce0002010000000102a00002010001010004b300001600a100010201010004b300001600b01601b10e6416020d64bf181600d1a2140a5f5f6d61705f5f315f5f1601404414403702040d164023402f0000010100051600ce00410c7b010000000102a00002010001010004b300001600a100010201010004b300001600b0b10d6416020d64bf18010001030040200c0e140a5f5f6d61705f5f305f5f16004744cb01011702170116020d2a0d0c140a5f5f6d61705f5f305f5f16004744cb010416020d2a0d0c140a5f5f6d61705f5f315f5f16014044cb010201000103001c0c0e140a5f5f6d61705f5f305f5f16004744cb01011702170116000d0c140a5f5f6d61705f5f305f5f16004744cb010516000d0c140a5f5f6d61705f5f315f5f16014044cb01030100010102090c0e140a5f5f6d61705f5f305f5f16004744cb010102010001010107140a5f5f6d61705f5f305f5f16004744cbc502", + "codeHash": "e41a3b6b637d7b7c145a6822cf4d382573a2a8f6374c09686bfd0757f07d6839", + "fieldsSig": { + "names": [ + "a", + "b", + "map0", + "map1" + ], + "types": [ + "U256", + "U256", + "Map[Address,MapValue]", + "Map[U256,U256]" + ], + "isMutable": [ + true, + false, + true, + true + ] + }, + "eventsSig": [], + "functions": [ + { + "name": "insert", + "usePreapprovedAssets": true, + "useAssetsInContract": false, + "isPublic": true, + "paramNames": [ + "key", + "value" + ], + "paramTypes": [ + "Address", + "MapValue" + ], + "paramIsMutable": [ + false, + false + ], + "returnTypes": [] + }, + { + "name": "update", + "usePreapprovedAssets": false, + "useAssetsInContract": false, + "isPublic": true, + "paramNames": [ + "key" + ], + "paramTypes": [ + "Address" + ], + "paramIsMutable": [ + false + ], + "returnTypes": [] + }, + { + "name": "remove", + "usePreapprovedAssets": false, + "useAssetsInContract": false, + "isPublic": true, + "paramNames": [ + "key" + ], + "paramTypes": [ + "Address" + ], + "paramIsMutable": [ + false + ], + "returnTypes": [] + }, + { + "name": "get", + "usePreapprovedAssets": false, + "useAssetsInContract": false, + "isPublic": true, + "paramNames": [ + "key" + ], + "paramTypes": [ + "Address" + ], + "paramIsMutable": [ + false + ], + "returnTypes": [ + "MapValue" + ] + }, + { + "name": "contains", + "usePreapprovedAssets": false, + "useAssetsInContract": false, + "isPublic": true, + "paramNames": [ + "key" + ], + "paramTypes": [ + "Address" + ], + "paramIsMutable": [ + false + ], + "returnTypes": [ + "Bool" + ] + } + ], + "constants": [], + "enums": [] +} \ No newline at end of file diff --git a/artifacts/test/RemoveFromMap.ral.json b/artifacts/test/RemoveFromMap.ral.json new file mode 100644 index 000000000..4b29b9acd --- /dev/null +++ b/artifacts/test/RemoveFromMap.ral.json @@ -0,0 +1,31 @@ +{ + "version": "v2.11.0", + "name": "RemoveFromMap", + "bytecodeTemplate": "01010300000005{1}0d0c{0}0102", + "fieldsSig": { + "names": [ + "mapTest", + "key" + ], + "types": [ + "MapTest", + "Address" + ], + "isMutable": [ + false, + false + ] + }, + "functions": [ + { + "name": "main", + "usePreapprovedAssets": true, + "useAssetsInContract": false, + "isPublic": true, + "paramNames": [], + "paramTypes": [], + "paramIsMutable": [], + "returnTypes": [] + } + ] +} \ No newline at end of file diff --git a/artifacts/test/UpdateMapValue.ral.json b/artifacts/test/UpdateMapValue.ral.json new file mode 100644 index 000000000..907d6e91c --- /dev/null +++ b/artifacts/test/UpdateMapValue.ral.json @@ -0,0 +1,31 @@ +{ + "version": "v2.11.0", + "name": "UpdateMapValue", + "bytecodeTemplate": "01010300000005{1}0d0c{0}0101", + "fieldsSig": { + "names": [ + "mapTest", + "key" + ], + "types": [ + "MapTest", + "Address" + ], + "isMutable": [ + false, + false + ] + }, + "functions": [ + { + "name": "main", + "usePreapprovedAssets": true, + "useAssetsInContract": false, + "isPublic": true, + "paramNames": [], + "paramTypes": [], + "paramIsMutable": [], + "returnTypes": [] + } + ] +} \ No newline at end of file diff --git a/artifacts/ts/Add.ts b/artifacts/ts/Add.ts index c16a75e6a..877b8bd1b 100644 --- a/artifacts/ts/Add.ts +++ b/artifacts/ts/Add.ts @@ -23,17 +23,20 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as AddContractJson } from "../add/Add.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace AddTypes { - export type Fields = { + export interface Fields extends Record { sub: HexString; result: bigint; - }; + } export type State = ContractState; @@ -74,12 +77,12 @@ class Factory extends ContractFactory { tests = { add: async ( params: TestContractParams - ): Promise> => { + ): Promise> => { return testMethod(this, "add", params); }, addPrivate: async ( params: TestContractParams - ): Promise> => { + ): Promise> => { return testMethod(this, "addPrivate", params); }, createSubContract: async ( @@ -87,12 +90,12 @@ class Factory extends ContractFactory { AddTypes.Fields, { a: bigint; path: HexString; subContractId: HexString; payer: Address } > - ): Promise> => { + ): Promise> => { return testMethod(this, "createSubContract", params); }, destroy: async ( params: TestContractParams - ): Promise> => { + ): Promise> => { return testMethod(this, "destroy", params); }, }; @@ -102,9 +105,10 @@ class Factory extends ContractFactory { export const Add = new Factory( Contract.fromJson( AddContractJson, - "=8+4=1-1=2-2+64=3-1+d=37+77e010a=1+1646450726976617465=154", - "a49f0624ccbec8df1bf3ad7f628fb47a42cc448fe7369fc0da02071df6787b69", - AllStructs + "=8+4=1-1=2-2+6c=2-2+75=37+77e010a=1+1646450726976617465=170", + "da908c46aa94ebe533cdb16d1f5f2ba771def332ae09dda36218bba7efc2de0a", + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/Assert.ts b/artifacts/ts/Assert.ts index ba3be46f1..e29444734 100644 --- a/artifacts/ts/Assert.ts +++ b/artifacts/ts/Assert.ts @@ -23,10 +23,13 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as AssertContractJson } from "../test/Assert.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace AssertTypes { @@ -57,7 +60,7 @@ class Factory extends ContractFactory { TestContractParams, "testArgs" | "initialFields" > - ): Promise> => { + ): Promise> => { return testMethod(this, "test", params === undefined ? {} : params); }, }; @@ -69,7 +72,8 @@ export const Assert = new Factory( AssertContractJson, "", "5bd05924fb9a23ea105df065a8c2dfa463b9ee53cc14a60320140d19dd6151ca", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/Debug.ts b/artifacts/ts/Debug.ts index d80c0137f..f8aa7891e 100644 --- a/artifacts/ts/Debug.ts +++ b/artifacts/ts/Debug.ts @@ -23,10 +23,13 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as DebugContractJson } from "../test/Debug.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace DebugTypes { @@ -44,7 +47,7 @@ class Factory extends ContractFactory { TestContractParams, "testArgs" | "initialFields" > - ): Promise> => { + ): Promise> => { return testMethod(this, "debug", params === undefined ? {} : params); }, }; @@ -56,7 +59,8 @@ export const Debug = new Factory( DebugContractJson, "=4-2+13=11+2ca7e=1+20748656c6c6f2c200121", "0ffc72054e3668c8933e53c892947dea1963c0c24cc006a4fb0aa028c13a7e13", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/DeprecatedNFTTest1.ts b/artifacts/ts/DeprecatedNFTTest1.ts index 67bd758ef..b33e34b70 100644 --- a/artifacts/ts/DeprecatedNFTTest1.ts +++ b/artifacts/ts/DeprecatedNFTTest1.ts @@ -23,17 +23,20 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as DeprecatedNFTTest1ContractJson } from "../nft/DeprecatedNFTTest1.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest1Types { - export type Fields = { + export interface Fields extends Record { collectionId: HexString; uri: HexString; - }; + } export type State = ContractState; @@ -75,7 +78,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "getTokenUri", params); }, }; @@ -87,7 +90,8 @@ export const DeprecatedNFTTest1 = new Factory( DeprecatedNFTTest1ContractJson, "", "3d89da71c0a6e905dd54267f897137ec6beb9603bb787e0e4a36bfc76f7a712b", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/DeprecatedNFTTest2.ts b/artifacts/ts/DeprecatedNFTTest2.ts index 995b871a9..293694cad 100644 --- a/artifacts/ts/DeprecatedNFTTest2.ts +++ b/artifacts/ts/DeprecatedNFTTest2.ts @@ -23,17 +23,20 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as DeprecatedNFTTest2ContractJson } from "../nft/DeprecatedNFTTest2.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest2Types { - export type Fields = { + export interface Fields extends Record { collectionId: HexString; uri: HexString; - }; + } export type State = ContractState; @@ -79,7 +82,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "getTokenUri", params); }, getCollectionId: async ( @@ -87,7 +90,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "getCollectionId", params); }, }; @@ -99,7 +102,8 @@ export const DeprecatedNFTTest2 = new Factory( DeprecatedNFTTest2ContractJson, "", "c3e8a33252664e2f79903788d8abd79ee2c6785c580fa6911a0868436c59f59e", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/DeprecatedNFTTest3.ts b/artifacts/ts/DeprecatedNFTTest3.ts index 58cc03240..aa414a4bb 100644 --- a/artifacts/ts/DeprecatedNFTTest3.ts +++ b/artifacts/ts/DeprecatedNFTTest3.ts @@ -23,17 +23,20 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as DeprecatedNFTTest3ContractJson } from "../nft/DeprecatedNFTTest3.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest3Types { - export type Fields = { + export interface Fields extends Record { collectionId: HexString; uri: HexString; - }; + } export type State = ContractState; @@ -75,7 +78,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "getTokenUri", params); }, returnNothing: async ( @@ -83,7 +86,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "returnNothing", params); }, }; @@ -95,7 +98,8 @@ export const DeprecatedNFTTest3 = new Factory( DeprecatedNFTTest3ContractJson, "", "75181639c8575ce108d1ecb0b1b73a373a8652ffe6f5f6621d9f9eee5a0b2eb4", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/DeprecatedNFTTest4.ts b/artifacts/ts/DeprecatedNFTTest4.ts index 3ff1f52c2..ec0788d81 100644 --- a/artifacts/ts/DeprecatedNFTTest4.ts +++ b/artifacts/ts/DeprecatedNFTTest4.ts @@ -23,17 +23,20 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as DeprecatedNFTTest4ContractJson } from "../nft/DeprecatedNFTTest4.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest4Types { - export type Fields = { + export interface Fields extends Record { collectionId: HexString; uri: HexString; - }; + } export type State = ContractState; @@ -79,7 +82,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "getTokenUri", params); }, getBool: async ( @@ -87,7 +90,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "getBool", params); }, }; @@ -99,7 +102,8 @@ export const DeprecatedNFTTest4 = new Factory( DeprecatedNFTTest4ContractJson, "", "d8f8650c15cc96211608a52ae7d43a15d7b28306ac13acec672c0f1ed02a0538", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/DeprecatedNFTTest5.ts b/artifacts/ts/DeprecatedNFTTest5.ts index 434829a76..8580c7f4e 100644 --- a/artifacts/ts/DeprecatedNFTTest5.ts +++ b/artifacts/ts/DeprecatedNFTTest5.ts @@ -23,17 +23,20 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as DeprecatedNFTTest5ContractJson } from "../nft/DeprecatedNFTTest5.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest5Types { - export type Fields = { + export interface Fields extends Record { collectionId: HexString; uri: HexString; - }; + } export type State = ContractState; @@ -79,7 +82,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "getTokenUri", params); }, returnMoreValues: async ( @@ -87,7 +90,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "returnMoreValues", params); }, }; @@ -99,7 +102,8 @@ export const DeprecatedNFTTest5 = new Factory( DeprecatedNFTTest5ContractJson, "", "65c9d8a07f42939e84b4ae2fdc94dbbe3545c8ddb0832df08ef69b3cab50ebe3", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/DeprecatedNFTTest6.ts b/artifacts/ts/DeprecatedNFTTest6.ts index df6b25f51..6b8810249 100644 --- a/artifacts/ts/DeprecatedNFTTest6.ts +++ b/artifacts/ts/DeprecatedNFTTest6.ts @@ -23,17 +23,20 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as DeprecatedNFTTest6ContractJson } from "../nft/DeprecatedNFTTest6.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest6Types { - export type Fields = { + export interface Fields extends Record { collectionId: HexString; uri: HexString; - }; + } export type State = ContractState; @@ -79,7 +82,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "getTokenUri", params); }, getArray: async ( @@ -87,7 +90,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "getArray", params); }, }; @@ -99,7 +102,8 @@ export const DeprecatedNFTTest6 = new Factory( DeprecatedNFTTest6ContractJson, "", "88822622be55e862a1759c4e0c02300da75fe9e3dbe73c8fbe0fa8714996629e", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/DeprecatedNFTTest7.ts b/artifacts/ts/DeprecatedNFTTest7.ts index aaac93e43..113f72b97 100644 --- a/artifacts/ts/DeprecatedNFTTest7.ts +++ b/artifacts/ts/DeprecatedNFTTest7.ts @@ -23,17 +23,20 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as DeprecatedNFTTest7ContractJson } from "../nft/DeprecatedNFTTest7.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest7Types { - export type Fields = { + export interface Fields extends Record { collectionId: HexString; uri: HexString; - }; + } export type State = ContractState; @@ -79,7 +82,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "getTokenUri", params); }, returnNegativeIndex: async ( @@ -87,7 +90,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "returnNegativeIndex", params); }, }; @@ -99,7 +102,8 @@ export const DeprecatedNFTTest7 = new Factory( DeprecatedNFTTest7ContractJson, "", "33ddc42a153c6b9940924d989dcd107d7ff234ecbe9c494ece35ed06bd24450d", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/FakeTokenTest.ts b/artifacts/ts/FakeTokenTest.ts index 2912b82c6..e229a4c26 100644 --- a/artifacts/ts/FakeTokenTest.ts +++ b/artifacts/ts/FakeTokenTest.ts @@ -23,16 +23,19 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as FakeTokenTestContractJson } from "../token/FakeTokenTest.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace FakeTokenTestTypes { - export type Fields = { + export interface Fields extends Record { a: bigint; - }; + } export type State = ContractState; @@ -86,7 +89,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "getSymbol", params); }, getName: async ( @@ -94,7 +97,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "getName", params); }, getDecimals: async ( @@ -102,7 +105,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "getDecimals", params); }, getTotalSupply: async ( @@ -110,7 +113,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "getTotalSupply", params); }, foo: async ( @@ -118,7 +121,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "foo", params); }, }; @@ -130,7 +133,8 @@ export const FakeTokenTest = new Factory( FakeTokenTestContractJson, "", "88d74dcc19bfd075e97c90ab5f48d374f9ff982133d8257d4efc32305c5885b3", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/Greeter.ts b/artifacts/ts/Greeter.ts index 9c17166b6..71b706c1d 100644 --- a/artifacts/ts/Greeter.ts +++ b/artifacts/ts/Greeter.ts @@ -23,14 +23,17 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as GreeterContractJson } from "../greeter/Greeter.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace GreeterTypes { - export type Fields = { + export interface Fields extends Record { btcPrice: bigint; array0: [[bigint, bigint], [bigint, bigint], [bigint, bigint]]; array1: [[boolean, boolean], [boolean, boolean], [boolean, boolean]]; @@ -40,7 +43,7 @@ export namespace GreeterTypes { [HexString, HexString] ]; array3: [[Address, Address], [Address, Address], [Address, Address]]; - }; + } export type State = ContractState; @@ -76,7 +79,7 @@ class Factory extends ContractFactory { tests = { greet: async ( params: Omit, "testArgs"> - ): Promise> => { + ): Promise> => { return testMethod(this, "greet", params); }, }; @@ -88,7 +91,8 @@ export const Greeter = new Factory( GreeterContractJson, "", "3813cf61a6e0f126463190119cd861a14ca9c2f92839e193c4f9934517b02477", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/MapTest.ts b/artifacts/ts/MapTest.ts new file mode 100644 index 000000000..7c6d6432c --- /dev/null +++ b/artifacts/ts/MapTest.ts @@ -0,0 +1,210 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { + Address, + Contract, + ContractState, + TestContractResult, + HexString, + ContractFactory, + EventSubscribeOptions, + EventSubscription, + CallContractParams, + CallContractResult, + TestContractParams, + ContractEvent, + subscribeContractEvent, + subscribeContractEvents, + testMethod, + callMethod, + multicallMethods, + fetchContractState, + ContractInstance, + getContractEventsCurrentCount, + Val, +} from "@alephium/web3"; +import { default as MapTestContractJson } from "../test/MapTest.ral.json"; +import { getContractByCodeHash } from "./contracts"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; + +// Custom types for the contract +export namespace MapTestTypes { + export interface Fields extends Record { + a: bigint; + b: bigint; + } + + export type State = ContractState; + + export interface CallMethodTable { + get: { + params: CallContractParams<{ key: Address }>; + result: CallContractResult; + }; + contains: { + params: CallContractParams<{ key: Address }>; + result: CallContractResult; + }; + } + export type CallMethodParams = + CallMethodTable[T]["params"]; + export type CallMethodResult = + CallMethodTable[T]["result"]; + export type MultiCallParams = Partial<{ + [Name in keyof CallMethodTable]: CallMethodTable[Name]["params"]; + }>; + export type MultiCallResults = { + [MaybeName in keyof T]: MaybeName extends keyof CallMethodTable + ? CallMethodTable[MaybeName]["result"] + : undefined; + }; +} + +class Factory extends ContractFactory { + getInitialFieldsWithDefaultValues() { + return this.contract.getInitialFieldsWithDefaultValues() as MapTestTypes.Fields; + } + + at(address: string): MapTestInstance { + return new MapTestInstance(address); + } + + tests = { + insert: async ( + params: TestContractParams< + MapTestTypes.Fields & { + map0?: Map; + map1?: Map; + }, + { key: Address; value: MapValue } + > + ): Promise< + TestContractResult< + null, + { map0?: Map; map1?: Map } + > + > => { + return testMethod(this, "insert", params); + }, + update: async ( + params: TestContractParams< + MapTestTypes.Fields & { + map0?: Map; + map1?: Map; + }, + { key: Address } + > + ): Promise< + TestContractResult< + null, + { map0?: Map; map1?: Map } + > + > => { + return testMethod(this, "update", params); + }, + remove: async ( + params: TestContractParams< + MapTestTypes.Fields & { + map0?: Map; + map1?: Map; + }, + { key: Address } + > + ): Promise< + TestContractResult< + null, + { map0?: Map; map1?: Map } + > + > => { + return testMethod(this, "remove", params); + }, + get: async ( + params: TestContractParams< + MapTestTypes.Fields & { + map0?: Map; + map1?: Map; + }, + { key: Address } + > + ): Promise< + TestContractResult< + MapValue, + { map0?: Map; map1?: Map } + > + > => { + return testMethod(this, "get", params); + }, + contains: async ( + params: TestContractParams< + MapTestTypes.Fields & { + map0?: Map; + map1?: Map; + }, + { key: Address } + > + ): Promise< + TestContractResult< + boolean, + { map0?: Map; map1?: Map } + > + > => { + return testMethod(this, "contains", params); + }, + }; +} + +// Use this object to test and deploy the contract +export const MapTest = new Factory( + Contract.fromJson( + MapTestContractJson, + "=6-1+d=3-1+3=3-2+8f=2-1=1+b=2-2+c4=13-1+7=40+7a037e0300012c00=226+7a037e0300012c00=308-2+4022=90+7a047e0300012c00=46+7a047e0300012c00=112", + "d012c5bf0e7658ee640d58506c576e5fdbcc5c2c7515b1ad9dcf3076f85af881", + AllStructs, + AllGeneratedContracts + ) +); + +// Use this class to interact with the blockchain +export class MapTestInstance extends ContractInstance { + constructor(address: Address) { + super(address); + } + + async fetchState(): Promise { + return fetchContractState(MapTest, this); + } + + methods = { + get: async ( + params: MapTestTypes.CallMethodParams<"get"> + ): Promise> => { + return callMethod(MapTest, this, "get", params, getContractByCodeHash); + }, + contains: async ( + params: MapTestTypes.CallMethodParams<"contains"> + ): Promise> => { + return callMethod( + MapTest, + this, + "contains", + params, + getContractByCodeHash + ); + }, + }; + + async multicall( + calls: Calls + ): Promise> { + return (await multicallMethods( + MapTest, + this, + calls, + getContractByCodeHash + )) as MapTestTypes.MultiCallResults; + } +} diff --git a/artifacts/ts/MetaData.ts b/artifacts/ts/MetaData.ts index 3b364f8fc..d7caeef6e 100644 --- a/artifacts/ts/MetaData.ts +++ b/artifacts/ts/MetaData.ts @@ -23,10 +23,13 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as MetaDataContractJson } from "../test/MetaData.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace MetaDataTypes { @@ -44,7 +47,7 @@ class Factory extends ContractFactory { TestContractParams, "testArgs" | "initialFields" > - ): Promise> => { + ): Promise> => { return testMethod(this, "foo", params === undefined ? {} : params); }, bar: async ( @@ -52,7 +55,7 @@ class Factory extends ContractFactory { TestContractParams, "testArgs" | "initialFields" > - ): Promise> => { + ): Promise> => { return testMethod(this, "bar", params === undefined ? {} : params); }, baz: async ( @@ -60,7 +63,7 @@ class Factory extends ContractFactory { TestContractParams, "testArgs" | "initialFields" > - ): Promise> => { + ): Promise> => { return testMethod(this, "baz", params === undefined ? {} : params); }, }; @@ -72,7 +75,8 @@ export const MetaData = new Factory( MetaDataContractJson, "", "cade0de390b8e15960b263ac35aa013cb84f844bce6e3e53e6bfe2cc9166623f", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/NFTCollectionTest.ts b/artifacts/ts/NFTCollectionTest.ts index 8851df8db..b0cdceb95 100644 --- a/artifacts/ts/NFTCollectionTest.ts +++ b/artifacts/ts/NFTCollectionTest.ts @@ -23,18 +23,21 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as NFTCollectionTestContractJson } from "../nft/NFTCollectionTest.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace NFTCollectionTestTypes { - export type Fields = { + export interface Fields extends Record { nftTemplateId: HexString; collectionUri: HexString; totalSupply: bigint; - }; + } export type State = ContractState; @@ -96,7 +99,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "getCollectionUri", params); }, totalSupply: async ( @@ -104,7 +107,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "totalSupply", params); }, nftByIndex: async ( @@ -112,7 +115,7 @@ class Factory extends ContractFactory< NFTCollectionTestTypes.Fields, { index: bigint } > - ): Promise> => { + ): Promise> => { return testMethod(this, "nftByIndex", params); }, validateNFT: async ( @@ -120,7 +123,7 @@ class Factory extends ContractFactory< NFTCollectionTestTypes.Fields, { nftId: HexString; nftIndex: bigint } > - ): Promise> => { + ): Promise> => { return testMethod(this, "validateNFT", params); }, mint: async ( @@ -128,7 +131,7 @@ class Factory extends ContractFactory< NFTCollectionTestTypes.Fields, { nftUri: HexString } > - ): Promise> => { + ): Promise> => { return testMethod(this, "mint", params); }, }; @@ -140,7 +143,8 @@ export const NFTCollectionTest = new Factory( NFTCollectionTestContractJson, "", "c84f4fd5d3fdee90b3421174c85011437a10c6f440e0c261b1f69ff77bc5ab70", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/NFTCollectionWithRoyaltyTest.ts b/artifacts/ts/NFTCollectionWithRoyaltyTest.ts index 653ea420d..430cf6cc9 100644 --- a/artifacts/ts/NFTCollectionWithRoyaltyTest.ts +++ b/artifacts/ts/NFTCollectionWithRoyaltyTest.ts @@ -23,20 +23,23 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as NFTCollectionWithRoyaltyTestContractJson } from "../nft/NFTCollectionWithRoyaltyTest.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace NFTCollectionWithRoyaltyTestTypes { - export type Fields = { + export interface Fields extends Record { nftTemplateId: HexString; collectionUri: HexString; collectionOwner: Address; royaltyRate: bigint; totalSupply: bigint; - }; + } export type State = ContractState; @@ -103,7 +106,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "getCollectionUri", params); }, totalSupply: async ( @@ -111,7 +114,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "totalSupply", params); }, nftByIndex: async ( @@ -119,7 +122,7 @@ class Factory extends ContractFactory< NFTCollectionWithRoyaltyTestTypes.Fields, { index: bigint } > - ): Promise> => { + ): Promise> => { return testMethod(this, "nftByIndex", params); }, validateNFT: async ( @@ -127,7 +130,7 @@ class Factory extends ContractFactory< NFTCollectionWithRoyaltyTestTypes.Fields, { nftId: HexString; nftIndex: bigint } > - ): Promise> => { + ): Promise> => { return testMethod(this, "validateNFT", params); }, royaltyAmount: async ( @@ -135,7 +138,7 @@ class Factory extends ContractFactory< NFTCollectionWithRoyaltyTestTypes.Fields, { tokenId: HexString; salePrice: bigint } > - ): Promise> => { + ): Promise> => { return testMethod(this, "royaltyAmount", params); }, payRoyalty: async ( @@ -143,7 +146,7 @@ class Factory extends ContractFactory< NFTCollectionWithRoyaltyTestTypes.Fields, { payer: Address; amount: bigint } > - ): Promise> => { + ): Promise> => { return testMethod(this, "payRoyalty", params); }, withdrawRoyalty: async ( @@ -151,7 +154,7 @@ class Factory extends ContractFactory< NFTCollectionWithRoyaltyTestTypes.Fields, { recipient: Address; amount: bigint } > - ): Promise> => { + ): Promise> => { return testMethod(this, "withdrawRoyalty", params); }, mint: async ( @@ -159,7 +162,7 @@ class Factory extends ContractFactory< NFTCollectionWithRoyaltyTestTypes.Fields, { nftUri: HexString } > - ): Promise> => { + ): Promise> => { return testMethod(this, "mint", params); }, }; @@ -171,7 +174,8 @@ export const NFTCollectionWithRoyaltyTest = new Factory( NFTCollectionWithRoyaltyTestContractJson, "", "1c162da87d31289c9b392bd48767386336bb1d208101a8680d92b7dc74098ce0", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/NFTTest.ts b/artifacts/ts/NFTTest.ts index a5adf5bbe..de1742c57 100644 --- a/artifacts/ts/NFTTest.ts +++ b/artifacts/ts/NFTTest.ts @@ -23,18 +23,21 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as NFTTestContractJson } from "../nft/NFTTest.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace NFTTestTypes { - export type Fields = { + export interface Fields extends Record { collectionId: HexString; nftIndex: bigint; uri: HexString; - }; + } export type State = ContractState; @@ -74,12 +77,12 @@ class Factory extends ContractFactory { tests = { getTokenUri: async ( params: Omit, "testArgs"> - ): Promise> => { + ): Promise> => { return testMethod(this, "getTokenUri", params); }, getCollectionIndex: async ( params: Omit, "testArgs"> - ): Promise> => { + ): Promise> => { return testMethod(this, "getCollectionIndex", params); }, }; @@ -91,7 +94,8 @@ export const NFTTest = new Factory( NFTTestContractJson, "", "4897086210869e612d82995b765a447c5319a55a56e8a0c3c07b4d9ca81e15b1", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/OwnerOnly.ts b/artifacts/ts/OwnerOnly.ts index 83b71b9a1..98ae413fc 100644 --- a/artifacts/ts/OwnerOnly.ts +++ b/artifacts/ts/OwnerOnly.ts @@ -23,16 +23,19 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as OwnerOnlyContractJson } from "../test/OwnerOnly.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace OwnerOnlyTypes { - export type Fields = { + export interface Fields extends Record { owner: Address; - }; + } export type State = ContractState; } @@ -52,7 +55,7 @@ class Factory extends ContractFactory< tests = { testOwner: async ( params: Omit, "testArgs"> - ): Promise> => { + ): Promise> => { return testMethod(this, "testOwner", params); }, }; @@ -64,7 +67,8 @@ export const OwnerOnly = new Factory( OwnerOnlyContractJson, "", "c21e66486f3fa9f78555b71d30ba1ffd2f5a4bf8624647b97ed3748db20e295a", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/Sub.ts b/artifacts/ts/Sub.ts index e2db025e8..cbe40cacc 100644 --- a/artifacts/ts/Sub.ts +++ b/artifacts/ts/Sub.ts @@ -23,16 +23,19 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as SubContractJson } from "../sub/Sub.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace SubTypes { - export type Fields = { + export interface Fields extends Record { result: bigint; - }; + } export type State = ContractState; @@ -72,7 +75,7 @@ class Factory extends ContractFactory { tests = { sub: async ( params: TestContractParams - ): Promise> => { + ): Promise> => { return testMethod(this, "sub", params); }, }; @@ -84,7 +87,8 @@ export const Sub = new Factory( SubContractJson, "", "513645f5c95a28d55a51070f3d5c51edbda05a98f46b23cad59952e2ee4846a1", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/TokenTest.ts b/artifacts/ts/TokenTest.ts index c9ecf8f3b..b33f756c9 100644 --- a/artifacts/ts/TokenTest.ts +++ b/artifacts/ts/TokenTest.ts @@ -23,19 +23,22 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as TokenTestContractJson } from "../token/TokenTest.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace TokenTestTypes { - export type Fields = { + export interface Fields extends Record { symbol: HexString; name: HexString; decimals: bigint; totalSupply: bigint; - }; + } export type State = ContractState; @@ -86,22 +89,22 @@ class Factory extends ContractFactory< tests = { getSymbol: async ( params: Omit, "testArgs"> - ): Promise> => { + ): Promise> => { return testMethod(this, "getSymbol", params); }, getName: async ( params: Omit, "testArgs"> - ): Promise> => { + ): Promise> => { return testMethod(this, "getName", params); }, getDecimals: async ( params: Omit, "testArgs"> - ): Promise> => { + ): Promise> => { return testMethod(this, "getDecimals", params); }, getTotalSupply: async ( params: Omit, "testArgs"> - ): Promise> => { + ): Promise> => { return testMethod(this, "getTotalSupply", params); }, }; @@ -113,7 +116,8 @@ export const TokenTest = new Factory( TokenTestContractJson, "", "a2800413eb2c5c23d48068db23df5f8eeaba04653e12c8ed59d589720d96dadd", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/UserAccount.ts b/artifacts/ts/UserAccount.ts index 49743d857..219ffc42d 100644 --- a/artifacts/ts/UserAccount.ts +++ b/artifacts/ts/UserAccount.ts @@ -23,19 +23,22 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as UserAccountContractJson } from "../test/UserAccount.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace UserAccountTypes { - export type Fields = { + export interface Fields extends Record { id: HexString; address: Address; balances: Balances; name: HexString; - }; + } export type State = ContractState; @@ -77,7 +80,7 @@ class Factory extends ContractFactory< UserAccountTypes.Fields, { tokens: [TokenBalance, TokenBalance] } > - ): Promise> => { + ): Promise> => { return testMethod(this, "updateBalance", params); }, updateAddress: async ( @@ -85,7 +88,7 @@ class Factory extends ContractFactory< UserAccountTypes.Fields, { newAddress: Address } > - ): Promise> => { + ): Promise> => { return testMethod(this, "updateAddress", params); }, getBalances: async ( @@ -93,7 +96,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "getBalances", params); }, }; @@ -105,7 +108,8 @@ export const UserAccount = new Factory( UserAccountContractJson, "", "be41c84b7e99a544bd39df7eb24bc8c221f4ac66b7c0d774dfe96b92745167cc", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/Warnings.ts b/artifacts/ts/Warnings.ts index ec6fe1277..468d585cd 100644 --- a/artifacts/ts/Warnings.ts +++ b/artifacts/ts/Warnings.ts @@ -23,17 +23,20 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as WarningsContractJson } from "../test/Warnings.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace WarningsTypes { - export type Fields = { + export interface Fields extends Record { a: bigint; b: bigint; - }; + } export type State = ContractState; } @@ -52,7 +55,7 @@ class Factory extends ContractFactory { tests = { foo: async ( params: TestContractParams - ): Promise> => { + ): Promise> => { return testMethod(this, "foo", params); }, }; @@ -64,7 +67,8 @@ export const Warnings = new Factory( WarningsContractJson, "", "9a0c90d67d729a478062d6794cf7b75c27483c50f6fe2ad13c5ed8873ad1fde2", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/WrongNFTTest.ts b/artifacts/ts/WrongNFTTest.ts index b43ab44a1..75181dc9c 100644 --- a/artifacts/ts/WrongNFTTest.ts +++ b/artifacts/ts/WrongNFTTest.ts @@ -23,18 +23,21 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + Val, } from "@alephium/web3"; import { default as WrongNFTTestContractJson } from "../nft/WrongNFTTest.ral.json"; import { getContractByCodeHash } from "./contracts"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace WrongNFTTestTypes { - export type Fields = { + export interface Fields extends Record { collectionId: HexString; nftIndex: bigint; uri: HexString; - }; + } export type State = ContractState; @@ -80,7 +83,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "getTokenUri", params); }, getCollectionIndex: async ( @@ -88,7 +91,7 @@ class Factory extends ContractFactory< TestContractParams, "testArgs" > - ): Promise> => { + ): Promise> => { return testMethod(this, "getCollectionIndex", params); }, }; @@ -100,7 +103,8 @@ export const WrongNFTTest = new Factory( WrongNFTTestContractJson, "", "7dd2ed643a98b2a1a52a9b9e536fcdae60d961b583b8109f777d846bfdfcae8d", - AllStructs + AllStructs, + AllGeneratedContracts ) ); diff --git a/artifacts/ts/contracts.ts b/artifacts/ts/contracts.ts index ce0333e2e..a5aee6027 100644 --- a/artifacts/ts/contracts.ts +++ b/artifacts/ts/contracts.ts @@ -3,6 +3,7 @@ /* eslint-disable */ import { Contract, ContractFactory } from "@alephium/web3"; +import { AllGeneratedContracts } from "./types"; import { Add, Assert, @@ -16,6 +17,7 @@ import { DeprecatedNFTTest7, FakeTokenTest, Greeter, + MapTest, MetaData, NFTCollectionTest, NFTCollectionWithRoyaltyTest, @@ -28,10 +30,10 @@ import { WrongNFTTest, } from "."; -let contracts: ContractFactory[] | undefined = undefined; +let contracts: Contract[] | undefined = undefined; export function getContractByCodeHash(codeHash: string): Contract { if (contracts === undefined) { - contracts = [ + const factories: ContractFactory[] = [ Add, Assert, Debug, @@ -44,6 +46,7 @@ export function getContractByCodeHash(codeHash: string): Contract { DeprecatedNFTTest7, FakeTokenTest, Greeter, + MapTest, MetaData, NFTCollectionTest, NFTCollectionWithRoyaltyTest, @@ -55,13 +58,14 @@ export function getContractByCodeHash(codeHash: string): Contract { Warnings, WrongNFTTest, ]; + contracts = factories.map((f) => f.contract); } - const c = contracts.find( - (c) => - c.contract.codeHash === codeHash || c.contract.codeHashDebug === codeHash + const allContracts = contracts.concat(AllGeneratedContracts); + const c = allContracts.find( + (c) => c.codeHash === codeHash || c.codeHashDebug === codeHash ); if (c === undefined) { throw new Error("Unknown code with code hash: " + codeHash); } - return c.contract; + return c; } diff --git a/artifacts/ts/index.ts b/artifacts/ts/index.ts index e7c07b699..f40f01af1 100644 --- a/artifacts/ts/index.ts +++ b/artifacts/ts/index.ts @@ -14,6 +14,7 @@ export * from "./DeprecatedNFTTest6"; export * from "./DeprecatedNFTTest7"; export * from "./FakeTokenTest"; export * from "./Greeter"; +export * from "./MapTest"; export * from "./MetaData"; export * from "./NFTCollectionTest"; export * from "./NFTCollectionWithRoyaltyTest"; diff --git a/artifacts/ts/scripts.ts b/artifacts/ts/scripts.ts index 469a9c350..390044608 100644 --- a/artifacts/ts/scripts.ts +++ b/artifacts/ts/scripts.ts @@ -13,12 +13,17 @@ import { } from "@alephium/web3"; import { default as DestroyAddScriptJson } from "../add/DestroyAdd.ral.json"; import { default as GreeterMainScriptJson } from "../greeter/GreeterMain.ral.json"; +import { default as InsertIntoMapScriptJson } from "../test/InsertIntoMap.ral.json"; import { default as MainScriptJson } from "../add/Main.ral.json"; import { default as MintNFTTestScriptJson } from "../nft/MintNFTTest.ral.json"; +import { default as RemoveFromMapScriptJson } from "../test/RemoveFromMap.ral.json"; import { default as TemplateArrayVarScriptJson } from "../test/TemplateArrayVar.ral.json"; +import { default as UpdateMapValueScriptJson } from "../test/UpdateMapValue.ral.json"; import { default as UpdateUserAccountScriptJson } from "../test/UpdateUserAccount.ral.json"; import { default as WithdrawNFTCollectionTestScriptJson } from "../nft/WithdrawNFTCollectionTest.ral.json"; -import { Balances, TokenBalance, AllStructs } from "./types"; + +import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; +import { AllGeneratedContracts } from "./types"; export const DestroyAdd = new ExecutableScript<{ add: HexString; @@ -29,6 +34,12 @@ export const GreeterMain = new ExecutableScript<{ greeterContractId: HexString; }>(Script.fromJson(GreeterMainScriptJson, "", AllStructs)); +export const InsertIntoMap = new ExecutableScript<{ + mapTest: HexString; + from: Address; + value: MapValue; +}>(Script.fromJson(InsertIntoMapScriptJson, "", AllStructs)); + export const Main = new ExecutableScript<{ addContractId: HexString }>( Script.fromJson(MainScriptJson, "", AllStructs) ); @@ -39,6 +50,11 @@ export const MintNFTTest = new ExecutableScript<{ royalty: boolean; }>(Script.fromJson(MintNFTTestScriptJson, "", AllStructs)); +export const RemoveFromMap = new ExecutableScript<{ + mapTest: HexString; + key: Address; +}>(Script.fromJson(RemoveFromMapScriptJson, "", AllStructs)); + export const TemplateArrayVar = new ExecutableScript<{ address: Address; numbers0: [[bigint, bigint], [bigint, bigint]]; @@ -46,6 +62,11 @@ export const TemplateArrayVar = new ExecutableScript<{ numbers1: [bigint, bigint, bigint]; }>(Script.fromJson(TemplateArrayVarScriptJson, "", AllStructs)); +export const UpdateMapValue = new ExecutableScript<{ + mapTest: HexString; + key: Address; +}>(Script.fromJson(UpdateMapValueScriptJson, "", AllStructs)); + export const UpdateUserAccount = new ExecutableScript<{ account: HexString; tokens: [TokenBalance, TokenBalance]; diff --git a/artifacts/ts/types.ts b/artifacts/ts/types.ts index c7785de96..6af0738ee 100644 --- a/artifacts/ts/types.ts +++ b/artifacts/ts/types.ts @@ -2,13 +2,21 @@ /* tslint:disable */ /* eslint-disable */ -import { Address, HexString, Val, Struct } from "@alephium/web3"; +import { Address, HexString, Val, Struct, Contract } from "@alephium/web3"; +import { default as allGeneratedContractsJson } from "../generated_contracts.ral.json"; import { default as allStructsJson } from "../structs.ral.json"; export const AllStructs = allStructsJson.map((json) => Struct.fromJson(json)); +export const AllGeneratedContracts = allGeneratedContractsJson.map((json) => + Contract.fromJson(json, "", "", AllStructs) +); export interface Balances extends Record { totalAmount: bigint; tokens: [TokenBalance, TokenBalance]; } +export interface MapValue extends Record { + id: bigint; + balance: bigint; +} export interface TokenBalance extends Record { tokenId: HexString; amount: bigint; diff --git a/contracts/test/map.ral b/contracts/test/map.ral new file mode 100644 index 000000000..65d1ac274 --- /dev/null +++ b/contracts/test/map.ral @@ -0,0 +1,43 @@ +struct MapValue { + id: U256, + mut balance: U256 +} +Contract MapTest(@unused mut a: U256, @unused b: U256, mut map0: Map[Address, MapValue], mut map1: Map[U256, U256]) { + @using(preapprovedAssets = true) + pub fn insert(key: Address, value: MapValue) -> () { + map0.insert!{key -> ALPH: minimalContractDeposit!()}(key, value) + map1.insert!{key -> ALPH: minimalContractDeposit!()}(value.id, value.balance) + } + + pub fn update(key: Address) -> () { + let value = map0[key] + map0[key].balance = value.balance + 1 + map1[value.id] = value.balance + 1 + } + + pub fn remove(key: Address) -> () { + let value = map0[key] + map0.remove!(key, key) + map1.remove!(value.id, key) + } + + pub fn get(key: Address) -> MapValue { + return map0[key] + } + + pub fn contains(key: Address) -> Bool { + return map0.contains!(key) + } +} + +TxScript InsertIntoMap(mapTest: MapTest, from: Address, value: MapValue) { + mapTest.insert{from -> ALPH: minimalContractDeposit!() * 2}(from, value) +} + +TxScript RemoveFromMap(mapTest: MapTest, key: Address) { + mapTest.remove(key) +} + +TxScript UpdateMapValue(mapTest: MapTest, key: Address) { + mapTest.update(key) +} diff --git a/test/contract.test.ts b/test/contract.test.ts index aa4e93c8c..fe1ccc85c 100644 --- a/test/contract.test.ts +++ b/test/contract.test.ts @@ -38,14 +38,21 @@ import { Contract, Project, Script, getContractIdFromUnsignedTx } from '../packa import { expectAssertionError, testAddress, randomContractAddress, getSigner, mintToken } from '../packages/web3-test' import { PrivateKeyWallet } from '@alephium/web3-wallet' import { Greeter } from '../artifacts/ts/Greeter' -import { GreeterMain, Main, TemplateArrayVar, UpdateUserAccount } from '../artifacts/ts/scripts' +import { + GreeterMain, + InsertIntoMap, + Main, + RemoveFromMap, + TemplateArrayVar, + UpdateUserAccount +} from '../artifacts/ts/scripts' import { Sub, SubTypes } from '../artifacts/ts/Sub' import { Add, AddTypes } from '../artifacts/ts/Add' import { MetaData } from '../artifacts/ts/MetaData' import { Assert } from '../artifacts/ts/Assert' import { Debug } from '../artifacts/ts/Debug' import { getContractByCodeHash } from '../artifacts/ts/contracts' -import { UserAccount, NFTTest, OwnerOnly, TokenTest } from '../artifacts/ts' +import { UserAccount, NFTTest, OwnerOnly, TokenTest, MapTest } from '../artifacts/ts' import { randomBytes } from 'crypto' import { TokenBalance } from '../artifacts/ts/types' @@ -436,4 +443,74 @@ describe('contract', function () { expect(balances1.returns.tokens[0].amount).toEqual(100n) expect(balances1.returns.tokens[1].amount).toEqual(101n) }) + + it('should test map(uint test)', async () => { + const insertResult = await MapTest.tests.insert({ + initialFields: { a: 0n, b: 0n }, + testArgs: { key: signer.address, value: { id: 1n, balance: 10n } }, + inputAssets: [{ address: signer.address, asset: { alphAmount: ONE_ALPH * 3n } }] + }) + expect(insertResult.maps?.map0?.get(signer.address)).toEqual({ id: 1n, balance: 10n }) + expect(insertResult.maps?.map1?.get(1n)).toEqual(10n) + + const updateResult = await MapTest.tests.update({ + initialFields: { + a: 0n, + b: 0n, + map0: new Map([[signer.address, { id: 1n, balance: 10n }]]), + map1: new Map([[1n, 10n]]) + }, + testArgs: { key: signer.address }, + inputAssets: [{ address: signer.address, asset: { alphAmount: ONE_ALPH } }] + }) + expect(updateResult.maps?.map0?.get(signer.address)).toEqual({ id: 1n, balance: 11n }) + expect(updateResult.maps?.map1?.get(1n)).toEqual(11n) + + const removeResult = await MapTest.tests.remove({ + initialFields: { + a: 0n, + b: 0n, + map0: new Map([[signer.address, { id: 1n, balance: 10n }]]), + map1: new Map([[1n, 10n]]) + }, + testArgs: { key: signer.address }, + inputAssets: [{ address: signer.address, asset: { alphAmount: ONE_ALPH } }] + }) + expect(removeResult.maps?.map0?.get(signer.address)).toEqual(undefined) + expect(removeResult.maps?.map1?.get(1n)).toEqual(undefined) + }) + + it('should test map(integration test)', async () => { + const result = await MapTest.deploy(signer, { + initialFields: { a: 0n, b: 1n } + }) + const state = await result.contractInstance.fetchState() + expect(state.fields).toEqual({ a: 0n, b: 1n }) + + const mapTest = result.contractInstance + await InsertIntoMap.execute(signer, { + initialFields: { + mapTest: mapTest.contractId, + from: signer.address, + value: { id: 1n, balance: 10n } + }, + attoAlphAmount: ONE_ALPH * 2n + }) + + const exist0 = (await mapTest.methods.contains({ args: { key: signer.address } })).returns + expect(exist0).toEqual(true) + + const value = (await mapTest.methods.get({ args: { key: signer.address } })).returns + expect(value).toEqual({ id: 1n, balance: 10n }) + + await RemoveFromMap.execute(signer, { + initialFields: { + mapTest: mapTest.contractId, + key: signer.address + } + }) + + const exist1 = (await mapTest.methods.contains({ args: { key: signer.address } })).returns + expect(exist1).toEqual(false) + }) }) From b65224ac226504d6e095548738b03fd22e13c138 Mon Sep 17 00:00:00 2001 From: lbqds Date: Thu, 21 Mar 2024 10:43:34 +0800 Subject: [PATCH 07/24] Fix tests --- packages/web3/src/codec/script-codec.test.ts | 2 +- packages/web3/src/codec/unsigned-tx-codec.test.ts | 12 ++++++++---- test/contract.test.ts | 15 ++++++++------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/packages/web3/src/codec/script-codec.test.ts b/packages/web3/src/codec/script-codec.test.ts index f05ffa9f3..ea4e58598 100644 --- a/packages/web3/src/codec/script-codec.test.ts +++ b/packages/web3/src/codec/script-codec.test.ts @@ -151,7 +151,7 @@ describe('Encode & decode scripts', function () { ) { const nodeProvider = web3.getCurrentNodeProvider() const compileScriptResult = await nodeProvider.contracts.postContractsCompileScript({ code: scriptCode }) - const scriptBytecode = buildScriptByteCode(compileScriptResult.bytecodeTemplate, fields, fieldsSig) + const scriptBytecode = buildScriptByteCode(compileScriptResult.bytecodeTemplate, fields, fieldsSig, []) const decoded = scriptCodec.decode(Buffer.from(scriptBytecode, 'hex')) const encoded = scriptCodec.encode(decoded) expect(scriptBytecode).toEqual(encoded.toString('hex')) diff --git a/packages/web3/src/codec/unsigned-tx-codec.test.ts b/packages/web3/src/codec/unsigned-tx-codec.test.ts index 87c814222..cc8dfb958 100644 --- a/packages/web3/src/codec/unsigned-tx-codec.test.ts +++ b/packages/web3/src/codec/unsigned-tx-codec.test.ts @@ -93,7 +93,8 @@ describe('Encode & decode unsigned transactions', function () { const contractByteCode = buildContractByteCode( compileContractResult.bytecode, {}, - { names: [], types: [], isMutable: [] } + { names: [], types: [], isMutable: [] }, + [] ) const deployContractResult = await signer1.signAndSubmitDeployContractTx({ signerAddress: signer1.address, @@ -111,7 +112,8 @@ describe('Encode & decode unsigned transactions', function () { const scriptBytecode = buildScriptByteCode( compileScriptResult.bytecodeTemplate, { testContract: deployContractResult.contractId }, - { names: ['testContract'], types: ['ByteVec'], isMutable: [false] } + { names: ['testContract'], types: ['ByteVec'], isMutable: [false] }, + [] ) const buildExecuteScriptTxResult = await signer1.buildExecuteScriptTx({ @@ -160,7 +162,8 @@ describe('Encode & decode unsigned transactions', function () { const contractByteCode = buildContractByteCode( compileContractResult.bytecode, {}, - { names: [], types: [], isMutable: [] } + { names: [], types: [], isMutable: [] }, + [] ) const deployContractResult = await signer1.signAndSubmitDeployContractTx({ signerAddress: signer1.address, @@ -180,7 +183,8 @@ describe('Encode & decode unsigned transactions', function () { const scriptBytecode = buildScriptByteCode( compileScriptResult.bytecodeTemplate, { faucetContract: deployContractResult.contractId }, - { names: ['faucetContract'], types: ['ByteVec'], isMutable: [false] } + { names: ['faucetContract'], types: ['ByteVec'], isMutable: [false] }, + [] ) // Get the token to signer1 diff --git a/test/contract.test.ts b/test/contract.test.ts index fe1ccc85c..1598c9c4f 100644 --- a/test/contract.test.ts +++ b/test/contract.test.ts @@ -243,12 +243,12 @@ describe('contract', function () { it('should load source files by order', async () => { const sourceFiles = await Project['loadSourceFiles']('.', './contracts') // `loadSourceFiles` is a private method - expect(sourceFiles.length).toEqual(38) - sourceFiles.slice(0, 22).forEach((c) => expect(c.type).toEqual(0)) // contracts - sourceFiles.slice(22, 29).forEach((s) => expect(s.type).toEqual(1)) // scripts - sourceFiles.slice(29, 31).forEach((i) => expect(i.type).toEqual(2)) // abstract class - sourceFiles.slice(31, 36).forEach((i) => expect(i.type).toEqual(3)) // interfaces - sourceFiles.slice(36).forEach((i) => expect(i.type).toEqual(4)) // structs + expect(sourceFiles.length).toEqual(43) + sourceFiles.slice(0, 23).forEach((c) => expect(c.type).toEqual(0)) // contracts + sourceFiles.slice(23, 33).forEach((s) => expect(s.type).toEqual(1)) // scripts + sourceFiles.slice(33, 35).forEach((i) => expect(i.type).toEqual(2)) // abstract class + sourceFiles.slice(35, 40).forEach((i) => expect(i.type).toEqual(3)) // interfaces + sourceFiles.slice(40).forEach((i) => expect(i.type).toEqual(4)) // structs }) it('should load contract from json', () => { @@ -291,7 +291,8 @@ describe('contract', function () { const result = await Debug.tests.debug() expect(result.debugMessages.length).toEqual(1) expect(result.debugMessages[0].contractAddress).toEqual(result.contractAddress) - expect(result.debugMessages[0].message).toEqual(`Hello, ${result.contractAddress}!`) + const nullContractAddress = addressFromContractId('0'.repeat(64)) + expect(result.debugMessages[0].message).toEqual(`Hello, ${nullContractAddress}!`) }) it('should test assert!', async () => { From 751c60975f2b57db13b942415b52dc5e0012c867 Mon Sep 17 00:00:00 2001 From: lbqds Date: Thu, 21 Mar 2024 12:07:49 +0800 Subject: [PATCH 08/24] Update devnet config to fix exchange tests --- docker/devnet.conf | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docker/devnet.conf b/docker/devnet.conf index be7916195..2a717cc0d 100644 --- a/docker/devnet.conf +++ b/docker/devnet.conf @@ -22,9 +22,12 @@ alephium.genesis.allocations = [ } ] // 1 million token allocated for your address alephium.consensus.num-zeros-at-least-in-hash = 0 -alephium.consensus.block-target-time = 10 millis -alephium.consensus.uncle-dependency-gap-time = 0 seconds +alephium.consensus.mainnet.block-target-time = 10 millis +alephium.consensus.mainnet.uncle-dependency-gap-time = 0 seconds +alephium.consensus.ghost.block-target-time = 5 millis +alephium.consensus.ghost.uncle-dependency-gap-time = 0 seconds alephium.network.leman-hard-fork-timestamp = 1643500800000 // GMT: 30 January 2022 00:00:00 +alephium.network.ghost-hard-fork-timestamp = 1643500800000 // GMT: 30 January 2022 00:00:00 alephium.network.network-id = 4 alephium.discovery.bootstrap = [] From 6bf1131d0a81a6ac312fe5189c6334c8a45bbb92 Mon Sep 17 00:00:00 2001 From: Cheng Wang Date: Mon, 25 Mar 2024 13:16:52 +0100 Subject: [PATCH 09/24] Update full node image --- docker/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index e2a1ebfe3..878642d56 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -31,7 +31,7 @@ services: condition: service_healthy alephium: - image: alephium/alephium:v2.11.0 + image: alephium/dev-alephium:rhone-0.2.0 restart: unless-stopped ports: - 19973:19973/tcp From ca9f43c830d2a64ebdd52780919d4beae9b5f40d Mon Sep 17 00:00:00 2001 From: lbqds Date: Wed, 27 Mar 2024 10:56:31 +0800 Subject: [PATCH 10/24] Revert "Save generated contracts" This reverts commit 666336ad515db1e5bb5195c12f7bea8a78bd7516. --- packages/cli/src/codegen.ts | 44 +++++----------- packages/web3/src/contract/contract.ts | 70 ++++---------------------- 2 files changed, 23 insertions(+), 91 deletions(-) diff --git a/packages/cli/src/codegen.ts b/packages/cli/src/codegen.ts index bbb1d277e..a686168f0 100644 --- a/packages/cli/src/codegen.ts +++ b/packages/cli/src/codegen.ts @@ -389,20 +389,15 @@ function getContractFields(contract: Contract): node.FieldsSig { } } -function importTypes(): string { - const hasGeneratedContracts = Project.currentProject.generatedContracts.length > 0 +function importStructs(): string { const structs = Project.currentProject.structs.map((s) => s.name) - if (structs.length === 0 && !hasGeneratedContracts) return '' - return ` - ${structs.length === 0 ? '' : `import { ${structs.join(',')}, AllStructs } from './types'`} - ${hasGeneratedContracts ? `import { AllGeneratedContracts } from './types'` : ''} - ` + if (structs.length === 0) return '' + return `import { ${structs.join(',')}, AllStructs } from './types'` } function genContract(contract: Contract, artifactRelativePath: string): string { const fieldsSig = getContractFields(contract) const hasStruct = Project.currentProject.structs.length > 0 - const hasGeneratedContracts = Project.currentProject.generatedContracts.length > 0 const projectArtifact = Project.currentProject.projectArtifact const contractInfo = projectArtifact.infos.get(contract.name) if (contractInfo === undefined) { @@ -420,7 +415,7 @@ function genContract(contract: Contract, artifactRelativePath: string): string { } from '@alephium/web3' import { default as ${contract.name}ContractJson } from '../${toUnixPath(artifactRelativePath)}' import { getContractByCodeHash } from './contracts' - ${importTypes()} + ${importStructs()} // Custom types for the contract export namespace ${contract.name}Types { @@ -442,8 +437,7 @@ function genContract(contract: Contract, artifactRelativePath: string): string { ${contract.name}ContractJson, '${contractInfo.bytecodeDebugPatch}', '${contractInfo.codeHashDebug}', - ${hasStruct ? 'AllStructs' : []}, - ${hasGeneratedContracts ? 'AllGeneratedContracts' : []} + ${hasStruct ? 'AllStructs' : []} )) // Use this class to interact with the blockchain @@ -502,7 +496,7 @@ function genScripts(outDir: string, artifactDir: string, exports: string[]) { HexString } from '@alephium/web3' ${importArtifacts} - ${importTypes()} + ${importStructs()} ${scriptsSource} ` @@ -749,11 +743,9 @@ function cleanCode(outDir: string) { }) } -function genTypes(outDir: string) { - const generatedContracts = Project.currentProject.generatedContracts +function genStructTypes(outDir: string) { const structs = Project.currentProject.structs - if (generatedContracts.length === 0 && structs.length === 0) return - + if (structs.length === 0) return const sorted = structs.sort((a, b) => (a.name > b.name ? 1 : -1)) const interfaces = sorted.map((struct) => { const fields = struct.fieldNames @@ -763,21 +755,9 @@ function genTypes(outDir: string) { }) const sourceCode = ` ${header} - import { Address, HexString, Val, Struct, Contract } from '@alephium/web3' - ${ - generatedContracts.length === 0 - ? '' - : `import { default as allGeneratedContractsJson } from '../generated_contracts.ral.json'` - } - ${interfaces.length === 0 ? '' : `import { default as allStructsJson } from '../structs.ral.json'`} - ${interfaces.length === 0 ? '' : `export const AllStructs = allStructsJson.map((json) => Struct.fromJson(json))`} - ${ - generatedContracts.length === 0 - ? '' - : interfaces.length !== 0 - ? `export const AllGeneratedContracts = allGeneratedContractsJson.map((json) => Contract.fromJson(json, '', '', AllStructs))` - : `export const AllGeneratedContracts = allGeneratedContractsJson.map((json) => Contract.fromJson(json, '', ''))` - } + import { Address, HexString, Val, Struct } from '@alephium/web3' + import { default as allStructsJson } from '../structs.ral.json' + export const AllStructs = allStructsJson.map((json) => Struct.fromJson(json)) ${interfaces.join('\n')} ` const sourcePath = path.join(outDir, 'types.ts') @@ -794,7 +774,7 @@ export function codegen(artifactDir: string) { const exports: string[] = [] try { - genTypes(outDir) + genStructTypes(outDir) genContracts(outDir, artifactDir, exports) const contractNames = exports.map((p) => p.slice(2)) genContractByCodeHash(outDir, contractNames) diff --git a/packages/web3/src/contract/contract.ts b/packages/web3/src/contract/contract.ts index 94eaf42cc..5d4fb63b3 100644 --- a/packages/web3/src/contract/contract.ts +++ b/packages/web3/src/contract/contract.ts @@ -368,7 +368,6 @@ export class Project { contracts: Map> scripts: Map> structs: Struct[] - generatedContracts: Contract[] projectArtifact: ProjectArtifact readonly contractsRootDir: string @@ -439,7 +438,6 @@ export class Project { contracts: Map>, scripts: Map>, structs: Struct[], - generatedContracts: Contract[], errorOnWarnings: boolean, projectArtifact: ProjectArtifact ) { @@ -449,7 +447,6 @@ export class Project { this.contracts = contracts this.scripts = scripts this.structs = structs - this.generatedContracts = generatedContracts this.projectArtifact = projectArtifact if (errorOnWarnings) { @@ -510,24 +507,6 @@ export class Project { return fsPromises.writeFile(filePath, JSON.stringify(structs, null, 2)) } - private static async loadGeneratedContracts(artifactsRootDir: string, structs: Struct[]): Promise { - const filePath = path.join(artifactsRootDir, 'generated_contracts.ral.json') - if (!fs.existsSync(filePath)) return [] - const content = await fsPromises.readFile(filePath) - const json = JSON.parse(content.toString()) - if (!Array.isArray(json)) { - throw Error(`Invalid contract JSON: ${content}`) - } - return Array.from(json).map((item) => Contract.fromJson(item, '', '', structs)) - } - - private async saveGeneratedContractsToFile(): Promise { - if (this.generatedContracts.length === 0) return - const contracts = this.generatedContracts.map((c) => c.toJson()) - const filePath = path.join(this.artifactsRootDir, 'generated_contracts.ral.json') - return fsPromises.writeFile(filePath, JSON.stringify(contracts, null, 2)) - } - private async saveArtifactsToFile(projectRootDir: string): Promise { const artifactsRootDir = this.artifactsRootDir const saveToFile = async function (compiled: Compiled): Promise { @@ -541,7 +520,6 @@ export class Project { this.contracts.forEach((contract) => saveToFile(contract)) this.scripts.forEach((script) => saveToFile(script)) this.saveStructsToFile() - this.saveGeneratedContractsToFile() await this.projectArtifact.saveToFile(projectRootDir) } @@ -609,17 +587,16 @@ export class Project { const contracts = new Map>() const scripts = new Map>() const structs = result.structs === undefined ? [] : result.structs.map((item) => Struct.fromStructSig(item)) - const generatedContracts = result.contracts - .filter((c) => sourceInfos.find((s) => s.type === SourceKind.Contract && s.name === c.name) === undefined) - .map((c) => Contract.fromCompileResult(c, structs)) result.contracts.forEach((contractResult) => { const sourceInfo = sourceInfos.find( (sourceInfo) => sourceInfo.type === SourceKind.Contract && sourceInfo.name === contractResult.name ) - if (sourceInfo !== undefined) { - const contract = Contract.fromCompileResult(contractResult, structs, generatedContracts) - contracts.set(contract.name, new Compiled(sourceInfo, contract, contractResult.warnings)) + if (sourceInfo === undefined) { + // this should never happen + throw new Error(`SourceInfo does not exist for contract ${contractResult.name}`) } + const contract = Contract.fromCompileResult(contractResult, structs) + contracts.set(contract.name, new Compiled(sourceInfo, contract, contractResult.warnings)) }) result.scripts.forEach((scriptResult) => { const sourceInfo = sourceInfos.find( @@ -646,7 +623,6 @@ export class Project { contracts, scripts, structs, - generatedContracts, errorOnWarnings, projectArtifact ) @@ -668,7 +644,6 @@ export class Project { const contracts = new Map>() const scripts = new Map>() const structs = await Project.loadStructs(artifactsRootDir) - const generatedContracts = await Project.loadGeneratedContracts(artifactsRootDir, structs) for (const sourceInfo of sourceInfos) { const info = projectArtifact.infos.get(sourceInfo.name) if (typeof info === 'undefined') { @@ -681,8 +656,7 @@ export class Project { artifactDir, info.bytecodeDebugPatch, info.codeHashDebug, - structs, - generatedContracts + structs ) contracts.set(artifact.name, new Compiled(sourceInfo, artifact, warnings)) } else if (sourceInfo.type === SourceKind.Script) { @@ -698,7 +672,6 @@ export class Project { contracts, scripts, structs, - generatedContracts, errorOnWarnings, projectArtifact ) @@ -921,7 +894,6 @@ export class Contract extends Artifact { readonly constants: Constant[] readonly enums: Enum[] readonly structs: Struct[] - readonly generatedContracts: Contract[] readonly stdInterfaceId?: HexString readonly bytecodeDebug: string @@ -940,7 +912,6 @@ export class Contract extends Artifact { constants: Constant[], enums: Enum[], structs: Struct[], - generatedContracts: Contract[], stdInterfaceId?: HexString ) { super(version, name, functions) @@ -953,7 +924,6 @@ export class Contract extends Artifact { this.constants = constants this.enums = enums this.structs = structs - this.generatedContracts = generatedContracts this.stdInterfaceId = stdInterfaceId this.bytecodeDebug = ralph.buildDebugBytecode(this.bytecode, this.bytecodeDebugPatch) @@ -961,13 +931,7 @@ export class Contract extends Artifact { } // TODO: safely parse json - static fromJson( - artifact: any, - bytecodeDebugPatch = '', - codeHashDebug = '', - structs: Struct[] = [], - generatedContracts: Contract[] = [] - ): Contract { + static fromJson(artifact: any, bytecodeDebugPatch = '', codeHashDebug = '', structs: Struct[] = []): Contract { if ( artifact.version == null || artifact.name == null || @@ -994,17 +958,12 @@ export class Contract extends Artifact { artifact.constants, artifact.enums, structs, - generatedContracts, artifact.stdInterfaceId === null ? undefined : artifact.stdInterfaceId ) return contract } - static fromCompileResult( - result: node.CompileContractResult, - structs: Struct[] = [], - generatedContracts: Contract[] = [] - ): Contract { + static fromCompileResult(result: node.CompileContractResult, structs: Struct[] = []): Contract { return new Contract( result.version, result.name, @@ -1018,7 +977,6 @@ export class Contract extends Artifact { result.constants, result.enums, structs, - generatedContracts, result.stdInterfaceId ) } @@ -1028,15 +986,14 @@ export class Contract extends Artifact { path: string, bytecodeDebugPatch: string, codeHashDebug: string, - structs: Struct[] = [], - generatedContracts: Contract[] = [] + structs: Struct[] = [] ): Promise { const content = await fsPromises.readFile(path) const artifact = JSON.parse(content.toString()) - return Contract.fromJson(artifact, bytecodeDebugPatch, codeHashDebug, structs, generatedContracts) + return Contract.fromJson(artifact, bytecodeDebugPatch, codeHashDebug, structs) } - toJson(): any { + override toString(): string { const object: any = { version: this.version, name: this.name, @@ -1051,11 +1008,6 @@ export class Contract extends Artifact { if (this.stdInterfaceId !== undefined) { object.stdInterfaceId = this.stdInterfaceId } - return object - } - - override toString(): string { - const object = this.toJson() return JSON.stringify(object, null, 2) } From f97b085fa7cb4b90a0de2dea6ebaa799c44ac376 Mon Sep 17 00:00:00 2001 From: lbqds Date: Wed, 27 Mar 2024 15:28:04 +0800 Subject: [PATCH 11/24] Add CreateMapEntry instr --- packages/web3/src/codec/instr-codec.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/web3/src/codec/instr-codec.ts b/packages/web3/src/codec/instr-codec.ts index 969ec5151..9bca894ce 100644 --- a/packages/web3/src/codec/instr-codec.ts +++ b/packages/web3/src/codec/instr-codec.ts @@ -43,6 +43,10 @@ export interface AddressConst extends InstrValue { export interface Debug extends InstrValue { stringParts: DecodedArray } +export interface CreateMapEntryValue extends InstrValue { + immFields: number + mutFields: number +} export interface Instr { code: number value: InstrValue @@ -238,6 +242,10 @@ export const LoadImmField = (index: number): Instr => ({ code: 0xce, value: { in export const LoadImmFieldByIndex: Instr = { code: 0xcf, value: {} } export const PayGasFee: Instr = { code: 0xd0, value: {} } export const MinimalContractDeposit: Instr = { code: 0xd1, value: {} } +export const CreateMapEntry: (immFields: number, mutFields: number) => Instr = ( + immFields: number, + mutFields: number +) => ({ code: 0xd2, value: { immFields, mutFields } }) export class InstrCodec implements Codec { parser = Parser.start() @@ -434,7 +442,8 @@ export class InstrCodec implements Codec { 0xce: Parser.start().uint8('index'), [LoadImmFieldByIndex.code]: Parser.start(), [PayGasFee.code]: Parser.start(), - [MinimalContractDeposit.code]: Parser.start() + [MinimalContractDeposit.code]: Parser.start(), + 0xd2: Parser.start().uint8('immFields').uint8('mutFields') } }) @@ -453,6 +462,9 @@ export class InstrCodec implements Codec { result.push(...compactUnsignedIntCodec.encode((instrValue as InstrValueWithCompactInt).value)) } else if (instrsWithIndex.includes(instr.code)) { result.push((instrValue as InstrValueWithIndex).index) + } else if (instr.code === 0xd2) { + const value = instrValue as CreateMapEntryValue + result.push(value.immFields, value.mutFields) } return Buffer.from(result) From b65c18ea29ffcd02b92d7cc5ea9101d85e426493 Mon Sep 17 00:00:00 2001 From: lbqds Date: Wed, 27 Mar 2024 14:06:52 +0800 Subject: [PATCH 12/24] Gen code for map --- contracts/test/map.ral | 6 +- packages/cli/src/codegen.ts | 12 +- .../web3/src/codec/contract-codec.test.ts | 6 +- packages/web3/src/codec/contract-codec.ts | 18 ++ packages/web3/src/codec/method-codec.ts | 11 + packages/web3/src/contract/contract.ts | 236 ++++++++++++------ packages/web3/src/contract/ralph.test.ts | 19 +- 7 files changed, 220 insertions(+), 88 deletions(-) diff --git a/contracts/test/map.ral b/contracts/test/map.ral index 65d1ac274..94078080e 100644 --- a/contracts/test/map.ral +++ b/contracts/test/map.ral @@ -5,8 +5,8 @@ struct MapValue { Contract MapTest(@unused mut a: U256, @unused b: U256, mut map0: Map[Address, MapValue], mut map1: Map[U256, U256]) { @using(preapprovedAssets = true) pub fn insert(key: Address, value: MapValue) -> () { - map0.insert!{key -> ALPH: minimalContractDeposit!()}(key, value) - map1.insert!{key -> ALPH: minimalContractDeposit!()}(value.id, value.balance) + map0.insert!{key -> ALPH: mapEntryDeposit!()}(key, value) + map1.insert!{key -> ALPH: mapEntryDeposit!()}(value.id, value.balance) } pub fn update(key: Address) -> () { @@ -31,7 +31,7 @@ Contract MapTest(@unused mut a: U256, @unused b: U256, mut map0: Map[Address, Ma } TxScript InsertIntoMap(mapTest: MapTest, from: Address, value: MapValue) { - mapTest.insert{from -> ALPH: minimalContractDeposit!() * 2}(from, value) + mapTest.insert{from -> ALPH: mapEntryDeposit!() * 2}(from, value) } TxScript RemoveFromMap(mapTest: MapTest, key: Address) { diff --git a/packages/cli/src/codegen.ts b/packages/cli/src/codegen.ts index a686168f0..92f753685 100644 --- a/packages/cli/src/codegen.ts +++ b/packages/cli/src/codegen.ts @@ -510,27 +510,23 @@ function genIndexTs(outDir: string, exports: string[]) { } function genContractByCodeHash(outDir: string, contractNames: string[]) { - const hasGeneratedContracts = Project.currentProject.generatedContracts.length > 0 const contracts = contractNames.join(',') const source = ` ${header} import { Contract, ContractFactory } from '@alephium/web3' - ${hasGeneratedContracts ? `import { AllGeneratedContracts } from './types'` : ''} ${contracts.length === 0 ? '' : `import { ${contracts} } from '.'`} - let contracts: Contract[] | undefined = undefined + let contracts: ContractFactory[] | undefined = undefined export function getContractByCodeHash(codeHash: string): Contract { if (contracts === undefined) { - const factories: ContractFactory[] = [${contracts}] - contracts = factories.map((f) => f.contract) + contracts = [${contracts}] } - const allContracts = ${hasGeneratedContracts ? 'contracts.concat(AllGeneratedContracts)' : 'contracts'} - const c = allContracts.find((c) => c.codeHash === codeHash || c.codeHashDebug === codeHash) + const c = contracts.find((c) => c.contract.codeHash === codeHash || c.contract.codeHashDebug === codeHash) if (c === undefined) { throw new Error("Unknown code with code hash: " + codeHash) } - return c + return c.contract } ` const filename = 'contracts.ts' diff --git a/packages/web3/src/codec/contract-codec.test.ts b/packages/web3/src/codec/contract-codec.test.ts index 14d359e9e..b5fe31884 100644 --- a/packages/web3/src/codec/contract-codec.test.ts +++ b/packages/web3/src/codec/contract-codec.test.ts @@ -19,7 +19,7 @@ along with the library. If not, see . import { Buffer } from 'buffer/' import { Contract, Project, web3 } from '@alephium/web3' import { Method } from './method-codec' -import { contractCodec } from './contract-codec' +import { contractCodec, toHalfDecoded } from './contract-codec' import { ApproveAlph, AssertWithErrorCode, @@ -310,6 +310,7 @@ describe('Encode & decode contract', function () { const decodedContract = contractCodec.decodeContract(Buffer.from(contractBytecode, 'hex')) expect(decodedContract.fieldLength).toEqual(methods.length) + expect(toHalfDecoded(decodedContract)).toEqual(decoded) decodedContract.methods.map((decodedMethod, index) => { expect(decodedMethod.isPublic).toEqual(methods[index].isPublic) expect(decodedMethod.assetModifier).toEqual(methods[index].assetModifier) @@ -326,8 +327,9 @@ describe('Encode & decode contract', function () { const encoded = contractCodec.encode(decoded) const decodedContract = contractCodec.decodeContract(Buffer.from(contract.bytecode, 'hex')) + expect(toHalfDecoded(decodedContract)).toEqual(decoded) - expect(decodedContract.fieldLength).toEqual(contract.fieldsSig.names.length) + expect(decodedContract.fieldLength).toEqual(contract.fieldsExceptMaps.names.length) decodedContract.methods.map((decodedMethod, index) => { const contractFunction = contract.functions[index] expect(decodedMethod.isPublic).toEqual(contractFunction.isPublic) diff --git a/packages/web3/src/codec/contract-codec.ts b/packages/web3/src/codec/contract-codec.ts index 132c0968e..8c59807f5 100644 --- a/packages/web3/src/codec/contract-codec.ts +++ b/packages/web3/src/codec/contract-codec.ts @@ -36,6 +36,24 @@ export interface Contract { methods: Method[] } +export function toHalfDecoded(contract: Contract): HalfDecodedContract { + const fieldLength = compactSignedIntCodec.fromI32(contract.fieldLength) + const methods = contract.methods.map((m) => methodCodec.encode(MethodCodec.fromMethod(m))) + let count = 0 + const methodIndexes = Array.from(Array(methods.length).keys()).map((index) => { + count += methods[`${index}`].length + return count + }) + return { + fieldLength, + methodIndexes: { + length: compactSignedIntCodec.fromI32(methodIndexes.length), + value: methodIndexes.map((value) => compactSignedIntCodec.fromI32(value)) + }, + methods: methods.reduce((acc, buffer) => Buffer.concat([acc, buffer])) + } +} + export class ContractCodec implements Codec { parser = Parser.start() .nest('fieldLength', { diff --git a/packages/web3/src/codec/method-codec.ts b/packages/web3/src/codec/method-codec.ts index 4353409ba..e31230018 100644 --- a/packages/web3/src/codec/method-codec.ts +++ b/packages/web3/src/codec/method-codec.ts @@ -80,6 +80,17 @@ export class MethodCodec implements Codec { instrs: decodedMethod.instrs.value } } + + static fromMethod(method: Method): DecodedMethod { + return { + isPublic: method.isPublic ? 1 : 0, + assetModifier: method.assetModifier, + argsLength: compactUnsignedIntCodec.fromU32(method.argsLength), + localsLength: compactUnsignedIntCodec.fromU32(method.localsLength), + returnLength: compactUnsignedIntCodec.fromU32(method.returnLength), + instrs: instrsCodec.fromArray(method.instrs) + } + } } export const methodCodec = new MethodCodec() diff --git a/packages/web3/src/contract/contract.ts b/packages/web3/src/contract/contract.ts index 5d4fb63b3..6094b0bd3 100644 --- a/packages/web3/src/contract/contract.ts +++ b/packages/web3/src/contract/contract.ts @@ -67,6 +67,19 @@ import { ONE_ALPH, TOTAL_NUMBER_OF_GROUPS } from '../constants' import * as blake from 'blakejs' import { parseError } from '../utils/error' import { isContractDebugMessageEnabled } from '../debug' +import { + contract, + Method, + LoadLocal, + LoadImmFieldByIndex, + LoadMutFieldByIndex, + CallerContractId, + LoadImmField, + ByteVecEq, + Assert, + StoreMutFieldByIndex, + DestroySelf +} from '../codec' const crypto = new WebCrypto() @@ -524,14 +537,13 @@ export class Project { } contractByCodeHash(codeHash: string): Contract { - const allContracts = Array.from(this.contracts.values()) - .map((c) => c.artifact) - .concat(this.generatedContracts) - const contract = allContracts.find((c) => c.codeHash === codeHash || c.codeHashDebug == codeHash) + const contract = [...this.contracts.values()].find( + (c) => c.artifact.codeHash === codeHash || c.artifact.codeHashDebug == codeHash + ) if (typeof contract === 'undefined') { throw new Error(`Unknown code with code hash: ${codeHash}`) } - return contract + return contract.artifact } private static async getCompileResult( @@ -1015,18 +1027,6 @@ export class Contract extends Artifact { return this.fieldsExceptMaps.names.length !== this.fieldsSig.names.length } - getGeneratedContract(type: string): Contract | undefined { - const struct = this.structs.find((s) => s.name === type) - if (struct !== undefined) { - const name = `StructWrapper${struct.name}` - return this.generatedContracts.find((c) => c.name === name) - } - const suffix = Array.from(type) - .filter((c) => !'[;]'.includes(c)) - .join('') - return this.generatedContracts.find((c) => c.name === `SimpleWrapper${suffix}`) - } - getInitialFieldsWithDefaultValues(): Fields { const fields = this.stdInterfaceId === undefined @@ -1859,6 +1859,79 @@ function calcWrapperContractId( return subContractId(parentContractId, path, group) } +function getFieldSize(type: string, isMutable: boolean, structs: Struct[]): { immFields: number; mutFields: number } { + const struct = structs.find((s) => s.name === type) + if (struct === undefined) { + return isMutable ? { immFields: 0, mutFields: 1 } : { immFields: 1, mutFields: 0 } + } + return struct.fieldTypes.reduce( + (acc, fieldType, index) => { + const isFieldMutable = isMutable && struct.isMutable[`${index}`] + const subFieldSize = getFieldSize(fieldType, isFieldMutable, structs) + return { + immFields: acc.immFields + subFieldSize.immFields, + mutFields: acc.mutFields + subFieldSize.mutFields + } + }, + { immFields: 0, mutFields: 0 } + ) +} + +function genCodeForType(type: string, structs: Struct[]): { bytecode: string; codeHash: string } { + const { immFields, mutFields } = getFieldSize(type, true, structs) + const loadImmFieldByIndex: Method = { + isPublic: true, + assetModifier: 0, + argsLength: 1, + localsLength: 1, + returnLength: 1, + instrs: [LoadLocal(0), LoadImmFieldByIndex] + } + const loadMutFieldByIndex: Method = { + ...loadImmFieldByIndex, + instrs: [LoadLocal(0), LoadMutFieldByIndex] + } + const parentContractIdIndex = immFields + const storeMutFieldByIndex: Method = { + ...loadImmFieldByIndex, + argsLength: 2, + localsLength: 2, + returnLength: 0, + instrs: [ + CallerContractId, + LoadImmField(parentContractIdIndex), + ByteVecEq, + Assert, + LoadLocal(0), // value + LoadLocal(1), // index + StoreMutFieldByIndex + ] + } + const destroy: Method = { + isPublic: true, + assetModifier: 2, + argsLength: 1, + localsLength: 1, + returnLength: 0, + instrs: [CallerContractId, LoadImmField(parentContractIdIndex), ByteVecEq, Assert, LoadLocal(0), DestroySelf] + } + const c = { + fieldLength: immFields + mutFields + 1, // parentContractId + methods: [loadImmFieldByIndex, loadMutFieldByIndex, storeMutFieldByIndex, destroy] + } + const bytecode = contract.contractCodec.encode(contract.toHalfDecoded(c)) + const codeHash = blake.blake2b(bytecode, undefined, 32) + return { bytecode: binToHex(bytecode), codeHash: binToHex(codeHash) } +} + +function getContractFieldsSig(mapValueType: string): FieldsSig { + return { + names: ['value', 'parentContractId'], + types: [mapValueType, 'ByteVec'], + isMutable: [true, false] + } +} + function mapToExistingContracts( contract: Contract, parentContractId: string, @@ -1868,24 +1941,15 @@ function mapToExistingContracts( type: string ): ContractState[] { const [keyType, valueType] = ralph.parseMapType(type) - const generatedContract = contract.getGeneratedContract(valueType) - if (generatedContract === undefined) { - throw new Error(`Contract for type ${valueType} does not exist`) - } + const generatedContract = genCodeForType(valueType, contract.structs) return Array.from(map.entries()).map(([key, value]) => { - const fields = - generatedContract.fieldsSig.names.length === 2 - ? { value } // simple wrapper - : { ...(value as Fields) } // struct wrapper - const parentContractIdName = generatedContract.fieldsSig.names[`${generatedContract.fieldsSig.names.length - 1}`] - fields[`${parentContractIdName}`] = parentContractId + const fields = { value, parentContractId } const contractId = calcWrapperContractId(parentContractId, mapIndex, key, keyType, group) return { + ...generatedContract, address: addressFromContractId(contractId), contractId: contractId, - bytecode: generatedContract.bytecode, - codeHash: generatedContract.codeHash, - fieldsSig: generatedContract.fieldsSig, + fieldsSig: getContractFieldsSig(valueType), fields, asset: { alphAmount: ONE_ALPH } } @@ -1938,15 +2002,8 @@ export async function testMethod< existingContracts: (params.existingContracts ?? []).concat(contractStates) }) const apiResult = await getCurrentNodeProvider().contracts.postContractsTestContract(apiParams) + const maps = existingContractsToMaps(contract, address, group, apiResult, initialFields) const testResult = contract.fromApiTestContractResult(methodName, apiResult, txId) - const maps = existingContractsToMaps( - contract, - address, - group, - testResult.contracts, - testResult.debugMessages, - initialFields - ) contract.printDebugMessages(methodName, testResult.debugMessages) return { ...testResult, @@ -1954,23 +2011,33 @@ export async function testMethod< } as TestContractResult } -function existingContractsToMaps( - contract: Contract, - address: Address, - group: number, - states: ContractState[], - messages: DebugMessage[], - fields: Fields -): Record> { - const allMaps = contract.mapFields.types.map((type, index) => { +interface MapInfo { + name: string + value: Map + keyType: string + valueType: string + index: number +} + +function buildMaps(contract: Contract, fields: Fields): MapInfo[] { + return contract.mapFields.types.map((type, index) => { const name = contract.mapFields.names[`${index}`] - const map = (fields[`${name}`] ?? new Map()) as Map + const value = (fields[`${name}`] ?? new Map()) as Map const [keyType, valueType] = ralph.parseMapType(type) - return { name, map, keyType, valueType, mapIndex: index } + return { name, value, keyType, valueType, index } }) +} + +function extractFromEventLog( + contract: Contract, + result: node.TestContractResult, + allMaps: MapInfo[], + address: string, + group: number +): string[] { const parentContractId = binToHex(contractIdFromAddress(address)) const newInserted: string[] = [] - messages.forEach((message) => { + result.debugMessages.forEach((message) => { if (message.contractAddress !== address) return const decoded = ralph.tryDecodeMapDebugLog(message.message) if (decoded === undefined) return @@ -1978,38 +2045,61 @@ function existingContractsToMaps( const decodedKey = ralph.decodePrimitive(decoded.encodedKey, map.keyType) const contractId = subContractId(parentContractId, decoded.path, group) if (!decoded.isInsert) { - map.map.delete(decodedKey) + map.value.delete(decodedKey) return } - const state = states.find((s) => s.contractId === contractId) + const state = result.contracts.find((s) => s.address === addressFromContractId(contractId)) if (state === undefined) { throw new Error(`Cannot find contract state for map value, map field: ${map.name}, value type: ${map.valueType}`) } - newInserted.push(contractId) - map.map.set(decodedKey, decodeWrapperFields(state.fields)) + newInserted.push(state.address) + const fieldsSig = getContractFieldsSig(map.valueType) + const fields = fromApiFields(state.immFields, state.mutFields, fieldsSig, contract.structs) + map.value.set(decodedKey, fields['value']) }) - return allMaps.reduce((acc, map) => { - Array.from(map.map.keys()).forEach((key) => { - const contractId = calcWrapperContractId(parentContractId, map.mapIndex, key, map.keyType, group) - if (newInserted.includes(contractId)) return - const updatedState = states.find((s) => s.contractId === contractId) - if (updatedState !== undefined) map.map.set(key, decodeWrapperFields(updatedState.fields)) + return newInserted +} + +function updateMaps( + contract: Contract, + result: node.TestContractResult, + allMaps: MapInfo[], + address: Address, + group: number +): string[] { + const parentContractId = binToHex(contractIdFromAddress(address)) + const updated: string[] = [] + allMaps.forEach((map) => { + Array.from(map.value.keys()).forEach((key) => { + const contractId = calcWrapperContractId(parentContractId, map.index, key, map.keyType, group) + const updatedState = result.contracts.find((s) => s.address === addressFromContractId(contractId)) + if (updatedState === undefined) return + updated.push(updatedState.address) + const fieldsSig = getContractFieldsSig(map.valueType) + const fields = fromApiFields(updatedState.immFields, updatedState.mutFields, fieldsSig, contract.structs) + map.value.set(key, fields['value']) }) - acc[`${map.name}`] = map.map - return acc - }, {}) + }) + return updated } -function decodeWrapperFields(fields: Fields): Val { - const allFields = Object.entries(fields).map(([name]) => name) - delete fields[allFields[`${allFields.length - 1}`]] // remove the `parentContractId` field - if (allFields.length === 2) { - // simple wrapper - return fields[allFields[0]] - } else { - // struct wrapper - return fields - } +function existingContractsToMaps( + contract: Contract, + address: Address, + group: number, + result: node.TestContractResult, + fields: Fields +): Record> { + const allMaps = buildMaps(contract, fields) + const updated = updateMaps(contract, result, allMaps, address, group) + const newInserted = extractFromEventLog(contract, result, allMaps, address, group) + const mapEntries = updated.concat(newInserted) + const remainContracts = result.contracts.filter((c) => mapEntries.find((addr) => c.address === addr) === undefined) + result.contracts = remainContracts + return allMaps.reduce((acc, map) => { + acc[`${map.name}`] = map.value + return acc + }, {}) } export abstract class ContractInstance { diff --git a/packages/web3/src/contract/ralph.test.ts b/packages/web3/src/contract/ralph.test.ts index 676b01978..1adca4f86 100644 --- a/packages/web3/src/contract/ralph.test.ts +++ b/packages/web3/src/contract/ralph.test.ts @@ -352,10 +352,25 @@ describe('contract', function () { }) it('should decode map debug message', () => { - const result = ralph.tryDecodeMapDebugLog( + expect(ralph.tryDecodeMapDebugLog('5f5f6d61705f5f')).toEqual(undefined) + expect(ralph.tryDecodeMapDebugLog('5f5f6d61705f5f,false')).toEqual(undefined) + expect(ralph.tryDecodeMapDebugLog('5f5f6d6170,false')).toEqual(undefined) + const result0 = ralph.tryDecodeMapDebugLog( '5f5f6d61705f5f305f5f00066fb0c875e171612b2da9135756faed416696b184d06d93a32f894e84f9e28a,true' ) - console.log(result) + expect(result0).toEqual({ + path: '5f5f6d61705f5f305f5f00066fb0c875e171612b2da9135756faed416696b184d06d93a32f894e84f9e28a', + mapIndex: 0, + encodedKey: utils.hexToBinUnsafe('00066fb0c875e171612b2da9135756faed416696b184d06d93a32f894e84f9e28a'), + isInsert: true + }) + const result1 = ralph.tryDecodeMapDebugLog('5f5f6d61705f5f315f5f00ec3d,false') + expect(result1).toEqual({ + path: '5f5f6d61705f5f315f5f00ec3d', + mapIndex: 1, + encodedKey: utils.hexToBinUnsafe('00ec3d'), + isInsert: false + }) }) it('should test buildScriptByteCode', () => { From 5444e131f8b61dc2e6cfd779bec986fa5196f463 Mon Sep 17 00:00:00 2001 From: lbqds Date: Thu, 28 Mar 2024 12:00:42 +0800 Subject: [PATCH 13/24] Update artifacts --- .project.json | 14 +- artifacts/generated_contracts.ral.json | 199 ------------------- artifacts/test/MapTest.ral.json | 4 +- artifacts/ts/Add.ts | 5 +- artifacts/ts/Assert.ts | 5 +- artifacts/ts/Debug.ts | 5 +- artifacts/ts/DeprecatedNFTTest1.ts | 5 +- artifacts/ts/DeprecatedNFTTest2.ts | 5 +- artifacts/ts/DeprecatedNFTTest3.ts | 5 +- artifacts/ts/DeprecatedNFTTest4.ts | 5 +- artifacts/ts/DeprecatedNFTTest5.ts | 5 +- artifacts/ts/DeprecatedNFTTest6.ts | 5 +- artifacts/ts/DeprecatedNFTTest7.ts | 5 +- artifacts/ts/FakeTokenTest.ts | 5 +- artifacts/ts/Greeter.ts | 5 +- artifacts/ts/MapTest.ts | 9 +- artifacts/ts/MetaData.ts | 5 +- artifacts/ts/NFTCollectionTest.ts | 5 +- artifacts/ts/NFTCollectionWithRoyaltyTest.ts | 5 +- artifacts/ts/NFTTest.ts | 5 +- artifacts/ts/OwnerOnly.ts | 5 +- artifacts/ts/Sub.ts | 5 +- artifacts/ts/TokenTest.ts | 5 +- artifacts/ts/UserAccount.ts | 5 +- artifacts/ts/Warnings.ts | 5 +- artifacts/ts/WrongNFTTest.ts | 5 +- artifacts/ts/contracts.ts | 14 +- artifacts/ts/scripts.ts | 2 - artifacts/ts/types.ts | 6 +- 29 files changed, 41 insertions(+), 317 deletions(-) delete mode 100644 artifacts/generated_contracts.ral.json diff --git a/.project.json b/.project.json index 086a5654e..73cd1b79e 100644 --- a/.project.json +++ b/.project.json @@ -166,7 +166,7 @@ }, "InsertIntoMap": { "sourceFile": "test/map.ral", - "sourceCodeHash": "79c5f8ba94a478a18b76f9ebb5f450632e557330cccb3de67ac2e2d4833aa567", + "sourceCodeHash": "1c3c388ac6c847f24971466d6a1385398a8ce7cb8bb6ee5275e3d01e8d69deb5", "bytecodeDebugPatch": "", "codeHashDebug": "", "warnings": [] @@ -182,16 +182,16 @@ }, "MapTest": { "sourceFile": "test/map.ral", - "sourceCodeHash": "79c5f8ba94a478a18b76f9ebb5f450632e557330cccb3de67ac2e2d4833aa567", - "bytecodeDebugPatch": "=6-1+d=3-1+3=3-2+8f=2-1=1+b=2-2+c4=13-1+7=40+7a037e0300012c00=226+7a037e0300012c00=308-2+4022=90+7a047e0300012c00=46+7a047e0300012c00=112", - "codeHashDebug": "d012c5bf0e7658ee640d58506c576e5fdbcc5c2c7515b1ad9dcf3076f85af881", + "sourceCodeHash": "1c3c388ac6c847f24971466d6a1385398a8ce7cb8bb6ee5275e3d01e8d69deb5", + "bytecodeDebugPatch": "=6-1+4=3-1+a=2-2+11=3-1+3=3-1+5=12-1+b=40+7a037e0300012c00=56+7a037e0300012c00=217-1+a=114+7a047e0300012c00=46+7a047e0300012c00=136", + "codeHashDebug": "23c1ab39042b459d30f531ad31f52620ec5c1bd8a9142d2c3c2fd27d72ce1370", "warnings": [ "No external caller check for function \"MapTest.insert\". Please use \"checkCaller!(...)\" in the function or its callees, or disable it with \"@using(checkExternalCaller = false)\"." ] }, "MapValue": { "sourceFile": "test/map.ral", - "sourceCodeHash": "79c5f8ba94a478a18b76f9ebb5f450632e557330cccb3de67ac2e2d4833aa567", + "sourceCodeHash": "1c3c388ac6c847f24971466d6a1385398a8ce7cb8bb6ee5275e3d01e8d69deb5", "bytecodeDebugPatch": "", "codeHashDebug": "", "warnings": [] @@ -258,7 +258,7 @@ }, "RemoveFromMap": { "sourceFile": "test/map.ral", - "sourceCodeHash": "79c5f8ba94a478a18b76f9ebb5f450632e557330cccb3de67ac2e2d4833aa567", + "sourceCodeHash": "1c3c388ac6c847f24971466d6a1385398a8ce7cb8bb6ee5275e3d01e8d69deb5", "bytecodeDebugPatch": "", "codeHashDebug": "", "warnings": [] @@ -293,7 +293,7 @@ }, "UpdateMapValue": { "sourceFile": "test/map.ral", - "sourceCodeHash": "79c5f8ba94a478a18b76f9ebb5f450632e557330cccb3de67ac2e2d4833aa567", + "sourceCodeHash": "1c3c388ac6c847f24971466d6a1385398a8ce7cb8bb6ee5275e3d01e8d69deb5", "bytecodeDebugPatch": "", "codeHashDebug": "", "warnings": [] diff --git a/artifacts/generated_contracts.ral.json b/artifacts/generated_contracts.ral.json deleted file mode 100644 index 4692db292..000000000 --- a/artifacts/generated_contracts.ral.json +++ /dev/null @@ -1,199 +0,0 @@ -[ - { - "version": "v2.11.0", - "name": "StructWrapperMapValue", - "bytecode": "03060d184021402a403740430000010100051600ce01410c7b010000000203ce00a00002010000000102ce0002010000000102a00002010001010004b300001600a100010201010004b300001600b0", - "codeHash": "3c92b960989b8044ebc882c2e4fed45f75a50b5936e92baef1c2dfdd820d9a7a", - "fieldsSig": { - "names": [ - "id", - "balance", - "parentContractId" - ], - "types": [ - "U256", - "U256", - "ByteVec" - ], - "isMutable": [ - false, - true, - false - ] - }, - "eventsSig": [], - "functions": [ - { - "name": "f0", - "usePreapprovedAssets": false, - "useAssetsInContract": false, - "isPublic": false, - "paramNames": [ - "callerContractId" - ], - "paramTypes": [ - "ByteVec" - ], - "paramIsMutable": [ - false - ], - "returnTypes": [] - }, - { - "name": "f1", - "usePreapprovedAssets": false, - "useAssetsInContract": false, - "isPublic": true, - "paramNames": [], - "paramTypes": [], - "paramIsMutable": [], - "returnTypes": [ - "MapValue" - ] - }, - { - "name": "f2", - "usePreapprovedAssets": false, - "useAssetsInContract": false, - "isPublic": true, - "paramNames": [], - "paramTypes": [], - "paramIsMutable": [], - "returnTypes": [ - "U256" - ] - }, - { - "name": "f3", - "usePreapprovedAssets": false, - "useAssetsInContract": false, - "isPublic": true, - "paramNames": [], - "paramTypes": [], - "paramIsMutable": [], - "returnTypes": [ - "U256" - ] - }, - { - "name": "f4", - "usePreapprovedAssets": false, - "useAssetsInContract": false, - "isPublic": true, - "paramNames": [ - "newValue" - ], - "paramTypes": [ - "U256" - ], - "paramIsMutable": [ - false - ], - "returnTypes": [] - }, - { - "name": "destroy", - "usePreapprovedAssets": false, - "useAssetsInContract": true, - "isPublic": true, - "paramNames": [ - "address" - ], - "paramTypes": [ - "Address" - ], - "paramIsMutable": [ - false - ], - "returnTypes": [] - } - ], - "constants": [], - "enums": [] - }, - { - "version": "v2.11.0", - "name": "SimpleWrapperU256", - "bytecode": "02040d164023402f0000010100051600ce00410c7b010000000102a00002010001010004b300001600a100010201010004b300001600b0", - "codeHash": "b8745b5749f063d70978956e10d267e6480b8e94469963042d9c326794f59449", - "fieldsSig": { - "names": [ - "value", - "parentContractId" - ], - "types": [ - "U256", - "ByteVec" - ], - "isMutable": [ - true, - false - ] - }, - "eventsSig": [], - "functions": [ - { - "name": "f0", - "usePreapprovedAssets": false, - "useAssetsInContract": false, - "isPublic": false, - "paramNames": [ - "callerContractId" - ], - "paramTypes": [ - "ByteVec" - ], - "paramIsMutable": [ - false - ], - "returnTypes": [] - }, - { - "name": "f1", - "usePreapprovedAssets": false, - "useAssetsInContract": false, - "isPublic": true, - "paramNames": [], - "paramTypes": [], - "paramIsMutable": [], - "returnTypes": [ - "U256" - ] - }, - { - "name": "f2", - "usePreapprovedAssets": false, - "useAssetsInContract": false, - "isPublic": true, - "paramNames": [ - "newValue" - ], - "paramTypes": [ - "U256" - ], - "paramIsMutable": [ - false - ], - "returnTypes": [] - }, - { - "name": "destroy", - "usePreapprovedAssets": false, - "useAssetsInContract": true, - "isPublic": true, - "paramNames": [ - "address" - ], - "paramTypes": [ - "Address" - ], - "paramIsMutable": [ - false - ], - "returnTypes": [] - } - ], - "constants": [], - "enums": [] - } -] \ No newline at end of file diff --git a/artifacts/test/MapTest.ral.json b/artifacts/test/MapTest.ral.json index 64ee890ec..bf0718e57 100644 --- a/artifacts/test/MapTest.ral.json +++ b/artifacts/test/MapTest.ral.json @@ -1,8 +1,8 @@ { "version": "v2.11.0", "name": "MapTest", - "bytecode": "020540cf4121416e418a41a3010303030040211600d1a2140a5f5f6d61705f5f305f5f1600474414404f03060d184021402a403740430000010100051600ce01410c7b010000000203ce00a00002010000000102ce0002010000000102a00002010001010004b300001600a100010201010004b300001600b01601b10e6416020d64bf181600d1a2140a5f5f6d61705f5f315f5f1601404414403702040d164023402f0000010100051600ce00410c7b010000000102a00002010001010004b300001600a100010201010004b300001600b0b10d6416020d64bf18010001030040200c0e140a5f5f6d61705f5f305f5f16004744cb01011702170116020d2a0d0c140a5f5f6d61705f5f305f5f16004744cb010416020d2a0d0c140a5f5f6d61705f5f315f5f16014044cb010201000103001c0c0e140a5f5f6d61705f5f305f5f16004744cb01011702170116000d0c140a5f5f6d61705f5f305f5f16004744cb010516000d0c140a5f5f6d61705f5f315f5f16014044cb01030100010102090c0e140a5f5f6d61705f5f305f5f16004744cb010102010001010107140a5f5f6d61705f5f305f5f16004744cbc502", - "codeHash": "e41a3b6b637d7b7c145a6822cf4d382573a2a8f6374c09686bfd0757f07d6839", + "bytecode": "0205403c409c40f6411e41370103030300151600d1a2140a5f5f6d61705f5f305f5f160047441601b11602d202011600d1a2140a5f5f6d61705f5f315f5f16014044b11602d201010100010400402a0c0d0d140a5f5f6d61705f5f305f5f16004744cb1703160301000c0d0d160301011702170116020d2a0c0e0c140a5f5f6d61705f5f305f5f16004744cb010216020d2a0c0e0c140a5f5f6d61705f5f315f5f16014044cb0102010001040040240c0d0d140a5f5f6d61705f5f305f5f16004744cb1703160301000c0d0d160301011702170116000d0c140a5f5f6d61705f5f305f5f16004744cb010316000d0c140a5f5f6d61705f5f315f5f16014044cb01030100010202110c0d0d140a5f5f6d61705f5f305f5f16004744cb1701160101000c0d0d1601010102010001010107140a5f5f6d61705f5f305f5f16004744cbc502", + "codeHash": "bbf8f1adaea6623d50dbf589c2400da85d1fa2fc57f568810bf161060c2d9b8b", "fieldsSig": { "names": [ "a", diff --git a/artifacts/ts/Add.ts b/artifacts/ts/Add.ts index 877b8bd1b..e9c1c0482 100644 --- a/artifacts/ts/Add.ts +++ b/artifacts/ts/Add.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as AddContractJson } from "../add/Add.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace AddTypes { @@ -107,8 +105,7 @@ export const Add = new Factory( AddContractJson, "=8+4=1-1=2-2+6c=2-2+75=37+77e010a=1+1646450726976617465=170", "da908c46aa94ebe533cdb16d1f5f2ba771def332ae09dda36218bba7efc2de0a", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/Assert.ts b/artifacts/ts/Assert.ts index e29444734..2829e7985 100644 --- a/artifacts/ts/Assert.ts +++ b/artifacts/ts/Assert.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as AssertContractJson } from "../test/Assert.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace AssertTypes { @@ -72,8 +70,7 @@ export const Assert = new Factory( AssertContractJson, "", "5bd05924fb9a23ea105df065a8c2dfa463b9ee53cc14a60320140d19dd6151ca", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/Debug.ts b/artifacts/ts/Debug.ts index f8aa7891e..b4862c091 100644 --- a/artifacts/ts/Debug.ts +++ b/artifacts/ts/Debug.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as DebugContractJson } from "../test/Debug.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace DebugTypes { @@ -59,8 +57,7 @@ export const Debug = new Factory( DebugContractJson, "=4-2+13=11+2ca7e=1+20748656c6c6f2c200121", "0ffc72054e3668c8933e53c892947dea1963c0c24cc006a4fb0aa028c13a7e13", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/DeprecatedNFTTest1.ts b/artifacts/ts/DeprecatedNFTTest1.ts index b33e34b70..797133440 100644 --- a/artifacts/ts/DeprecatedNFTTest1.ts +++ b/artifacts/ts/DeprecatedNFTTest1.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as DeprecatedNFTTest1ContractJson } from "../nft/DeprecatedNFTTest1.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest1Types { @@ -90,8 +88,7 @@ export const DeprecatedNFTTest1 = new Factory( DeprecatedNFTTest1ContractJson, "", "3d89da71c0a6e905dd54267f897137ec6beb9603bb787e0e4a36bfc76f7a712b", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/DeprecatedNFTTest2.ts b/artifacts/ts/DeprecatedNFTTest2.ts index 293694cad..6d862edf2 100644 --- a/artifacts/ts/DeprecatedNFTTest2.ts +++ b/artifacts/ts/DeprecatedNFTTest2.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as DeprecatedNFTTest2ContractJson } from "../nft/DeprecatedNFTTest2.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest2Types { @@ -102,8 +100,7 @@ export const DeprecatedNFTTest2 = new Factory( DeprecatedNFTTest2ContractJson, "", "c3e8a33252664e2f79903788d8abd79ee2c6785c580fa6911a0868436c59f59e", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/DeprecatedNFTTest3.ts b/artifacts/ts/DeprecatedNFTTest3.ts index aa414a4bb..8496b9b30 100644 --- a/artifacts/ts/DeprecatedNFTTest3.ts +++ b/artifacts/ts/DeprecatedNFTTest3.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as DeprecatedNFTTest3ContractJson } from "../nft/DeprecatedNFTTest3.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest3Types { @@ -98,8 +96,7 @@ export const DeprecatedNFTTest3 = new Factory( DeprecatedNFTTest3ContractJson, "", "75181639c8575ce108d1ecb0b1b73a373a8652ffe6f5f6621d9f9eee5a0b2eb4", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/DeprecatedNFTTest4.ts b/artifacts/ts/DeprecatedNFTTest4.ts index ec0788d81..215888105 100644 --- a/artifacts/ts/DeprecatedNFTTest4.ts +++ b/artifacts/ts/DeprecatedNFTTest4.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as DeprecatedNFTTest4ContractJson } from "../nft/DeprecatedNFTTest4.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest4Types { @@ -102,8 +100,7 @@ export const DeprecatedNFTTest4 = new Factory( DeprecatedNFTTest4ContractJson, "", "d8f8650c15cc96211608a52ae7d43a15d7b28306ac13acec672c0f1ed02a0538", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/DeprecatedNFTTest5.ts b/artifacts/ts/DeprecatedNFTTest5.ts index 8580c7f4e..47eab77d4 100644 --- a/artifacts/ts/DeprecatedNFTTest5.ts +++ b/artifacts/ts/DeprecatedNFTTest5.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as DeprecatedNFTTest5ContractJson } from "../nft/DeprecatedNFTTest5.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest5Types { @@ -102,8 +100,7 @@ export const DeprecatedNFTTest5 = new Factory( DeprecatedNFTTest5ContractJson, "", "65c9d8a07f42939e84b4ae2fdc94dbbe3545c8ddb0832df08ef69b3cab50ebe3", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/DeprecatedNFTTest6.ts b/artifacts/ts/DeprecatedNFTTest6.ts index 6b8810249..d45657681 100644 --- a/artifacts/ts/DeprecatedNFTTest6.ts +++ b/artifacts/ts/DeprecatedNFTTest6.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as DeprecatedNFTTest6ContractJson } from "../nft/DeprecatedNFTTest6.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest6Types { @@ -102,8 +100,7 @@ export const DeprecatedNFTTest6 = new Factory( DeprecatedNFTTest6ContractJson, "", "88822622be55e862a1759c4e0c02300da75fe9e3dbe73c8fbe0fa8714996629e", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/DeprecatedNFTTest7.ts b/artifacts/ts/DeprecatedNFTTest7.ts index 113f72b97..913583d88 100644 --- a/artifacts/ts/DeprecatedNFTTest7.ts +++ b/artifacts/ts/DeprecatedNFTTest7.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as DeprecatedNFTTest7ContractJson } from "../nft/DeprecatedNFTTest7.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest7Types { @@ -102,8 +100,7 @@ export const DeprecatedNFTTest7 = new Factory( DeprecatedNFTTest7ContractJson, "", "33ddc42a153c6b9940924d989dcd107d7ff234ecbe9c494ece35ed06bd24450d", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/FakeTokenTest.ts b/artifacts/ts/FakeTokenTest.ts index e229a4c26..55bbda383 100644 --- a/artifacts/ts/FakeTokenTest.ts +++ b/artifacts/ts/FakeTokenTest.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as FakeTokenTestContractJson } from "../token/FakeTokenTest.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace FakeTokenTestTypes { @@ -133,8 +131,7 @@ export const FakeTokenTest = new Factory( FakeTokenTestContractJson, "", "88d74dcc19bfd075e97c90ab5f48d374f9ff982133d8257d4efc32305c5885b3", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/Greeter.ts b/artifacts/ts/Greeter.ts index 71b706c1d..e3d31fd84 100644 --- a/artifacts/ts/Greeter.ts +++ b/artifacts/ts/Greeter.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as GreeterContractJson } from "../greeter/Greeter.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace GreeterTypes { @@ -91,8 +89,7 @@ export const Greeter = new Factory( GreeterContractJson, "", "3813cf61a6e0f126463190119cd861a14ca9c2f92839e193c4f9934517b02477", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/MapTest.ts b/artifacts/ts/MapTest.ts index 7c6d6432c..53a404570 100644 --- a/artifacts/ts/MapTest.ts +++ b/artifacts/ts/MapTest.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as MapTestContractJson } from "../test/MapTest.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace MapTestTypes { @@ -161,10 +159,9 @@ class Factory extends ContractFactory { export const MapTest = new Factory( Contract.fromJson( MapTestContractJson, - "=6-1+d=3-1+3=3-2+8f=2-1=1+b=2-2+c4=13-1+7=40+7a037e0300012c00=226+7a037e0300012c00=308-2+4022=90+7a047e0300012c00=46+7a047e0300012c00=112", - "d012c5bf0e7658ee640d58506c576e5fdbcc5c2c7515b1ad9dcf3076f85af881", - AllStructs, - AllGeneratedContracts + "=6-1+4=3-1+a=2-2+11=3-1+3=3-1+5=12-1+b=40+7a037e0300012c00=56+7a037e0300012c00=217-1+a=114+7a047e0300012c00=46+7a047e0300012c00=136", + "23c1ab39042b459d30f531ad31f52620ec5c1bd8a9142d2c3c2fd27d72ce1370", + AllStructs ) ); diff --git a/artifacts/ts/MetaData.ts b/artifacts/ts/MetaData.ts index d7caeef6e..85f848098 100644 --- a/artifacts/ts/MetaData.ts +++ b/artifacts/ts/MetaData.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as MetaDataContractJson } from "../test/MetaData.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace MetaDataTypes { @@ -75,8 +73,7 @@ export const MetaData = new Factory( MetaDataContractJson, "", "cade0de390b8e15960b263ac35aa013cb84f844bce6e3e53e6bfe2cc9166623f", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/NFTCollectionTest.ts b/artifacts/ts/NFTCollectionTest.ts index b0cdceb95..b5c53ebb7 100644 --- a/artifacts/ts/NFTCollectionTest.ts +++ b/artifacts/ts/NFTCollectionTest.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as NFTCollectionTestContractJson } from "../nft/NFTCollectionTest.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace NFTCollectionTestTypes { @@ -143,8 +141,7 @@ export const NFTCollectionTest = new Factory( NFTCollectionTestContractJson, "", "c84f4fd5d3fdee90b3421174c85011437a10c6f440e0c261b1f69ff77bc5ab70", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/NFTCollectionWithRoyaltyTest.ts b/artifacts/ts/NFTCollectionWithRoyaltyTest.ts index 430cf6cc9..cc9d3dcac 100644 --- a/artifacts/ts/NFTCollectionWithRoyaltyTest.ts +++ b/artifacts/ts/NFTCollectionWithRoyaltyTest.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as NFTCollectionWithRoyaltyTestContractJson } from "../nft/NFTCollectionWithRoyaltyTest.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace NFTCollectionWithRoyaltyTestTypes { @@ -174,8 +172,7 @@ export const NFTCollectionWithRoyaltyTest = new Factory( NFTCollectionWithRoyaltyTestContractJson, "", "1c162da87d31289c9b392bd48767386336bb1d208101a8680d92b7dc74098ce0", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/NFTTest.ts b/artifacts/ts/NFTTest.ts index de1742c57..f280e485e 100644 --- a/artifacts/ts/NFTTest.ts +++ b/artifacts/ts/NFTTest.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as NFTTestContractJson } from "../nft/NFTTest.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace NFTTestTypes { @@ -94,8 +92,7 @@ export const NFTTest = new Factory( NFTTestContractJson, "", "4897086210869e612d82995b765a447c5319a55a56e8a0c3c07b4d9ca81e15b1", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/OwnerOnly.ts b/artifacts/ts/OwnerOnly.ts index 98ae413fc..0e6093d08 100644 --- a/artifacts/ts/OwnerOnly.ts +++ b/artifacts/ts/OwnerOnly.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as OwnerOnlyContractJson } from "../test/OwnerOnly.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace OwnerOnlyTypes { @@ -67,8 +65,7 @@ export const OwnerOnly = new Factory( OwnerOnlyContractJson, "", "c21e66486f3fa9f78555b71d30ba1ffd2f5a4bf8624647b97ed3748db20e295a", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/Sub.ts b/artifacts/ts/Sub.ts index cbe40cacc..182e8a9b2 100644 --- a/artifacts/ts/Sub.ts +++ b/artifacts/ts/Sub.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as SubContractJson } from "../sub/Sub.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace SubTypes { @@ -87,8 +85,7 @@ export const Sub = new Factory( SubContractJson, "", "513645f5c95a28d55a51070f3d5c51edbda05a98f46b23cad59952e2ee4846a1", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/TokenTest.ts b/artifacts/ts/TokenTest.ts index b33f756c9..c778de173 100644 --- a/artifacts/ts/TokenTest.ts +++ b/artifacts/ts/TokenTest.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as TokenTestContractJson } from "../token/TokenTest.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace TokenTestTypes { @@ -116,8 +114,7 @@ export const TokenTest = new Factory( TokenTestContractJson, "", "a2800413eb2c5c23d48068db23df5f8eeaba04653e12c8ed59d589720d96dadd", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/UserAccount.ts b/artifacts/ts/UserAccount.ts index 219ffc42d..a953e1453 100644 --- a/artifacts/ts/UserAccount.ts +++ b/artifacts/ts/UserAccount.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as UserAccountContractJson } from "../test/UserAccount.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace UserAccountTypes { @@ -108,8 +106,7 @@ export const UserAccount = new Factory( UserAccountContractJson, "", "be41c84b7e99a544bd39df7eb24bc8c221f4ac66b7c0d774dfe96b92745167cc", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/Warnings.ts b/artifacts/ts/Warnings.ts index 468d585cd..108fa4381 100644 --- a/artifacts/ts/Warnings.ts +++ b/artifacts/ts/Warnings.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as WarningsContractJson } from "../test/Warnings.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace WarningsTypes { @@ -67,8 +65,7 @@ export const Warnings = new Factory( WarningsContractJson, "", "9a0c90d67d729a478062d6794cf7b75c27483c50f6fe2ad13c5ed8873ad1fde2", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/WrongNFTTest.ts b/artifacts/ts/WrongNFTTest.ts index 75181dc9c..f8502a96b 100644 --- a/artifacts/ts/WrongNFTTest.ts +++ b/artifacts/ts/WrongNFTTest.ts @@ -27,9 +27,7 @@ import { } from "@alephium/web3"; import { default as WrongNFTTestContractJson } from "../nft/WrongNFTTest.ral.json"; import { getContractByCodeHash } from "./contracts"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; // Custom types for the contract export namespace WrongNFTTestTypes { @@ -103,8 +101,7 @@ export const WrongNFTTest = new Factory( WrongNFTTestContractJson, "", "7dd2ed643a98b2a1a52a9b9e536fcdae60d961b583b8109f777d846bfdfcae8d", - AllStructs, - AllGeneratedContracts + AllStructs ) ); diff --git a/artifacts/ts/contracts.ts b/artifacts/ts/contracts.ts index a5aee6027..3eaa159ee 100644 --- a/artifacts/ts/contracts.ts +++ b/artifacts/ts/contracts.ts @@ -3,7 +3,6 @@ /* eslint-disable */ import { Contract, ContractFactory } from "@alephium/web3"; -import { AllGeneratedContracts } from "./types"; import { Add, Assert, @@ -30,10 +29,10 @@ import { WrongNFTTest, } from "."; -let contracts: Contract[] | undefined = undefined; +let contracts: ContractFactory[] | undefined = undefined; export function getContractByCodeHash(codeHash: string): Contract { if (contracts === undefined) { - const factories: ContractFactory[] = [ + contracts = [ Add, Assert, Debug, @@ -58,14 +57,13 @@ export function getContractByCodeHash(codeHash: string): Contract { Warnings, WrongNFTTest, ]; - contracts = factories.map((f) => f.contract); } - const allContracts = contracts.concat(AllGeneratedContracts); - const c = allContracts.find( - (c) => c.codeHash === codeHash || c.codeHashDebug === codeHash + const c = contracts.find( + (c) => + c.contract.codeHash === codeHash || c.contract.codeHashDebug === codeHash ); if (c === undefined) { throw new Error("Unknown code with code hash: " + codeHash); } - return c; + return c.contract; } diff --git a/artifacts/ts/scripts.ts b/artifacts/ts/scripts.ts index 390044608..80cbeba0e 100644 --- a/artifacts/ts/scripts.ts +++ b/artifacts/ts/scripts.ts @@ -21,9 +21,7 @@ import { default as TemplateArrayVarScriptJson } from "../test/TemplateArrayVar. import { default as UpdateMapValueScriptJson } from "../test/UpdateMapValue.ral.json"; import { default as UpdateUserAccountScriptJson } from "../test/UpdateUserAccount.ral.json"; import { default as WithdrawNFTCollectionTestScriptJson } from "../nft/WithdrawNFTCollectionTest.ral.json"; - import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; -import { AllGeneratedContracts } from "./types"; export const DestroyAdd = new ExecutableScript<{ add: HexString; diff --git a/artifacts/ts/types.ts b/artifacts/ts/types.ts index 6af0738ee..c6897fb19 100644 --- a/artifacts/ts/types.ts +++ b/artifacts/ts/types.ts @@ -2,13 +2,9 @@ /* tslint:disable */ /* eslint-disable */ -import { Address, HexString, Val, Struct, Contract } from "@alephium/web3"; -import { default as allGeneratedContractsJson } from "../generated_contracts.ral.json"; +import { Address, HexString, Val, Struct } from "@alephium/web3"; import { default as allStructsJson } from "../structs.ral.json"; export const AllStructs = allStructsJson.map((json) => Struct.fromJson(json)); -export const AllGeneratedContracts = allGeneratedContractsJson.map((json) => - Contract.fromJson(json, "", "", AllStructs) -); export interface Balances extends Record { totalAmount: bigint; tokens: [TokenBalance, TokenBalance]; From 17402d281f3b80ac76db59b96a684604e5d4e82c Mon Sep 17 00:00:00 2001 From: lbqds Date: Thu, 28 Mar 2024 13:29:23 +0800 Subject: [PATCH 14/24] Add more tests for contract codec --- .../web3/src/codec/contract-codec.test.ts | 39 ++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/packages/web3/src/codec/contract-codec.test.ts b/packages/web3/src/codec/contract-codec.test.ts index b5fe31884..61e5ceba8 100644 --- a/packages/web3/src/codec/contract-codec.test.ts +++ b/packages/web3/src/codec/contract-codec.test.ts @@ -17,7 +17,7 @@ along with the library. If not, see . */ import { Buffer } from 'buffer/' -import { Contract, Project, web3 } from '@alephium/web3' +import { Contract, Project, web3, Struct, decodeArrayType } from '@alephium/web3' import { Method } from './method-codec' import { contractCodec, toHalfDecoded } from './contract-codec' import { @@ -48,7 +48,17 @@ import { U256Lt, U256SHL } from './instr-codec' -import { Assert, Debug, MetaData, NFTTest, OwnerOnly, TokenTest, Warnings } from '../../../../artifacts/ts' +import { + Assert, + Debug, + MapTest, + MetaData, + NFTTest, + OwnerOnly, + TokenTest, + UserAccount, + Warnings +} from '../../../../artifacts/ts' describe('Encode & decode contract', function () { beforeAll(async () => { @@ -299,6 +309,8 @@ describe('Encode & decode contract', function () { testContract(MetaData.contract) testContract(Debug.contract) testContract(Assert.contract) + testContract(UserAccount.contract) + testContract(MapTest.contract) }) async function testContractCode(contractCode: string, methods: Method[]) { @@ -322,6 +334,23 @@ describe('Encode & decode contract', function () { expect(contractBytecode).toEqual(encoded.toString('hex')) } + function getTypeLength(type: string): number { + const structs = MapTest.contract.structs + const struct = structs.find((s) => s.name === type) + if (struct !== undefined) { + return struct.fieldTypes.reduce((acc, fieldType) => acc + getTypeLength(fieldType), 0) + } + if (type.startsWith('[')) { + const [baseType, size] = decodeArrayType(type) + return size * getTypeLength(baseType) + } + return 1 + } + + function getTypesLength(types: string[]): number { + return types.reduce((acc, type) => acc + getTypeLength(type), 0) + } + function testContract(contract: Contract) { const decoded = contractCodec.decode(Buffer.from(contract.bytecode, 'hex')) const encoded = contractCodec.encode(decoded) @@ -329,15 +358,15 @@ describe('Encode & decode contract', function () { const decodedContract = contractCodec.decodeContract(Buffer.from(contract.bytecode, 'hex')) expect(toHalfDecoded(decodedContract)).toEqual(decoded) - expect(decodedContract.fieldLength).toEqual(contract.fieldsExceptMaps.names.length) + expect(decodedContract.fieldLength).toEqual(getTypesLength(contract.fieldsExceptMaps.types)) decodedContract.methods.map((decodedMethod, index) => { const contractFunction = contract.functions[index] expect(decodedMethod.isPublic).toEqual(contractFunction.isPublic) expect(decodedMethod.assetModifier).toEqual( assetModifier(contractFunction.usePreapprovedAssets, contractFunction.useAssetsInContract) ) - expect(decodedMethod.argsLength).toEqual(contractFunction.paramNames.length) - expect(decodedMethod.returnLength).toEqual(contractFunction.returnTypes.length) + expect(decodedMethod.argsLength).toEqual(getTypesLength(contractFunction.paramTypes)) + expect(decodedMethod.returnLength).toEqual(getTypesLength(contractFunction.returnTypes)) }) expect(contract.bytecode).toEqual(encoded.toString('hex')) From a5b3f04b0717089e96b0eee92d19a577d88598bf Mon Sep 17 00:00:00 2001 From: lbqds Date: Thu, 28 Mar 2024 15:40:11 +0800 Subject: [PATCH 15/24] Add test to calculate field size --- packages/web3/src/contract/contract.ts | 20 +----------------- packages/web3/src/contract/ralph.test.ts | 14 ++++++++++++ packages/web3/src/contract/ralph.ts | 27 ++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/packages/web3/src/contract/contract.ts b/packages/web3/src/contract/contract.ts index 6094b0bd3..535ad0091 100644 --- a/packages/web3/src/contract/contract.ts +++ b/packages/web3/src/contract/contract.ts @@ -1859,26 +1859,8 @@ function calcWrapperContractId( return subContractId(parentContractId, path, group) } -function getFieldSize(type: string, isMutable: boolean, structs: Struct[]): { immFields: number; mutFields: number } { - const struct = structs.find((s) => s.name === type) - if (struct === undefined) { - return isMutable ? { immFields: 0, mutFields: 1 } : { immFields: 1, mutFields: 0 } - } - return struct.fieldTypes.reduce( - (acc, fieldType, index) => { - const isFieldMutable = isMutable && struct.isMutable[`${index}`] - const subFieldSize = getFieldSize(fieldType, isFieldMutable, structs) - return { - immFields: acc.immFields + subFieldSize.immFields, - mutFields: acc.mutFields + subFieldSize.mutFields - } - }, - { immFields: 0, mutFields: 0 } - ) -} - function genCodeForType(type: string, structs: Struct[]): { bytecode: string; codeHash: string } { - const { immFields, mutFields } = getFieldSize(type, true, structs) + const { immFields, mutFields } = ralph.calcFieldSize(type, true, structs) const loadImmFieldByIndex: Method = { isPublic: true, assetModifier: 0, diff --git a/packages/web3/src/contract/ralph.test.ts b/packages/web3/src/contract/ralph.test.ts index 1adca4f86..18fe44da2 100644 --- a/packages/web3/src/contract/ralph.test.ts +++ b/packages/web3/src/contract/ralph.test.ts @@ -373,6 +373,20 @@ describe('contract', function () { }) }) + it('should calc field size', () => { + const bar = new Struct('Bar', ['a', 'b'], ['U256', '[U256;2]'], [false, true]) + const foo = new Struct('Foo', ['a', 'c', 'd'], ['U256', 'ByteVec', '[Bar;2]'], [false, false, true]) + const structs = [bar, foo] + expect(ralph.calcFieldSize('Bar', false, structs)).toEqual({ immFields: 3, mutFields: 0 }) + expect(ralph.calcFieldSize('Bar', true, structs)).toEqual({ immFields: 1, mutFields: 2 }) + expect(ralph.calcFieldSize('[Bar;2]', false, structs)).toEqual({ immFields: 6, mutFields: 0 }) + expect(ralph.calcFieldSize('[Bar;2]', true, structs)).toEqual({ immFields: 2, mutFields: 4 }) + expect(ralph.calcFieldSize('Foo', false, structs)).toEqual({ immFields: 8, mutFields: 0 }) + expect(ralph.calcFieldSize('Foo', true, structs)).toEqual({ immFields: 4, mutFields: 4 }) + expect(ralph.calcFieldSize('[Foo; 2]', false, structs)).toEqual({ immFields: 16, mutFields: 0 }) + expect(ralph.calcFieldSize('[Foo; 2]', true, structs)).toEqual({ immFields: 8, mutFields: 8 }) + }) + it('should test buildScriptByteCode', () => { const variables = { x: true, y: 0x05n, z: 'ff', a: '1C2RAVWSuaXw8xtUxqVERR7ChKBE1XgscNFw73NSHE1v3' } const fieldsSig: FieldsSig = { diff --git a/packages/web3/src/contract/ralph.ts b/packages/web3/src/contract/ralph.ts index 24790dff5..bedc5e257 100644 --- a/packages/web3/src/contract/ralph.ts +++ b/packages/web3/src/contract/ralph.ts @@ -299,6 +299,33 @@ function fromAscii(str: string): string { return result } +export function calcFieldSize( + type: string, + isMutable: boolean, + structs: Struct[] +): { immFields: number; mutFields: number } { + const struct = structs.find((s) => s.name === type) + if (struct !== undefined) { + return struct.fieldTypes.reduce( + (acc, fieldType, index) => { + const isFieldMutable = isMutable && struct.isMutable[`${index}`] + const subFieldSize = calcFieldSize(fieldType, isFieldMutable, structs) + return { + immFields: acc.immFields + subFieldSize.immFields, + mutFields: acc.mutFields + subFieldSize.mutFields + } + }, + { immFields: 0, mutFields: 0 } + ) + } + if (type.startsWith('[')) { + const [baseType, size] = decodeArrayType(type) + const base = calcFieldSize(baseType, isMutable, structs) + return { immFields: base.immFields * size, mutFields: base.mutFields * size } + } + return isMutable ? { immFields: 0, mutFields: 1 } : { immFields: 1, mutFields: 0 } +} + export function tryDecodeMapDebugLog( message: string ): { path: string; mapIndex: number; encodedKey: Uint8Array; isInsert: boolean } | undefined { From 90dfc4a4584176e9b3e18f0886b1832a29e015b0 Mon Sep 17 00:00:00 2001 From: Cheng Wang Date: Fri, 29 Mar 2024 08:02:52 +0100 Subject: [PATCH 16/24] Minor updates --- .project.json | 8 ++++---- artifacts/add/Add.ral.json | 4 ++-- artifacts/ts/Add.ts | 4 ++-- contracts/add/add.ral | 2 +- docker/docker-compose.yml | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.project.json b/.project.json index 73cd1b79e..ccfc38dc6 100644 --- a/.project.json +++ b/.project.json @@ -11,9 +11,9 @@ "infos": { "Add": { "sourceFile": "add/add.ral", - "sourceCodeHash": "65456a08b5d277114f65beda04224055eda3df8ad61d6fe5894a00af1df986c1", - "bytecodeDebugPatch": "=8+4=1-1=2-2+6c=2-2+75=37+77e010a=1+1646450726976617465=170", - "codeHashDebug": "da908c46aa94ebe533cdb16d1f5f2ba771def332ae09dda36218bba7efc2de0a", + "sourceCodeHash": "95b2d5b3755f9a00b616a8beaccf7b42da269ae57a25ec825c333395cd2a23bc", + "bytecodeDebugPatch": "=8+4=1-1=2-1=1+3=2-2+6c=37+77e010a=1+1646450726976617465=152", + "codeHashDebug": "6d87d293224fce4601a8e315e6a384aca46fdd1adab1402ffae8cc454b94a66e", "warnings": [ "The return values of the function \"Add.copyCreateSubContract\" are not used. If this is intentional, consider using anonymous variables to suppress this warning.", "No external caller check for function \"Add.createSubContract\". Please use \"checkCaller!(...)\" in the function or its callees, or disable it with \"@using(checkExternalCaller = false)\".", @@ -173,7 +173,7 @@ }, "Main": { "sourceFile": "add/add.ral", - "sourceCodeHash": "65456a08b5d277114f65beda04224055eda3df8ad61d6fe5894a00af1df986c1", + "sourceCodeHash": "95b2d5b3755f9a00b616a8beaccf7b42da269ae57a25ec825c333395cd2a23bc", "bytecodeDebugPatch": "", "codeHashDebug": "", "warnings": [ diff --git a/artifacts/add/Add.ral.json b/artifacts/add/Add.ral.json index 8f1a4d730..78efae435 100644 --- a/artifacts/add/Add.ral.json +++ b/artifacts/add/Add.ral.json @@ -1,8 +1,8 @@ { "version": "v2.11.0", "name": "Add", - "bytecode": "02040d4036405f40680100020402041600160100010200000202021605160016015f06160016015fa00016002a16012aa100a000160016010e0dce00010002010304060010130064160013016417051704160313c40de0b6b3a7640000a21601160216041605c1180102010100021600b0", - "codeHash": "733064f0cc76f1e6a9451e701d01595c78e4972c21a25323f7c5e0199fb68d8d", + "bytecode": "02040d40364056405f0100020402041600160100010200000202021605160016015f06160016015fa00016002a16012aa100a000160016010e0dce000100020103040600101300641600130164170517041603d1a21601160216041605c1180102010100021600b0", + "codeHash": "97dbb799a710b8cf8dd878e3892333657c26020014bd2f0099850a26bd39668a", "fieldsSig": { "names": [ "sub", diff --git a/artifacts/ts/Add.ts b/artifacts/ts/Add.ts index e9c1c0482..e9aa7bfa4 100644 --- a/artifacts/ts/Add.ts +++ b/artifacts/ts/Add.ts @@ -103,8 +103,8 @@ class Factory extends ContractFactory { export const Add = new Factory( Contract.fromJson( AddContractJson, - "=8+4=1-1=2-2+6c=2-2+75=37+77e010a=1+1646450726976617465=170", - "da908c46aa94ebe533cdb16d1f5f2ba771def332ae09dda36218bba7efc2de0a", + "=8+4=1-1=2-1=1+3=2-2+6c=37+77e010a=1+1646450726976617465=152", + "6d87d293224fce4601a8e315e6a384aca46fdd1adab1402ffae8cc454b94a66e", AllStructs ) ); diff --git a/contracts/add/add.ral b/contracts/add/add.ral index d167a344b..5254c4033 100644 --- a/contracts/add/add.ral +++ b/contracts/add/add.ral @@ -18,7 +18,7 @@ Contract Add(sub: Sub, mut result : U256) { @using(preapprovedAssets = true) pub fn createSubContract(a: U256, path: ByteVec, subContractId: ByteVec, payer: Address) -> () { let (immFields, mutFields) = Sub.encodeFields!(a) - copyCreateSubContract!{payer -> ALPH: 1 alph}(path, subContractId, immFields, mutFields) + copyCreateSubContract!{payer -> ALPH: minimalContractDeposit!()}(path, subContractId, immFields, mutFields) } @using(checkExternalCaller = false, assetsInContract = true) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 878642d56..e67d53ec2 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -31,7 +31,7 @@ services: condition: service_healthy alephium: - image: alephium/dev-alephium:rhone-0.2.0 + image: alephium/dev-alephium:rhone-0.3.0 restart: unless-stopped ports: - 19973:19973/tcp From cc4f3a524439f0591131a14462f387ae8f20b726 Mon Sep 17 00:00:00 2001 From: lbqds Date: Fri, 29 Mar 2024 17:33:47 +0800 Subject: [PATCH 17/24] Replace interface with type --- artifacts/ts/Add.ts | 5 ++--- artifacts/ts/Assert.ts | 1 - artifacts/ts/Debug.ts | 1 - artifacts/ts/DeprecatedNFTTest1.ts | 5 ++--- artifacts/ts/DeprecatedNFTTest2.ts | 5 ++--- artifacts/ts/DeprecatedNFTTest3.ts | 5 ++--- artifacts/ts/DeprecatedNFTTest4.ts | 5 ++--- artifacts/ts/DeprecatedNFTTest5.ts | 5 ++--- artifacts/ts/DeprecatedNFTTest6.ts | 5 ++--- artifacts/ts/DeprecatedNFTTest7.ts | 5 ++--- artifacts/ts/FakeTokenTest.ts | 5 ++--- artifacts/ts/Greeter.ts | 5 ++--- artifacts/ts/MapTest.ts | 5 ++--- artifacts/ts/MetaData.ts | 1 - artifacts/ts/NFTCollectionTest.ts | 5 ++--- artifacts/ts/NFTCollectionWithRoyaltyTest.ts | 5 ++--- artifacts/ts/NFTTest.ts | 5 ++--- artifacts/ts/OwnerOnly.ts | 5 ++--- artifacts/ts/Sub.ts | 5 ++--- artifacts/ts/TokenTest.ts | 5 ++--- artifacts/ts/UserAccount.ts | 5 ++--- artifacts/ts/Warnings.ts | 5 ++--- artifacts/ts/WrongNFTTest.ts | 5 ++--- packages/cli/src/codegen.ts | 4 ++-- 24 files changed, 42 insertions(+), 65 deletions(-) diff --git a/artifacts/ts/Add.ts b/artifacts/ts/Add.ts index e9aa7bfa4..102dd54be 100644 --- a/artifacts/ts/Add.ts +++ b/artifacts/ts/Add.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as AddContractJson } from "../add/Add.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,10 +30,10 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace AddTypes { - export interface Fields extends Record { + export type Fields = { sub: HexString; result: bigint; - } + }; export type State = ContractState; diff --git a/artifacts/ts/Assert.ts b/artifacts/ts/Assert.ts index 2829e7985..5d9d136c9 100644 --- a/artifacts/ts/Assert.ts +++ b/artifacts/ts/Assert.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as AssertContractJson } from "../test/Assert.ral.json"; import { getContractByCodeHash } from "./contracts"; diff --git a/artifacts/ts/Debug.ts b/artifacts/ts/Debug.ts index b4862c091..c6f4b5f9d 100644 --- a/artifacts/ts/Debug.ts +++ b/artifacts/ts/Debug.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as DebugContractJson } from "../test/Debug.ral.json"; import { getContractByCodeHash } from "./contracts"; diff --git a/artifacts/ts/DeprecatedNFTTest1.ts b/artifacts/ts/DeprecatedNFTTest1.ts index 797133440..9ae72fff9 100644 --- a/artifacts/ts/DeprecatedNFTTest1.ts +++ b/artifacts/ts/DeprecatedNFTTest1.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as DeprecatedNFTTest1ContractJson } from "../nft/DeprecatedNFTTest1.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,10 +30,10 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest1Types { - export interface Fields extends Record { + export type Fields = { collectionId: HexString; uri: HexString; - } + }; export type State = ContractState; diff --git a/artifacts/ts/DeprecatedNFTTest2.ts b/artifacts/ts/DeprecatedNFTTest2.ts index 6d862edf2..13cfd4225 100644 --- a/artifacts/ts/DeprecatedNFTTest2.ts +++ b/artifacts/ts/DeprecatedNFTTest2.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as DeprecatedNFTTest2ContractJson } from "../nft/DeprecatedNFTTest2.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,10 +30,10 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest2Types { - export interface Fields extends Record { + export type Fields = { collectionId: HexString; uri: HexString; - } + }; export type State = ContractState; diff --git a/artifacts/ts/DeprecatedNFTTest3.ts b/artifacts/ts/DeprecatedNFTTest3.ts index 8496b9b30..e138dcd7a 100644 --- a/artifacts/ts/DeprecatedNFTTest3.ts +++ b/artifacts/ts/DeprecatedNFTTest3.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as DeprecatedNFTTest3ContractJson } from "../nft/DeprecatedNFTTest3.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,10 +30,10 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest3Types { - export interface Fields extends Record { + export type Fields = { collectionId: HexString; uri: HexString; - } + }; export type State = ContractState; diff --git a/artifacts/ts/DeprecatedNFTTest4.ts b/artifacts/ts/DeprecatedNFTTest4.ts index 215888105..b8959bd99 100644 --- a/artifacts/ts/DeprecatedNFTTest4.ts +++ b/artifacts/ts/DeprecatedNFTTest4.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as DeprecatedNFTTest4ContractJson } from "../nft/DeprecatedNFTTest4.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,10 +30,10 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest4Types { - export interface Fields extends Record { + export type Fields = { collectionId: HexString; uri: HexString; - } + }; export type State = ContractState; diff --git a/artifacts/ts/DeprecatedNFTTest5.ts b/artifacts/ts/DeprecatedNFTTest5.ts index 47eab77d4..f65bb447c 100644 --- a/artifacts/ts/DeprecatedNFTTest5.ts +++ b/artifacts/ts/DeprecatedNFTTest5.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as DeprecatedNFTTest5ContractJson } from "../nft/DeprecatedNFTTest5.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,10 +30,10 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest5Types { - export interface Fields extends Record { + export type Fields = { collectionId: HexString; uri: HexString; - } + }; export type State = ContractState; diff --git a/artifacts/ts/DeprecatedNFTTest6.ts b/artifacts/ts/DeprecatedNFTTest6.ts index d45657681..36730e76b 100644 --- a/artifacts/ts/DeprecatedNFTTest6.ts +++ b/artifacts/ts/DeprecatedNFTTest6.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as DeprecatedNFTTest6ContractJson } from "../nft/DeprecatedNFTTest6.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,10 +30,10 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest6Types { - export interface Fields extends Record { + export type Fields = { collectionId: HexString; uri: HexString; - } + }; export type State = ContractState; diff --git a/artifacts/ts/DeprecatedNFTTest7.ts b/artifacts/ts/DeprecatedNFTTest7.ts index 913583d88..0f016bb97 100644 --- a/artifacts/ts/DeprecatedNFTTest7.ts +++ b/artifacts/ts/DeprecatedNFTTest7.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as DeprecatedNFTTest7ContractJson } from "../nft/DeprecatedNFTTest7.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,10 +30,10 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace DeprecatedNFTTest7Types { - export interface Fields extends Record { + export type Fields = { collectionId: HexString; uri: HexString; - } + }; export type State = ContractState; diff --git a/artifacts/ts/FakeTokenTest.ts b/artifacts/ts/FakeTokenTest.ts index 55bbda383..ada739135 100644 --- a/artifacts/ts/FakeTokenTest.ts +++ b/artifacts/ts/FakeTokenTest.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as FakeTokenTestContractJson } from "../token/FakeTokenTest.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,9 +30,9 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace FakeTokenTestTypes { - export interface Fields extends Record { + export type Fields = { a: bigint; - } + }; export type State = ContractState; diff --git a/artifacts/ts/Greeter.ts b/artifacts/ts/Greeter.ts index e3d31fd84..4b32ff866 100644 --- a/artifacts/ts/Greeter.ts +++ b/artifacts/ts/Greeter.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as GreeterContractJson } from "../greeter/Greeter.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,7 +30,7 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace GreeterTypes { - export interface Fields extends Record { + export type Fields = { btcPrice: bigint; array0: [[bigint, bigint], [bigint, bigint], [bigint, bigint]]; array1: [[boolean, boolean], [boolean, boolean], [boolean, boolean]]; @@ -41,7 +40,7 @@ export namespace GreeterTypes { [HexString, HexString] ]; array3: [[Address, Address], [Address, Address], [Address, Address]]; - } + }; export type State = ContractState; diff --git a/artifacts/ts/MapTest.ts b/artifacts/ts/MapTest.ts index 53a404570..e864c4ef3 100644 --- a/artifacts/ts/MapTest.ts +++ b/artifacts/ts/MapTest.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as MapTestContractJson } from "../test/MapTest.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,10 +30,10 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace MapTestTypes { - export interface Fields extends Record { + export type Fields = { a: bigint; b: bigint; - } + }; export type State = ContractState; diff --git a/artifacts/ts/MetaData.ts b/artifacts/ts/MetaData.ts index 85f848098..00c90529c 100644 --- a/artifacts/ts/MetaData.ts +++ b/artifacts/ts/MetaData.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as MetaDataContractJson } from "../test/MetaData.ral.json"; import { getContractByCodeHash } from "./contracts"; diff --git a/artifacts/ts/NFTCollectionTest.ts b/artifacts/ts/NFTCollectionTest.ts index b5c53ebb7..b7dfb29d8 100644 --- a/artifacts/ts/NFTCollectionTest.ts +++ b/artifacts/ts/NFTCollectionTest.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as NFTCollectionTestContractJson } from "../nft/NFTCollectionTest.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,11 +30,11 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace NFTCollectionTestTypes { - export interface Fields extends Record { + export type Fields = { nftTemplateId: HexString; collectionUri: HexString; totalSupply: bigint; - } + }; export type State = ContractState; diff --git a/artifacts/ts/NFTCollectionWithRoyaltyTest.ts b/artifacts/ts/NFTCollectionWithRoyaltyTest.ts index cc9d3dcac..61f9e5408 100644 --- a/artifacts/ts/NFTCollectionWithRoyaltyTest.ts +++ b/artifacts/ts/NFTCollectionWithRoyaltyTest.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as NFTCollectionWithRoyaltyTestContractJson } from "../nft/NFTCollectionWithRoyaltyTest.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,13 +30,13 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace NFTCollectionWithRoyaltyTestTypes { - export interface Fields extends Record { + export type Fields = { nftTemplateId: HexString; collectionUri: HexString; collectionOwner: Address; royaltyRate: bigint; totalSupply: bigint; - } + }; export type State = ContractState; diff --git a/artifacts/ts/NFTTest.ts b/artifacts/ts/NFTTest.ts index f280e485e..39da094f8 100644 --- a/artifacts/ts/NFTTest.ts +++ b/artifacts/ts/NFTTest.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as NFTTestContractJson } from "../nft/NFTTest.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,11 +30,11 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace NFTTestTypes { - export interface Fields extends Record { + export type Fields = { collectionId: HexString; nftIndex: bigint; uri: HexString; - } + }; export type State = ContractState; diff --git a/artifacts/ts/OwnerOnly.ts b/artifacts/ts/OwnerOnly.ts index 0e6093d08..76559fb14 100644 --- a/artifacts/ts/OwnerOnly.ts +++ b/artifacts/ts/OwnerOnly.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as OwnerOnlyContractJson } from "../test/OwnerOnly.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,9 +30,9 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace OwnerOnlyTypes { - export interface Fields extends Record { + export type Fields = { owner: Address; - } + }; export type State = ContractState; } diff --git a/artifacts/ts/Sub.ts b/artifacts/ts/Sub.ts index 182e8a9b2..9146aaf25 100644 --- a/artifacts/ts/Sub.ts +++ b/artifacts/ts/Sub.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as SubContractJson } from "../sub/Sub.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,9 +30,9 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace SubTypes { - export interface Fields extends Record { + export type Fields = { result: bigint; - } + }; export type State = ContractState; diff --git a/artifacts/ts/TokenTest.ts b/artifacts/ts/TokenTest.ts index c778de173..a4aac3e8f 100644 --- a/artifacts/ts/TokenTest.ts +++ b/artifacts/ts/TokenTest.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as TokenTestContractJson } from "../token/TokenTest.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,12 +30,12 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace TokenTestTypes { - export interface Fields extends Record { + export type Fields = { symbol: HexString; name: HexString; decimals: bigint; totalSupply: bigint; - } + }; export type State = ContractState; diff --git a/artifacts/ts/UserAccount.ts b/artifacts/ts/UserAccount.ts index a953e1453..e6c934fad 100644 --- a/artifacts/ts/UserAccount.ts +++ b/artifacts/ts/UserAccount.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as UserAccountContractJson } from "../test/UserAccount.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,12 +30,12 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace UserAccountTypes { - export interface Fields extends Record { + export type Fields = { id: HexString; address: Address; balances: Balances; name: HexString; - } + }; export type State = ContractState; diff --git a/artifacts/ts/Warnings.ts b/artifacts/ts/Warnings.ts index 108fa4381..778f66848 100644 --- a/artifacts/ts/Warnings.ts +++ b/artifacts/ts/Warnings.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as WarningsContractJson } from "../test/Warnings.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,10 +30,10 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace WarningsTypes { - export interface Fields extends Record { + export type Fields = { a: bigint; b: bigint; - } + }; export type State = ContractState; } diff --git a/artifacts/ts/WrongNFTTest.ts b/artifacts/ts/WrongNFTTest.ts index f8502a96b..f1e8e624a 100644 --- a/artifacts/ts/WrongNFTTest.ts +++ b/artifacts/ts/WrongNFTTest.ts @@ -23,7 +23,6 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, - Val, } from "@alephium/web3"; import { default as WrongNFTTestContractJson } from "../nft/WrongNFTTest.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -31,11 +30,11 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace WrongNFTTestTypes { - export interface Fields extends Record { + export type Fields = { collectionId: HexString; nftIndex: bigint; uri: HexString; - } + }; export type State = ContractState; diff --git a/packages/cli/src/codegen.ts b/packages/cli/src/codegen.ts index 92f753685..3fb9927ca 100644 --- a/packages/cli/src/codegen.ts +++ b/packages/cli/src/codegen.ts @@ -258,7 +258,7 @@ function genContractStateType(contract: Contract): string { return `export type State = Omit, 'fields'>` } return ` - export interface Fields extends Record { + export type Fields = { ${formatParameters(contract.fieldsExceptMaps)} } @@ -411,7 +411,7 @@ function genContract(contract: Contract, artifactRelativePath: string): string { EventSubscribeOptions, EventSubscription, CallContractParams, CallContractResult, TestContractParams, ContractEvent, subscribeContractEvent, subscribeContractEvents, testMethod, callMethod, multicallMethods, fetchContractState, - ContractInstance, getContractEventsCurrentCount, Val + ContractInstance, getContractEventsCurrentCount } from '@alephium/web3' import { default as ${contract.name}ContractJson } from '../${toUnixPath(artifactRelativePath)}' import { getContractByCodeHash } from './contracts' From ba10ebba46a0fbba5909e3e86dc28c9a89fc33be Mon Sep 17 00:00:00 2001 From: lbqds Date: Fri, 29 Mar 2024 20:46:33 +0800 Subject: [PATCH 18/24] Replace map contract fields with global map vars --- .project.json | 12 +-- artifacts/add/Add.ral.json | 1 + artifacts/greeter/Greeter.ral.json | 1 + artifacts/nft/DeprecatedNFTTest1.ral.json | 1 + artifacts/nft/DeprecatedNFTTest2.ral.json | 1 + artifacts/nft/DeprecatedNFTTest3.ral.json | 1 + artifacts/nft/DeprecatedNFTTest4.ral.json | 1 + artifacts/nft/DeprecatedNFTTest5.ral.json | 1 + artifacts/nft/DeprecatedNFTTest6.ral.json | 1 + artifacts/nft/DeprecatedNFTTest7.ral.json | 1 + artifacts/nft/NFTCollectionTest.ral.json | 1 + .../nft/NFTCollectionWithRoyaltyTest.ral.json | 1 + artifacts/nft/NFTTest.ral.json | 1 + artifacts/nft/WrongNFTTest.ral.json | 1 + artifacts/sub/Sub.ral.json | 1 + artifacts/test/Assert.ral.json | 1 + artifacts/test/Debug.ral.json | 1 + artifacts/test/MapTest.ral.json | 35 +++---- artifacts/test/MetaData.ral.json | 1 + artifacts/test/OwnerOnly.ral.json | 1 + artifacts/test/UserAccount.ral.json | 1 + artifacts/test/Warnings.ral.json | 1 + artifacts/token/FakeTokenTest.ral.json | 1 + artifacts/token/TokenTest.ral.json | 1 + artifacts/ts/Add.ts | 22 ++++- artifacts/ts/Assert.ts | 2 +- artifacts/ts/Debug.ts | 2 +- artifacts/ts/DeprecatedNFTTest1.ts | 2 +- artifacts/ts/DeprecatedNFTTest2.ts | 4 +- artifacts/ts/DeprecatedNFTTest3.ts | 4 +- artifacts/ts/DeprecatedNFTTest4.ts | 4 +- artifacts/ts/DeprecatedNFTTest5.ts | 4 +- artifacts/ts/DeprecatedNFTTest6.ts | 4 +- artifacts/ts/DeprecatedNFTTest7.ts | 4 +- artifacts/ts/FakeTokenTest.ts | 10 +- artifacts/ts/Greeter.ts | 5 +- artifacts/ts/MapTest.ts | 80 +++++++-------- artifacts/ts/MetaData.ts | 6 +- artifacts/ts/NFTCollectionTest.ts | 13 ++- artifacts/ts/NFTCollectionWithRoyaltyTest.ts | 22 +++-- artifacts/ts/NFTTest.ts | 10 +- artifacts/ts/OwnerOnly.ts | 5 +- artifacts/ts/Sub.ts | 6 +- artifacts/ts/TokenTest.ts | 20 +++- artifacts/ts/UserAccount.ts | 8 +- artifacts/ts/Warnings.ts | 6 +- artifacts/ts/WrongNFTTest.ts | 4 +- contracts/test/map.ral | 5 +- packages/cli/src/codegen.ts | 46 ++++----- packages/web3/src/api/api-alephium.ts | 6 ++ packages/web3/src/contract/contract.ts | 98 ++++++++++--------- test/contract.test.ts | 27 ++--- 52 files changed, 286 insertions(+), 212 deletions(-) diff --git a/.project.json b/.project.json index ccfc38dc6..da324bcdc 100644 --- a/.project.json +++ b/.project.json @@ -166,7 +166,7 @@ }, "InsertIntoMap": { "sourceFile": "test/map.ral", - "sourceCodeHash": "1c3c388ac6c847f24971466d6a1385398a8ce7cb8bb6ee5275e3d01e8d69deb5", + "sourceCodeHash": "b82412a32b7acab72adc262504937fe2c101f2f74a29a5a61444a2c6b95f0557", "bytecodeDebugPatch": "", "codeHashDebug": "", "warnings": [] @@ -182,16 +182,16 @@ }, "MapTest": { "sourceFile": "test/map.ral", - "sourceCodeHash": "1c3c388ac6c847f24971466d6a1385398a8ce7cb8bb6ee5275e3d01e8d69deb5", + "sourceCodeHash": "b82412a32b7acab72adc262504937fe2c101f2f74a29a5a61444a2c6b95f0557", "bytecodeDebugPatch": "=6-1+4=3-1+a=2-2+11=3-1+3=3-1+5=12-1+b=40+7a037e0300012c00=56+7a037e0300012c00=217-1+a=114+7a047e0300012c00=46+7a047e0300012c00=136", - "codeHashDebug": "23c1ab39042b459d30f531ad31f52620ec5c1bd8a9142d2c3c2fd27d72ce1370", + "codeHashDebug": "76d94621028b765345f083b3d7124c355a7fd8ca45e9253fc2661102f5533d11", "warnings": [ "No external caller check for function \"MapTest.insert\". Please use \"checkCaller!(...)\" in the function or its callees, or disable it with \"@using(checkExternalCaller = false)\"." ] }, "MapValue": { "sourceFile": "test/map.ral", - "sourceCodeHash": "1c3c388ac6c847f24971466d6a1385398a8ce7cb8bb6ee5275e3d01e8d69deb5", + "sourceCodeHash": "b82412a32b7acab72adc262504937fe2c101f2f74a29a5a61444a2c6b95f0557", "bytecodeDebugPatch": "", "codeHashDebug": "", "warnings": [] @@ -258,7 +258,7 @@ }, "RemoveFromMap": { "sourceFile": "test/map.ral", - "sourceCodeHash": "1c3c388ac6c847f24971466d6a1385398a8ce7cb8bb6ee5275e3d01e8d69deb5", + "sourceCodeHash": "b82412a32b7acab72adc262504937fe2c101f2f74a29a5a61444a2c6b95f0557", "bytecodeDebugPatch": "", "codeHashDebug": "", "warnings": [] @@ -293,7 +293,7 @@ }, "UpdateMapValue": { "sourceFile": "test/map.ral", - "sourceCodeHash": "1c3c388ac6c847f24971466d6a1385398a8ce7cb8bb6ee5275e3d01e8d69deb5", + "sourceCodeHash": "b82412a32b7acab72adc262504937fe2c101f2f74a29a5a61444a2c6b95f0557", "bytecodeDebugPatch": "", "codeHashDebug": "", "warnings": [] diff --git a/artifacts/add/Add.ral.json b/artifacts/add/Add.ral.json index 78efae435..b29df2a96 100644 --- a/artifacts/add/Add.ral.json +++ b/artifacts/add/Add.ral.json @@ -17,6 +17,7 @@ true ] }, + "mapsSig": [], "eventsSig": [ { "name": "Add", diff --git a/artifacts/greeter/Greeter.ral.json b/artifacts/greeter/Greeter.ral.json index 8b5318a93..f75cc3bc6 100644 --- a/artifacts/greeter/Greeter.ral.json +++ b/artifacts/greeter/Greeter.ral.json @@ -26,6 +26,7 @@ false ] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/DeprecatedNFTTest1.ral.json b/artifacts/nft/DeprecatedNFTTest1.ral.json index 0dcf655b4..00b587eef 100644 --- a/artifacts/nft/DeprecatedNFTTest1.ral.json +++ b/artifacts/nft/DeprecatedNFTTest1.ral.json @@ -17,6 +17,7 @@ false ] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/DeprecatedNFTTest2.ral.json b/artifacts/nft/DeprecatedNFTTest2.ral.json index 02d91d992..f2d849230 100644 --- a/artifacts/nft/DeprecatedNFTTest2.ral.json +++ b/artifacts/nft/DeprecatedNFTTest2.ral.json @@ -17,6 +17,7 @@ false ] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/DeprecatedNFTTest3.ral.json b/artifacts/nft/DeprecatedNFTTest3.ral.json index b4aa0a277..b59cea791 100644 --- a/artifacts/nft/DeprecatedNFTTest3.ral.json +++ b/artifacts/nft/DeprecatedNFTTest3.ral.json @@ -17,6 +17,7 @@ false ] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/DeprecatedNFTTest4.ral.json b/artifacts/nft/DeprecatedNFTTest4.ral.json index baf8e9a5e..4d583fcd7 100644 --- a/artifacts/nft/DeprecatedNFTTest4.ral.json +++ b/artifacts/nft/DeprecatedNFTTest4.ral.json @@ -17,6 +17,7 @@ false ] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/DeprecatedNFTTest5.ral.json b/artifacts/nft/DeprecatedNFTTest5.ral.json index 59df47ca2..f90ebc9c9 100644 --- a/artifacts/nft/DeprecatedNFTTest5.ral.json +++ b/artifacts/nft/DeprecatedNFTTest5.ral.json @@ -17,6 +17,7 @@ false ] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/DeprecatedNFTTest6.ral.json b/artifacts/nft/DeprecatedNFTTest6.ral.json index ad622c1f6..5c5b26d54 100644 --- a/artifacts/nft/DeprecatedNFTTest6.ral.json +++ b/artifacts/nft/DeprecatedNFTTest6.ral.json @@ -17,6 +17,7 @@ false ] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/DeprecatedNFTTest7.ral.json b/artifacts/nft/DeprecatedNFTTest7.ral.json index 13371e495..be5345d59 100644 --- a/artifacts/nft/DeprecatedNFTTest7.ral.json +++ b/artifacts/nft/DeprecatedNFTTest7.ral.json @@ -17,6 +17,7 @@ false ] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/NFTCollectionTest.ral.json b/artifacts/nft/NFTCollectionTest.ral.json index 926795741..20325fa42 100644 --- a/artifacts/nft/NFTCollectionTest.ral.json +++ b/artifacts/nft/NFTCollectionTest.ral.json @@ -23,6 +23,7 @@ false ] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/NFTCollectionWithRoyaltyTest.ral.json b/artifacts/nft/NFTCollectionWithRoyaltyTest.ral.json index 505ede5d4..98819f725 100644 --- a/artifacts/nft/NFTCollectionWithRoyaltyTest.ral.json +++ b/artifacts/nft/NFTCollectionWithRoyaltyTest.ral.json @@ -29,6 +29,7 @@ false ] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/NFTTest.ral.json b/artifacts/nft/NFTTest.ral.json index 45538f024..aa6c5dd21 100644 --- a/artifacts/nft/NFTTest.ral.json +++ b/artifacts/nft/NFTTest.ral.json @@ -23,6 +23,7 @@ false ] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/WrongNFTTest.ral.json b/artifacts/nft/WrongNFTTest.ral.json index a9038be4d..fac884cbb 100644 --- a/artifacts/nft/WrongNFTTest.ral.json +++ b/artifacts/nft/WrongNFTTest.ral.json @@ -23,6 +23,7 @@ false ] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/sub/Sub.ral.json b/artifacts/sub/Sub.ral.json index d2500f4d2..8813fbc1d 100644 --- a/artifacts/sub/Sub.ral.json +++ b/artifacts/sub/Sub.ral.json @@ -14,6 +14,7 @@ true ] }, + "mapsSig": [], "eventsSig": [ { "name": "Sub", diff --git a/artifacts/test/Assert.ral.json b/artifacts/test/Assert.ral.json index 413c3bf28..fcb30d264 100644 --- a/artifacts/test/Assert.ral.json +++ b/artifacts/test/Assert.ral.json @@ -8,6 +8,7 @@ "types": [], "isMutable": [] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/test/Debug.ral.json b/artifacts/test/Debug.ral.json index dd7e4aa30..68641ee77 100644 --- a/artifacts/test/Debug.ral.json +++ b/artifacts/test/Debug.ral.json @@ -8,6 +8,7 @@ "types": [], "isMutable": [] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/test/MapTest.ral.json b/artifacts/test/MapTest.ral.json index bf0718e57..2a90d0dd5 100644 --- a/artifacts/test/MapTest.ral.json +++ b/artifacts/test/MapTest.ral.json @@ -1,28 +1,23 @@ { "version": "v2.11.0", "name": "MapTest", - "bytecode": "0205403c409c40f6411e41370103030300151600d1a2140a5f5f6d61705f5f305f5f160047441601b11602d202011600d1a2140a5f5f6d61705f5f315f5f16014044b11602d201010100010400402a0c0d0d140a5f5f6d61705f5f305f5f16004744cb1703160301000c0d0d160301011702170116020d2a0c0e0c140a5f5f6d61705f5f305f5f16004744cb010216020d2a0c0e0c140a5f5f6d61705f5f315f5f16014044cb0102010001040040240c0d0d140a5f5f6d61705f5f305f5f16004744cb1703160301000c0d0d160301011702170116000d0c140a5f5f6d61705f5f305f5f16004744cb010316000d0c140a5f5f6d61705f5f315f5f16014044cb01030100010202110c0d0d140a5f5f6d61705f5f305f5f16004744cb1701160101000c0d0d1601010102010001010107140a5f5f6d61705f5f305f5f16004744cbc502", - "codeHash": "bbf8f1adaea6623d50dbf589c2400da85d1fa2fc57f568810bf161060c2d9b8b", + "bytecode": "0005403c409c40f6411e41370103030300151600d1a2140a5f5f6d61705f5f305f5f160047441601b11602d202011600d1a2140a5f5f6d61705f5f315f5f16014044b11602d201010100010400402a0c0d0d140a5f5f6d61705f5f305f5f16004744cb1703160301000c0d0d160301011702170116020d2a0c0e0c140a5f5f6d61705f5f305f5f16004744cb010216020d2a0c0e0c140a5f5f6d61705f5f315f5f16014044cb0102010001040040240c0d0d140a5f5f6d61705f5f305f5f16004744cb1703160301000c0d0d160301011702170116000d0c140a5f5f6d61705f5f305f5f16004744cb010316000d0c140a5f5f6d61705f5f315f5f16014044cb01030100010202110c0d0d140a5f5f6d61705f5f305f5f16004744cb1701160101000c0d0d1601010102010001010107140a5f5f6d61705f5f305f5f16004744cbc502", + "codeHash": "9ff6f47837ee2d8f2cb22fe5cfeb05f64d42915aa8b30dbb96783f3e99c363f6", "fieldsSig": { - "names": [ - "a", - "b", - "map0", - "map1" - ], - "types": [ - "U256", - "U256", - "Map[Address,MapValue]", - "Map[U256,U256]" - ], - "isMutable": [ - true, - false, - true, - true - ] + "names": [], + "types": [], + "isMutable": [] }, + "mapsSig": [ + { + "name": "map0", + "type": "Map[Address,MapValue]" + }, + { + "name": "map1", + "type": "Map[U256,U256]" + } + ], "eventsSig": [], "functions": [ { diff --git a/artifacts/test/MetaData.ral.json b/artifacts/test/MetaData.ral.json index 9602d0382..0d4ed55d5 100644 --- a/artifacts/test/MetaData.ral.json +++ b/artifacts/test/MetaData.ral.json @@ -8,6 +8,7 @@ "types": [], "isMutable": [] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/test/OwnerOnly.ral.json b/artifacts/test/OwnerOnly.ral.json index 017cff9dd..3c33bf8a0 100644 --- a/artifacts/test/OwnerOnly.ral.json +++ b/artifacts/test/OwnerOnly.ral.json @@ -14,6 +14,7 @@ false ] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/test/UserAccount.ral.json b/artifacts/test/UserAccount.ral.json index 03217c596..00dbfbca5 100644 --- a/artifacts/test/UserAccount.ral.json +++ b/artifacts/test/UserAccount.ral.json @@ -23,6 +23,7 @@ false ] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/test/Warnings.ral.json b/artifacts/test/Warnings.ral.json index 09a550d7f..53702acd5 100644 --- a/artifacts/test/Warnings.ral.json +++ b/artifacts/test/Warnings.ral.json @@ -17,6 +17,7 @@ false ] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/token/FakeTokenTest.ral.json b/artifacts/token/FakeTokenTest.ral.json index 626cfa353..ec0e68ef2 100644 --- a/artifacts/token/FakeTokenTest.ral.json +++ b/artifacts/token/FakeTokenTest.ral.json @@ -14,6 +14,7 @@ false ] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/token/TokenTest.ral.json b/artifacts/token/TokenTest.ral.json index ea72fb647..b98845da0 100644 --- a/artifacts/token/TokenTest.ral.json +++ b/artifacts/token/TokenTest.ral.json @@ -26,6 +26,7 @@ false ] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/ts/Add.ts b/artifacts/ts/Add.ts index 102dd54be..83d5957df 100644 --- a/artifacts/ts/Add.ts +++ b/artifacts/ts/Add.ts @@ -73,25 +73,39 @@ class Factory extends ContractFactory { tests = { add: async ( - params: TestContractParams + params: TestContractParams< + AddTypes.Fields, + { array: [bigint, bigint] }, + {} + > ): Promise> => { return testMethod(this, "add", params); }, addPrivate: async ( - params: TestContractParams + params: TestContractParams< + AddTypes.Fields, + { array: [bigint, bigint] }, + {} + > ): Promise> => { return testMethod(this, "addPrivate", params); }, createSubContract: async ( params: TestContractParams< AddTypes.Fields, - { a: bigint; path: HexString; subContractId: HexString; payer: Address } + { + a: bigint; + path: HexString; + subContractId: HexString; + payer: Address; + }, + {} > ): Promise> => { return testMethod(this, "createSubContract", params); }, destroy: async ( - params: TestContractParams + params: TestContractParams ): Promise> => { return testMethod(this, "destroy", params); }, diff --git a/artifacts/ts/Assert.ts b/artifacts/ts/Assert.ts index 5d9d136c9..9f8a8efa7 100644 --- a/artifacts/ts/Assert.ts +++ b/artifacts/ts/Assert.ts @@ -54,7 +54,7 @@ class Factory extends ContractFactory { tests = { test: async ( params?: Omit< - TestContractParams, + TestContractParams, "testArgs" | "initialFields" > ): Promise> => { diff --git a/artifacts/ts/Debug.ts b/artifacts/ts/Debug.ts index c6f4b5f9d..b0597071b 100644 --- a/artifacts/ts/Debug.ts +++ b/artifacts/ts/Debug.ts @@ -41,7 +41,7 @@ class Factory extends ContractFactory { tests = { debug: async ( params?: Omit< - TestContractParams, + TestContractParams, "testArgs" | "initialFields" > ): Promise> => { diff --git a/artifacts/ts/DeprecatedNFTTest1.ts b/artifacts/ts/DeprecatedNFTTest1.ts index 9ae72fff9..15d352c03 100644 --- a/artifacts/ts/DeprecatedNFTTest1.ts +++ b/artifacts/ts/DeprecatedNFTTest1.ts @@ -72,7 +72,7 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { diff --git a/artifacts/ts/DeprecatedNFTTest2.ts b/artifacts/ts/DeprecatedNFTTest2.ts index 13cfd4225..7c7de7765 100644 --- a/artifacts/ts/DeprecatedNFTTest2.ts +++ b/artifacts/ts/DeprecatedNFTTest2.ts @@ -76,7 +76,7 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { @@ -84,7 +84,7 @@ class Factory extends ContractFactory< }, getCollectionId: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { diff --git a/artifacts/ts/DeprecatedNFTTest3.ts b/artifacts/ts/DeprecatedNFTTest3.ts index e138dcd7a..e2cc81314 100644 --- a/artifacts/ts/DeprecatedNFTTest3.ts +++ b/artifacts/ts/DeprecatedNFTTest3.ts @@ -72,7 +72,7 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { @@ -80,7 +80,7 @@ class Factory extends ContractFactory< }, returnNothing: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { diff --git a/artifacts/ts/DeprecatedNFTTest4.ts b/artifacts/ts/DeprecatedNFTTest4.ts index b8959bd99..f75f1a71f 100644 --- a/artifacts/ts/DeprecatedNFTTest4.ts +++ b/artifacts/ts/DeprecatedNFTTest4.ts @@ -76,7 +76,7 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { @@ -84,7 +84,7 @@ class Factory extends ContractFactory< }, getBool: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { diff --git a/artifacts/ts/DeprecatedNFTTest5.ts b/artifacts/ts/DeprecatedNFTTest5.ts index f65bb447c..5dd8fe38f 100644 --- a/artifacts/ts/DeprecatedNFTTest5.ts +++ b/artifacts/ts/DeprecatedNFTTest5.ts @@ -76,7 +76,7 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { @@ -84,7 +84,7 @@ class Factory extends ContractFactory< }, returnMoreValues: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { diff --git a/artifacts/ts/DeprecatedNFTTest6.ts b/artifacts/ts/DeprecatedNFTTest6.ts index 36730e76b..35905d02f 100644 --- a/artifacts/ts/DeprecatedNFTTest6.ts +++ b/artifacts/ts/DeprecatedNFTTest6.ts @@ -76,7 +76,7 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { @@ -84,7 +84,7 @@ class Factory extends ContractFactory< }, getArray: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { diff --git a/artifacts/ts/DeprecatedNFTTest7.ts b/artifacts/ts/DeprecatedNFTTest7.ts index 0f016bb97..b265e8479 100644 --- a/artifacts/ts/DeprecatedNFTTest7.ts +++ b/artifacts/ts/DeprecatedNFTTest7.ts @@ -76,7 +76,7 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { @@ -84,7 +84,7 @@ class Factory extends ContractFactory< }, returnNegativeIndex: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { diff --git a/artifacts/ts/FakeTokenTest.ts b/artifacts/ts/FakeTokenTest.ts index ada739135..e85835fb3 100644 --- a/artifacts/ts/FakeTokenTest.ts +++ b/artifacts/ts/FakeTokenTest.ts @@ -83,7 +83,7 @@ class Factory extends ContractFactory< tests = { getSymbol: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { @@ -91,7 +91,7 @@ class Factory extends ContractFactory< }, getName: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { @@ -99,7 +99,7 @@ class Factory extends ContractFactory< }, getDecimals: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { @@ -107,7 +107,7 @@ class Factory extends ContractFactory< }, getTotalSupply: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { @@ -115,7 +115,7 @@ class Factory extends ContractFactory< }, foo: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { diff --git a/artifacts/ts/Greeter.ts b/artifacts/ts/Greeter.ts index 4b32ff866..c8907998b 100644 --- a/artifacts/ts/Greeter.ts +++ b/artifacts/ts/Greeter.ts @@ -75,7 +75,10 @@ class Factory extends ContractFactory { tests = { greet: async ( - params: Omit, "testArgs"> + params: Omit< + TestContractParams, + "testArgs" + > ): Promise> => { return testMethod(this, "greet", params); }, diff --git a/artifacts/ts/MapTest.ts b/artifacts/ts/MapTest.ts index e864c4ef3..4bac0717c 100644 --- a/artifacts/ts/MapTest.ts +++ b/artifacts/ts/MapTest.ts @@ -30,12 +30,7 @@ import { Balances, MapValue, TokenBalance, AllStructs } from "./types"; // Custom types for the contract export namespace MapTestTypes { - export type Fields = { - a: bigint; - b: bigint; - }; - - export type State = ContractState; + export type State = Omit, "fields">; export interface CallMethodTable { get: { @@ -61,23 +56,20 @@ export namespace MapTestTypes { }; } -class Factory extends ContractFactory { - getInitialFieldsWithDefaultValues() { - return this.contract.getInitialFieldsWithDefaultValues() as MapTestTypes.Fields; - } - +class Factory extends ContractFactory { at(address: string): MapTestInstance { return new MapTestInstance(address); } tests = { insert: async ( - params: TestContractParams< - MapTestTypes.Fields & { - map0?: Map; - map1?: Map; - }, - { key: Address; value: MapValue } + params: Omit< + TestContractParams< + never, + { key: Address; value: MapValue }, + { map0?: Map; map1?: Map } + >, + "initialFields" > ): Promise< TestContractResult< @@ -88,12 +80,13 @@ class Factory extends ContractFactory { return testMethod(this, "insert", params); }, update: async ( - params: TestContractParams< - MapTestTypes.Fields & { - map0?: Map; - map1?: Map; - }, - { key: Address } + params: Omit< + TestContractParams< + never, + { key: Address }, + { map0?: Map; map1?: Map } + >, + "initialFields" > ): Promise< TestContractResult< @@ -104,12 +97,13 @@ class Factory extends ContractFactory { return testMethod(this, "update", params); }, remove: async ( - params: TestContractParams< - MapTestTypes.Fields & { - map0?: Map; - map1?: Map; - }, - { key: Address } + params: Omit< + TestContractParams< + never, + { key: Address }, + { map0?: Map; map1?: Map } + >, + "initialFields" > ): Promise< TestContractResult< @@ -120,12 +114,13 @@ class Factory extends ContractFactory { return testMethod(this, "remove", params); }, get: async ( - params: TestContractParams< - MapTestTypes.Fields & { - map0?: Map; - map1?: Map; - }, - { key: Address } + params: Omit< + TestContractParams< + never, + { key: Address }, + { map0?: Map; map1?: Map } + >, + "initialFields" > ): Promise< TestContractResult< @@ -136,12 +131,13 @@ class Factory extends ContractFactory { return testMethod(this, "get", params); }, contains: async ( - params: TestContractParams< - MapTestTypes.Fields & { - map0?: Map; - map1?: Map; - }, - { key: Address } + params: Omit< + TestContractParams< + never, + { key: Address }, + { map0?: Map; map1?: Map } + >, + "initialFields" > ): Promise< TestContractResult< @@ -159,7 +155,7 @@ export const MapTest = new Factory( Contract.fromJson( MapTestContractJson, "=6-1+4=3-1+a=2-2+11=3-1+3=3-1+5=12-1+b=40+7a037e0300012c00=56+7a037e0300012c00=217-1+a=114+7a047e0300012c00=46+7a047e0300012c00=136", - "23c1ab39042b459d30f531ad31f52620ec5c1bd8a9142d2c3c2fd27d72ce1370", + "76d94621028b765345f083b3d7124c355a7fd8ca45e9253fc2661102f5533d11", AllStructs ) ); diff --git a/artifacts/ts/MetaData.ts b/artifacts/ts/MetaData.ts index 00c90529c..1d3233c6f 100644 --- a/artifacts/ts/MetaData.ts +++ b/artifacts/ts/MetaData.ts @@ -41,7 +41,7 @@ class Factory extends ContractFactory { tests = { foo: async ( params?: Omit< - TestContractParams, + TestContractParams, "testArgs" | "initialFields" > ): Promise> => { @@ -49,7 +49,7 @@ class Factory extends ContractFactory { }, bar: async ( params?: Omit< - TestContractParams, + TestContractParams, "testArgs" | "initialFields" > ): Promise> => { @@ -57,7 +57,7 @@ class Factory extends ContractFactory { }, baz: async ( params?: Omit< - TestContractParams, + TestContractParams, "testArgs" | "initialFields" > ): Promise> => { diff --git a/artifacts/ts/NFTCollectionTest.ts b/artifacts/ts/NFTCollectionTest.ts index b7dfb29d8..be9cc83bc 100644 --- a/artifacts/ts/NFTCollectionTest.ts +++ b/artifacts/ts/NFTCollectionTest.ts @@ -93,7 +93,7 @@ class Factory extends ContractFactory< tests = { getCollectionUri: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { @@ -101,7 +101,7 @@ class Factory extends ContractFactory< }, totalSupply: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { @@ -110,7 +110,8 @@ class Factory extends ContractFactory< nftByIndex: async ( params: TestContractParams< NFTCollectionTestTypes.Fields, - { index: bigint } + { index: bigint }, + {} > ): Promise> => { return testMethod(this, "nftByIndex", params); @@ -118,7 +119,8 @@ class Factory extends ContractFactory< validateNFT: async ( params: TestContractParams< NFTCollectionTestTypes.Fields, - { nftId: HexString; nftIndex: bigint } + { nftId: HexString; nftIndex: bigint }, + {} > ): Promise> => { return testMethod(this, "validateNFT", params); @@ -126,7 +128,8 @@ class Factory extends ContractFactory< mint: async ( params: TestContractParams< NFTCollectionTestTypes.Fields, - { nftUri: HexString } + { nftUri: HexString }, + {} > ): Promise> => { return testMethod(this, "mint", params); diff --git a/artifacts/ts/NFTCollectionWithRoyaltyTest.ts b/artifacts/ts/NFTCollectionWithRoyaltyTest.ts index 61f9e5408..424ab4a81 100644 --- a/artifacts/ts/NFTCollectionWithRoyaltyTest.ts +++ b/artifacts/ts/NFTCollectionWithRoyaltyTest.ts @@ -100,7 +100,7 @@ class Factory extends ContractFactory< tests = { getCollectionUri: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { @@ -108,7 +108,7 @@ class Factory extends ContractFactory< }, totalSupply: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { @@ -117,7 +117,8 @@ class Factory extends ContractFactory< nftByIndex: async ( params: TestContractParams< NFTCollectionWithRoyaltyTestTypes.Fields, - { index: bigint } + { index: bigint }, + {} > ): Promise> => { return testMethod(this, "nftByIndex", params); @@ -125,7 +126,8 @@ class Factory extends ContractFactory< validateNFT: async ( params: TestContractParams< NFTCollectionWithRoyaltyTestTypes.Fields, - { nftId: HexString; nftIndex: bigint } + { nftId: HexString; nftIndex: bigint }, + {} > ): Promise> => { return testMethod(this, "validateNFT", params); @@ -133,7 +135,8 @@ class Factory extends ContractFactory< royaltyAmount: async ( params: TestContractParams< NFTCollectionWithRoyaltyTestTypes.Fields, - { tokenId: HexString; salePrice: bigint } + { tokenId: HexString; salePrice: bigint }, + {} > ): Promise> => { return testMethod(this, "royaltyAmount", params); @@ -141,7 +144,8 @@ class Factory extends ContractFactory< payRoyalty: async ( params: TestContractParams< NFTCollectionWithRoyaltyTestTypes.Fields, - { payer: Address; amount: bigint } + { payer: Address; amount: bigint }, + {} > ): Promise> => { return testMethod(this, "payRoyalty", params); @@ -149,7 +153,8 @@ class Factory extends ContractFactory< withdrawRoyalty: async ( params: TestContractParams< NFTCollectionWithRoyaltyTestTypes.Fields, - { recipient: Address; amount: bigint } + { recipient: Address; amount: bigint }, + {} > ): Promise> => { return testMethod(this, "withdrawRoyalty", params); @@ -157,7 +162,8 @@ class Factory extends ContractFactory< mint: async ( params: TestContractParams< NFTCollectionWithRoyaltyTestTypes.Fields, - { nftUri: HexString } + { nftUri: HexString }, + {} > ): Promise> => { return testMethod(this, "mint", params); diff --git a/artifacts/ts/NFTTest.ts b/artifacts/ts/NFTTest.ts index 39da094f8..32afb0fb5 100644 --- a/artifacts/ts/NFTTest.ts +++ b/artifacts/ts/NFTTest.ts @@ -73,12 +73,18 @@ class Factory extends ContractFactory { tests = { getTokenUri: async ( - params: Omit, "testArgs"> + params: Omit< + TestContractParams, + "testArgs" + > ): Promise> => { return testMethod(this, "getTokenUri", params); }, getCollectionIndex: async ( - params: Omit, "testArgs"> + params: Omit< + TestContractParams, + "testArgs" + > ): Promise> => { return testMethod(this, "getCollectionIndex", params); }, diff --git a/artifacts/ts/OwnerOnly.ts b/artifacts/ts/OwnerOnly.ts index 76559fb14..8583c4908 100644 --- a/artifacts/ts/OwnerOnly.ts +++ b/artifacts/ts/OwnerOnly.ts @@ -51,7 +51,10 @@ class Factory extends ContractFactory< tests = { testOwner: async ( - params: Omit, "testArgs"> + params: Omit< + TestContractParams, + "testArgs" + > ): Promise> => { return testMethod(this, "testOwner", params); }, diff --git a/artifacts/ts/Sub.ts b/artifacts/ts/Sub.ts index 9146aaf25..4d444e17e 100644 --- a/artifacts/ts/Sub.ts +++ b/artifacts/ts/Sub.ts @@ -71,7 +71,11 @@ class Factory extends ContractFactory { tests = { sub: async ( - params: TestContractParams + params: TestContractParams< + SubTypes.Fields, + { array: [bigint, bigint] }, + {} + > ): Promise> => { return testMethod(this, "sub", params); }, diff --git a/artifacts/ts/TokenTest.ts b/artifacts/ts/TokenTest.ts index a4aac3e8f..c96dc6332 100644 --- a/artifacts/ts/TokenTest.ts +++ b/artifacts/ts/TokenTest.ts @@ -85,22 +85,34 @@ class Factory extends ContractFactory< tests = { getSymbol: async ( - params: Omit, "testArgs"> + params: Omit< + TestContractParams, + "testArgs" + > ): Promise> => { return testMethod(this, "getSymbol", params); }, getName: async ( - params: Omit, "testArgs"> + params: Omit< + TestContractParams, + "testArgs" + > ): Promise> => { return testMethod(this, "getName", params); }, getDecimals: async ( - params: Omit, "testArgs"> + params: Omit< + TestContractParams, + "testArgs" + > ): Promise> => { return testMethod(this, "getDecimals", params); }, getTotalSupply: async ( - params: Omit, "testArgs"> + params: Omit< + TestContractParams, + "testArgs" + > ): Promise> => { return testMethod(this, "getTotalSupply", params); }, diff --git a/artifacts/ts/UserAccount.ts b/artifacts/ts/UserAccount.ts index e6c934fad..cbb8b4e6d 100644 --- a/artifacts/ts/UserAccount.ts +++ b/artifacts/ts/UserAccount.ts @@ -75,7 +75,8 @@ class Factory extends ContractFactory< updateBalance: async ( params: TestContractParams< UserAccountTypes.Fields, - { tokens: [TokenBalance, TokenBalance] } + { tokens: [TokenBalance, TokenBalance] }, + {} > ): Promise> => { return testMethod(this, "updateBalance", params); @@ -83,14 +84,15 @@ class Factory extends ContractFactory< updateAddress: async ( params: TestContractParams< UserAccountTypes.Fields, - { newAddress: Address } + { newAddress: Address }, + {} > ): Promise> => { return testMethod(this, "updateAddress", params); }, getBalances: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { diff --git a/artifacts/ts/Warnings.ts b/artifacts/ts/Warnings.ts index 778f66848..3cb10ea36 100644 --- a/artifacts/ts/Warnings.ts +++ b/artifacts/ts/Warnings.ts @@ -51,7 +51,11 @@ class Factory extends ContractFactory { tests = { foo: async ( - params: TestContractParams + params: TestContractParams< + WarningsTypes.Fields, + { x: bigint; y: bigint }, + {} + > ): Promise> => { return testMethod(this, "foo", params); }, diff --git a/artifacts/ts/WrongNFTTest.ts b/artifacts/ts/WrongNFTTest.ts index f1e8e624a..b97561f3e 100644 --- a/artifacts/ts/WrongNFTTest.ts +++ b/artifacts/ts/WrongNFTTest.ts @@ -77,7 +77,7 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { @@ -85,7 +85,7 @@ class Factory extends ContractFactory< }, getCollectionIndex: async ( params: Omit< - TestContractParams, + TestContractParams, "testArgs" > ): Promise> => { diff --git a/contracts/test/map.ral b/contracts/test/map.ral index 94078080e..db8a57c3a 100644 --- a/contracts/test/map.ral +++ b/contracts/test/map.ral @@ -2,7 +2,10 @@ struct MapValue { id: U256, mut balance: U256 } -Contract MapTest(@unused mut a: U256, @unused b: U256, mut map0: Map[Address, MapValue], mut map1: Map[U256, U256]) { +Contract MapTest() { + map[Address, MapValue] map0 + map[U256, U256] map1 + @using(preapprovedAssets = true) pub fn insert(key: Address, value: MapValue) -> () { map0.insert!{key -> ALPH: mapEntryDeposit!()}(key, value) diff --git a/packages/cli/src/codegen.ts b/packages/cli/src/codegen.ts index 3fb9927ca..3bac9b655 100644 --- a/packages/cli/src/codegen.ts +++ b/packages/cli/src/codegen.ts @@ -254,12 +254,12 @@ function genGetInitialFieldsWithDefaultValues(contract: Contract): string { } function genContractStateType(contract: Contract): string { - if (contract.fieldsExceptMaps.names.length === 0) { + if (contract.fieldsSig.names.length === 0) { return `export type State = Omit, 'fields'>` } return ` export type Fields = { - ${formatParameters(contract.fieldsExceptMaps)} + ${formatParameters(contract.fieldsSig)} } export type State = ContractState @@ -267,43 +267,37 @@ function genContractStateType(contract: Contract): string { } function genMapFields(contract: Contract): string { - const mapFields = contract.mapFields.names.map((name, index) => { - const type = contract.mapFields.types[`${index}`] - const [key, value] = parseMapType(type) - return `${name}?: Map<${toTsType(key)}, ${toTsType(value)}>` + const mapFields = contract.mapsSig.map((mapSig) => { + const [key, value] = parseMapType(mapSig.type) + return `${mapSig.name}?: Map<${toTsType(key)}, ${toTsType(value)}>` }) return `{ ${mapFields.join(', ')} }` } function genTestMethod(contract: Contract, functionSig: node.FunctionSig): string { const funcHasArgs = functionSig.paramNames.length > 0 - const fieldsSig = contract.fieldsExceptMaps + const fieldsSig = contract.fieldsSig const contractHasFields = fieldsSig.names.length > 0 const argsType = funcHasArgs ? `{${formatParameters({ names: functionSig.paramNames, types: functionSig.paramTypes })}}` : 'never' - const fieldsType = - contractHasFields && contract.hasMapFields() - ? `${contractFieldType(contract.name, fieldsSig)} & ${genMapFields(contract)}` - : contractHasFields - ? `${contractFieldType(contract.name, fieldsSig)}` - : 'never' + const fieldsType = contractHasFields ? contractFieldType(contract.name, fieldsSig) : 'never' + const mapsType = contract.hasMapFields() ? genMapFields(contract) : '{}' const params = funcHasArgs && contractHasFields - ? `params: TestContractParams<${fieldsType}, ${argsType}>` + ? `params: TestContractParams<${fieldsType}, ${argsType}, ${mapsType}>` : funcHasArgs - ? `params: Omit, 'initialFields'>` + ? `params: Omit, 'initialFields'>` : contractHasFields - ? `params: Omit, 'testArgs'>` - : `params?: Omit, 'testArgs' | 'initialFields'>` + ? `params: Omit, 'testArgs'>` + : `params?: Omit, 'testArgs' | 'initialFields'>` const tsReturnTypes = functionSig.returnTypes.map((tpe) => toTsType(tpe)) - const mapFields = genMapFields(contract) const retType = tsReturnTypes.length === 0 - ? `TestContractResult` + ? `TestContractResult` : tsReturnTypes.length === 1 - ? `TestContractResult<${tsReturnTypes[0]}, ${mapFields}>` - : `TestContractResult<[${tsReturnTypes.join(', ')}], ${mapFields}>` + ? `TestContractResult<${tsReturnTypes[0]}, ${mapsType}>` + : `TestContractResult<[${tsReturnTypes.join(', ')}], ${mapsType}>` const callParams = funcHasArgs || contractHasFields ? 'params' : 'params === undefined ? {} : params' return ` ${functionSig.name}: async (${params}): Promise<${retType}> => { @@ -378,14 +372,14 @@ function toUnixPath(p: string): string { } function getContractFields(contract: Contract): node.FieldsSig { - const stdIdFieldIndex = contract.fieldsExceptMaps.names.findIndex((name) => name === StdIdFieldName) + const stdIdFieldIndex = contract.fieldsSig.names.findIndex((name) => name === StdIdFieldName) if (stdIdFieldIndex === -1) { - return contract.fieldsExceptMaps + return contract.fieldsSig } return { - names: contract.fieldsExceptMaps.names.filter((_, index) => index !== stdIdFieldIndex), - types: contract.fieldsExceptMaps.types.filter((_, index) => index !== stdIdFieldIndex), - isMutable: contract.fieldsExceptMaps.isMutable.filter((_, index) => index !== stdIdFieldIndex) + names: contract.fieldsSig.names.filter((_, index) => index !== stdIdFieldIndex), + types: contract.fieldsSig.types.filter((_, index) => index !== stdIdFieldIndex), + isMutable: contract.fieldsSig.isMutable.filter((_, index) => index !== stdIdFieldIndex) } } diff --git a/packages/web3/src/api/api-alephium.ts b/packages/web3/src/api/api-alephium.ts index fc2e2dda9..fa1f7d133 100644 --- a/packages/web3/src/api/api-alephium.ts +++ b/packages/web3/src/api/api-alephium.ts @@ -420,6 +420,7 @@ export interface CompileContractResult { codeHashDebug: string fields: FieldsSig functions: FunctionSig[] + maps: MapSig[] constants: Constant[] enums: Enum[] events: EventSig[] @@ -658,6 +659,11 @@ export interface InternalServerError { detail: string } +export interface MapSig { + name: string + type: string +} + export interface MemPooled { type: string } diff --git a/packages/web3/src/contract/contract.ts b/packages/web3/src/contract/contract.ts index 535ad0091..e609334ee 100644 --- a/packages/web3/src/contract/contract.ts +++ b/packages/web3/src/contract/contract.ts @@ -84,6 +84,7 @@ import { const crypto = new WebCrypto() export type FieldsSig = node.FieldsSig +export type MapSig = node.MapSig export type EventSig = node.EventSig export type FunctionSig = node.FunctionSig export type Fields = NamedVals @@ -900,8 +901,7 @@ export class Contract extends Artifact { readonly bytecodeDebugPatch: string readonly codeHash: string readonly fieldsSig: FieldsSig - readonly fieldsExceptMaps: FieldsSig - readonly mapFields: FieldsSig + readonly mapsSig: MapSig[] readonly eventsSig: EventSig[] readonly constants: Constant[] readonly enums: Enum[] @@ -919,6 +919,7 @@ export class Contract extends Artifact { codeHash: string, codeHashDebug: string, fieldsSig: FieldsSig, + mapsSig: MapSig[], eventsSig: EventSig[], functions: FunctionSig[], constants: Constant[], @@ -931,7 +932,7 @@ export class Contract extends Artifact { this.bytecodeDebugPatch = bytecodeDebugPatch this.codeHash = codeHash this.fieldsSig = fieldsSig - ;[this.mapFields, this.fieldsExceptMaps] = ralph.splitFields(fieldsSig) + this.mapsSig = mapsSig this.eventsSig = eventsSig this.constants = constants this.enums = enums @@ -950,6 +951,7 @@ export class Contract extends Artifact { artifact.bytecode == null || artifact.codeHash == null || artifact.fieldsSig == null || + artifact.mapsSig == null || artifact.eventsSig == null || artifact.constants == null || artifact.enums == null || @@ -965,6 +967,7 @@ export class Contract extends Artifact { artifact.codeHash, codeHashDebug ? codeHashDebug : artifact.codeHash, artifact.fieldsSig, + artifact.mapsSig, artifact.eventsSig, artifact.functions, artifact.constants, @@ -984,6 +987,7 @@ export class Contract extends Artifact { result.codeHash, result.codeHashDebug, result.fields, + result.maps, result.events, result.functions, result.constants, @@ -1012,6 +1016,7 @@ export class Contract extends Artifact { bytecode: this.bytecode, codeHash: this.codeHash, fieldsSig: this.fieldsSig, + mapsSig: this.mapsSig, eventsSig: this.eventsSig, functions: this.functions, constants: this.constants, @@ -1024,17 +1029,17 @@ export class Contract extends Artifact { } hasMapFields(): boolean { - return this.fieldsExceptMaps.names.length !== this.fieldsSig.names.length + return this.mapsSig.length > 0 } getInitialFieldsWithDefaultValues(): Fields { const fields = this.stdInterfaceId === undefined - ? this.fieldsExceptMaps + ? this.fieldsSig : { - names: this.fieldsExceptMaps.names.slice(0, -1), - types: this.fieldsExceptMaps.types.slice(0, -1), - isMutable: this.fieldsExceptMaps.isMutable.slice(0, -1) + names: this.fieldsSig.names.slice(0, -1), + types: this.fieldsSig.types.slice(0, -1), + isMutable: this.fieldsSig.isMutable.slice(0, -1) } return getDefaultValue(fields, this.structs) } @@ -1047,7 +1052,7 @@ export class Contract extends Artifact { bytecode: this.bytecode, codeHash: this.codeHash, fields: fields, - fieldsSig: this.fieldsExceptMaps, + fieldsSig: this.fieldsSig, asset: asset } } @@ -1071,7 +1076,7 @@ export class Contract extends Artifact { if (typeof fields === 'undefined') { return [] } else { - return toApiFields(fields, this.fieldsExceptMaps, this.structs) + return toApiFields(fields, this.fieldsSig, this.structs) } } @@ -1102,9 +1107,9 @@ export class Contract extends Artifact { ? [] : ralph.flattenFields( params.initialFields, - this.fieldsExceptMaps.names, - this.fieldsExceptMaps.types, - this.fieldsExceptMaps.isMutable, + this.fieldsSig.names, + this.fieldsSig.types, + this.fieldsSig.isMutable, this.structs ) const immFields = allFields.filter((f) => !f.isMutable).map((f) => toApiVal(f.value, f.type)) @@ -1134,8 +1139,8 @@ export class Contract extends Artifact { bytecode: state.bytecode, initialStateHash: state.initialStateHash, codeHash: state.codeHash, - fields: fromApiFields(state.immFields, state.mutFields, this.fieldsExceptMaps, this.structs), - fieldsSig: this.fieldsExceptMaps, + fields: fromApiFields(state.immFields, state.mutFields, this.fieldsSig, this.structs), + fieldsSig: this.fieldsSig, asset: fromApiAsset(state.asset) } } @@ -1250,7 +1255,7 @@ export class Contract extends Artifact { return ralph.buildContractByteCode( isDevnet ? this.bytecodeDebug : this.bytecode, initialFields, - this.fieldsExceptMaps, + this.fieldsSig, this.structs ) } catch (error) { @@ -1563,7 +1568,11 @@ function toApiInputAssets(inputAssets?: InputAsset[]): node.TestInputAsset[] | u return typeof inputAssets !== 'undefined' ? inputAssets.map(toApiInputAsset) : undefined } -export interface TestContractParams { +export interface TestContractParams< + F extends Fields = Fields, + A extends Arguments = Arguments, + M extends Record> = Record> +> { group?: number // default 0 address?: string callerAddress?: string @@ -1571,6 +1580,7 @@ export interface TestContractParams> = contractAddress: string returns: R gasUsed: number - maps?: M + resultMaps?: M contracts: ContractState[] txOutputs: Output[] events: ContractEvent[] @@ -1938,23 +1948,21 @@ function mapToExistingContracts( }) } -function mapsToExistingContracts(contract: Contract, parentContractId: string, group: number, fields: Fields) { - const fieldsExceptMaps: Fields = {} +function mapsToExistingContracts( + contract: Contract, + parentContractId: string, + group: number, + initialMaps: Record> +) { const contractStates: ContractState[] = [] - let mapIndex = 0 - Object.keys(fields).forEach((name) => { - const index = contract.fieldsSig.names.indexOf(name) - const type = contract.fieldsSig.types[`${index}`] - const field = fields[`${name}`] - if (type.startsWith('Map[')) { - const states = mapToExistingContracts(contract, parentContractId, group, field as Map, mapIndex, type) - contractStates.push(...states) - mapIndex += 1 - } else { - fieldsExceptMaps[`${name}`] = field - } + Object.keys(initialMaps).forEach((name) => { + const index = contract.mapsSig.findIndex((m) => m.name === name) + if (index === -1) throw new Error(`Map var ${name} does not exist in contract ${contract.name}`) + const mapSig = contract.mapsSig[`${index}`] + const states = mapToExistingContracts(contract, parentContractId, group, initialMaps[`${name}`], index, mapSig.type) + contractStates.push(...states) }) - return { fieldsExceptMaps, contractStates } + return contractStates } export async function testMethod< @@ -1966,30 +1974,30 @@ export async function testMethod< >( factory: ContractFactory, methodName: string, - params: Optional, 'testArgs' | 'initialFields'> + params: Optional, 'testArgs' | 'initialFields'> ): Promise> { const txId = params?.txId ?? randomTxId() - const initialFields = params.initialFields === undefined ? {} : params.initialFields const contract = factory.contract const address = params.address ?? addressFromContractId(binToHex(crypto.getRandomValues(new Uint8Array(32)))) const contractId = binToHex(contractIdFromAddress(address)) const group = params.group ?? 0 - const { fieldsExceptMaps, contractStates } = mapsToExistingContracts(contract, contractId, group, initialFields) + const initialMaps = params.initialMaps ?? {} + const contractStates = mapsToExistingContracts(contract, contractId, group, initialMaps) const apiParams = contract.toApiTestContractParams(methodName, { ...params, address, txId: txId, - initialFields: addStdIdToFields(contract, fieldsExceptMaps), + initialFields: addStdIdToFields(contract, params.initialFields ?? {}), testArgs: params.testArgs === undefined ? {} : params.testArgs, existingContracts: (params.existingContracts ?? []).concat(contractStates) }) const apiResult = await getCurrentNodeProvider().contracts.postContractsTestContract(apiParams) - const maps = existingContractsToMaps(contract, address, group, apiResult, initialFields) + const resultMaps = existingContractsToMaps(contract, address, group, apiResult, initialMaps) const testResult = contract.fromApiTestContractResult(methodName, apiResult, txId) contract.printDebugMessages(methodName, testResult.debugMessages) return { ...testResult, - maps + resultMaps } as TestContractResult } @@ -2001,11 +2009,11 @@ interface MapInfo { index: number } -function buildMaps(contract: Contract, fields: Fields): MapInfo[] { - return contract.mapFields.types.map((type, index) => { - const name = contract.mapFields.names[`${index}`] +function buildMapInfo(contract: Contract, fields: Fields): MapInfo[] { + return contract.mapsSig.map((mapSig, index) => { + const name = mapSig.name const value = (fields[`${name}`] ?? new Map()) as Map - const [keyType, valueType] = ralph.parseMapType(type) + const [keyType, valueType] = ralph.parseMapType(mapSig.type) return { name, value, keyType, valueType, index } }) } @@ -2070,9 +2078,9 @@ function existingContractsToMaps( address: Address, group: number, result: node.TestContractResult, - fields: Fields + maps: Record> ): Record> { - const allMaps = buildMaps(contract, fields) + const allMaps = buildMapInfo(contract, maps) const updated = updateMaps(contract, result, allMaps, address, group) const newInserted = extractFromEventLog(contract, result, allMaps, address, group) const mapEntries = updated.concat(newInserted) diff --git a/test/contract.test.ts b/test/contract.test.ts index 1598c9c4f..09a2920e0 100644 --- a/test/contract.test.ts +++ b/test/contract.test.ts @@ -445,48 +445,41 @@ describe('contract', function () { expect(balances1.returns.tokens[1].amount).toEqual(101n) }) - it('should test map(uint test)', async () => { + it('should test map(unit test)', async () => { const insertResult = await MapTest.tests.insert({ - initialFields: { a: 0n, b: 0n }, testArgs: { key: signer.address, value: { id: 1n, balance: 10n } }, inputAssets: [{ address: signer.address, asset: { alphAmount: ONE_ALPH * 3n } }] }) - expect(insertResult.maps?.map0?.get(signer.address)).toEqual({ id: 1n, balance: 10n }) - expect(insertResult.maps?.map1?.get(1n)).toEqual(10n) + expect(insertResult.resultMaps?.map0?.get(signer.address)).toEqual({ id: 1n, balance: 10n }) + expect(insertResult.resultMaps?.map1?.get(1n)).toEqual(10n) const updateResult = await MapTest.tests.update({ - initialFields: { - a: 0n, - b: 0n, + initialMaps: { map0: new Map([[signer.address, { id: 1n, balance: 10n }]]), map1: new Map([[1n, 10n]]) }, testArgs: { key: signer.address }, inputAssets: [{ address: signer.address, asset: { alphAmount: ONE_ALPH } }] }) - expect(updateResult.maps?.map0?.get(signer.address)).toEqual({ id: 1n, balance: 11n }) - expect(updateResult.maps?.map1?.get(1n)).toEqual(11n) + expect(updateResult.resultMaps?.map0?.get(signer.address)).toEqual({ id: 1n, balance: 11n }) + expect(updateResult.resultMaps?.map1?.get(1n)).toEqual(11n) const removeResult = await MapTest.tests.remove({ - initialFields: { - a: 0n, - b: 0n, + initialMaps: { map0: new Map([[signer.address, { id: 1n, balance: 10n }]]), map1: new Map([[1n, 10n]]) }, testArgs: { key: signer.address }, inputAssets: [{ address: signer.address, asset: { alphAmount: ONE_ALPH } }] }) - expect(removeResult.maps?.map0?.get(signer.address)).toEqual(undefined) - expect(removeResult.maps?.map1?.get(1n)).toEqual(undefined) + expect(removeResult.resultMaps?.map0?.get(signer.address)).toEqual(undefined) + expect(removeResult.resultMaps?.map1?.get(1n)).toEqual(undefined) }) it('should test map(integration test)', async () => { const result = await MapTest.deploy(signer, { - initialFields: { a: 0n, b: 1n } + initialFields: {} }) - const state = await result.contractInstance.fetchState() - expect(state.fields).toEqual({ a: 0n, b: 1n }) const mapTest = result.contractInstance await InsertIntoMap.execute(signer, { From 72de8e9124c501e1ca990cb0882dfcf5d02c5820 Mon Sep 17 00:00:00 2001 From: lbqds Date: Fri, 29 Mar 2024 20:56:50 +0800 Subject: [PATCH 19/24] Fix unit tests --- packages/cli/templates/react/src/artifacts/Greeter.ral.json | 1 + packages/walletconnect/artifacts/Greeter.ral.json | 1 + packages/web3/src/codec/contract-codec.test.ts | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/cli/templates/react/src/artifacts/Greeter.ral.json b/packages/cli/templates/react/src/artifacts/Greeter.ral.json index 308e89e6d..5a5cda0ae 100644 --- a/packages/cli/templates/react/src/artifacts/Greeter.ral.json +++ b/packages/cli/templates/react/src/artifacts/Greeter.ral.json @@ -14,6 +14,7 @@ false ] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/packages/walletconnect/artifacts/Greeter.ral.json b/packages/walletconnect/artifacts/Greeter.ral.json index 573d1d360..04db9acb7 100644 --- a/packages/walletconnect/artifacts/Greeter.ral.json +++ b/packages/walletconnect/artifacts/Greeter.ral.json @@ -14,6 +14,7 @@ false ] }, + "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/packages/web3/src/codec/contract-codec.test.ts b/packages/web3/src/codec/contract-codec.test.ts index 61e5ceba8..3c0bc8f76 100644 --- a/packages/web3/src/codec/contract-codec.test.ts +++ b/packages/web3/src/codec/contract-codec.test.ts @@ -358,7 +358,7 @@ describe('Encode & decode contract', function () { const decodedContract = contractCodec.decodeContract(Buffer.from(contract.bytecode, 'hex')) expect(toHalfDecoded(decodedContract)).toEqual(decoded) - expect(decodedContract.fieldLength).toEqual(getTypesLength(contract.fieldsExceptMaps.types)) + expect(decodedContract.fieldLength).toEqual(getTypesLength(contract.fieldsSig.types)) decodedContract.methods.map((decodedMethod, index) => { const contractFunction = contract.functions[index] expect(decodedMethod.isPublic).toEqual(contractFunction.isPublic) From cbe16694bc9d57c4f40d6db096ba0cbf3f9b00b8 Mon Sep 17 00:00:00 2001 From: lbqds Date: Fri, 29 Mar 2024 21:19:35 +0800 Subject: [PATCH 20/24] Improve generated types --- artifacts/ts/Add.ts | 52 ++++++----- artifacts/ts/Assert.ts | 6 +- artifacts/ts/Debug.ts | 6 +- artifacts/ts/DeprecatedNFTTest1.ts | 6 +- artifacts/ts/DeprecatedNFTTest2.ts | 12 +-- artifacts/ts/DeprecatedNFTTest3.ts | 12 +-- artifacts/ts/DeprecatedNFTTest4.ts | 12 +-- artifacts/ts/DeprecatedNFTTest5.ts | 17 ++-- artifacts/ts/DeprecatedNFTTest6.ts | 14 +-- artifacts/ts/DeprecatedNFTTest7.ts | 14 +-- artifacts/ts/FakeTokenTest.ts | 30 +++--- artifacts/ts/Greeter.ts | 6 +- artifacts/ts/MetaData.ts | 18 ++-- artifacts/ts/NFTCollectionTest.ts | 51 +++++----- artifacts/ts/NFTCollectionWithRoyaltyTest.ts | 98 +++++++++++++------- artifacts/ts/NFTTest.ts | 14 +-- artifacts/ts/OwnerOnly.ts | 6 +- artifacts/ts/Sub.ts | 9 +- artifacts/ts/TokenTest.ts | 24 ++--- artifacts/ts/UserAccount.ts | 32 ++++--- artifacts/ts/Warnings.ts | 13 ++- artifacts/ts/WrongNFTTest.ts | 14 +-- packages/cli/src/codegen.ts | 25 +++-- packages/web3/src/contract/contract.ts | 2 +- 24 files changed, 281 insertions(+), 212 deletions(-) diff --git a/artifacts/ts/Add.ts b/artifacts/ts/Add.ts index 83d5957df..47584827b 100644 --- a/artifacts/ts/Add.ts +++ b/artifacts/ts/Add.ts @@ -73,40 +73,48 @@ class Factory extends ContractFactory { tests = { add: async ( - params: TestContractParams< - AddTypes.Fields, - { array: [bigint, bigint] }, - {} + params: Omit< + TestContractParams, + "initialMaps" > - ): Promise> => { + ): Promise< + Omit, "initialMaps"> + > => { return testMethod(this, "add", params); }, addPrivate: async ( - params: TestContractParams< - AddTypes.Fields, - { array: [bigint, bigint] }, - {} + params: Omit< + TestContractParams, + "initialMaps" > - ): Promise> => { + ): Promise< + Omit, "initialMaps"> + > => { return testMethod(this, "addPrivate", params); }, createSubContract: async ( - params: TestContractParams< - AddTypes.Fields, - { - a: bigint; - path: HexString; - subContractId: HexString; - payer: Address; - }, - {} + params: Omit< + TestContractParams< + AddTypes.Fields, + { + a: bigint; + path: HexString; + subContractId: HexString; + payer: Address; + }, + never + >, + "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "createSubContract", params); }, destroy: async ( - params: TestContractParams - ): Promise> => { + params: Omit< + TestContractParams, + "initialMaps" + > + ): Promise, "initialMaps">> => { return testMethod(this, "destroy", params); }, }; diff --git a/artifacts/ts/Assert.ts b/artifacts/ts/Assert.ts index 9f8a8efa7..85b8c3ee7 100644 --- a/artifacts/ts/Assert.ts +++ b/artifacts/ts/Assert.ts @@ -54,10 +54,10 @@ class Factory extends ContractFactory { tests = { test: async ( params?: Omit< - TestContractParams, - "testArgs" | "initialFields" + TestContractParams, + "testArgs" | "initialFields" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "test", params === undefined ? {} : params); }, }; diff --git a/artifacts/ts/Debug.ts b/artifacts/ts/Debug.ts index b0597071b..a70a1e208 100644 --- a/artifacts/ts/Debug.ts +++ b/artifacts/ts/Debug.ts @@ -41,10 +41,10 @@ class Factory extends ContractFactory { tests = { debug: async ( params?: Omit< - TestContractParams, - "testArgs" | "initialFields" + TestContractParams, + "testArgs" | "initialFields" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "debug", params === undefined ? {} : params); }, }; diff --git a/artifacts/ts/DeprecatedNFTTest1.ts b/artifacts/ts/DeprecatedNFTTest1.ts index 15d352c03..d8ff8079a 100644 --- a/artifacts/ts/DeprecatedNFTTest1.ts +++ b/artifacts/ts/DeprecatedNFTTest1.ts @@ -72,10 +72,10 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getTokenUri", params); }, }; diff --git a/artifacts/ts/DeprecatedNFTTest2.ts b/artifacts/ts/DeprecatedNFTTest2.ts index 7c7de7765..3d8cc1f05 100644 --- a/artifacts/ts/DeprecatedNFTTest2.ts +++ b/artifacts/ts/DeprecatedNFTTest2.ts @@ -76,18 +76,18 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getTokenUri", params); }, getCollectionId: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getCollectionId", params); }, }; diff --git a/artifacts/ts/DeprecatedNFTTest3.ts b/artifacts/ts/DeprecatedNFTTest3.ts index e2cc81314..4df1d71c5 100644 --- a/artifacts/ts/DeprecatedNFTTest3.ts +++ b/artifacts/ts/DeprecatedNFTTest3.ts @@ -72,18 +72,18 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getTokenUri", params); }, returnNothing: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "returnNothing", params); }, }; diff --git a/artifacts/ts/DeprecatedNFTTest4.ts b/artifacts/ts/DeprecatedNFTTest4.ts index f75f1a71f..8c788437c 100644 --- a/artifacts/ts/DeprecatedNFTTest4.ts +++ b/artifacts/ts/DeprecatedNFTTest4.ts @@ -76,18 +76,18 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getTokenUri", params); }, getBool: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getBool", params); }, }; diff --git a/artifacts/ts/DeprecatedNFTTest5.ts b/artifacts/ts/DeprecatedNFTTest5.ts index 5dd8fe38f..dbf480583 100644 --- a/artifacts/ts/DeprecatedNFTTest5.ts +++ b/artifacts/ts/DeprecatedNFTTest5.ts @@ -76,18 +76,23 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getTokenUri", params); }, returnMoreValues: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise< + Omit< + TestContractResult<[HexString, bigint, bigint], never>, + "initialMaps" + > + > => { return testMethod(this, "returnMoreValues", params); }, }; diff --git a/artifacts/ts/DeprecatedNFTTest6.ts b/artifacts/ts/DeprecatedNFTTest6.ts index 35905d02f..c9e7bb0d0 100644 --- a/artifacts/ts/DeprecatedNFTTest6.ts +++ b/artifacts/ts/DeprecatedNFTTest6.ts @@ -76,18 +76,20 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getTokenUri", params); }, getArray: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise< + Omit, "initialMaps"> + > => { return testMethod(this, "getArray", params); }, }; diff --git a/artifacts/ts/DeprecatedNFTTest7.ts b/artifacts/ts/DeprecatedNFTTest7.ts index b265e8479..919394e67 100644 --- a/artifacts/ts/DeprecatedNFTTest7.ts +++ b/artifacts/ts/DeprecatedNFTTest7.ts @@ -76,18 +76,20 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getTokenUri", params); }, returnNegativeIndex: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise< + Omit, "initialMaps"> + > => { return testMethod(this, "returnNegativeIndex", params); }, }; diff --git a/artifacts/ts/FakeTokenTest.ts b/artifacts/ts/FakeTokenTest.ts index e85835fb3..1a1cb7890 100644 --- a/artifacts/ts/FakeTokenTest.ts +++ b/artifacts/ts/FakeTokenTest.ts @@ -83,42 +83,42 @@ class Factory extends ContractFactory< tests = { getSymbol: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getSymbol", params); }, getName: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getName", params); }, getDecimals: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getDecimals", params); }, getTotalSupply: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getTotalSupply", params); }, foo: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "foo", params); }, }; diff --git a/artifacts/ts/Greeter.ts b/artifacts/ts/Greeter.ts index c8907998b..b50465826 100644 --- a/artifacts/ts/Greeter.ts +++ b/artifacts/ts/Greeter.ts @@ -76,10 +76,10 @@ class Factory extends ContractFactory { tests = { greet: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "greet", params); }, }; diff --git a/artifacts/ts/MetaData.ts b/artifacts/ts/MetaData.ts index 1d3233c6f..b684aaca5 100644 --- a/artifacts/ts/MetaData.ts +++ b/artifacts/ts/MetaData.ts @@ -41,26 +41,26 @@ class Factory extends ContractFactory { tests = { foo: async ( params?: Omit< - TestContractParams, - "testArgs" | "initialFields" + TestContractParams, + "testArgs" | "initialFields" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "foo", params === undefined ? {} : params); }, bar: async ( params?: Omit< - TestContractParams, - "testArgs" | "initialFields" + TestContractParams, + "testArgs" | "initialFields" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "bar", params === undefined ? {} : params); }, baz: async ( params?: Omit< - TestContractParams, - "testArgs" | "initialFields" + TestContractParams, + "testArgs" | "initialFields" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "baz", params === undefined ? {} : params); }, }; diff --git a/artifacts/ts/NFTCollectionTest.ts b/artifacts/ts/NFTCollectionTest.ts index be9cc83bc..0ba6ebb47 100644 --- a/artifacts/ts/NFTCollectionTest.ts +++ b/artifacts/ts/NFTCollectionTest.ts @@ -93,45 +93,54 @@ class Factory extends ContractFactory< tests = { getCollectionUri: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getCollectionUri", params); }, totalSupply: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "totalSupply", params); }, nftByIndex: async ( - params: TestContractParams< - NFTCollectionTestTypes.Fields, - { index: bigint }, - {} + params: Omit< + TestContractParams< + NFTCollectionTestTypes.Fields, + { index: bigint }, + never + >, + "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "nftByIndex", params); }, validateNFT: async ( - params: TestContractParams< - NFTCollectionTestTypes.Fields, - { nftId: HexString; nftIndex: bigint }, - {} + params: Omit< + TestContractParams< + NFTCollectionTestTypes.Fields, + { nftId: HexString; nftIndex: bigint }, + never + >, + "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "validateNFT", params); }, mint: async ( - params: TestContractParams< - NFTCollectionTestTypes.Fields, - { nftUri: HexString }, - {} + params: Omit< + TestContractParams< + NFTCollectionTestTypes.Fields, + { nftUri: HexString }, + never + >, + "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "mint", params); }, }; diff --git a/artifacts/ts/NFTCollectionWithRoyaltyTest.ts b/artifacts/ts/NFTCollectionWithRoyaltyTest.ts index 424ab4a81..32f0bd086 100644 --- a/artifacts/ts/NFTCollectionWithRoyaltyTest.ts +++ b/artifacts/ts/NFTCollectionWithRoyaltyTest.ts @@ -100,72 +100,98 @@ class Factory extends ContractFactory< tests = { getCollectionUri: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams< + NFTCollectionWithRoyaltyTestTypes.Fields, + never, + never + >, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getCollectionUri", params); }, totalSupply: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams< + NFTCollectionWithRoyaltyTestTypes.Fields, + never, + never + >, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "totalSupply", params); }, nftByIndex: async ( - params: TestContractParams< - NFTCollectionWithRoyaltyTestTypes.Fields, - { index: bigint }, - {} + params: Omit< + TestContractParams< + NFTCollectionWithRoyaltyTestTypes.Fields, + { index: bigint }, + never + >, + "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "nftByIndex", params); }, validateNFT: async ( - params: TestContractParams< - NFTCollectionWithRoyaltyTestTypes.Fields, - { nftId: HexString; nftIndex: bigint }, - {} + params: Omit< + TestContractParams< + NFTCollectionWithRoyaltyTestTypes.Fields, + { nftId: HexString; nftIndex: bigint }, + never + >, + "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "validateNFT", params); }, royaltyAmount: async ( - params: TestContractParams< - NFTCollectionWithRoyaltyTestTypes.Fields, - { tokenId: HexString; salePrice: bigint }, - {} + params: Omit< + TestContractParams< + NFTCollectionWithRoyaltyTestTypes.Fields, + { tokenId: HexString; salePrice: bigint }, + never + >, + "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "royaltyAmount", params); }, payRoyalty: async ( - params: TestContractParams< - NFTCollectionWithRoyaltyTestTypes.Fields, - { payer: Address; amount: bigint }, - {} + params: Omit< + TestContractParams< + NFTCollectionWithRoyaltyTestTypes.Fields, + { payer: Address; amount: bigint }, + never + >, + "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "payRoyalty", params); }, withdrawRoyalty: async ( - params: TestContractParams< - NFTCollectionWithRoyaltyTestTypes.Fields, - { recipient: Address; amount: bigint }, - {} + params: Omit< + TestContractParams< + NFTCollectionWithRoyaltyTestTypes.Fields, + { recipient: Address; amount: bigint }, + never + >, + "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "withdrawRoyalty", params); }, mint: async ( - params: TestContractParams< - NFTCollectionWithRoyaltyTestTypes.Fields, - { nftUri: HexString }, - {} + params: Omit< + TestContractParams< + NFTCollectionWithRoyaltyTestTypes.Fields, + { nftUri: HexString }, + never + >, + "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "mint", params); }, }; diff --git a/artifacts/ts/NFTTest.ts b/artifacts/ts/NFTTest.ts index 32afb0fb5..aaaa66b62 100644 --- a/artifacts/ts/NFTTest.ts +++ b/artifacts/ts/NFTTest.ts @@ -74,18 +74,20 @@ class Factory extends ContractFactory { tests = { getTokenUri: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getTokenUri", params); }, getCollectionIndex: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise< + Omit, "initialMaps"> + > => { return testMethod(this, "getCollectionIndex", params); }, }; diff --git a/artifacts/ts/OwnerOnly.ts b/artifacts/ts/OwnerOnly.ts index 8583c4908..c89419b82 100644 --- a/artifacts/ts/OwnerOnly.ts +++ b/artifacts/ts/OwnerOnly.ts @@ -52,10 +52,10 @@ class Factory extends ContractFactory< tests = { testOwner: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "testOwner", params); }, }; diff --git a/artifacts/ts/Sub.ts b/artifacts/ts/Sub.ts index 4d444e17e..414eab542 100644 --- a/artifacts/ts/Sub.ts +++ b/artifacts/ts/Sub.ts @@ -71,12 +71,11 @@ class Factory extends ContractFactory { tests = { sub: async ( - params: TestContractParams< - SubTypes.Fields, - { array: [bigint, bigint] }, - {} + params: Omit< + TestContractParams, + "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "sub", params); }, }; diff --git a/artifacts/ts/TokenTest.ts b/artifacts/ts/TokenTest.ts index c96dc6332..e2a6191b1 100644 --- a/artifacts/ts/TokenTest.ts +++ b/artifacts/ts/TokenTest.ts @@ -86,34 +86,34 @@ class Factory extends ContractFactory< tests = { getSymbol: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getSymbol", params); }, getName: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getName", params); }, getDecimals: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getDecimals", params); }, getTotalSupply: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getTotalSupply", params); }, }; diff --git a/artifacts/ts/UserAccount.ts b/artifacts/ts/UserAccount.ts index cbb8b4e6d..752abb469 100644 --- a/artifacts/ts/UserAccount.ts +++ b/artifacts/ts/UserAccount.ts @@ -73,29 +73,35 @@ class Factory extends ContractFactory< tests = { updateBalance: async ( - params: TestContractParams< - UserAccountTypes.Fields, - { tokens: [TokenBalance, TokenBalance] }, - {} + params: Omit< + TestContractParams< + UserAccountTypes.Fields, + { tokens: [TokenBalance, TokenBalance] }, + never + >, + "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "updateBalance", params); }, updateAddress: async ( - params: TestContractParams< - UserAccountTypes.Fields, - { newAddress: Address }, - {} + params: Omit< + TestContractParams< + UserAccountTypes.Fields, + { newAddress: Address }, + never + >, + "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "updateAddress", params); }, getBalances: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getBalances", params); }, }; diff --git a/artifacts/ts/Warnings.ts b/artifacts/ts/Warnings.ts index 3cb10ea36..51324db69 100644 --- a/artifacts/ts/Warnings.ts +++ b/artifacts/ts/Warnings.ts @@ -51,12 +51,15 @@ class Factory extends ContractFactory { tests = { foo: async ( - params: TestContractParams< - WarningsTypes.Fields, - { x: bigint; y: bigint }, - {} + params: Omit< + TestContractParams< + WarningsTypes.Fields, + { x: bigint; y: bigint }, + never + >, + "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "foo", params); }, }; diff --git a/artifacts/ts/WrongNFTTest.ts b/artifacts/ts/WrongNFTTest.ts index b97561f3e..a33f9d996 100644 --- a/artifacts/ts/WrongNFTTest.ts +++ b/artifacts/ts/WrongNFTTest.ts @@ -77,18 +77,20 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise, "initialMaps">> => { return testMethod(this, "getTokenUri", params); }, getCollectionIndex: async ( params: Omit< - TestContractParams, - "testArgs" + TestContractParams, + "testArgs" | "initialMaps" > - ): Promise> => { + ): Promise< + Omit, "initialMaps"> + > => { return testMethod(this, "getCollectionIndex", params); }, }; diff --git a/packages/cli/src/codegen.ts b/packages/cli/src/codegen.ts index 3bac9b655..ad05eb3ff 100644 --- a/packages/cli/src/codegen.ts +++ b/packages/cli/src/codegen.ts @@ -266,7 +266,7 @@ function genContractStateType(contract: Contract): string { ` } -function genMapFields(contract: Contract): string { +function genMapsType(contract: Contract): string { const mapFields = contract.mapsSig.map((mapSig) => { const [key, value] = parseMapType(mapSig.type) return `${mapSig.name}?: Map<${toTsType(key)}, ${toTsType(value)}>` @@ -282,22 +282,27 @@ function genTestMethod(contract: Contract, functionSig: node.FunctionSig): strin ? `{${formatParameters({ names: functionSig.paramNames, types: functionSig.paramTypes })}}` : 'never' const fieldsType = contractHasFields ? contractFieldType(contract.name, fieldsSig) : 'never' - const mapsType = contract.hasMapFields() ? genMapFields(contract) : '{}' + const hasMapVars: boolean = contract.hasMapVars() + const mapsType = hasMapVars ? genMapsType(contract) : 'never' + const paramsType = `TestContractParams<${fieldsType}, ${argsType}, ${mapsType}>` + const omitList: string[] = [] + if (!funcHasArgs) omitList.push('testArgs') + if (!contractHasFields) omitList.push('initialFields') + if (!hasMapVars) omitList.push('initialMaps') const params = - funcHasArgs && contractHasFields - ? `params: TestContractParams<${fieldsType}, ${argsType}, ${mapsType}>` - : funcHasArgs - ? `params: Omit, 'initialFields'>` - : contractHasFields - ? `params: Omit, 'testArgs'>` - : `params?: Omit, 'testArgs' | 'initialFields'>` + omitList.length === 0 + ? `params: ${paramsType}` + : (omitList.length === 2 && !omitList.includes('initialMaps')) || omitList.length === 3 + ? `params?: Omit<${paramsType}, ${omitList.map((n) => `'${n}'`).join(' | ')}>` + : `params: Omit<${paramsType}, ${omitList.map((n) => `'${n}'`).join(' | ')}>` const tsReturnTypes = functionSig.returnTypes.map((tpe) => toTsType(tpe)) - const retType = + const baseRetType = tsReturnTypes.length === 0 ? `TestContractResult` : tsReturnTypes.length === 1 ? `TestContractResult<${tsReturnTypes[0]}, ${mapsType}>` : `TestContractResult<[${tsReturnTypes.join(', ')}], ${mapsType}>` + const retType = !hasMapVars ? `Omit<${baseRetType}, 'initialMaps'>` : baseRetType const callParams = funcHasArgs || contractHasFields ? 'params' : 'params === undefined ? {} : params' return ` ${functionSig.name}: async (${params}): Promise<${retType}> => { diff --git a/packages/web3/src/contract/contract.ts b/packages/web3/src/contract/contract.ts index e609334ee..1ebde83a7 100644 --- a/packages/web3/src/contract/contract.ts +++ b/packages/web3/src/contract/contract.ts @@ -1028,7 +1028,7 @@ export class Contract extends Artifact { return JSON.stringify(object, null, 2) } - hasMapFields(): boolean { + hasMapVars(): boolean { return this.mapsSig.length > 0 } From 394349dbd578ba329254969aa231fe7cc39febf2 Mon Sep 17 00:00:00 2001 From: lbqds Date: Fri, 29 Mar 2024 23:25:04 +0800 Subject: [PATCH 21/24] Address comments --- .project.json | 10 +-- artifacts/add/Add.ral.json | 1 - artifacts/greeter/Greeter.ral.json | 1 - artifacts/nft/DeprecatedNFTTest1.ral.json | 1 - artifacts/nft/DeprecatedNFTTest2.ral.json | 1 - artifacts/nft/DeprecatedNFTTest3.ral.json | 1 - artifacts/nft/DeprecatedNFTTest4.ral.json | 1 - artifacts/nft/DeprecatedNFTTest5.ral.json | 1 - artifacts/nft/DeprecatedNFTTest6.ral.json | 1 - artifacts/nft/DeprecatedNFTTest7.ral.json | 1 - artifacts/nft/NFTCollectionTest.ral.json | 1 - .../nft/NFTCollectionWithRoyaltyTest.ral.json | 1 - artifacts/nft/NFTTest.ral.json | 1 - artifacts/nft/WrongNFTTest.ral.json | 1 - artifacts/sub/Sub.ral.json | 1 - artifacts/test/Assert.ral.json | 1 - artifacts/test/Debug.ral.json | 1 - artifacts/test/MapTest.ral.json | 22 ++--- artifacts/test/MetaData.ral.json | 1 - artifacts/test/OwnerOnly.ral.json | 1 - artifacts/test/UserAccount.ral.json | 1 - artifacts/test/Warnings.ral.json | 1 - artifacts/token/FakeTokenTest.ral.json | 1 - artifacts/token/TokenTest.ral.json | 1 - artifacts/ts/Add.ts | 47 ++++------ artifacts/ts/Assert.ts | 8 +- artifacts/ts/Debug.ts | 8 +- artifacts/ts/DeprecatedNFTTest1.ts | 8 +- artifacts/ts/DeprecatedNFTTest2.ts | 14 +-- artifacts/ts/DeprecatedNFTTest3.ts | 14 +-- artifacts/ts/DeprecatedNFTTest4.ts | 14 +-- artifacts/ts/DeprecatedNFTTest5.ts | 19 ++-- artifacts/ts/DeprecatedNFTTest6.ts | 16 ++-- artifacts/ts/DeprecatedNFTTest7.ts | 16 ++-- artifacts/ts/FakeTokenTest.ts | 32 +++---- artifacts/ts/Greeter.ts | 8 +- artifacts/ts/MapTest.ts | 2 + artifacts/ts/MetaData.ts | 20 +++-- artifacts/ts/NFTCollectionTest.ts | 50 +++++------ artifacts/ts/NFTCollectionWithRoyaltyTest.ts | 88 +++++++------------ artifacts/ts/NFTTest.ts | 16 ++-- artifacts/ts/OwnerOnly.ts | 8 +- artifacts/ts/Sub.ts | 10 ++- artifacts/ts/TokenTest.ts | 26 +++--- artifacts/ts/UserAccount.ts | 32 +++---- artifacts/ts/Warnings.ts | 14 ++- artifacts/ts/WrongNFTTest.ts | 16 ++-- contracts/test/map.ral | 4 +- packages/cli/src/codegen.ts | 46 +++++----- .../react/src/artifacts/Greeter.ral.json | 1 - .../walletconnect/artifacts/Greeter.ral.json | 1 - packages/web3/src/api/api-alephium.ts | 8 +- packages/web3/src/contract/contract.ts | 50 ++++++----- test/contract.test.ts | 12 +-- 54 files changed, 311 insertions(+), 351 deletions(-) diff --git a/.project.json b/.project.json index da324bcdc..ac7977450 100644 --- a/.project.json +++ b/.project.json @@ -166,7 +166,7 @@ }, "InsertIntoMap": { "sourceFile": "test/map.ral", - "sourceCodeHash": "b82412a32b7acab72adc262504937fe2c101f2f74a29a5a61444a2c6b95f0557", + "sourceCodeHash": "f035aeb3d53b039a81f497a02e5d3fb6fdd38a09251c55a41c3672b31fdd4182", "bytecodeDebugPatch": "", "codeHashDebug": "", "warnings": [] @@ -182,7 +182,7 @@ }, "MapTest": { "sourceFile": "test/map.ral", - "sourceCodeHash": "b82412a32b7acab72adc262504937fe2c101f2f74a29a5a61444a2c6b95f0557", + "sourceCodeHash": "f035aeb3d53b039a81f497a02e5d3fb6fdd38a09251c55a41c3672b31fdd4182", "bytecodeDebugPatch": "=6-1+4=3-1+a=2-2+11=3-1+3=3-1+5=12-1+b=40+7a037e0300012c00=56+7a037e0300012c00=217-1+a=114+7a047e0300012c00=46+7a047e0300012c00=136", "codeHashDebug": "76d94621028b765345f083b3d7124c355a7fd8ca45e9253fc2661102f5533d11", "warnings": [ @@ -191,7 +191,7 @@ }, "MapValue": { "sourceFile": "test/map.ral", - "sourceCodeHash": "b82412a32b7acab72adc262504937fe2c101f2f74a29a5a61444a2c6b95f0557", + "sourceCodeHash": "f035aeb3d53b039a81f497a02e5d3fb6fdd38a09251c55a41c3672b31fdd4182", "bytecodeDebugPatch": "", "codeHashDebug": "", "warnings": [] @@ -258,7 +258,7 @@ }, "RemoveFromMap": { "sourceFile": "test/map.ral", - "sourceCodeHash": "b82412a32b7acab72adc262504937fe2c101f2f74a29a5a61444a2c6b95f0557", + "sourceCodeHash": "f035aeb3d53b039a81f497a02e5d3fb6fdd38a09251c55a41c3672b31fdd4182", "bytecodeDebugPatch": "", "codeHashDebug": "", "warnings": [] @@ -293,7 +293,7 @@ }, "UpdateMapValue": { "sourceFile": "test/map.ral", - "sourceCodeHash": "b82412a32b7acab72adc262504937fe2c101f2f74a29a5a61444a2c6b95f0557", + "sourceCodeHash": "f035aeb3d53b039a81f497a02e5d3fb6fdd38a09251c55a41c3672b31fdd4182", "bytecodeDebugPatch": "", "codeHashDebug": "", "warnings": [] diff --git a/artifacts/add/Add.ral.json b/artifacts/add/Add.ral.json index b29df2a96..78efae435 100644 --- a/artifacts/add/Add.ral.json +++ b/artifacts/add/Add.ral.json @@ -17,7 +17,6 @@ true ] }, - "mapsSig": [], "eventsSig": [ { "name": "Add", diff --git a/artifacts/greeter/Greeter.ral.json b/artifacts/greeter/Greeter.ral.json index f75cc3bc6..8b5318a93 100644 --- a/artifacts/greeter/Greeter.ral.json +++ b/artifacts/greeter/Greeter.ral.json @@ -26,7 +26,6 @@ false ] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/DeprecatedNFTTest1.ral.json b/artifacts/nft/DeprecatedNFTTest1.ral.json index 00b587eef..0dcf655b4 100644 --- a/artifacts/nft/DeprecatedNFTTest1.ral.json +++ b/artifacts/nft/DeprecatedNFTTest1.ral.json @@ -17,7 +17,6 @@ false ] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/DeprecatedNFTTest2.ral.json b/artifacts/nft/DeprecatedNFTTest2.ral.json index f2d849230..02d91d992 100644 --- a/artifacts/nft/DeprecatedNFTTest2.ral.json +++ b/artifacts/nft/DeprecatedNFTTest2.ral.json @@ -17,7 +17,6 @@ false ] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/DeprecatedNFTTest3.ral.json b/artifacts/nft/DeprecatedNFTTest3.ral.json index b59cea791..b4aa0a277 100644 --- a/artifacts/nft/DeprecatedNFTTest3.ral.json +++ b/artifacts/nft/DeprecatedNFTTest3.ral.json @@ -17,7 +17,6 @@ false ] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/DeprecatedNFTTest4.ral.json b/artifacts/nft/DeprecatedNFTTest4.ral.json index 4d583fcd7..baf8e9a5e 100644 --- a/artifacts/nft/DeprecatedNFTTest4.ral.json +++ b/artifacts/nft/DeprecatedNFTTest4.ral.json @@ -17,7 +17,6 @@ false ] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/DeprecatedNFTTest5.ral.json b/artifacts/nft/DeprecatedNFTTest5.ral.json index f90ebc9c9..59df47ca2 100644 --- a/artifacts/nft/DeprecatedNFTTest5.ral.json +++ b/artifacts/nft/DeprecatedNFTTest5.ral.json @@ -17,7 +17,6 @@ false ] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/DeprecatedNFTTest6.ral.json b/artifacts/nft/DeprecatedNFTTest6.ral.json index 5c5b26d54..ad622c1f6 100644 --- a/artifacts/nft/DeprecatedNFTTest6.ral.json +++ b/artifacts/nft/DeprecatedNFTTest6.ral.json @@ -17,7 +17,6 @@ false ] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/DeprecatedNFTTest7.ral.json b/artifacts/nft/DeprecatedNFTTest7.ral.json index be5345d59..13371e495 100644 --- a/artifacts/nft/DeprecatedNFTTest7.ral.json +++ b/artifacts/nft/DeprecatedNFTTest7.ral.json @@ -17,7 +17,6 @@ false ] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/NFTCollectionTest.ral.json b/artifacts/nft/NFTCollectionTest.ral.json index 20325fa42..926795741 100644 --- a/artifacts/nft/NFTCollectionTest.ral.json +++ b/artifacts/nft/NFTCollectionTest.ral.json @@ -23,7 +23,6 @@ false ] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/NFTCollectionWithRoyaltyTest.ral.json b/artifacts/nft/NFTCollectionWithRoyaltyTest.ral.json index 98819f725..505ede5d4 100644 --- a/artifacts/nft/NFTCollectionWithRoyaltyTest.ral.json +++ b/artifacts/nft/NFTCollectionWithRoyaltyTest.ral.json @@ -29,7 +29,6 @@ false ] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/NFTTest.ral.json b/artifacts/nft/NFTTest.ral.json index aa6c5dd21..45538f024 100644 --- a/artifacts/nft/NFTTest.ral.json +++ b/artifacts/nft/NFTTest.ral.json @@ -23,7 +23,6 @@ false ] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/nft/WrongNFTTest.ral.json b/artifacts/nft/WrongNFTTest.ral.json index fac884cbb..a9038be4d 100644 --- a/artifacts/nft/WrongNFTTest.ral.json +++ b/artifacts/nft/WrongNFTTest.ral.json @@ -23,7 +23,6 @@ false ] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/sub/Sub.ral.json b/artifacts/sub/Sub.ral.json index 8813fbc1d..d2500f4d2 100644 --- a/artifacts/sub/Sub.ral.json +++ b/artifacts/sub/Sub.ral.json @@ -14,7 +14,6 @@ true ] }, - "mapsSig": [], "eventsSig": [ { "name": "Sub", diff --git a/artifacts/test/Assert.ral.json b/artifacts/test/Assert.ral.json index fcb30d264..413c3bf28 100644 --- a/artifacts/test/Assert.ral.json +++ b/artifacts/test/Assert.ral.json @@ -8,7 +8,6 @@ "types": [], "isMutable": [] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/test/Debug.ral.json b/artifacts/test/Debug.ral.json index 68641ee77..dd7e4aa30 100644 --- a/artifacts/test/Debug.ral.json +++ b/artifacts/test/Debug.ral.json @@ -8,7 +8,6 @@ "types": [], "isMutable": [] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/test/MapTest.ral.json b/artifacts/test/MapTest.ral.json index 2a90d0dd5..5e8ef4b63 100644 --- a/artifacts/test/MapTest.ral.json +++ b/artifacts/test/MapTest.ral.json @@ -8,16 +8,6 @@ "types": [], "isMutable": [] }, - "mapsSig": [ - { - "name": "map0", - "type": "Map[Address,MapValue]" - }, - { - "name": "map1", - "type": "Map[U256,U256]" - } - ], "eventsSig": [], "functions": [ { @@ -109,5 +99,15 @@ } ], "constants": [], - "enums": [] + "enums": [], + "mapsSig": { + "names": [ + "map0", + "map1" + ], + "types": [ + "Map[Address,MapValue]", + "Map[U256,U256]" + ] + } } \ No newline at end of file diff --git a/artifacts/test/MetaData.ral.json b/artifacts/test/MetaData.ral.json index 0d4ed55d5..9602d0382 100644 --- a/artifacts/test/MetaData.ral.json +++ b/artifacts/test/MetaData.ral.json @@ -8,7 +8,6 @@ "types": [], "isMutable": [] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/test/OwnerOnly.ral.json b/artifacts/test/OwnerOnly.ral.json index 3c33bf8a0..017cff9dd 100644 --- a/artifacts/test/OwnerOnly.ral.json +++ b/artifacts/test/OwnerOnly.ral.json @@ -14,7 +14,6 @@ false ] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/test/UserAccount.ral.json b/artifacts/test/UserAccount.ral.json index 00dbfbca5..03217c596 100644 --- a/artifacts/test/UserAccount.ral.json +++ b/artifacts/test/UserAccount.ral.json @@ -23,7 +23,6 @@ false ] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/test/Warnings.ral.json b/artifacts/test/Warnings.ral.json index 53702acd5..09a550d7f 100644 --- a/artifacts/test/Warnings.ral.json +++ b/artifacts/test/Warnings.ral.json @@ -17,7 +17,6 @@ false ] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/token/FakeTokenTest.ral.json b/artifacts/token/FakeTokenTest.ral.json index ec0e68ef2..626cfa353 100644 --- a/artifacts/token/FakeTokenTest.ral.json +++ b/artifacts/token/FakeTokenTest.ral.json @@ -14,7 +14,6 @@ false ] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/token/TokenTest.ral.json b/artifacts/token/TokenTest.ral.json index b98845da0..ea72fb647 100644 --- a/artifacts/token/TokenTest.ral.json +++ b/artifacts/token/TokenTest.ral.json @@ -26,7 +26,6 @@ false ] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/artifacts/ts/Add.ts b/artifacts/ts/Add.ts index 47584827b..cb04cb83a 100644 --- a/artifacts/ts/Add.ts +++ b/artifacts/ts/Add.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as AddContractJson } from "../add/Add.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -73,48 +75,35 @@ class Factory extends ContractFactory { tests = { add: async ( - params: Omit< - TestContractParams, - "initialMaps" + params: TestContractParamsWithoutMaps< + AddTypes.Fields, + { array: [bigint, bigint] } > - ): Promise< - Omit, "initialMaps"> - > => { + ): Promise> => { return testMethod(this, "add", params); }, addPrivate: async ( - params: Omit< - TestContractParams, - "initialMaps" + params: TestContractParamsWithoutMaps< + AddTypes.Fields, + { array: [bigint, bigint] } > - ): Promise< - Omit, "initialMaps"> - > => { + ): Promise> => { return testMethod(this, "addPrivate", params); }, createSubContract: async ( - params: Omit< - TestContractParams< - AddTypes.Fields, - { - a: bigint; - path: HexString; - subContractId: HexString; - payer: Address; - }, - never - >, - "initialMaps" + params: TestContractParamsWithoutMaps< + AddTypes.Fields, + { a: bigint; path: HexString; subContractId: HexString; payer: Address } > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "createSubContract", params); }, destroy: async ( - params: Omit< - TestContractParams, - "initialMaps" + params: TestContractParamsWithoutMaps< + AddTypes.Fields, + { caller: Address } > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "destroy", params); }, }; diff --git a/artifacts/ts/Assert.ts b/artifacts/ts/Assert.ts index 85b8c3ee7..a939b219f 100644 --- a/artifacts/ts/Assert.ts +++ b/artifacts/ts/Assert.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as AssertContractJson } from "../test/Assert.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -54,10 +56,10 @@ class Factory extends ContractFactory { tests = { test: async ( params?: Omit< - TestContractParams, - "testArgs" | "initialFields" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" | "initialFields" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "test", params === undefined ? {} : params); }, }; diff --git a/artifacts/ts/Debug.ts b/artifacts/ts/Debug.ts index a70a1e208..9b9b3351a 100644 --- a/artifacts/ts/Debug.ts +++ b/artifacts/ts/Debug.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as DebugContractJson } from "../test/Debug.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -41,10 +43,10 @@ class Factory extends ContractFactory { tests = { debug: async ( params?: Omit< - TestContractParams, - "testArgs" | "initialFields" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" | "initialFields" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "debug", params === undefined ? {} : params); }, }; diff --git a/artifacts/ts/DeprecatedNFTTest1.ts b/artifacts/ts/DeprecatedNFTTest1.ts index d8ff8079a..cc113c949 100644 --- a/artifacts/ts/DeprecatedNFTTest1.ts +++ b/artifacts/ts/DeprecatedNFTTest1.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as DeprecatedNFTTest1ContractJson } from "../nft/DeprecatedNFTTest1.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -72,10 +74,10 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getTokenUri", params); }, }; diff --git a/artifacts/ts/DeprecatedNFTTest2.ts b/artifacts/ts/DeprecatedNFTTest2.ts index 3d8cc1f05..586d6b783 100644 --- a/artifacts/ts/DeprecatedNFTTest2.ts +++ b/artifacts/ts/DeprecatedNFTTest2.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as DeprecatedNFTTest2ContractJson } from "../nft/DeprecatedNFTTest2.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -76,18 +78,18 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getTokenUri", params); }, getCollectionId: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getCollectionId", params); }, }; diff --git a/artifacts/ts/DeprecatedNFTTest3.ts b/artifacts/ts/DeprecatedNFTTest3.ts index 4df1d71c5..8903593a6 100644 --- a/artifacts/ts/DeprecatedNFTTest3.ts +++ b/artifacts/ts/DeprecatedNFTTest3.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as DeprecatedNFTTest3ContractJson } from "../nft/DeprecatedNFTTest3.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -72,18 +74,18 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getTokenUri", params); }, returnNothing: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "returnNothing", params); }, }; diff --git a/artifacts/ts/DeprecatedNFTTest4.ts b/artifacts/ts/DeprecatedNFTTest4.ts index 8c788437c..3cc43dc2c 100644 --- a/artifacts/ts/DeprecatedNFTTest4.ts +++ b/artifacts/ts/DeprecatedNFTTest4.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as DeprecatedNFTTest4ContractJson } from "../nft/DeprecatedNFTTest4.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -76,18 +78,18 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getTokenUri", params); }, getBool: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getBool", params); }, }; diff --git a/artifacts/ts/DeprecatedNFTTest5.ts b/artifacts/ts/DeprecatedNFTTest5.ts index dbf480583..8a9303156 100644 --- a/artifacts/ts/DeprecatedNFTTest5.ts +++ b/artifacts/ts/DeprecatedNFTTest5.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as DeprecatedNFTTest5ContractJson } from "../nft/DeprecatedNFTTest5.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -76,23 +78,18 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getTokenUri", params); }, returnMoreValues: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise< - Omit< - TestContractResult<[HexString, bigint, bigint], never>, - "initialMaps" - > - > => { + ): Promise> => { return testMethod(this, "returnMoreValues", params); }, }; diff --git a/artifacts/ts/DeprecatedNFTTest6.ts b/artifacts/ts/DeprecatedNFTTest6.ts index c9e7bb0d0..dedf477b7 100644 --- a/artifacts/ts/DeprecatedNFTTest6.ts +++ b/artifacts/ts/DeprecatedNFTTest6.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as DeprecatedNFTTest6ContractJson } from "../nft/DeprecatedNFTTest6.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -76,20 +78,18 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getTokenUri", params); }, getArray: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise< - Omit, "initialMaps"> - > => { + ): Promise> => { return testMethod(this, "getArray", params); }, }; diff --git a/artifacts/ts/DeprecatedNFTTest7.ts b/artifacts/ts/DeprecatedNFTTest7.ts index 919394e67..5d00f4e55 100644 --- a/artifacts/ts/DeprecatedNFTTest7.ts +++ b/artifacts/ts/DeprecatedNFTTest7.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as DeprecatedNFTTest7ContractJson } from "../nft/DeprecatedNFTTest7.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -76,20 +78,18 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getTokenUri", params); }, returnNegativeIndex: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise< - Omit, "initialMaps"> - > => { + ): Promise> => { return testMethod(this, "returnNegativeIndex", params); }, }; diff --git a/artifacts/ts/FakeTokenTest.ts b/artifacts/ts/FakeTokenTest.ts index 1a1cb7890..db52c258f 100644 --- a/artifacts/ts/FakeTokenTest.ts +++ b/artifacts/ts/FakeTokenTest.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as FakeTokenTestContractJson } from "../token/FakeTokenTest.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -83,42 +85,42 @@ class Factory extends ContractFactory< tests = { getSymbol: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getSymbol", params); }, getName: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getName", params); }, getDecimals: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getDecimals", params); }, getTotalSupply: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getTotalSupply", params); }, foo: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "foo", params); }, }; diff --git a/artifacts/ts/Greeter.ts b/artifacts/ts/Greeter.ts index b50465826..cd407f23a 100644 --- a/artifacts/ts/Greeter.ts +++ b/artifacts/ts/Greeter.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as GreeterContractJson } from "../greeter/Greeter.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -76,10 +78,10 @@ class Factory extends ContractFactory { tests = { greet: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "greet", params); }, }; diff --git a/artifacts/ts/MapTest.ts b/artifacts/ts/MapTest.ts index 4bac0717c..6dfc9d525 100644 --- a/artifacts/ts/MapTest.ts +++ b/artifacts/ts/MapTest.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as MapTestContractJson } from "../test/MapTest.ral.json"; import { getContractByCodeHash } from "./contracts"; diff --git a/artifacts/ts/MetaData.ts b/artifacts/ts/MetaData.ts index b684aaca5..f6c5ccae2 100644 --- a/artifacts/ts/MetaData.ts +++ b/artifacts/ts/MetaData.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as MetaDataContractJson } from "../test/MetaData.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -41,26 +43,26 @@ class Factory extends ContractFactory { tests = { foo: async ( params?: Omit< - TestContractParams, - "testArgs" | "initialFields" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" | "initialFields" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "foo", params === undefined ? {} : params); }, bar: async ( params?: Omit< - TestContractParams, - "testArgs" | "initialFields" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" | "initialFields" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "bar", params === undefined ? {} : params); }, baz: async ( params?: Omit< - TestContractParams, - "testArgs" | "initialFields" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" | "initialFields" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "baz", params === undefined ? {} : params); }, }; diff --git a/artifacts/ts/NFTCollectionTest.ts b/artifacts/ts/NFTCollectionTest.ts index 0ba6ebb47..1ee92e364 100644 --- a/artifacts/ts/NFTCollectionTest.ts +++ b/artifacts/ts/NFTCollectionTest.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as NFTCollectionTestContractJson } from "../nft/NFTCollectionTest.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -93,54 +95,42 @@ class Factory extends ContractFactory< tests = { getCollectionUri: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getCollectionUri", params); }, totalSupply: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "totalSupply", params); }, nftByIndex: async ( - params: Omit< - TestContractParams< - NFTCollectionTestTypes.Fields, - { index: bigint }, - never - >, - "initialMaps" + params: TestContractParamsWithoutMaps< + NFTCollectionTestTypes.Fields, + { index: bigint } > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "nftByIndex", params); }, validateNFT: async ( - params: Omit< - TestContractParams< - NFTCollectionTestTypes.Fields, - { nftId: HexString; nftIndex: bigint }, - never - >, - "initialMaps" + params: TestContractParamsWithoutMaps< + NFTCollectionTestTypes.Fields, + { nftId: HexString; nftIndex: bigint } > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "validateNFT", params); }, mint: async ( - params: Omit< - TestContractParams< - NFTCollectionTestTypes.Fields, - { nftUri: HexString }, - never - >, - "initialMaps" + params: TestContractParamsWithoutMaps< + NFTCollectionTestTypes.Fields, + { nftUri: HexString } > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "mint", params); }, }; diff --git a/artifacts/ts/NFTCollectionWithRoyaltyTest.ts b/artifacts/ts/NFTCollectionWithRoyaltyTest.ts index 32f0bd086..572ab2d15 100644 --- a/artifacts/ts/NFTCollectionWithRoyaltyTest.ts +++ b/artifacts/ts/NFTCollectionWithRoyaltyTest.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as NFTCollectionWithRoyaltyTestContractJson } from "../nft/NFTCollectionWithRoyaltyTest.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -100,98 +102,72 @@ class Factory extends ContractFactory< tests = { getCollectionUri: async ( params: Omit< - TestContractParams< + TestContractParamsWithoutMaps< NFTCollectionWithRoyaltyTestTypes.Fields, - never, never >, - "testArgs" | "initialMaps" + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getCollectionUri", params); }, totalSupply: async ( params: Omit< - TestContractParams< + TestContractParamsWithoutMaps< NFTCollectionWithRoyaltyTestTypes.Fields, - never, never >, - "testArgs" | "initialMaps" + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "totalSupply", params); }, nftByIndex: async ( - params: Omit< - TestContractParams< - NFTCollectionWithRoyaltyTestTypes.Fields, - { index: bigint }, - never - >, - "initialMaps" + params: TestContractParamsWithoutMaps< + NFTCollectionWithRoyaltyTestTypes.Fields, + { index: bigint } > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "nftByIndex", params); }, validateNFT: async ( - params: Omit< - TestContractParams< - NFTCollectionWithRoyaltyTestTypes.Fields, - { nftId: HexString; nftIndex: bigint }, - never - >, - "initialMaps" + params: TestContractParamsWithoutMaps< + NFTCollectionWithRoyaltyTestTypes.Fields, + { nftId: HexString; nftIndex: bigint } > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "validateNFT", params); }, royaltyAmount: async ( - params: Omit< - TestContractParams< - NFTCollectionWithRoyaltyTestTypes.Fields, - { tokenId: HexString; salePrice: bigint }, - never - >, - "initialMaps" + params: TestContractParamsWithoutMaps< + NFTCollectionWithRoyaltyTestTypes.Fields, + { tokenId: HexString; salePrice: bigint } > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "royaltyAmount", params); }, payRoyalty: async ( - params: Omit< - TestContractParams< - NFTCollectionWithRoyaltyTestTypes.Fields, - { payer: Address; amount: bigint }, - never - >, - "initialMaps" + params: TestContractParamsWithoutMaps< + NFTCollectionWithRoyaltyTestTypes.Fields, + { payer: Address; amount: bigint } > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "payRoyalty", params); }, withdrawRoyalty: async ( - params: Omit< - TestContractParams< - NFTCollectionWithRoyaltyTestTypes.Fields, - { recipient: Address; amount: bigint }, - never - >, - "initialMaps" + params: TestContractParamsWithoutMaps< + NFTCollectionWithRoyaltyTestTypes.Fields, + { recipient: Address; amount: bigint } > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "withdrawRoyalty", params); }, mint: async ( - params: Omit< - TestContractParams< - NFTCollectionWithRoyaltyTestTypes.Fields, - { nftUri: HexString }, - never - >, - "initialMaps" + params: TestContractParamsWithoutMaps< + NFTCollectionWithRoyaltyTestTypes.Fields, + { nftUri: HexString } > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "mint", params); }, }; diff --git a/artifacts/ts/NFTTest.ts b/artifacts/ts/NFTTest.ts index aaaa66b62..4c189e5fa 100644 --- a/artifacts/ts/NFTTest.ts +++ b/artifacts/ts/NFTTest.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as NFTTestContractJson } from "../nft/NFTTest.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -74,20 +76,18 @@ class Factory extends ContractFactory { tests = { getTokenUri: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getTokenUri", params); }, getCollectionIndex: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise< - Omit, "initialMaps"> - > => { + ): Promise> => { return testMethod(this, "getCollectionIndex", params); }, }; diff --git a/artifacts/ts/OwnerOnly.ts b/artifacts/ts/OwnerOnly.ts index c89419b82..d85626693 100644 --- a/artifacts/ts/OwnerOnly.ts +++ b/artifacts/ts/OwnerOnly.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as OwnerOnlyContractJson } from "../test/OwnerOnly.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -52,10 +54,10 @@ class Factory extends ContractFactory< tests = { testOwner: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "testOwner", params); }, }; diff --git a/artifacts/ts/Sub.ts b/artifacts/ts/Sub.ts index 414eab542..a52ec5c9c 100644 --- a/artifacts/ts/Sub.ts +++ b/artifacts/ts/Sub.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as SubContractJson } from "../sub/Sub.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -71,11 +73,11 @@ class Factory extends ContractFactory { tests = { sub: async ( - params: Omit< - TestContractParams, - "initialMaps" + params: TestContractParamsWithoutMaps< + SubTypes.Fields, + { array: [bigint, bigint] } > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "sub", params); }, }; diff --git a/artifacts/ts/TokenTest.ts b/artifacts/ts/TokenTest.ts index e2a6191b1..9f1843b43 100644 --- a/artifacts/ts/TokenTest.ts +++ b/artifacts/ts/TokenTest.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as TokenTestContractJson } from "../token/TokenTest.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -86,34 +88,34 @@ class Factory extends ContractFactory< tests = { getSymbol: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getSymbol", params); }, getName: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getName", params); }, getDecimals: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getDecimals", params); }, getTotalSupply: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getTotalSupply", params); }, }; diff --git a/artifacts/ts/UserAccount.ts b/artifacts/ts/UserAccount.ts index 752abb469..fdcc47d63 100644 --- a/artifacts/ts/UserAccount.ts +++ b/artifacts/ts/UserAccount.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as UserAccountContractJson } from "../test/UserAccount.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -73,35 +75,27 @@ class Factory extends ContractFactory< tests = { updateBalance: async ( - params: Omit< - TestContractParams< - UserAccountTypes.Fields, - { tokens: [TokenBalance, TokenBalance] }, - never - >, - "initialMaps" + params: TestContractParamsWithoutMaps< + UserAccountTypes.Fields, + { tokens: [TokenBalance, TokenBalance] } > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "updateBalance", params); }, updateAddress: async ( - params: Omit< - TestContractParams< - UserAccountTypes.Fields, - { newAddress: Address }, - never - >, - "initialMaps" + params: TestContractParamsWithoutMaps< + UserAccountTypes.Fields, + { newAddress: Address } > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "updateAddress", params); }, getBalances: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getBalances", params); }, }; diff --git a/artifacts/ts/Warnings.ts b/artifacts/ts/Warnings.ts index 51324db69..448900053 100644 --- a/artifacts/ts/Warnings.ts +++ b/artifacts/ts/Warnings.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as WarningsContractJson } from "../test/Warnings.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -51,15 +53,11 @@ class Factory extends ContractFactory { tests = { foo: async ( - params: Omit< - TestContractParams< - WarningsTypes.Fields, - { x: bigint; y: bigint }, - never - >, - "initialMaps" + params: TestContractParamsWithoutMaps< + WarningsTypes.Fields, + { x: bigint; y: bigint } > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "foo", params); }, }; diff --git a/artifacts/ts/WrongNFTTest.ts b/artifacts/ts/WrongNFTTest.ts index a33f9d996..2ed73d838 100644 --- a/artifacts/ts/WrongNFTTest.ts +++ b/artifacts/ts/WrongNFTTest.ts @@ -23,6 +23,8 @@ import { fetchContractState, ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, + TestContractResultWithoutMaps, } from "@alephium/web3"; import { default as WrongNFTTestContractJson } from "../nft/WrongNFTTest.ral.json"; import { getContractByCodeHash } from "./contracts"; @@ -77,20 +79,18 @@ class Factory extends ContractFactory< tests = { getTokenUri: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise, "initialMaps">> => { + ): Promise> => { return testMethod(this, "getTokenUri", params); }, getCollectionIndex: async ( params: Omit< - TestContractParams, - "testArgs" | "initialMaps" + TestContractParamsWithoutMaps, + "testArgs" > - ): Promise< - Omit, "initialMaps"> - > => { + ): Promise> => { return testMethod(this, "getCollectionIndex", params); }, }; diff --git a/contracts/test/map.ral b/contracts/test/map.ral index db8a57c3a..53e7be449 100644 --- a/contracts/test/map.ral +++ b/contracts/test/map.ral @@ -3,8 +3,8 @@ struct MapValue { mut balance: U256 } Contract MapTest() { - map[Address, MapValue] map0 - map[U256, U256] map1 + mapping[Address, MapValue] map0 + mapping[U256, U256] map1 @using(preapprovedAssets = true) pub fn insert(key: Address, value: MapValue) -> () { diff --git a/packages/cli/src/codegen.ts b/packages/cli/src/codegen.ts index ad05eb3ff..fde9632d6 100644 --- a/packages/cli/src/codegen.ts +++ b/packages/cli/src/codegen.ts @@ -267,9 +267,12 @@ function genContractStateType(contract: Contract): string { } function genMapsType(contract: Contract): string { - const mapFields = contract.mapsSig.map((mapSig) => { - const [key, value] = parseMapType(mapSig.type) - return `${mapSig.name}?: Map<${toTsType(key)}, ${toTsType(value)}>` + const mapsSig = contract.mapsSig + if (mapsSig === undefined) return '' + const mapFields = mapsSig.names.map((name, index) => { + const mapType = mapsSig.types[`${index}`] + const [key, value] = parseMapType(mapType) + return `${name}?: Map<${toTsType(key)}, ${toTsType(value)}>` }) return `{ ${mapFields.join(', ')} }` } @@ -282,27 +285,29 @@ function genTestMethod(contract: Contract, functionSig: node.FunctionSig): strin ? `{${formatParameters({ names: functionSig.paramNames, types: functionSig.paramTypes })}}` : 'never' const fieldsType = contractHasFields ? contractFieldType(contract.name, fieldsSig) : 'never' - const hasMapVars: boolean = contract.hasMapVars() - const mapsType = hasMapVars ? genMapsType(contract) : 'never' - const paramsType = `TestContractParams<${fieldsType}, ${argsType}, ${mapsType}>` - const omitList: string[] = [] - if (!funcHasArgs) omitList.push('testArgs') - if (!contractHasFields) omitList.push('initialFields') - if (!hasMapVars) omitList.push('initialMaps') + const hasMapVars: boolean = contract.mapsSig !== undefined + const mapsType = genMapsType(contract) + const baseParamsType = hasMapVars + ? `TestContractParams<${fieldsType}, ${argsType}, ${mapsType}>` + : `TestContractParamsWithoutMaps<${fieldsType}, ${argsType}>` const params = - omitList.length === 0 - ? `params: ${paramsType}` - : (omitList.length === 2 && !omitList.includes('initialMaps')) || omitList.length === 3 - ? `params?: Omit<${paramsType}, ${omitList.map((n) => `'${n}'`).join(' | ')}>` - : `params: Omit<${paramsType}, ${omitList.map((n) => `'${n}'`).join(' | ')}>` + funcHasArgs && contractHasFields + ? `params: ${baseParamsType}` + : funcHasArgs + ? `params: Omit<${baseParamsType}, 'initialFields'>` + : contractHasFields + ? `params: Omit<${baseParamsType}, 'testArgs'>` + : `params?: Omit<${baseParamsType}, 'testArgs' | 'initialFields'>` const tsReturnTypes = functionSig.returnTypes.map((tpe) => toTsType(tpe)) const baseRetType = tsReturnTypes.length === 0 - ? `TestContractResult` + ? 'null' : tsReturnTypes.length === 1 - ? `TestContractResult<${tsReturnTypes[0]}, ${mapsType}>` - : `TestContractResult<[${tsReturnTypes.join(', ')}], ${mapsType}>` - const retType = !hasMapVars ? `Omit<${baseRetType}, 'initialMaps'>` : baseRetType + ? tsReturnTypes[0] + : `[${tsReturnTypes.join(', ')}]` + const retType = hasMapVars + ? `TestContractResult<${baseRetType}, ${mapsType}>` + : `TestContractResultWithoutMaps<${baseRetType}>` const callParams = funcHasArgs || contractHasFields ? 'params' : 'params === undefined ? {} : params' return ` ${functionSig.name}: async (${params}): Promise<${retType}> => { @@ -410,7 +415,8 @@ function genContract(contract: Contract, artifactRelativePath: string): string { EventSubscribeOptions, EventSubscription, CallContractParams, CallContractResult, TestContractParams, ContractEvent, subscribeContractEvent, subscribeContractEvents, testMethod, callMethod, multicallMethods, fetchContractState, - ContractInstance, getContractEventsCurrentCount + ContractInstance, getContractEventsCurrentCount, + TestContractParamsWithoutMaps, TestContractResultWithoutMaps } from '@alephium/web3' import { default as ${contract.name}ContractJson } from '../${toUnixPath(artifactRelativePath)}' import { getContractByCodeHash } from './contracts' diff --git a/packages/cli/templates/react/src/artifacts/Greeter.ral.json b/packages/cli/templates/react/src/artifacts/Greeter.ral.json index 5a5cda0ae..308e89e6d 100644 --- a/packages/cli/templates/react/src/artifacts/Greeter.ral.json +++ b/packages/cli/templates/react/src/artifacts/Greeter.ral.json @@ -14,7 +14,6 @@ false ] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/packages/walletconnect/artifacts/Greeter.ral.json b/packages/walletconnect/artifacts/Greeter.ral.json index 04db9acb7..573d1d360 100644 --- a/packages/walletconnect/artifacts/Greeter.ral.json +++ b/packages/walletconnect/artifacts/Greeter.ral.json @@ -14,7 +14,6 @@ false ] }, - "mapsSig": [], "eventsSig": [], "functions": [ { diff --git a/packages/web3/src/api/api-alephium.ts b/packages/web3/src/api/api-alephium.ts index fa1f7d133..d74e2b12b 100644 --- a/packages/web3/src/api/api-alephium.ts +++ b/packages/web3/src/api/api-alephium.ts @@ -420,11 +420,11 @@ export interface CompileContractResult { codeHashDebug: string fields: FieldsSig functions: FunctionSig[] - maps: MapSig[] constants: Constant[] enums: Enum[] events: EventSig[] warnings: string[] + maps?: MapsSig stdInterfaceId?: string } @@ -659,9 +659,9 @@ export interface InternalServerError { detail: string } -export interface MapSig { - name: string - type: string +export interface MapsSig { + names: string[] + types: string[] } export interface MemPooled { diff --git a/packages/web3/src/contract/contract.ts b/packages/web3/src/contract/contract.ts index 1ebde83a7..9089d726b 100644 --- a/packages/web3/src/contract/contract.ts +++ b/packages/web3/src/contract/contract.ts @@ -84,7 +84,7 @@ import { const crypto = new WebCrypto() export type FieldsSig = node.FieldsSig -export type MapSig = node.MapSig +export type MapsSig = node.MapsSig export type EventSig = node.EventSig export type FunctionSig = node.FunctionSig export type Fields = NamedVals @@ -901,11 +901,11 @@ export class Contract extends Artifact { readonly bytecodeDebugPatch: string readonly codeHash: string readonly fieldsSig: FieldsSig - readonly mapsSig: MapSig[] readonly eventsSig: EventSig[] readonly constants: Constant[] readonly enums: Enum[] readonly structs: Struct[] + readonly mapsSig?: MapsSig readonly stdInterfaceId?: HexString readonly bytecodeDebug: string @@ -919,12 +919,12 @@ export class Contract extends Artifact { codeHash: string, codeHashDebug: string, fieldsSig: FieldsSig, - mapsSig: MapSig[], eventsSig: EventSig[], functions: FunctionSig[], constants: Constant[], enums: Enum[], structs: Struct[], + mapsSig?: MapsSig, stdInterfaceId?: HexString ) { super(version, name, functions) @@ -932,11 +932,11 @@ export class Contract extends Artifact { this.bytecodeDebugPatch = bytecodeDebugPatch this.codeHash = codeHash this.fieldsSig = fieldsSig - this.mapsSig = mapsSig this.eventsSig = eventsSig this.constants = constants this.enums = enums this.structs = structs + this.mapsSig = mapsSig this.stdInterfaceId = stdInterfaceId this.bytecodeDebug = ralph.buildDebugBytecode(this.bytecode, this.bytecodeDebugPatch) @@ -951,7 +951,6 @@ export class Contract extends Artifact { artifact.bytecode == null || artifact.codeHash == null || artifact.fieldsSig == null || - artifact.mapsSig == null || artifact.eventsSig == null || artifact.constants == null || artifact.enums == null || @@ -967,12 +966,12 @@ export class Contract extends Artifact { artifact.codeHash, codeHashDebug ? codeHashDebug : artifact.codeHash, artifact.fieldsSig, - artifact.mapsSig, artifact.eventsSig, artifact.functions, artifact.constants, artifact.enums, structs, + artifact.mapsSig === null ? undefined : artifact.mapsSig, artifact.stdInterfaceId === null ? undefined : artifact.stdInterfaceId ) return contract @@ -987,12 +986,12 @@ export class Contract extends Artifact { result.codeHash, result.codeHashDebug, result.fields, - result.maps, result.events, result.functions, result.constants, result.enums, structs, + result.maps, result.stdInterfaceId ) } @@ -1016,22 +1015,20 @@ export class Contract extends Artifact { bytecode: this.bytecode, codeHash: this.codeHash, fieldsSig: this.fieldsSig, - mapsSig: this.mapsSig, eventsSig: this.eventsSig, functions: this.functions, constants: this.constants, enums: this.enums } + if (this.mapsSig !== undefined) { + object.mapsSig = this.mapsSig + } if (this.stdInterfaceId !== undefined) { object.stdInterfaceId = this.stdInterfaceId } return JSON.stringify(object, null, 2) } - hasMapVars(): boolean { - return this.mapsSig.length > 0 - } - getInitialFieldsWithDefaultValues(): Fields { const fields = this.stdInterfaceId === undefined @@ -1568,6 +1565,11 @@ function toApiInputAssets(inputAssets?: InputAsset[]): node.TestInputAsset[] | u return typeof inputAssets !== 'undefined' ? inputAssets.map(toApiInputAsset) : undefined } +export type TestContractParamsWithoutMaps = Omit< + TestContractParams, + 'initialMaps' +> + export interface TestContractParams< F extends Fields = Fields, A extends Arguments = Arguments, @@ -1598,12 +1600,14 @@ export interface ContractEvent { export type DebugMessage = node.DebugMessage +export type TestContractResultWithoutMaps = Omit, 'maps'> + export interface TestContractResult> = Record>> { contractId: string contractAddress: string returns: R gasUsed: number - resultMaps?: M + maps?: M contracts: ContractState[] txOutputs: Output[] events: ContractEvent[] @@ -1954,12 +1958,14 @@ function mapsToExistingContracts( group: number, initialMaps: Record> ) { + const mapsSig = contract.mapsSig + if (mapsSig === undefined) return [] const contractStates: ContractState[] = [] Object.keys(initialMaps).forEach((name) => { - const index = contract.mapsSig.findIndex((m) => m.name === name) + const index = mapsSig.names.findIndex((n) => n === name) if (index === -1) throw new Error(`Map var ${name} does not exist in contract ${contract.name}`) - const mapSig = contract.mapsSig[`${index}`] - const states = mapToExistingContracts(contract, parentContractId, group, initialMaps[`${name}`], index, mapSig.type) + const mapType = mapsSig.types[`${index}`] + const states = mapToExistingContracts(contract, parentContractId, group, initialMaps[`${name}`], index, mapType) contractStates.push(...states) }) return contractStates @@ -1992,12 +1998,12 @@ export async function testMethod< existingContracts: (params.existingContracts ?? []).concat(contractStates) }) const apiResult = await getCurrentNodeProvider().contracts.postContractsTestContract(apiParams) - const resultMaps = existingContractsToMaps(contract, address, group, apiResult, initialMaps) + const maps = existingContractsToMaps(contract, address, group, apiResult, initialMaps) const testResult = contract.fromApiTestContractResult(methodName, apiResult, txId) contract.printDebugMessages(methodName, testResult.debugMessages) return { ...testResult, - resultMaps + maps } as TestContractResult } @@ -2010,10 +2016,12 @@ interface MapInfo { } function buildMapInfo(contract: Contract, fields: Fields): MapInfo[] { - return contract.mapsSig.map((mapSig, index) => { - const name = mapSig.name + const mapsSig = contract.mapsSig + if (mapsSig === undefined) return [] + return mapsSig.names.map((name, index) => { + const mapType = mapsSig.types[`${index}`] const value = (fields[`${name}`] ?? new Map()) as Map - const [keyType, valueType] = ralph.parseMapType(mapSig.type) + const [keyType, valueType] = ralph.parseMapType(mapType) return { name, value, keyType, valueType, index } }) } diff --git a/test/contract.test.ts b/test/contract.test.ts index 09a2920e0..c68a3d2b0 100644 --- a/test/contract.test.ts +++ b/test/contract.test.ts @@ -450,8 +450,8 @@ describe('contract', function () { testArgs: { key: signer.address, value: { id: 1n, balance: 10n } }, inputAssets: [{ address: signer.address, asset: { alphAmount: ONE_ALPH * 3n } }] }) - expect(insertResult.resultMaps?.map0?.get(signer.address)).toEqual({ id: 1n, balance: 10n }) - expect(insertResult.resultMaps?.map1?.get(1n)).toEqual(10n) + expect(insertResult.maps?.map0?.get(signer.address)).toEqual({ id: 1n, balance: 10n }) + expect(insertResult.maps?.map1?.get(1n)).toEqual(10n) const updateResult = await MapTest.tests.update({ initialMaps: { @@ -461,8 +461,8 @@ describe('contract', function () { testArgs: { key: signer.address }, inputAssets: [{ address: signer.address, asset: { alphAmount: ONE_ALPH } }] }) - expect(updateResult.resultMaps?.map0?.get(signer.address)).toEqual({ id: 1n, balance: 11n }) - expect(updateResult.resultMaps?.map1?.get(1n)).toEqual(11n) + expect(updateResult.maps?.map0?.get(signer.address)).toEqual({ id: 1n, balance: 11n }) + expect(updateResult.maps?.map1?.get(1n)).toEqual(11n) const removeResult = await MapTest.tests.remove({ initialMaps: { @@ -472,8 +472,8 @@ describe('contract', function () { testArgs: { key: signer.address }, inputAssets: [{ address: signer.address, asset: { alphAmount: ONE_ALPH } }] }) - expect(removeResult.resultMaps?.map0?.get(signer.address)).toEqual(undefined) - expect(removeResult.resultMaps?.map1?.get(1n)).toEqual(undefined) + expect(removeResult.maps?.map0?.get(signer.address)).toEqual(undefined) + expect(removeResult.maps?.map1?.get(1n)).toEqual(undefined) }) it('should test map(integration test)', async () => { From f86421d9578260a3b1e87ae58623264135071899 Mon Sep 17 00:00:00 2001 From: Cheng Wang Date: Sat, 30 Mar 2024 09:10:37 +0100 Subject: [PATCH 22/24] Use node rhone-0.4.0 --- docker/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index e67d53ec2..2ea1b5992 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -31,7 +31,7 @@ services: condition: service_healthy alephium: - image: alephium/dev-alephium:rhone-0.3.0 + image: alephium/dev-alephium:rhone-0.4.0 restart: unless-stopped ports: - 19973:19973/tcp From eea97713ef329e6e807557094cacf97faa1890cc Mon Sep 17 00:00:00 2001 From: Cheng Wang Date: Sat, 30 Mar 2024 09:16:57 +0100 Subject: [PATCH 23/24] Update schema --- packages/web3/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web3/package.json b/packages/web3/package.json index 5c215b6c0..03b10ac0a 100644 --- a/packages/web3/package.json +++ b/packages/web3/package.json @@ -34,7 +34,7 @@ "build": "rm -rf dist/* && npx tsc --build . && webpack", "test": "jest -i --config ./jest-config.json", "update-schemas": "npm run update-schema:alephium && npm run update-schema:explorer", - "update-schema:alephium": "npx swagger-typescript-api --disable-throw-on-error -t ./configs -o ./src/api -n api-alephium.ts -p https://raw.githubusercontent.com/alephium/alephium/v${npm_package_config_alephium_version}/api/src/main/resources/openapi.json", + "update-schema:alephium": "npx swagger-typescript-api --disable-throw-on-error -t ./configs -o ./src/api -n api-alephium.ts -p https://raw.githubusercontent.com/alephium/alephium/rhone-upgrade/api/src/main/resources/openapi.json", "update-schema:explorer": "npx swagger-typescript-api --disable-throw-on-error -t ./configs -o ./src/api -n api-explorer.ts -p https://raw.githubusercontent.com/alephium/explorer-backend/v${npm_package_config_explorer_backend_version}/app/src/main/resources/explorer-backend-openapi.json", "check-versions": "node scripts/check-versions.js ${npm_package_config_alephium_version} ${npm_package_config_explorer_backend_version}" }, From c49cb4cafdb1fde884a8f2ccf7100203c2979a60 Mon Sep 17 00:00:00 2001 From: Cheng Wang Date: Sat, 30 Mar 2024 09:25:46 +0100 Subject: [PATCH 24/24] 0.38.0 --- packages/cli/package.json | 2 +- packages/cli/templates/base/package.json | 8 ++++---- packages/cli/templates/react/package.json | 2 +- packages/get-extension-wallet/package.json | 2 +- packages/walletconnect/package.json | 2 +- packages/web3-react/package.json | 2 +- packages/web3-test/package.json | 2 +- packages/web3-wallet/package.json | 2 +- packages/web3/package.json | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 29101406c..8b96a6c77 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@alephium/cli", - "version": "0.37.0", + "version": "0.38.0", "description": "Alephium command line tool", "license": "GPL", "repository": { diff --git a/packages/cli/templates/base/package.json b/packages/cli/templates/base/package.json index aeeae8d46..13ef38304 100644 --- a/packages/cli/templates/base/package.json +++ b/packages/cli/templates/base/package.json @@ -14,10 +14,10 @@ "test": "jest -i --config ./jest-config.json" }, "dependencies": { - "@alephium/cli": "^0.37.0", - "@alephium/web3": "^0.37.0", - "@alephium/web3-test": "^0.37.0", - "@alephium/web3-wallet": "^0.37.0" + "@alephium/cli": "^0.38.0", + "@alephium/web3": "^0.38.0", + "@alephium/web3-test": "^0.38.0", + "@alephium/web3-wallet": "^0.38.0" }, "devDependencies": { "@types/jest": "^27.5.1", diff --git a/packages/cli/templates/react/package.json b/packages/cli/templates/react/package.json index cfc56659f..d58bfb224 100644 --- a/packages/cli/templates/react/package.json +++ b/packages/cli/templates/react/package.json @@ -9,7 +9,7 @@ "@types/node": "^16.18.23", "@types/react": "^18.0.3", "@types/react-dom": "^18.0.0", - "@alephium/web3": "^0.37.0", + "@alephium/web3": "^0.38.0", "react": "^18.0.0", "react-dom": "^18.0.0", "react-scripts": "5.0.1", diff --git a/packages/get-extension-wallet/package.json b/packages/get-extension-wallet/package.json index 5d457bc16..9adb75c2c 100644 --- a/packages/get-extension-wallet/package.json +++ b/packages/get-extension-wallet/package.json @@ -1,6 +1,6 @@ { "name": "@alephium/get-extension-wallet", - "version": "0.37.0", + "version": "0.38.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { diff --git a/packages/walletconnect/package.json b/packages/walletconnect/package.json index c0826211c..c77c9b6bc 100644 --- a/packages/walletconnect/package.json +++ b/packages/walletconnect/package.json @@ -1,7 +1,7 @@ { "name": "@alephium/walletconnect-provider", "description": "Alephium Provider for WalletConnect Protocol", - "version": "0.37.0", + "version": "0.38.0", "author": "Alephium dev", "homepage": "https://github.com/alephium/walletconnect", "repository": { diff --git a/packages/web3-react/package.json b/packages/web3-react/package.json index e80e0d058..6708fbbed 100644 --- a/packages/web3-react/package.json +++ b/packages/web3-react/package.json @@ -1,6 +1,6 @@ { "name": "@alephium/web3-react", - "version": "0.37.0", + "version": "0.38.0", "homepage": "https://github.com/alephium/alephium-web3-react", "license": "GPL", "description": "React components for Alephium Web3.", diff --git a/packages/web3-test/package.json b/packages/web3-test/package.json index 097c2fe74..9b3cbdc36 100644 --- a/packages/web3-test/package.json +++ b/packages/web3-test/package.json @@ -1,6 +1,6 @@ { "name": "@alephium/web3-test", - "version": "0.37.0", + "version": "0.38.0", "description": "Utility functions for Alephium test", "keywords": [ "alephium", diff --git a/packages/web3-wallet/package.json b/packages/web3-wallet/package.json index 2179b9a2d..6d4d0cbdc 100644 --- a/packages/web3-wallet/package.json +++ b/packages/web3-wallet/package.json @@ -1,6 +1,6 @@ { "name": "@alephium/web3-wallet", - "version": "0.37.0", + "version": "0.38.0", "description": "Simple wallets for Alephium", "keywords": [ "alephium", diff --git a/packages/web3/package.json b/packages/web3/package.json index 03b10ac0a..186ddba93 100644 --- a/packages/web3/package.json +++ b/packages/web3/package.json @@ -1,6 +1,6 @@ { "name": "@alephium/web3", - "version": "0.37.0", + "version": "0.38.0", "description": "A JS/TS library to interact with the Alephium platform", "license": "GPL", "main": "dist/src/index.js",