Skip to content

Commit

Permalink
smart contract transaction intents factory
Browse files Browse the repository at this point in the history
  • Loading branch information
popenta committed Sep 4, 2023
1 parent a8091a9 commit 7db0a4a
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,52 @@ describe("test smart contract intents factory", function () {

assert.deepEqual(deployIntent, abiDeployIntent);
});

it("should build execute intent", async function () {
const sender = Address.fromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th");
const contract = Address.fromBech32("erd1qqqqqqqqqqqqqpgqhy6nl6zq07rnzry8uyh6rtyq0uzgtk3e69fqgtz9l4");
const func = "add";
const gasLimit = 6000000;
const args = [new U32Value(7)];

const deployIntent = smartContractIntentsFactory.createTransactionIntentForExecute(sender, contract, func, gasLimit, args);
const abiDeployIntent = abiSmartContractIntentsFactory.createTransactionIntentForExecute(sender, contract, func, gasLimit, args);

assert.equal(deployIntent.sender, "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th");
assert.equal(deployIntent.receiver, "erd1qqqqqqqqqqqqqpgqhy6nl6zq07rnzry8uyh6rtyq0uzgtk3e69fqgtz9l4");

assert.isDefined(deployIntent.data);
let decoder = new TextDecoder();
assert.equal(decoder.decode(deployIntent.data), "add@07");

assert.equal(deployIntent.gasLimit.valueOf(), 6059000);
assert.equal(deployIntent.value, 0);

assert.deepEqual(deployIntent, abiDeployIntent);
});

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

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

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

if (deployIntent.data) {
let decoder = new TextDecoder();
assert(decoder.decode(deployIntent.data).startsWith("upgradeContract@", 0));

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
@@ -1,7 +1,7 @@
import { BigNumber } from "bignumber.js";
import { IAddress } from "../interface";
import { TransactionIntent } from "../transactionIntent";
import { AbiRegistry, ArgSerializer, CodeMetadata, TypedValue } from "../smartcontracts";
import { AbiRegistry, ArgSerializer, CodeMetadata, EndpointDefinition, TypedValue } from "../smartcontracts";
import { byteArrayToHex } from "../utils.codec";
import { CONTRACT_DEPLOY_ADDRESS, VM_TYPE_WASM_VM } from "../constants";
import { NativeSerializer } from "../smartcontracts/nativeSerializer";
Expand Down Expand Up @@ -29,10 +29,10 @@ export class SmartContractTransactionIntentsFactory {
bytecode: Uint8Array,
gasLimit: BigNumber.Value,
args: any[],
isUpgradeable: boolean = true,
isReadable: boolean = true,
isPayable: boolean = false,
isPayableBySmartContract: boolean = true
isUpgradeable = true,
isReadable = true,
isPayable = false,
isPayableBySmartContract = true
): TransactionIntent {
const metadata = new CodeMetadata(isUpgradeable, isReadable, isPayable, isPayableBySmartContract);
let parts = [
Expand All @@ -41,22 +41,92 @@ export class SmartContractTransactionIntentsFactory {
metadata.toString()
];

parts = parts.concat(this.argsToStrings(args));
let preparedArgs: string[];
if (this.abiRegistry) {
preparedArgs = this.argsToStrings(args, this.abiRegistry.constructorDefinition)
}
else {
preparedArgs = this.argsToStrings(args)
}
parts = parts.concat(preparedArgs);

return new TransactionIntentBuilder(
this.config,
sender,
Address.fromBech32(CONTRACT_DEPLOY_ADDRESS),
parts,
gasLimit
).build()
).build();
}

private argsToStrings(args: any[]): string[] {
if (this.abiRegistry !== undefined) {
const constructorDefinition = this.abiRegistry.constructorDefinition
const typedArgs = NativeSerializer.nativeToTypedValues(args, constructorDefinition)
return new ArgSerializer().valuesToStrings(args);
createTransactionIntentForExecute(
sender: IAddress,
contractAddress: IAddress,
func: string,
gasLimit: BigNumber.Value,
args: any[] = []
): TransactionIntent {
let parts: string[] = [func];

let preparedArgs: string[];
if (this.abiRegistry) {
preparedArgs = this.argsToStrings(args, this.abiRegistry.getEndpoint(func));
}
else {
preparedArgs = this.argsToStrings(args);
}
parts = parts.concat(preparedArgs);

return new TransactionIntentBuilder(
this.config,
sender,
contractAddress,
parts,
gasLimit
).build();
}

createTransactionIntentForUpgrade(
sender: IAddress,
contract: IAddress,
bytecode: Uint8Array,
gasLimit: BigNumber.Value,
args: any[],
isUpgradeable = true,
isReadable = true,
isPayable = false,
isPayableBySmartContract = true
): TransactionIntent {
const metadata = new CodeMetadata(isUpgradeable, isReadable, isPayable, isPayableBySmartContract);

let parts = [
"upgradeContract",
byteArrayToHex(bytecode),
metadata.toString()
];

let preparedArgs: string[];
if (this.abiRegistry) {
preparedArgs = this.argsToStrings(args, this.abiRegistry.constructorDefinition)
}
else {
preparedArgs = this.argsToStrings(args)
}
parts = parts.concat(preparedArgs);

return new TransactionIntentBuilder(
this.config,
sender,
contract,
parts,
gasLimit
).build();
}

private argsToStrings(args: any[], endpoint?: EndpointDefinition): string[] {
if (endpoint) {
const typedArgs = NativeSerializer.nativeToTypedValues(args, endpoint)
return new ArgSerializer().valuesToStrings(typedArgs);
}

if (this.areArgsOfTypedValue(args)) {
Expand Down
7 changes: 3 additions & 4 deletions src/transactionIntentsFactories/transactionIntentBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,15 @@ export class TransactionIntentBuilder {
return gasLimit;
}

private buildTransactionPayload(dataParts: string[]): TransactionPayload {
const data = dataParts.join(ARGUMENTS_SEPARATOR);
private buildTransactionPayload(): TransactionPayload {
const data = this.dataParts.join(ARGUMENTS_SEPARATOR);
return new TransactionPayload(data);
}

build(): TransactionIntent {
const data = this.buildTransactionPayload(this.dataParts)
const data = this.buildTransactionPayload()
const gasLimit = this.computeGasLimit(data, this.executionGasLimit);


return new TransactionIntent(
this.sender.bech32(),
this.receiver.bech32(),
Expand Down

0 comments on commit 7db0a4a

Please sign in to comment.