Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to deriveFromChain given a module reference when initializing a contract instance #154

4 changes: 4 additions & 0 deletions front-end-tools/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 3.1.0

- Add option to `deriveFromChain` given a module reference in Step 2.

## 3.0.2

- Fix error message when specifying input parameter without uploading schema.
Expand Down
12 changes: 9 additions & 3 deletions front-end-tools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@
The front end contains useful functionalities for smart contract developers:

- Upload and deploy a smart contract module to chain.
- Initialize a smart contract module on chain.
- Initialize a smart contract instance on chain.
- Invoke a smart contract on chain (reading from chain).
- Update a smart contract on chain (writing to chain).

Only the browser wallet is supported in the first version (no support for mobile wallets).

## Hosted front end

[Hosted front end link](https://sctools.mainnet.concordium.software/)

## Prerequisites

- Browser wallet extension must be installed in a Chromium-based browser.
Expand All @@ -30,13 +36,13 @@ To start the front end locally, do the following:

- Run `yarn build` in this folder.
- Run `yarn start` in this folder.
- Open URL logged in console (typically http://127.0.0.1:8080).
- Open URL logged in console (typically http://127.0.0.1:5173).

To have hot-reload (useful for development), do the following instead:

- Run `yarn watch` in this folder in a terminal.
- Run `yarn start` in this folder in another terminal.
- Open URL logged in console (typically http://127.0.0.1:8080).
- Open URL logged in console (typically http://127.0.0.1:5173).

## Using yarn (on Unix/macOS systems)

Expand Down
2 changes: 1 addition & 1 deletion front-end-tools/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "front-end-tools",
"packageManager": "yarn@4.0.2",
"version": "3.0.2",
"version": "3.1.0",
"license": "Apache-2.0",
"engines": {
"node": ">=16.x"
Expand Down
14 changes: 4 additions & 10 deletions front-end-tools/src/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
MAINNET,
useWalletConnectorSelector,
} from '@concordium/react-components';
import { ModuleReference } from '@concordium/web-sdk';

import { Alert } from 'react-bootstrap';
import DeployComponent from './components/DeployComponent';
Expand Down Expand Up @@ -48,10 +49,9 @@ export default function Main(props: ConnectionProps) {
const [accountBalance, setAccountBalance] = useState<string | undefined>(undefined);

// Shared state between deploy step and init step
const [moduleReferenceCalculated, setModuleReferenceCalculated] = useState<string | undefined>(undefined);
const [moduleReferenceDeployed, setModuleReferenceDeployed] = useState<string | undefined>(undefined);
const [contracts, setContracts] = useState<string[]>([]);
const [embeddedModuleSchemaBase64Init, setEmbeddedModuleSchemaBase64Init] = useState<string | undefined>(undefined);
const [moduleReferenceCalculated, setModuleReferenceCalculated] = useState<ModuleReference.Type | undefined>(
undefined
);

// Refresh accountInfo periodically.
// eslint-disable-next-line consistent-return
Expand Down Expand Up @@ -135,22 +135,16 @@ export default function Main(props: ConnectionProps) {
connection={connection}
account={account}
client={client}
setContracts={setContracts}
moduleReferenceCalculated={moduleReferenceCalculated}
setModuleReferenceDeployed={setModuleReferenceDeployed}
setModuleReferenceCalculated={setModuleReferenceCalculated}
setEmbeddedModuleSchemaBase64Init={setEmbeddedModuleSchemaBase64Init}
/>

<InitComponent
isTestnet={isTestnet}
connection={connection}
account={account}
client={client}
contracts={contracts}
moduleReferenceDeployed={moduleReferenceDeployed}
moduleReferenceCalculated={moduleReferenceCalculated}
embeddedModuleSchemaBase64={embeddedModuleSchemaBase64Init}
/>

<ReadComponent connection={connection} account={account} client={client} />
Expand Down
56 changes: 6 additions & 50 deletions front-end-tools/src/components/DeployComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,16 @@ interface ConnectionProps {
connection: WalletConnection;
client: ConcordiumGRPCClient | undefined;
isTestnet: boolean;
setContracts: (contracts: string[]) => void;
setEmbeddedModuleSchemaBase64Init: (embeddedModuleSchemaBase64Init: string) => void;
setModuleReferenceDeployed: (moduleReferenceDeployed: string | undefined) => void;
setModuleReferenceCalculated: (moduleReferenceCalculated: string) => void;
moduleReferenceCalculated: string | undefined;
setModuleReferenceCalculated: (moduleReferenceCalculated: ModuleReference.Type) => void;
moduleReferenceCalculated: ModuleReference.Type | undefined;
}

/**
* A component that manages the input fields and corresponding state to deploy a new smart contract wasm module on chain.
* This components creates a `DeployModule` transaction.
*/
export default function DeployComponenet(props: ConnectionProps) {
const {
isTestnet,
client,
connection,
account,
setContracts,
setModuleReferenceDeployed,
setModuleReferenceCalculated,
moduleReferenceCalculated,
setEmbeddedModuleSchemaBase64Init,
} = props;
const { isTestnet, client, connection, account, setModuleReferenceCalculated, moduleReferenceCalculated } = props;

type FormType = {
file: FileList | undefined;
Expand Down Expand Up @@ -76,7 +63,6 @@ export default function DeployComponenet(props: ConnectionProps) {
report.outcome.summary.transactionType === TransactionKindString.DeployModule
) {
setTransactionOutcome('Success');
setModuleReferenceDeployed(report.outcome.summary.moduleDeployed.contents);
clearInterval(interval);
} else {
setTransactionOutcome('Fail');
Expand All @@ -85,7 +71,6 @@ export default function DeployComponenet(props: ConnectionProps) {
}
})
.catch((e) => {
setModuleReferenceDeployed(undefined);
setTransactionOutcome(`Fail; Error: ${(e as Error).message}`);
clearInterval(interval);
});
Expand All @@ -97,7 +82,7 @@ export default function DeployComponenet(props: ConnectionProps) {
useEffect(() => {
if (connection && client && moduleReferenceCalculated) {
client
.getModuleSource(ModuleReference.fromHexString(moduleReferenceCalculated))
.getModuleSource(moduleReferenceCalculated)
.then((value) => {
if (value === undefined) {
setIsModuleReferenceAlreadyDeployedStep1(false);
Expand All @@ -120,7 +105,6 @@ export default function DeployComponenet(props: ConnectionProps) {

const tx = deploy(connection, AccountAddress.fromBase58(account), base64Module);
tx.then((txHash) => {
setModuleReferenceDeployed(undefined);
setTxHashDeploy(txHash);
}).catch((err: Error) => setTransactionErrorDeploy((err as Error).message));
}
Expand All @@ -140,7 +124,6 @@ export default function DeployComponenet(props: ConnectionProps) {
register.onChange(e);

setUploadError(undefined);
setModuleReferenceDeployed(undefined);
setTransactionErrorDeploy(undefined);
setTxHashDeploy(undefined);

Expand All @@ -160,7 +143,7 @@ export default function DeployComponenet(props: ConnectionProps) {

setBase64Module(module);
setModuleReferenceCalculated(
Buffer.from(sha256([new Uint8Array(arrayBuffer)])).toString('hex')
ModuleReference.fromBuffer(Buffer.from(sha256([new Uint8Array(arrayBuffer)])))
DOBEN marked this conversation as resolved.
Show resolved Hide resolved
);

// Concordium's tooling create versioned modules e.g. `.wasm.v1` now.
Expand Down Expand Up @@ -195,33 +178,6 @@ export default function DeployComponenet(props: ConnectionProps) {
}

if (wasmModule) {
const moduleFunctions = WebAssembly.Module.exports(wasmModule);

const contractNames = [];
for (let i = 0; i < moduleFunctions.length; i += 1) {
if (moduleFunctions[i].name.startsWith('init_')) {
contractNames.push(moduleFunctions[i].name.slice(5));
}
}
setContracts(contractNames);

const customSection = WebAssembly.Module.customSections(
wasmModule,
'concordium-schema'
);

const schema = new Uint8Array(customSection[0]);

// Use `reduce` to be able to convert large schema.
const moduleSchemaBase64Embedded = btoa(
new Uint8Array(schema).reduce(
(data, byte) => data + String.fromCharCode(byte),
''
)
);

setEmbeddedModuleSchemaBase64Init(moduleSchemaBase64Embedded);

// Check if the module was built as a reproducible build.
const buildInfoSection = WebAssembly.Module.customSections(
wasmModule,
Expand Down Expand Up @@ -250,7 +206,7 @@ export default function DeployComponenet(props: ConnectionProps) {
<>
<div className="actionResultBox">
Calculated module reference:
<div>{moduleReferenceCalculated}</div>
<div>{moduleReferenceCalculated.moduleRef}</div>
</div>
<div className="actionResultBox">
Module in base64:
Expand Down
Loading
Loading