Skip to content

Commit 20dea03

Browse files
Merge pull request #113 from Concordium/serialize-type-value
Add function to serialize parameters with the direct type schemas
2 parents 900ae77 + f462041 commit 20dea03

File tree

15 files changed

+259
-17
lines changed

15 files changed

+259
-17
lines changed

packages/common/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## 6.2.0 2023-01-04
4+
5+
### Added
6+
7+
- `serializeTypeValue` that allows smart contract types to be serialized using the specific schema, instead of only by providing the entire module's schema.
8+
- `getInitContractParameterSchema` Given a buffer containing the schema for a module, extract the schema for a given contract's init function's parameters.
9+
- `getReceiveContractParameterSchema` Given a buffer containing the schema for a module, extract the schema for a given contract's receive methods' parameters.
10+
311
## 6.1.0 2022-11-30
412

513
### Added

packages/common/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,26 @@ const updateContractTransaction: AccountTransaction = {
447447
```
448448
Finally, to actually update the contract on the chain, send the constructed `updateContractTransaction` to the chain using `sendAccountTransaction`. (See [Send Account Transaction](#Send-Account-Transaction) for how to do this)
449449

450+
## Serialize parameters with only the specific type's schema
451+
In the previous section the schema used was assumed to be the schema for an entire module. In some cases one might want to use a schema containing only the specific type of the parameter.
452+
453+
For this, the function `serializeTypeValue` can used.
454+
```
455+
const inputParams = serializeTypeValue(userInput, rawTypeSchema);
456+
```
457+
458+
For reference, the type schema for parameters can be extracted using the functions `getInitContractParameterSchema` and `getUpdateContractParameterSchema`.
459+
460+
```
461+
const rawTypeSchema = getUpdateContractParameterSchema(
462+
rawModuleSchema,
463+
contractName,
464+
receiveFunctionName,
465+
userInput,
466+
schemaVersion
467+
)
468+
```
469+
450470
# Utility functions
451471

452472
## Generate account alias

packages/common/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@concordium/common-sdk",
3-
"version": "6.1.0",
3+
"version": "6.2.0",
44
"license": "Apache-2.0",
55
"engines": {
66
"node": ">=14.16.0"
@@ -39,7 +39,7 @@
3939
"build": "tsc"
4040
},
4141
"dependencies": {
42-
"@concordium/rust-bindings": "0.8.0",
42+
"@concordium/rust-bindings": "0.9.0",
4343
"@noble/ed25519": "^1.7.1",
4444
"@scure/bip39": "^1.1.0",
4545
"bs58check": "^2.1.2",

packages/common/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export {
1111
serializeAccountTransactionForSubmission,
1212
serializeCredentialDeploymentTransactionForSubmission,
1313
getSignedCredentialDeploymentTransactionHash,
14+
serializeTypeValue,
1415
} from './serialization';
1516
export { sha256 };
1617
export { CredentialRegistrationId } from './types/CredentialRegistrationId';
@@ -42,6 +43,7 @@ export * from './accountHelpers';
4243
export * from './blockSummaryHelpers';
4344
export * from './rewardStatusHelpers';
4445
export * from './HdWallet';
46+
export * from './schemaHelpers';
4547

4648
export { isHex } from './util';
4749

packages/common/src/schemaHelpers.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { Buffer } from 'buffer/';
2+
import { SchemaVersion } from './types';
3+
import * as wasm from '@concordium/rust-bindings';
4+
5+
/**
6+
* @param moduleSchema buffer for the schema of a module that contains the contract
7+
* @param contractName name of the contract that the init contract transaction will initialize
8+
* @param schemaVersion the version of the schema provided
9+
* @returns buffer containing the schema for of init contract parameters
10+
*/
11+
export function getInitContractParameterSchema(
12+
moduleSchema: Buffer,
13+
contractName: string,
14+
schemaVersion?: SchemaVersion
15+
): Buffer {
16+
const parameterSchema = wasm.getInitContractParameterSchema(
17+
moduleSchema.toString('hex'),
18+
contractName,
19+
schemaVersion
20+
);
21+
try {
22+
return Buffer.from(parameterSchema, 'hex');
23+
} catch (e) {
24+
throw new Error(
25+
'unable to get parameter schema, due to: ' + parameterSchema
26+
); // In this case parameterSchema is the error message from the rust module
27+
}
28+
}
29+
30+
/**
31+
* @param moduleSchema buffer for the schema of a module that contains the contract
32+
* @param contractName name of the contract that the update contract transaction will update
33+
* @param receiveFunctionName name of function that the update contract transaction will invoke
34+
* @param schemaVersion the version of the schema provided
35+
* @returns buffer containing the schema for of update contract parameters
36+
*/
37+
export function getUpdateContractParameterSchema(
38+
moduleSchema: Buffer,
39+
contractName: string,
40+
receiveFunctionName: string,
41+
schemaVersion?: SchemaVersion
42+
): Buffer {
43+
const parameterSchema = wasm.getReceiveContractParameterSchema(
44+
moduleSchema.toString('hex'),
45+
contractName,
46+
receiveFunctionName,
47+
schemaVersion
48+
);
49+
try {
50+
return Buffer.from(parameterSchema, 'hex');
51+
} catch (e) {
52+
throw new Error(
53+
'unable to get parameter schema, due to: ' + parameterSchema
54+
); // In this case parameterSchema is the error message from the rust module
55+
}
56+
}

packages/common/src/serialization.ts

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ export function getCredentialForExistingAccountSignDigest(
362362

363363
/**
364364
* Returns the digest of the credential deployment transaction that has to be signed.
365-
* @param credentialDeploymentTransaction the credential deployment transaction
365+
* @param credentialDeployment the credential deployment transaction
366366
* @returns the sha256 of the serialized unsigned credential deployment information
367367
*/
368368
export function getCredentialDeploymentSignDigest(
@@ -392,7 +392,7 @@ interface DeploymentDetailsResult {
392392
/**
393393
* Gets the transaction hash that is used to look up the status of a credential
394394
* deployment transaction.
395-
* @param credentialDeploymentTransaction the transaction to hash
395+
* @param credentialDeployment the transaction to hash
396396
* @param signatures the signatures that will also be part of the hash
397397
* @returns the sha256 hash of the serialized block item kind, signatures, and credential deployment transaction
398398
*/
@@ -413,7 +413,7 @@ export function getCredentialDeploymentTransactionHash(
413413
/**
414414
* Serializes a credential deployment transaction of a new account, so that it is ready for being
415415
* submitted to the node.
416-
* @param credentialDeploymentTransaction the credenetial deployment transaction
416+
* @param credentialDeployment the credenetial deployment transaction
417417
* @param signatures the signatures on the hash of unsigned credential deployment information
418418
* @returns the serialization of the credential deployment transaction ready for being submitted to a node
419419
*/
@@ -468,7 +468,6 @@ export function serializeInitContractParameters(
468468
* @param schemaVersion the version of the schema provided
469469
* @returns serialized buffer of update contract parameters
470470
*/
471-
472471
export function serializeUpdateContractParameters(
473472
contractName: string,
474473
receiveFunctionName: string,
@@ -493,6 +492,30 @@ export function serializeUpdateContractParameters(
493492
}
494493
}
495494

495+
/**
496+
* Given a value for a smart contract type, and the raw schema for that type, serialize the value into binary format.
497+
* @param value the value that should be serialized. Should correspond to the JSON representation
498+
* @param rawSchema the schema for the type that the given value should be serialized as
499+
* @returns serialized buffer of the value
500+
*/
501+
export function serializeTypeValue(
502+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
503+
value: any,
504+
rawSchema: Buffer
505+
): Buffer {
506+
const serializedValue = wasm.serializeTypeValue(
507+
JSON.stringify(value),
508+
rawSchema.toString('hex')
509+
);
510+
try {
511+
return Buffer.from(serializedValue, 'hex');
512+
} catch (e) {
513+
throw new Error(
514+
'unable to deserialize value, due to: ' + serializedValue
515+
); // In this case serializedValue is the error message from the rust module
516+
}
517+
}
518+
496519
function serializeSignedCredentialDeploymentDetails(
497520
credentialDetails: SignedCredentialDeploymentDetails
498521
): Buffer {

packages/common/test/serialization.test.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
serializeAccountTransactionForSubmission,
77
serializeAccountTransactionSignature,
88
serializeUpdateContractParameters,
9+
serializeTypeValue,
910
} from '../src/serialization';
1011
import {
1112
AccountTransaction,
@@ -23,6 +24,7 @@ import {
2324
serializeULeb128,
2425
} from '../src/serializationHelpers';
2526
import { SizeLength } from '../src/deserializeSchema';
27+
import { getUpdateContractParameterSchema } from '../src';
2628

2729
test('fail account transaction serialization if no signatures', () => {
2830
const simpleTransferPayload: SimpleTransferPayload = {
@@ -100,6 +102,50 @@ test('serialize UpdateContractParameters using CIS2 contract', () => {
100102
);
101103
});
102104

105+
test('serialize type value and serializeUpdateContractParameters give same result', () => {
106+
const parameters = [
107+
{
108+
token_id: [],
109+
amount: [200, 0],
110+
from: {
111+
Account: ['4RgTGQhg1Y8DAUkC2TpZsKmXdicArDqY9gcgJmBDECg4kkYNg4'],
112+
},
113+
to: {
114+
Account: ['3UiNwnmZ64YR423uamgZyY8RnRkD88tfn6SYtKzvWZCkyFdN94'],
115+
},
116+
data: [],
117+
},
118+
];
119+
const fullSchema = Buffer.from(
120+
fs.readFileSync('./test/resources/cis2-nft-schema.bin')
121+
);
122+
const schemaVersion = 1;
123+
const contractName = 'CIS2-NFT';
124+
const functionName = 'transfer';
125+
126+
const serializedParameter = serializeUpdateContractParameters(
127+
contractName,
128+
functionName,
129+
parameters,
130+
fullSchema,
131+
schemaVersion
132+
);
133+
134+
const serializedType = serializeTypeValue(
135+
parameters,
136+
getUpdateContractParameterSchema(
137+
fullSchema,
138+
contractName,
139+
functionName,
140+
schemaVersion
141+
)
142+
);
143+
144+
expect(serializedParameter.toString('hex')).toEqual(
145+
serializedType.toString('hex')
146+
);
147+
});
148+
103149
test('serialize ULeb128', () => {
104150
let parameter = serializeULeb128(
105151
{ typeTag: ParameterType.ULeb128, constraint: 5 },

packages/nodejs/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
"build": "rm -rf grpc; mkdir -p grpc; yarn generate && tsc"
5858
},
5959
"dependencies": {
60-
"@concordium/common-sdk": "6.1.0",
60+
"@concordium/common-sdk": "6.2.0",
6161
"@grpc/grpc-js": "^1.3.4",
6262
"@protobuf-ts/grpc-transport": "2.8.1",
6363
"buffer": "^6.0.3",

packages/rust-bindings/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## 0.9.0 2023-1-4
4+
5+
### Added
6+
7+
- `serializeTypeValue`
8+
- `getInitContractParameterSchema`
9+
- `getReceiveContractParameterSchema`
10+
311
## 0.8.0 2022-11-30
412

513
### Added

packages/rust-bindings/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@concordium/rust-bindings",
3-
"version": "0.8.0",
3+
"version": "0.9.0",
44
"license": "Apache-2.0",
55
"engines": {
66
"node": ">=14.16.0"

0 commit comments

Comments
 (0)