Skip to content

Commit

Permalink
Merge pull request #357 from MeshJS/docs-smart-contracts
Browse files Browse the repository at this point in the history
Docs and Readme for smart contracts
  • Loading branch information
jinglescode authored Nov 2, 2024
2 parents 515bcc3 + 2783b13 commit 523c68d
Show file tree
Hide file tree
Showing 32 changed files with 223 additions and 115 deletions.
20 changes: 2 additions & 18 deletions apps/docs/src/app/[package]/contracts.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,14 @@
import { CodeGroup } from "@/components/Code";
import { Prose } from "@/components/Prose";
import Markdown from "react-markdown";

export default function IntroContracts() {
return (
<article className="flex h-full flex-col pb-10 pt-16">
<Prose className="flex-auto">
<h1>Smart Contracts</h1>
<p className="lead">
Want to get started with smart contracts? Here are some contracts for
the most common use-cases.
Here's a list of open-source smart contracts, complete with documentation, live
demos, and end-to-end source code.
</p>
{/* <p>
Something
</p> */}
{/* <h2 className="scroll-mt-24" id="getting-started">
Getting started
</h2>
<p className="lead">
To get started with Mesh, you need to install the latest version of
Mesh with npm:
</p>
<CodeGroup title="" code={`npm install @meshsdk/core @meshsdk/react`}>
<Markdown>npm install @meshsdk/core @meshsdk/react</Markdown>
</CodeGroup> */}
</Prose>
</article>
);
Expand Down
2 changes: 1 addition & 1 deletion apps/playground/src/data/links-guides.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const guidestandalone = {
};
export const guideVesting = {
title: "Vesting Script End-to-End",
desc: "Learn how to vesting contract that locks up funds for a period of time and allows the owner to withdraw the funds after the lockup period.",
desc: "Learn how to vesting contract that locks up funds for a period of time and allows the beneficiary to withdraw the funds after the lockup period.",
link: "/guides/vesting",
thumbnail: "/guides/vesting.png",
image: "/guides/laptop-3196481_640.jpg",
Expand Down
12 changes: 10 additions & 2 deletions apps/playground/src/data/links-smart-contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
GiftIcon,
LockClosedIcon,
PhotoIcon,
PlayIcon,
ShoppingCartIcon,
} from "@heroicons/react/24/solid";

Expand All @@ -18,7 +19,7 @@ export const metaMarketplace = {
};
export const metaVesting = {
title: "Vesting",
desc: "Locks up funds for a period of time and allows the owner to withdraw the funds after the lockup period",
desc: "Locks up funds and allows the beneficiary to withdraw the funds after the lockup period",
link: "/smart-contracts/vesting",
icon: LockClosedIcon,
};
Expand Down Expand Up @@ -58,11 +59,18 @@ export const metaMintPlutusNft = {
link: "/smart-contracts/plutus-nft",
icon: PhotoIcon,
};
export const metaHelloWorld = {
title: "Hello World",
desc: "Simple lock and unlock assets contract",
link: "/smart-contracts/hello-world",
icon: PlayIcon,
};

export const linksSmartContracts: MenuItem[] = [
metaContentOwnership,
metaEscrow,
metaGiftcard,
metaHelloWorld,
metaMarketplace,
metaMintPlutusNft,
metaPaymentSplitter,
Expand All @@ -72,7 +80,7 @@ export const linksSmartContracts: MenuItem[] = [

export const metaSmartContract: MenuItem = {
title: "Smart Contracts",
desc: "Want to get started with smart contracts? Here are some contracts for the most common use-cases.",
desc: "Here's a list of open-source smart contracts, complete with documentation, live demos, and end-to-end source code.",
link: "/smart-contracts",
icon: DocumentCheckIcon,
items: linksSmartContracts,
Expand Down
2 changes: 1 addition & 1 deletion apps/playground/src/pages/guides/vesting/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function MDXPage({ children }) {
);
}

Vesting contract is a smart contract that locks up funds for a period of time and allows the owner to withdraw the funds after the lockup period. Usually, vesting contract defines a beneficiary who can be different from the original owner.
Vesting contract is a smart contract that locks up funds and allows the beneficiary to withdraw the funds after the lockup period.

When a new employee joins an organization, they typically receive a promise of compensation to be disbursed after a specified duration of employment. This arrangement often involves the organization depositing the funds into a vesting contract, with the employee gaining access to the funds upon the completion of a predetermined lockup period. Through the utilization of vesting contracts, organizations establish a mechanism to encourage employee retention by linking financial rewards to tenure.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export function getContract(

export const sampleParamUtxo = {
outputIndex: 0,
txHash: "e781a02ed4159b47b144e960c4b155918f50b4841eafc443c66fec40616b6df2",
txHash: "2aba4d6705cfe6405cf02e4e2c8b71965d2b86b828e3f6ffbf3f8bded3df2359",
};

interface State {
Expand Down Expand Up @@ -80,22 +80,22 @@ export const useContentOwnership = create<State>()(
set(() => ({
paramUtxo: paramUtxo,
})),
contentRegistry: "",
contentRegistry: "dfd2a2616e6154a092807b1ceebb9ddcadc0f22cf5c8e0e6b0757815083ccb70",
setContentRegistry: (address: string) =>
set(() => ({
contentRegistry: address,
})),
contentRefToken: "",
contentRefToken: "8f731be135171df172c07578a5d74589ec8fb30b37c12fdbe2639d69b7587f5e",
setContentRefToken: (address: string) =>
set(() => ({
contentRefToken: address,
})),
ownershipRegistry: "",
ownershipRegistry: "ec874b61eec4e5e8e395dead6c9bb18690e6d6ea64d773760c5e654ec9ff5f97",
setOwnershipRegistry: (address: string) =>
set(() => ({
ownershipRegistry: address,
})),
ownershipRefToken: "",
ownershipRefToken: "e1bdfc7ae6929f934cf9d418273dde143cbb65ec0eec23bdb6c342e4cd91dbd0",
setOwnershipRefToken: (address: string) =>
set(() => ({
ownershipRefToken: address,
Expand Down
37 changes: 22 additions & 15 deletions apps/playground/src/pages/smart-contracts/hello-world/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Link from "~/components/link";
import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body";
import Metatags from "~/components/site/metatags";
import Codeblock from "~/components/text/codeblock";
import { metaGiftcard } from "~/data/links-smart-contracts";
import { metaHelloWorld } from "~/data/links-smart-contracts";
import { InstallSmartContract } from "../common";
import HelloWorldLock from "./lock-asset";
import HelloWorldUnlock from "./unlock-asset";
Expand Down Expand Up @@ -37,31 +37,38 @@ const ReactPage: NextPage = () => {

return (
<>
<Metatags title={metaGiftcard.title} description={metaGiftcard.desc} />
<Metatags
title={metaHelloWorld.title}
description={metaHelloWorld.desc}
/>
<SidebarFullwidth sidebarItems={sidebarItems}>
<TitleIconDescriptionBody
title={metaGiftcard.title}
description={metaGiftcard.desc}
heroicon={metaGiftcard.icon}
title={metaHelloWorld.title}
description={metaHelloWorld.desc}
heroicon={metaHelloWorld.icon}
>
<>
<p>
Giftcard contract allows users to create a transactions to lock
assets into the smart contract, which can be redeemed by any user.
</p>
<p>
Creating a giftcard will mint a token and send the assets to the
contract. While redeeming will burn the token and send the assets
to the redeemer.
The Hello World smart contract is a simple lock-and-unlock assets
contract, providing a hands-on introduction to end-to-end smart
contract validation and transaction building.
</p>

<p>There are 2 conditions to unlock the assets:</p>
<ul>
<li>Signer must be the same as the one who locked the assets</li>
<li>
Signer must provide the message <code>Hello, World!</code>
</li>
</ul>

<p>
There are 2 actions (or endpoints) available to interact with this
smart contract:
</p>
<ul>
<li>create giftcard</li>
<li>redeem giftcard</li>
<li>Lock assets</li>
<li>Redeem assets</li>
</ul>

<InstallSmartContract />
Expand All @@ -75,7 +82,7 @@ const ReactPage: NextPage = () => {
<Codeblock data={example} />
<p>
Both on-chain and off-chain codes are open-source and available on{" "}
<Link href="https://github.com/MeshJS/mesh/tree/main/packages/mesh-contract/src/giftcard">
<Link href="https://github.com/MeshJS/mesh/tree/main/packages/mesh-contract/src/hello-world">
Mesh Github Repository
</Link>
.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,52 @@ import Input from "~/components/form/input";
import InputTable from "~/components/sections/input-table";
import LiveCodeDemo from "~/components/sections/live-code-demo";
import TwoColumnsScroll from "~/components/sections/two-columns-scroll";
import Codeblock from "~/components/text/codeblock";
import { getContract } from "./common";

export default function HelloWorldLock() {
return (
<TwoColumnsScroll
sidebarTo="lockAsset"
title="Lock Asset"
title="Lock Assets"
leftSection={Left()}
rightSection={Right()}
/>
);
}

function Left() {
let codeDatum = ``;
codeDatum += `pub type Datum {\n`;
codeDatum += ` owner: VerificationKeyHash,\n`;
codeDatum += `}\n`;

let codeTx = ``;
codeTx += `await txBuilder\n`;
codeTx += ` .txOut(scriptAddress, assets)\n`;
codeTx += ` .txOutDatumHashValue(mConStr0([signerHash]))\n`;
codeTx += ` .changeAddress(walletAddress)\n`;
codeTx += ` .selectUtxosFrom(utxos)\n`;
codeTx += ` .complete();\n`;

return (
<>
<p></p>
<p>This transaction locks funds into the contract.</p>

<p>
The datum must match the representation expected by the validator (and
as specified in the blueprint), so this is a constructor with a single
field that is a byte array.
</p>

<Codeblock data={codeDatum} />

<p>
Thus, we provide a hash digest of our public key, which will be needed
to unlock the funds.
</p>

<Codeblock data={codeTx} />
</>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,57 @@ import Input from "~/components/form/input";
import InputTable from "~/components/sections/input-table";
import LiveCodeDemo from "~/components/sections/live-code-demo";
import TwoColumnsScroll from "~/components/sections/two-columns-scroll";
import Codeblock from "~/components/text/codeblock";
import { getContract } from "./common";

export default function HelloWorldUnlock() {
return (
<TwoColumnsScroll
sidebarTo="unlockAsset"
title="Unlock Asset"
title="Unlock Assets"
leftSection={Left()}
rightSection={Right()}
/>
);
}

function Left() {
let codeValidator = ``;
codeValidator += `validator hello_world {\n`;
codeValidator += ` spend(\n`;
codeValidator += ` datum_opt: Option<Datum>,\n`;
codeValidator += ` redeemer: Redeemer,\n`;
codeValidator += ` _input: OutputReference,\n`;
codeValidator += ` tx: Transaction,\n`;
codeValidator += ` ) {\n`;
codeValidator += ` expect Some(datum) = datum_opt\n`;
codeValidator += ` let must_say_hello = redeemer.msg == "Hello, World!"\n`;
codeValidator += ` let must_be_signed = list.has(tx.extra_signatories, datum.owner)\n`;
codeValidator += ` must_say_hello && must_be_signed\n`;
codeValidator += ` }\n`;
codeValidator += `\n`;
codeValidator += ` else(_) {\n`;
codeValidator += ` fail\n`;
codeValidator += ` }\n`;
codeValidator += `}\n`;

return (
<>
<p></p>
<p>There are 2 conditions to unlock the assets:</p>
<ul>
<li>Signer must be the same as the one who locked the assets</li>
<li>
Signer must provide the message <code>Hello, World!</code>
</li>
</ul>

<p>
The validator script for the contract checks that the redeemer is the
same as the owner of the datum and that the message is{" "}
<code>Hello, World!</code>:
</p>

<Codeblock data={codeValidator} />
</>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function Left() {
<>
<p>
Vesting contract is a smart contract that locks up funds for a period of
time and allows the owner to withdraw the funds after the lockup period.
time and allows the beneficiary to withdraw the funds after the lockup period.
Usually, vesting contract defines a beneficiary who can be different
from the original owner.
</p>
Expand Down
2 changes: 1 addition & 1 deletion packages/mesh-common/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@meshsdk/common",
"version": "1.7.11",
"version": "1.7.12",
"description": "",
"main": "./dist/index.cjs",
"browser": "./dist/index.js",
Expand Down
17 changes: 14 additions & 3 deletions packages/mesh-contract/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# mesh-contracts
# Mesh Smart Contracts Library

A collection of smart contracts and its transactions - [meshjs.dev/smart-contracts](https://meshjs.dev/smart-contracts)
Here's a list of open-source smart contracts, complete with documentation, live demos, and end-to-end source code.

[meshjs.dev](https://meshjs.dev/)
[meshjs.dev/smart-contracts](https://meshjs.dev/smart-contracts)

| Contract | Description | Links |
| --- | --- | --- |
| Content Ownership | Create a content registry and users can create content that is stored in the registry | [[demo](https://meshjs.dev/smart-contracts/content-ownership)] [[source](https://github.com/MeshJS/mesh/tree/main/packages/mesh-contract/src/content-ownership)] |
| Escrow | Facilitates the secure exchange of assets between two parties by acting as a trusted intermediary that holds the assets until the conditions of the agreement are met | [[demo](https://meshjs.dev/smart-contracts/escrow)] [[source](https://github.com/MeshJS/mesh/tree/main/packages/mesh-contract/src/escrow)] |
| Giftcard | Allows users to create a transactions to lock assets into the smart contract, which can be redeemed by any user | [[demo](https://meshjs.dev/smart-contracts/giftcard)] [[source](https://github.com/MeshJS/mesh/tree/main/packages/mesh-contract/src/giftcard)] |
| Marketplace | Allows anyone to buy and sell native assets such as NFTs | [[demo](https://meshjs.dev/smart-contracts/marketplace)] [[source](https://github.com/MeshJS/mesh/tree/main/packages/mesh-contract/src/marketplace)] |
| NFT Minting | Mint NFTs with an automatically incremented index, which increases by one for each newly minted NFT | [[demo](https://meshjs.dev/smart-contracts/plutus-nft)] [[source](https://github.com/MeshJS/mesh/tree/main/packages/mesh-contract/src/plutus-nft)] |
| Payment Splitter | Allows users to split incoming payments among a group of accounts | [[demo](https://meshjs.dev/smart-contracts/payment-splitter)] [[source](https://github.com/MeshJS/mesh/tree/main/packages/mesh-contract/src/payment-splitter)] |
| Swap | Facilitates the exchange of assets between two parties | [[demo](https://meshjs.dev/smart-contracts/swap)] [[source](https://github.com/MeshJS/mesh/tree/main/packages/mesh-contract/src/swap)] |
| Vesting | Allows users to lock tokens for a period of time and withdraw the funds after the lockup period | [[demo](https://meshjs.dev/smart-contracts/vesting)] [[source](https://github.com/MeshJS/mesh/tree/main/packages/mesh-contract/src/vesting)] |
8 changes: 4 additions & 4 deletions packages/mesh-contract/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@meshsdk/contract",
"version": "1.7.11",
"version": "1.7.12",
"description": "",
"main": "./dist/index.cjs",
"browser": "./dist/index.js",
Expand Down Expand Up @@ -34,9 +34,9 @@
"typescript": "^5.3.3"
},
"dependencies": {
"@meshsdk/common": "1.7.11",
"@meshsdk/core": "1.7.11",
"@meshsdk/core-csl": "1.7.11"
"@meshsdk/common": "1.7.12",
"@meshsdk/core": "1.7.12",
"@meshsdk/core-csl": "1.7.12"
},
"prettier": "@meshsdk/configs/prettier",
"publishConfig": {
Expand Down
2 changes: 2 additions & 0 deletions packages/mesh-contract/src/asteria/readme.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Asteria contract

> Work in progress
A Cardano bot challenge to showcase the capabilities of the eUTxO model.

## Mechanics
Expand Down
8 changes: 7 additions & 1 deletion packages/mesh-contract/src/content-ownership/readme.md
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
# Content Ownership contract
# Content Ownership

This contract allows you to create a content registry and users can create content that is stored in the registry.

It facilitates on-chain record of content (i.e. file on IPFS) ownership and transfer. While one cannot prefer others from obtaining a copy of the content, the app owner of the contract can serve the single source of truth of who owns the content. With the blockchain trace and record in place, it provides a trustless way to verify the ownership of the content and facilitates further application logics such as royalties, licensing, etc.

[Read more and live demo](https://meshjs.dev/smart-contracts/content-ownership)
Loading

0 comments on commit 523c68d

Please sign in to comment.