Step 2 - Start Solidity Contract
2.1 Solidity Contract with Interface
Solidity interfaces are useful for calling external contracts that might have different compiler versions.
For example: new protocols might use more recent Solidity compiler versions for contracts while wanting to use WETH9.sol. This can be done using an ERC-20 interface such as IERC20.sol to avoid Solidity compiler errors from using incompatible Solidity compiler versions.
In this context, a Solidity interface is used to call an external Rust contract based on its method name and types.
contracts/FluentSdkRustTypesTest.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
interface IFluentRust {
// Make sure type interfaces are defined here or else there will be a compiler error.
function rustString() external view returns (string memory);
function rustUint256() external view returns (uint256);
function rustInt256() external view returns (int256);
function rustAddress() external view returns (address);
function rustBytes() external view returns (bytes memory);
function rustBytes32() external view returns (bytes32);
function rustBool() external view returns (bool);
}
contract FluentSdkRustTypesTest {
IFluentRust public fluentRust;
constructor(address FluentRustAddress) {
fluentRust = IFluentRust(FluentRustAddress);
}
function getRustString() external view returns (string memory) {
string memory rustString = fluentRust.rustString();
return string(abi.encodePacked(rustString, " World"));
}
function getRustUint256() external view returns (uint256) {
uint256 rustUint256 = fluentRust.rustUint256();
return rustUint256;
}
function getRustInt256() external view returns (int256) {
int256 rustInt256 = fluentRust.rustInt256();
return rustInt256;
}
function getRustAddress() external view returns (address) {
address rustAddress = fluentRust.rustAddress();
return rustAddress;
}
function getRustBytes() external view returns (bytes memory) {
bytes memory rustBytes = fluentRust.rustBytes();
return rustBytes;
}
function getRustBytes32() external view returns (bytes32) {
bytes32 rustBytes32 = fluentRust.rustBytes32();
return rustBytes32;
}
function getRustBool() external view returns (bool) {
bool rustBool = fluentRust.rustBool();
return rustBool;
}
}
Detailed Code Explanation
Import Statement: Imports the IFluentGreeting interface defined earlier.
Contract Definition: Defines a contract GreetingWithWorld.
State Variable: Declares a state variable fluentGreetingContract of type IFluentGreeting. This variable will hold the address of the deployed Rust smart contract.
Constructor:
-
Takes an address
_fluentGreetingContractAddressas a parameter. -
Initializes the
fluentGreetingContractwith the provided address. -
Function
getGreeting:- Calls the
greetingfunction of thefluentGreetingContractto get the greeting message from the Rust contract. - Concatenates the greeting message with ", World" using
abi.encodePackedand returns the resulting string.
- Calls the
Interaction with Rust Code:
- The
GreetingWithWorldcontract interacts with the Rust smart contract by calling thegreetingfunction via theIFluentGreetinginterface. - When
getGreetingis called, it fetches the greeting message ("Hello") from the Rust contract, concatenates it with ", World", and returns the complete greeting ("Hello, World").
How Solidity and Rust Interact:
- Rust Smart Contract Deployment: The Rust smart contract is compiled to Wasm and deployed to the blockchain. It contains a function that returns the greeting "Hello".
- Solidity Interface (
IFluentGreeting): The Solidity interface declares agreetingfunction that matches the function in the Rust contract. - Solidity Implementation (
GreetingWithWorld):- The
GreetingWithWorldcontract uses theIFluentGreetinginterface to interact with the Rust contract. - It initializes with the address of the deployed Rust contract.
- It calls the
greetingfunction of the Rust contract to fetch the greeting message. - It concatenates the Rust greeting with ", World" and returns the result.
- The