Skip to content

Commit

Permalink
add deploy intent and unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
popenta committed Sep 4, 2023
1 parent 2099f3d commit a8091a9
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 8 deletions.
62 changes: 62 additions & 0 deletions src/testdata/adder.abi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"buildInfo": {
"rustc": {
"version": "1.71.0-nightly",
"commitHash": "7f94b314cead7059a71a265a8b64905ef2511796",
"commitDate": "2023-04-23",
"channel": "Nightly",
"short": "rustc 1.71.0-nightly (7f94b314c 2023-04-23)"
},
"contractCrate": {
"name": "adder",
"version": "0.0.0"
},
"framework": {
"name": "multiversx-sc",
"version": "0.41.3"
}
},
"docs": [
"One of the simplest smart contracts possible,",
"it holds a single variable in storage, which anyone can increment."
],
"name": "Adder",
"constructor": {
"inputs": [
{
"name": "initial_value",
"type": "BigUint"
}
],
"outputs": []
},
"endpoints": [
{
"name": "getSum",
"mutability": "readonly",
"inputs": [],
"outputs": [
{
"type": "BigUint"
}
]
},
{
"docs": [
"Add desired amount to the storage variable."
],
"name": "add",
"mutability": "mutable",
"inputs": [
{
"name": "value",
"type": "BigUint"
}
],
"outputs": []
}
],
"events": [],
"hasCallback": false,
"types": {}
}
Binary file added src/testdata/adder.wasm
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { assert, expect } from "chai";
import { SmartContractTransactionIntentsFactory } from "./smartContractTransactionIntentsFactory";
import { Address } from "../address";
import { Code } from "../smartcontracts/code";
import { promises } from "fs";
import { AbiRegistry } from "../smartcontracts/typesystem/abiRegistry";
import { U32Value } from "../smartcontracts";
import { CONTRACT_DEPLOY_ADDRESS } from "../constants";

describe("test smart contract intents factory", function () {
let smartContractIntentsFactory: SmartContractTransactionIntentsFactory;
let abiSmartContractIntentsFactory: SmartContractTransactionIntentsFactory;
let adderByteCode: Code;
let abiRegistry: AbiRegistry;

before(async function () {
smartContractIntentsFactory = new SmartContractTransactionIntentsFactory({ chainID: "D", minGasLimit: 50000, gasLimitPerByte: 1500 });
let adderBuffer = await promises.readFile("src/testdata/adder.wasm");
adderByteCode = Code.fromBuffer(adderBuffer);

let abiJson = await promises.readFile("src/testdata/adder.abi.json", { encoding: "utf8" });
let abiObj = JSON.parse(abiJson);
abiRegistry = AbiRegistry.create(abiObj);

abiSmartContractIntentsFactory = new SmartContractTransactionIntentsFactory({ chainID: "D", minGasLimit: 50000, gasLimitPerByte: 1500 }, abiRegistry);
});

it("should throw error", async function () {
const sender = Address.fromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th");
const gasLimit = 6000000;
const args = [0];
try {
smartContractIntentsFactory.createTransactionIntentForDeploy(sender, adderByteCode.valueOf(), gasLimit, args);
}
catch (err) {
expect(err.message).to.equal("Can't convert args to TypedValues");
}
});

it("should build deploy intent", async function () {
const sender = Address.fromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th");
const gasLimit = 6000000;
const args = [new U32Value(0)];

const deployIntent = smartContractIntentsFactory.createTransactionIntentForDeploy(sender, adderByteCode.valueOf(), gasLimit, args);
const abiDeployIntent = abiSmartContractIntentsFactory.createTransactionIntentForDeploy(sender, adderByteCode.valueOf(), gasLimit, args);

assert.equal(deployIntent.sender, "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th");
assert.equal(deployIntent.receiver, CONTRACT_DEPLOY_ADDRESS);
assert.isDefined(deployIntent.data);

if (deployIntent.data) {
const expectedGasLimit = 6000000 + 50000 + 1500 * deployIntent.data.length;
assert.equal(deployIntent.gasLimit.valueOf(), expectedGasLimit);
}
assert.equal(deployIntent.value, 0);

assert.deepEqual(deployIntent, abiDeployIntent);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { BigNumber } from "bignumber.js";
import { IAddress } from "../interface";
import { TransactionIntent } from "../transactionIntent";
import { AbiRegistry, ArgSerializer, CodeMetadata, TypedValue } from "../smartcontracts";
import { utf8ToHex } from "../utils.codec";
import { byteArrayToHex } from "../utils.codec";
import { CONTRACT_DEPLOY_ADDRESS, VM_TYPE_WASM_VM } from "../constants";
import { NativeSerializer } from "../smartcontracts/nativeSerializer";
import { Err } from "../errors";
Expand Down Expand Up @@ -32,12 +32,12 @@ export class SmartContractTransactionIntentsFactory {
isUpgradeable: boolean = true,
isReadable: boolean = true,
isPayable: boolean = false,
isPayableBySmartContract: boolean = false
isPayableBySmartContract: boolean = true
): TransactionIntent {
const metadata = new CodeMetadata(isUpgradeable, isReadable, isPayable, isPayableBySmartContract);
let parts = [
utf8ToHex(bytecode.toString()),
utf8ToHex(VM_TYPE_WASM_VM.toString()),
byteArrayToHex(bytecode),
byteArrayToHex(VM_TYPE_WASM_VM),
metadata.toString()
];

Expand All @@ -52,7 +52,7 @@ export class SmartContractTransactionIntentsFactory {
).build()
}

private argsToStrings(args: any): string[] {
private argsToStrings(args: any[]): string[] {
if (this.abiRegistry !== undefined) {
const constructorDefinition = this.abiRegistry.constructorDefinition
const typedArgs = NativeSerializer.nativeToTypedValues(args, constructorDefinition)
Expand Down
6 changes: 3 additions & 3 deletions src/transactionIntentsFactories/transactionIntentBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ export class TransactionIntentBuilder {
}

private computeGasLimit(payload: ITransactionPayload, executionGasLimit: BigNumber.Value): BigNumber.Value {
const dataMovementGas = new BigNumber(this.config.minGasLimit).plus(new BigNumber(this.config.gasLimitPerByte).plus(new BigNumber(payload.length())));
const dataMovementGas = new BigNumber(this.config.minGasLimit).plus(new BigNumber(this.config.gasLimitPerByte).multipliedBy(new BigNumber(payload.length())));
const gasLimit = new BigNumber(dataMovementGas).plus(new BigNumber(executionGasLimit));
return gasLimit;
}

private buildTransactionPayload(dataParts: string[]): ITransactionPayload {
private buildTransactionPayload(dataParts: string[]): TransactionPayload {
const data = dataParts.join(ARGUMENTS_SEPARATOR);
return new TransactionPayload(data);
}
Expand All @@ -46,7 +46,7 @@ export class TransactionIntentBuilder {
this.sender.bech32(),
this.receiver.bech32(),
gasLimit,
this.value !== 0 ? this.value : 0,
this.value !== undefined ? this.value : 0,
data.valueOf()
)
}
Expand Down
4 changes: 4 additions & 0 deletions src/utils.codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@ export function utf8ToHex(value: string) {
const hex = Buffer.from(value).toString("hex");
return zeroPadStringIfOddLength(hex);
}

export function byteArrayToHex(byteArray: Uint8Array): string {
return Buffer.from(byteArray).toString("hex");
}

0 comments on commit a8091a9

Please sign in to comment.