Skip to content

Commit

Permalink
Update way to get wasm code (#41)
Browse files Browse the repository at this point in the history
### Summary
- We want to replace the current way of getting the contract code,
according to [this
comment](stellar/js-soroban-client#166 (comment))
we should do it in a different way.

### Changes
- Remove `getLedgerKeyWasmId` function
- Add `getInstanceValue` and `getWasmCode` functions
  • Loading branch information
tammaroivan authored Nov 3, 2023
1 parent 1baa7ae commit d51e61e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 51 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { xdr } from 'soroban-client';

import { Method } from '@/modules/method/domain/method.domain';

import { IGeneratedMethod } from '../service/stellar.service';

export interface IContractService {
getLedgerKeyWasmId(contractCodeLedgerEntryData: string);
getInstanceValue(contractId: string): Promise<xdr.ContractDataEntry>;
getWasmCode(instance: xdr.ScContractInstance): Promise<Buffer>;
decodeContractSpecBuffer(buffer);
extractFunctionInfo(decodedSection, SCSpecTypeMap);
generateMethodsFromContractId(
Expand Down
85 changes: 35 additions & 50 deletions src/common/application/service/stellar.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Injectable } from '@nestjs/common';
import {
Address,
BASE_FEE,
Contract,
ContractSpec,
Expand Down Expand Up @@ -54,34 +55,6 @@ export class StellarService implements IContractService {
};
}

getLedgerKeyWasmId(contractCodeLedgerEntryData: string) {
const entry = xdr.LedgerEntryData.fromXDR(
contractCodeLedgerEntryData,
'base64',
);

const instance = new xdr.ScContractInstance({
executable: entry.contractData().val() as any,
storage: [],
});

const ledgerKey = xdr.LedgerKey.contractCode(
new xdr.LedgerKeyContractCode({
hash: (
xdr.ContractExecutable.contractExecutableWasm(
instance.executable() as any,
) as any
)
.wasmHash()
.instance()
.executable()
.wasmHash(),
}),
);

return ledgerKey;
}

async decodeContractSpecBuffer(buffer) {
const arrayBuffer = new Uint8Array(buffer);
const decodedData = [];
Expand Down Expand Up @@ -163,35 +136,47 @@ export class StellarService implements IContractService {
return functionObj;
}

async getContractSpecEntries(contractId) {
async getInstanceValue(contractId: string): Promise<xdr.ContractDataEntry> {
try {
const contract = new Contract(contractId);

const ledgerKeys = await contract.getFootprint();

const { entries } = await this.server.getLedgerEntries(...ledgerKeys);

const entry = entries?.[0];
if (!entry) {
throw new Error('No entry found for the given hash');
}
const instanceKey = xdr.LedgerKey.contractData(
new xdr.LedgerKeyContractData({
contract: new Address(contractId).toScAddress(),
key: xdr.ScVal.scvLedgerKeyContractInstance(),
durability: xdr.ContractDataDurability.persistent(),
}),
);

const wasmLedgerKey = this.getLedgerKeyWasmId(entry.val.toXDR('base64'));
const response = await this.server.getLedgerEntries(instanceKey);
const dataEntry = response.entries[0].val.contractData();
return dataEntry;
} catch (error) {
console.log('Error while getting instance value: ', error);
}
}

const wasmResponse = await this.server.getLedgerEntries(wasmLedgerKey);
async getWasmCode(instance: xdr.ScContractInstance): Promise<Buffer> {
try {
const codeKey = xdr.LedgerKey.contractCode(
new xdr.LedgerKeyContractCode({
hash: instance.executable().wasmHash(),
}),
);

const wasmEntry = wasmResponse.entries?.[0];
if (!wasmEntry) {
throw new Error('No entry found for the given wasmLedgerKey');
}
const response = await this.server.getLedgerEntries(codeKey);
const wasmCode = response.entries[0].val.contractCode().code();
return wasmCode;
} catch (error) {
console.log('Error while getting wasm code: ', error);
}
}

const entryData = xdr.LedgerEntryData.fromXDR(
wasmEntry.val.toXDR('base64'),
'base64',
async getContractSpecEntries(contractId) {
try {
const instanceValue = await this.getInstanceValue(contractId);
const contractCode = await this.getWasmCode(
instanceValue.val().instance(),
);

const contractCode = entryData.contractCode().code();

const wasmModule = new WebAssembly.Module(contractCode);

const buffer = WebAssembly.Module.customSections(
Expand Down

0 comments on commit d51e61e

Please sign in to comment.