Skip to content
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

HOWTO: Set Up a Testnet and Deploy Custom Contracts #10

Closed
wants to merge 2 commits into from
Closed

Conversation

Kukovec
Copy link
Collaborator

@Kukovec Kukovec commented Apr 12, 2024

closes #9

This HOWTO describes the steps required to:

  • Create a local Stellar network
  • Write and compile a custom contract
  • Deploy said contract to a (test)net and invoke it

Rendered doc

@Kukovec
Copy link
Collaborator Author

Kukovec commented Apr 12, 2024

In case someone wants a quick contract to play around with, here's a lib.rs from Foo. It has a map of vectors in addition to an integer counter.

#![no_std]
use soroban_sdk::{contract, contractimpl, log, symbol_short, Env, Symbol, Vec, Map, Address};

const VAL: Symbol = symbol_short!("VAL");
const ADDRS: Symbol = symbol_short!("ADDRS");

#[contract]
pub struct FooContract;

type AddrMap = Map<u32, Vec<Address>>;

#[contractimpl]
impl FooContract {
    pub fn bar(env: Env, addr: Address) -> u32 {
        // Get the current count.
        let mut val: u32 = env.storage().instance().get(&VAL).unwrap_or(1); // If no value set, assume 0.
        log!(&env, "val: {}", val);

        // If val < 50, double, else set to 1
        val = if val < 5 { 2 * val } else { 1 };

        // Save val.
        env.storage().instance().set(&VAL, &val);

        // Save the caller, for the current counter value
        let mut addrs: AddrMap = env.storage().instance().get(&ADDRS).unwrap_or(AddrMap::new(&env));

        let mut new_vec = addrs.get(val).unwrap_or(Vec::new(&env));
        new_vec.push_back(addr);

        addrs.set(val, new_vec);

        // Save addrs.
        env.storage().instance().set(&ADDRS, &addrs);

        // The contract instance will be bumped to have a lifetime of at least 100 ledgers if the current expiration lifetime at most 50.
        // If the lifetime is already more than 100 ledgers, this is a no-op. Otherwise,
        // the lifetime is extended to 100 ledgers. This lifetime bump includes the contract
        // instance itself and all entries in storage().instance(), i.e, COUNTER.
        env.storage().instance().extend_ttl(50, 100);

        // Return val to the caller.
        val
    }

    pub fn baz(env: Env) -> AddrMap {
        return env.storage().instance().get(&ADDRS).unwrap_or(AddrMap::new(&env));
    }
}

mod test;

@Kukovec
Copy link
Collaborator Author

Kukovec commented Apr 12, 2024

As we've discussed, we should create a megacontract in the future, and when we do I'll link it here as an example.

Copy link
Contributor

@konnov konnov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have made it through the first half of the doc! It's nice and detailed. I left a few comments. Stopped at a blocker that requires me to find a contract somewhere. Please add one.

doc/HOWTO/howto_setupAndDeployCustom.md Outdated Show resolved Hide resolved
- you probably want to add `~/.cargo/bin` to your PATH

### Local Stellar Network
Instead of building from source, Stellar provides a quickstart Docker image. You can call the below command from anywhere, and Docker will fetch the image.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you mention Nixos above, we should add a link to setting up docker on Nixos: https://nixos.wiki/wiki/Docker

soroban-sdk = { version = "20.3.2", features = ["testutils"] }
```

Write your contract code in `lib.rs`, and tests in `test.rs`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have made till this point. Could you add an example contract in the repo, so all of us could the same one to make sure that we have our setup working.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might as well take this chance to set up the megacontract repo going forward.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#11 for tracking

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#12

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is soroban contract init --with-example, you could just use one of those.

@Kukovec
Copy link
Collaborator Author

Kukovec commented Apr 12, 2024

I have made it through the first half of the doc! It's nice and detailed. I left a few comments. Stopped at a blocker that requires me to find a contract somewhere. Please add one.

#10 (comment)

@konnov
Copy link
Contributor

konnov commented Apr 12, 2024

I have made it through the first half of the doc! It's nice and detailed. I left a few comments. Stopped at a blocker that requires me to find a contract somewhere. Please add one.

#10 (comment)

Yeah, that's where I got stuck. Why would not you just commit the whole contract layout, e.g., under examples/contracts

Copy link
Collaborator

@thpani thpani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, got my first contract deployed! Thanks Jure!

I left I few comments that I needed to get everything going, I think we should wait for someone else to follow along and see if those are quirks of my local setup or needed in general.

doc/HOWTO/howto_setupAndDeployCustom.md Show resolved Hide resolved
Comment on lines +102 to +115
Next, we create agents within this network. To do this, run
```sh
soroban keys generate <AGENT> --network <NETWORK>
```
followed by
```sh
soroban config identity fund <AGENT> --network <NETWORK>
```
The latter will show a warning, saying that `<AGENT>` already exists, but if you call this command before the previous one it fails to execute, and if you don't call it at all the next command fails, so just ignore the warning.
Copy link
Collaborator

@thpani thpani Apr 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

afaict soroban keys generate fails with the funding error only if it cannot make a connection to the node. Otherwise, the config identity fund is not needed.


Having defined an agent, you can have them deploy the contract with:
```sh
soroban contract deploy --wasm <CONTRACT>.wasm --source <AGENT> --network <NETWORK>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to provide also the passphrase, otherwise the command fails:

Suggested change
soroban contract deploy --wasm <CONTRACT>.wasm --source <AGENT> --network <NETWORK>
soroban contract deploy --wasm <CONTRACT>.wasm --source <AGENT> --network <NETWORK> --network-passphrase <PASSPHRASE>

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact for my setup, this step was failing with

error: provided network passphrase "soroban testnet" does not match the server: "Test SDF Network ; September 2015"

Only when the previous step was executed exactly with this passphrase, i.e.

soroban config network add testnet --rpc-url "http://localhost:8000/soroban/rpc" --network-passphrase "Test SDF Network ; September 2015"

and then all arguments repeated in the deploy call like that

soroban contract deploy --wasm target/wasm32-unknown-unknown/release/hello_world.wasm --source alice --network testnet --network-passphrase "Test SDF Network ; September 2015" --rpc-url "http://localhost:8000/soroban/rpc

it did succeed...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might be related to https://github.com/freespek/solarkraft/pull/10/files#r1565784375, since the node is joining an existing testnet. It should work as is written with --local.

@thpani
Copy link
Collaborator

thpani commented Jun 19, 2024

We got this working for the dev team quite some time ago, and the Soroban "getting started" docs are probably a more up-to-date resource: https://developers.stellar.org/docs/smart-contracts/getting-started

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Write a HOWTO for the configuration and deployment process
4 participants