DEV Community

esteblock
esteblock

Posted on

Converting a Soroban Smart Contract into a crate library

I am working developing Soroswap.Finance, an AMM in Soroban and we write our Smart Contracts based on the UniswapV2 Smart Contracts written in Solidity.

In Solidity we can write an smart contract, deploy it and use it as an smart contract and also use the same code as a library, so another smart contract can inherit its logic.

Common usage is:

contract MyContract is ContractFather

Enter fullscreen mode Exit fullscreen mode

Another usage is to use a Solidity library like:

import './libraries/UniswapV2Library.sol';

...
// and then use the library like:
uint amountBOptimal = UniswapV2Library.quote(amountADesired, reserveA, reserveB);

Enter fullscreen mode Exit fullscreen mode

How can we do something similar with rust and soroban-sdk?

The Library Contract

I wrote the SoroswapLibrary Smart Contract and it was working perfectly: Here is the code I had at the moment:
https://github.com/soroswap/core/tree/c65cebcfe69f05b38567158610dab25a941d4e6a/contracts/library

Publishing into crates.io

In order to transform this "pure" Smart Contract into a Library that can be imported by another Smart Contract I did the following:

1.- Edit the Cargo.toml to add some information necessary to publish into crates.io

[package]
name = "soroswap-library"
version = "0.1.1"
description = "Library that enables efficient and optimized code execution across different contracts on the Soroswap.Finance protocol"
homepage = "https://github.com/soroswap/core/tree/main/contracts/library"
repository = "https://github.com/soroswap/core/tree/main/contracts/library"
authors = ["esteblock <esteblock@paltalabs.io>"]
readme = "README.md"
license = "GPL-3.0"
edition = "2021"
keywords = ["no_std", "wasm", "soroswap", "amm", "soroban"]
rust-version = "1.73"
publish = true
Enter fullscreen mode Exit fullscreen mode

2.- Create an account in crates.io and login

cargo login
Enter fullscreen mode Exit fullscreen mode

3.- Publish:

cargo publish
Enter fullscreen mode Exit fullscreen mode

If everything goes well, your contract will be published in crates.io and you can use it

Importing it into your code:

In my Router contract I can use it as a library, editing Cargo.toml

[dependencies]
soroban-sdk = { version = "20.0.0-rc2" }
num-integer = { version = "0.1.45", default-features = false, features = ["i128"] }
soroswap-library = "0.1.1"
Enter fullscreen mode Exit fullscreen mode

And I should be able to use it inside my lib.rs as

use soroswap_library;
Enter fullscreen mode Exit fullscreen mode

The "no external crate" error

When I complile the Router contract I had the following error:

error[E0432]: unresolved import `soroswap_library`
 --> src/lib.rs:9:5
  |
9 | use soroswap_library;
  |     ^^^^^^^^^^^^^^^^ no external crate `soroswap_library`

Enter fullscreen mode Exit fullscreen mode

Very strange... But I found that I could solve it, adding the rlib crate type in the library contract... So it stays like this:


[lib]
crate-type = ["cdylib", "rlib"]
Enter fullscreen mode Exit fullscreen mode

Moving out your desired functions.

Also, in order to use a function as a crate library, you'll need to move them out from the contract Trait... and re-export them:

In my case, the Library's lib.rs has:

mod test;
mod tokens;
mod reserves;
mod quotes;

pub use tokens::{
    sort_tokens,
    pair_for
};
pub use reserves::{
    get_reserves
};
pub use quotes::{
    quote, 
    get_amount_out, 
    get_amount_in, 
    get_amounts_out, 
    get_amounts_in
};

Enter fullscreen mode Exit fullscreen mode

Check the final code here: https://github.com/soroswap/core/tree/main/contracts/library

Using the library

With this change (and of course after publishing a new version of the library in crates.io), I could use in my Router

use soroswap_library;
// and then

let amount_b_optimal = soroswap_library::quote(amount_a_desired.clone(), reserve_a.clone(), reserve_b.clone());
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
icolomina profile image
Nacho Colomina Torregrosa

Hey, fantastic post !! Thanks!