Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Refactor wrap/deploy of SAC #718

Merged
merged 13 commits into from
Feb 20, 2024
8 changes: 4 additions & 4 deletions dapps/guides/initialization.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,9 @@ curl --silent -X POST "$FRIENDBOT_URL?addr=$TOKEN_ADMIN_ADDRESS" >/dev/null

ARGS="--network $NETWORK --source token-admin"

echo Wrap the Stellar asset
TOKEN_ID=$(soroban lab token wrap $ARGS --asset "EXT:$TOKEN_ADMIN_ADDRESS")
echo "Token wrapped successfully with TOKEN_ID: $TOKEN_ID"
echo Deploy the Stellar asset contract
TOKEN_ID=$(soroban contract asset deploy $ARGS --asset "EXT:$TOKEN_ADMIN_ADDRESS")
echo "Token deployed successfully with TOKEN_ID: $TOKEN_ID"

# TODO - remove this workaround when
# https://github.com/stellar/soroban-tools/issues/661 is resolved.
Expand Down Expand Up @@ -212,7 +212,7 @@ Here's a summary of what the `initialize.sh` script does:
- Fetches the TOKEN_ADMIN_SECRET and TOKEN_ADMIN_ADDRESS from the newly generated identity
- Saves the TOKEN_ADMIN_SECRET and TOKEN_ADMIN_ADDRESS in the .soroban directory
- Funds the token-admin account using Friendbot
- Wraps the Stellar asset with `soroban lab token wrap` and stores the resulting TOKEN_ID
- Deploy the Stellar asset contract with `soroban contract asset deploy` and stores the resulting TOKEN_ID
- Builds the crowdfund contract with `make build` and deploys it using `soroban contract deploy`, storing the returned CROWDFUND_ID
- Initializes the crowdfund contract by invoking the initialize function with necessary parameters
- Prints "Done" to signify the end of the initialization process
Expand Down
55 changes: 55 additions & 0 deletions docs/guides/cli/deploy-stellar-asset-contract.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
title: Deploy the Stellar Asset Contract for a Stellar Asset
hide_table_of_contents: true
---

The Soroban CLI can deploy a [Stellar Asset Contract] for a Stellar asset so that any Soroban contract can interact with the asset.

Every Stellar asset has reserved a contract that anyone can deploy. Once deployed any contract can interact with that asset by holding a balance of the asset, receiving the asset, or sending the asset.

Deploying the Stellar Asset Contract for a Stellar asset enables that asset for use on Soroban.

The Stellar Asset Contract can be deployed for any possible Stellar asset, either assets already in use on Stellar or assets that have never seen any activity. This means that the issuer doesn't need to have been created, and no one needs to be yet holding the asset on Stellar.

To perform the deploy, use the following command:

```bash
soroban contract asset deploy \
--source S... \
--network testnet \
--asset USDC:GCYEIQEWOCTTSA72VPZ6LYIZIK4W4KNGJR72UADIXUXG45VDFRVCQTYE
```

The `asset` argument corresponds to the symbol and it's issuer address, which is how assets are identified on Stellar.

The same can be done for the native [Lumens] asset:

```bash
soroban contract asset deploy \
--source S... \
--network testnet \
--asset native
```

:::note

Deploying the native asset will fail on testnet or mainnet as
a Stellar Asset Contract already exists.

:::

For any asset, the contract address can be fetched with:

```bash
soroban contract id asset \
--source S... \
--network testnet \
--asset native
```

[Stellar Asset Contract]: ../../tokens/stellar-asset-contract.mdx
[Lumens]: https://developers.stellar.org/docs/fundamentals-and-concepts/lumens
[SEP-41]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0041.md
[`soroban_sdk::token`]: https://docs.rs/soroban-sdk/latest/soroban_sdk/token/
[`token::TokenClient`]: https://docs.rs/soroban-sdk/latest/soroban_sdk/token/struct.TokenClient.html
[`token::StellarAssetClient`]: https://docs.rs/soroban-sdk/latest/soroban_sdk/token/struct.StellarAssetClient.html
25 changes: 0 additions & 25 deletions docs/guides/cli/wrap-token.mdx

This file was deleted.

46 changes: 35 additions & 11 deletions docs/tokens/stellar-asset-contract.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,29 @@ assets. For this reason, we introduced the Stellar Asset Contract, or SAC for
short, which allows users to use their Stellar account and trustline balances in
Soroban.

The SAC implements the [token interface](token-interface.mdx), which is similar to the
The SAC implements the SEP-41 [Token Interface], which is similar to the
widely used ERC-20 token standard. This should make it easier for existing
smart contract developers to get started on Stellar.

## Deployment

For every Stellar asset exactly one respective Stellar Asset Contract can be
deployed. It can be deployed using the `InvokeHostFunctionOp` with
Every Stellar asset on Stellar has reserved a contract address that the Stellar Asset Contract can be deployed to. Anyone can initiate the deploy and the Stellar Asset issuer does not need to be involved.

It can be deployed using the `InvokeHostFunctionOp` with
`HOST_FUNCTION_TYPE_CREATE_CONTRACT` and `CONTRACT_ID_FROM_ASSET` specified
[here](../soroban-internals/contract-interactions/stellar-transaction.mdx). The resulting token will have a
deterministic identifier, which will be the sha256 hash of
`HashIDPreimage::ENVELOPE_TYPE_CONTRACT_ID_FROM_ASSET` xdr specified [here][contract_id].

Or the [Soroban-CLI] can be used as showed [here](../guides/cli/deploy-stellar-asset-contract.mdx).

Anyone can deploy the instances of Stellar Asset Contract. Note, that the
initialization of the Stellar Asset Contracts happens automatically during the
deployment. Asset Issuer will have the administrative permissions after the
contract has been deployed.

[contract_id]: https://github.com/stellar/stellar-xdr/blob/dc23adf60e095a6ce626b2b09128e58a5eae0cd0/Stellar-transaction.x#L661
[Soroban-CLI]: ../reference/soroban-cli.mdx

## Interacting with classic Stellar assets

Expand Down Expand Up @@ -152,17 +156,33 @@ struct MyContract;

#[contractimpl]
impl MyContract {
fn token_fn(e: Env, token_id: BytesN<32>) {
// Create a client instance for the provided token identifier. If the
// `token_id` value corresponds to an SAC contract, then SAC implementation
// is used.
let client = token::Client::new(&env, &token_id);
// Call token operations.
fn token_fn(e: Env, id: Address) {
// Create a client instance for the provided token identifier. If the id
// value corresponds to an SAC contract, then SAC implementation is used.
let client = token::Client::new(&env, &id);
// Call token operations part of the SEP-41 token interface
client.transfer(...);
}
}
```

:::info Clients

A client created by [`token::Client`] implements the functions defined by any
contract that implements the SEP-41 [Token Interface]. But the Stellar Asset
Contract exposes additional functions such as `mint`. To access the additional
functions, another client needs to be used: [`token::StellarAssetClient`]. This
client only implements the functions which are not part of the SEP-41.

```rust
let client = token::StellarAssetClient::new(&env, &id);
// Call token operations which are not part of the SEP-41 token interface
// but part of the CAP-46-6 Smart Contract Standardized Asset
client.mint(...);
```

:::

### Examples

See the full examples that utilize the token contract in various ways for more
Expand All @@ -183,7 +203,7 @@ tokens using `register_stellar_asset_contract`. For example:
```rust
let admin = Address::random();
let user = Address::random();
let token = TokenClient::new(e, &e.register_stellar_asset_contract(admin.clone()));
let token = StellarAssetClient::new(e, &e.register_stellar_asset_contract(admin.clone()));
token.mint(&admin, &user, &1000);
```

Expand All @@ -193,6 +213,10 @@ implementation.
## Contract Interface

This interface can be found in the [SDK]. It extends the common
[token interface](token-interface.mdx).
[Token Interface].

[SDK]: https://github.com/stellar/rs-soroban-sdk/blob/v20.0.0/soroban-sdk/src/token.rs
[Token Interface]: token-interface.mdx
[`soroban_sdk::token`]: https://docs.rs/soroban-sdk/latest/soroban_sdk/token/
[`token::TokenClient`]: https://docs.rs/soroban-sdk/latest/soroban_sdk/token/struct.TokenClient.html
[`token::StellarAssetClient`]: https://docs.rs/soroban-sdk/latest/soroban_sdk/token/struct.StellarAssetClient.html
38 changes: 3 additions & 35 deletions docs/tutorials/tokens.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -547,14 +547,14 @@ transfers, balance queries, etc.). In an effort to minimize repetition and
streamline token deployments, Soroban implements the [Token Interface], which
provides a uniform, predictable interface for developers and users.

Creating a Soroban token from an existing Stellar asset is very easy, and the
wrapped token makes use of the [Stellar Asset Contract] (more on that [later]).
Creating a Soroban token compatible contract from an existing Stellar asset is
very easy, it requires deploying the built-in [Stellar Asset Contract].

This example contract, however, demonstrates how a smart contract token might be
constructed that doesn't take advantage of the Stellar Asset Contract, but does
still satisfy the commonly used Token Interface to maximize interoperability.

[Stellar Asset Contract]: ../tokens/stellar-asset-contract.mdx
[later]: #compatibility-with-stellar-assets

### Separation of Functionality

Expand Down Expand Up @@ -648,38 +648,6 @@ _require_ the right kind of behavior to take place.

:::

### Compatibility with Stellar Assets

One of the key benefits of the Stellar network is that assets are first-class
citizens. On a protocol level, asset issuers have a robust set of tools to
manage the authorization and behavior of assets. Any asset that already exists
on the Stellar network can also make use of the [Stellar Asset Contract] on the
Soroban platform. All that is required is a simple, one-time action of wrapping
the asset to be deployed for Soroban.

At that point, the asset can use all the features of the Stellar Asset Contract
that are highlighted in this example (allowance, mint, burn, etc.), while still
maintaining the high-quality asset issuer features included with Stellar.

Additionally, all of that comes with **no contract writing required**. Any asset
can be easily wrapped using the [Soroban-CLI]:

```bash
soroban lab token wrap \
--asset USDC:GCYEIQEWOCTTSA72VPZ6LYIZIK4W4KNGJR72UADIXUXG45VDFRVCQTYE
```

:::note

A Stellar asset could be wrapped for Soroban by _any_ user. This command will
set the asset issuer account as the `admin` address for the Soroban token,
meaning that issuer account will still maintain control over asset minting,
authorization, etc.

:::

[Soroban-CLI]: ../reference/soroban-cli.mdx

## Tests

Open the `token/src/test.rs` file to follow along.
Expand Down
1 change: 1 addition & 0 deletions nginx/includes/redirects.conf
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ rewrite "^/docs/getting-started/connect-freighter-wallet$" "/docs/reference/frei
rewrite "^/docs/common-interfaces/token$" "/docs/tokens/token-interface" permanent;
rewrite "^/docs/how-to-guides/tokens$" "/docs/tutorials/tokens" permanent;
rewrite "^/dapps/category/challenges$" "/dashboard" permanent;
rewrite "^/docs/guides/cli/wrap-token$" "/docs/guides/cli/deploy-stellar-asset-contract" permanent;
# BEGIN re-structure redirects
rewrite "^/sorobanathon" "/" permanent;
rewrite "^/docs/reference/interfaces/token-interface" "/docs/tokens/token-interface" permanent;
Expand Down
Loading