Skip to content

Docs(update): Correcting the Modular contract getting started tutoria… #5074

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

Merged
merged 2 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@ Install Forge from Foundry and add the modular contract framework:

```bash
forge init
forge install https://github.com/thirdweb-dev/modular-contracts.git
forge remappings > remappings.txt
forge install thirdweb-dev/modular-contracts --no-commit
```

Add the Thirdweb modular contracts to `foundry.toml` under `remappings`:

```toml
remappings = ['@thirdweb-dev=lib/modular-contracts/']
```

### Setup Core Contract
Expand All @@ -29,152 +34,196 @@ forge remappings > remappings.txt
<Step title="Create a Core Contract">
Create a new file in the `src` folder called `CounterCore.sol`, and inherit the `Core` contract.

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {Core} from "modular-contracts/src/Core.sol";
import {Core} from "@thirdweb-dev/src/Core.sol";
import {BeforeIncrementCallback} from "./interface/BeforeIncrementCallback.sol";

contract CounterCore is Core {
contract CounterCore is Core {
constructor(address owner) {
_initializeOwner(owner);
}
}

constructor(address owner) {
_initializeOwner(owner);
}
```

> **Note**
> The `Core` contract is the base contract that needs to be inherited for this contract to be recognized as a core contract.

</Step>

}
```
<Step title="Set Get Supported Callback Function">
Implement the `getSupportedCallbackFunctions` function. The Core contract is abstract because this function is not implemented. To avoid compilation errors, declare the function with an empty body for now.

> **Note**
> The `Core` contract is the base contract that needs to be inherited for this contract to be recognized as a core contract.
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {Core} from "@thirdweb-dev/src/Core.sol";

contract CounterCore is Core {
constructor(address owner) {
_initializeOwner(owner);
}

function getSupportedCallbackFunctions()
public
pure
override
returns (SupportedCallbackFunction[] memory supportedCallbackFunctions)
{}
}
```

</Step>

<Step title="Set Up Increment Function">
Define a function to increment a counter.

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {Core} from "modular-contracts/src/Core.sol";
import {Core} from "@thirdweb-dev/src/Core.sol";

contract CounterCore is Core {
uint256 public count;
contract CounterCore is Core {
uint256 public count;

constructor(address owner) {
_initializeOwner(owner);
}
constructor(address owner) {
_initializeOwner(owner);
}

function getSupportedCallbackFunctions()
public
pure
override
returns (SupportedCallbackFunction[] memory supportedCallbackFunctions)
{}

function increment() public {
count += 1;
}
}
```
// 👇👇👇👇👇👇👇👇👇
function increment() public {
count += 1;
}
}
```

</Step>

<Step title="Add a Callback Function">
Introduce the `_beforeIncrement` function to use the `beforeIncrement` callback from a module.
Introduce the `_beforeIncrement` function to use the `beforeIncrement` callback from a module to achieve this, we'll introduce the interface `BeforeIncrementCallback`

> **Note**
> Callback functions are hook-like functionalities that can be used before or after the main functionality of a core contract.
> In this example, the `beforeIncrement` callback is executed before the main increment functionality.
> **Note**
> Callback functions are hook-like functionalities that can be used before or after the main functionality of a core contract.
> In this example, the `beforeIncrement` callback is executed before the main increment functionality.

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {Core} from "modular-contracts/src/Core.sol";
import {Core} from "@thirdweb-dev/src/Core.sol";

interface BeforeIncrementCallback {
function beforeIncrement(uint256 count) external returns (uint256);
}
// 👇👇👇👇👇👇👇👇👇

contract CounterCore is Core {
uint256 public count;
interface BeforeIncrementCallback {
function beforeIncrement(uint256 count) external returns (uint256);
}

constructor(address owner) {
_initializeOwner(owner);
}
contract CounterCore is Core {
uint256 public count;

function increment() public {
uint256 newCount = _beforeIncrement(count);
count = newCount;
}

function _beforeIncrement(
uint256 count
) internal returns (uint256 newCount) {
(, bytes memory returndata) = _executeCallbackFunction(
BeforeIncrementCallback.beforeIncrement.selector,
abi.encodeCall(BeforeIncrementCallback.beforeIncrement, (count))
);
newCount = abi.decode(returndata, (uint256));
}
}
```
constructor(address owner) {
_initializeOwner(owner);
}

</Step>
function getSupportedCallbackFunctions()
public
pure
override
returns (SupportedCallbackFunction[] memory supportedCallbackFunctions)
{}

<Step title="Implement Supported Functions">
Implement the `getSupportedCallbackFunctions` and `supportsInterface` functions to expose which callback functions and interfaces this core contract supports.
function increment() public {
count += 1;
}

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;
// 👇👇👇👇👇👇👇👇👇

import {Core} from "modular-contracts/src/Core.sol";
function _beforeIncrement(
uint256 _count
) internal returns (uint256 newCount) {
(, bytes memory returnData) = _executeCallbackFunction(
BeforeIncrementCallback.beforeIncrement.selector,
abi.encodeCall(BeforeIncrementCallback.beforeIncrement, (_count))
);

interface BeforeIncrementCallback {
function beforeIncrement(uint256 count) external returns (uint256);
}
newCount = abi.decode(returnData, (uint256));
}
}

contract CounterCore is Core {
uint256 public count;
```

constructor(address owner) {
_initializeOwner(owner);
}
</Step>

function increment() public {
uint256 newCount = _beforeIncrement(count);
count = newCount;
}

function getSupportedCallbackFunctions()
public
pure
override
returns (SupportedCallbackFunction[] memory supportedCallbackFunctions)
{
supportedCallbackFunctions = new SupportedCallbackFunction ;
supportedCallbackFunctions[0] = SupportedCallbackFunction({
selector: BeforeIncrementCallback.beforeIncrement.selector,
mode: CallbackMode.REQUIRED
});
}

function supportsInterface(bytes4 interfaceId)
public
view
override
returns (bool)
{
return
interfaceId == 0x00000001 || super.supportsInterface(interfaceId);
}

function _beforeIncrement(
uint256 count
) internal returns (uint256 newCount) {
(bool success, bytes memory returndata) = _executeCallbackFunction(
BeforeIncrementCallback.beforeIncrement.selector,
abi.encodeCall(BeforeIncrementCallback.beforeIncrement, (count))
);
newCount = abi.decode(returndata, (uint256));
}
}
```
<Step title="Implement Supported Functions">
Implement the `getSupportedCallbackFunctions` and `supportsInterface` functions to expose which callback functions and interfaces this core contract supports.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {Core} from "@thirdweb-dev/src/Core.sol";

interface BeforeIncrementCallback {
function beforeIncrement(uint256 count) external returns (uint256);
}

contract CounterCore is Core {
uint256 public count;

constructor(address owner) {
_initializeOwner(owner);
}

// 👇👇👇👇👇👇👇👇👇
function getSupportedCallbackFunctions()
public
pure
override
returns (SupportedCallbackFunction[] memory supportedCallbackFunctions)
{
supportedCallbackFunctions = new SupportedCallbackFunction[](1);
supportedCallbackFunctions[0] = SupportedCallbackFunction({
selector: BeforeIncrementCallback.beforeIncrement.selector,
mode: CallbackMode.OPTIONAL
});
}

function increment() public {
count += 1;
}

function _beforeIncrement(
uint256 _count
) internal returns (uint256 newCount) {
(, bytes memory returnData) = _executeCallbackFunction(
BeforeIncrementCallback.beforeIncrement.selector,
abi.encodeCall(BeforeIncrementCallback.beforeIncrement, (_count))
);

newCount = abi.decode(returnData, (uint256));
}

// 👇👇👇👇👇👇👇👇👇
function supportsInterface(
bytes4 interfaceId
) public view override returns (bool) {
return interfaceId == 0x00000001 || super.supportsInterface(interfaceId);
}
}

```

</Step>

Expand All @@ -183,5 +232,3 @@ forge remappings > remappings.txt
---

This guide will help you create a core contract that can increment a counter with optional callback functions for additional modular functionality.


Loading
Loading