stellar / soroban-examples Goto Github PK
View Code? Open in Web Editor NEWExample Soroban Contracts
License: Apache License 2.0
Example Soroban Contracts
License: Apache License 2.0
For example here:
soroban-examples/token/src/contract.rs
Line 18 in 622ce39
There is this function to ensure that it's an error if a negative number is sent:
soroban-examples/token/src/contract.rs
Line 51 in 622ce39
However, if it's a u128 then a negative number cannot be encoded into XDR. Is there a reason not to make this change?
The current single offer and liquidity pool contracts follow a model where tokens need to be transferred to the contract methods like trade
or deposit
are called in the same transaction. A "router" contract is required to safely run these contract functions, so we should provide these examples as well.
Demonstrate creating a token that has a contract as it's admin.
For example, only the owner can mint but there are predefined velocity limits for minting .
Our current examples that make use of tokens cover a lot of ground. Single offer, Liquidity pool and Timelock are all great but are not trivial and also implement advanced auth.
It would be beneficial to have an almost trivial contract example accompanied by a tutorial that focuses on basic token usage.
One option is to make a simplified version of the timelock contract: single claimant, only "after" timebound, no advance auth.
Currently in this repo every example of retrieving things from storage is either storage().get(..).unwrap()
or storage().get_unchecked(..)
, both of which are followed by an .unwrap()
.
I also find it strange that it's an option wrapping a result. Intuitively to me the operation either success or fails and then the value returned is an option.
And get_unchecked
makes more sense if it is not checking the de-serialization not whether the value is present.
Some of the methods in the liquidity pool router and single offer router contracts are missing authorization. The methods are sf_deposit
, sf_withdraw
, and safe_trade
. This should be done using the cryptography module in the authorization example contract.
We intend the BigInt
type would be used instead of u128
, u256
, etc integer types. The examples (and token contract) use the term U256
to refer to 32 byte arrays, which is confusing because these are not integer types and can't be used as such.
This has created some confusion.
We should reserve uN
terms for integer types, and use BytesN<...>
(or FixedBinary<...>
in the current released SDK) for fixed bytes.
Related discussion: https://discord.com/channels/897514728459468821/966788672164855829/1007336560506699806
Related: stellar/go#4723. This is split off into a separate issue for better tracking.
Things to be done:
Ex.
check_auth(
...
vec![&e, nonce.into_val(&e), num.clone().into_val(&e)],
);
should be
check_auth(
...
(nonce, num.clone()).into_val(&e),
);
It will be possible to implement a signatures-only atomic swap once the call-stack from stellar/stellar-protocol#1289 is implemented. That would be a good way to exercise the new functionality.
A signatures-only atomic swap.
N/A
The liqpool contract uses strict-receive semantics. It requires the user performing a swap to specify an exact amount to receive, and then takes up to a maximum amount to fulfill it.
We should rewrite the liqpool contract such that it uses strict-send semantics. i.e. The user performing a swap chooses the amount to send in and gets a variable amount out inside a range defined by the user.
Why: Strict-send is more common in AMMs. It's also easier to code for since there isn't a undetermined transfer amount to move out of the users wallet.
Related conversation is at: https://discord.com/channels/897514728459468821/1108150361136566322
The current single offer contract follows a model where tokens need to be transferred to the contract before 'trade' is called. Both actions need to be done atomically for safety. We should demonstrate an alternative approach as well using 'approve' and 'xfer_from', which would allow the contract to send tokens between participants.
We should make the data model in examples more efficient.
Related conversation in the liquidity pool example for more information - #206 (comment).
The current custom account example is fairly advanced. I think we can benefit from a "simpler" custom account example.
The simplest viable account I can think of is a single signer account (similar to EOA, externally owned account, on Ethereum). Should we create it as an example?
update to use the updated token interface.
examples : Update to new contract method names
epic : stellar/soroban-tools#519
Add an Approval event and a Transfer event.
Just clicking the link in the README.
Tried to open the repo in Gitpod
Success
Is it just me or is the Gitpod for Soroban Examples broken? Iām getting
#11 [ 8/15] RUN rustup update stable
#11 0.185 info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
#11 0.357 warning: Signature verification failed for 'https://static.rust-lang.org/dist/channel-rust-stable.toml'
#11 0.395 info: latest update on 2023-01-26, rust version 1.67.0 (fc594f156 2023-01-24)
#11 0.427 info: downloading component 'cargo'
#11 0.539 info: downloading component 'clippy'
#11 0.596 info: downloading component 'rls'
#11 0.610 info: downloading component 'rust-analysis'
#11 0.632 info: downloading component 'rust-src'
#11 0.688 info: downloading component 'rust-std'
#11 1.179 info: downloading component 'rustc'
#11 1.616 info: downloading component 'rustfmt'
#11 1.688 info: removing previous version of component 'cargo'
#11 1.726 info: rolling back changes
#11 1.730 error: could not rename component file from '/home/gitpod/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/etc/bash_completion.d' to '/home/gitpod/.rustup/tmp/l8jml8yosamyrfil_dir/bk': Invalid cross-device link (os error 18)
#11 ERROR: process "/bin/sh -c rustup update stable" did not complete successfully: exit code: 1
------
> [ 8/15] RUN rustup update stable:
#11 0.539 info: downloading component 'clippy'
#11 0.596 info: downloading component 'rls'
#11 0.610 info: downloading component 'rust-analysis'
#11 0.632 info: downloading component 'rust-src'
#11 0.688 info: downloading component 'rust-std'
#11 1.179 info: downloading component 'rustc'
#11 1.616 info: downloading component 'rustfmt'
#11 1.688 info: removing previous version of component 'cargo'
#11 1.726 info: rolling back changes
#11 1.730 error: could not rename component file from '/home/gitpod/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/etc/bash_completion.d' to '/home/gitpod/.rustup/tmp/l8jml8yosamyrfil_dir/bk': Invalid cross-device link (os error 18)
------
.gitpod.Dockerfile:14
--------------------
12 | ENV SCCACHE_DIR=/workspace/.sccache
13 |
14 | >>> RUN rustup update stable
15 | RUN rustup target add --toolchain stable wasm32-unknown-unknown
16 | RUN rustup component add --toolchain stable rust-src
--------------------
error: failed to solve: process "/bin/sh -c rustup update stable" did not complete successfully: exit code: 1
{"@type":"type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent","command":"build","error":"exit status 1","file":"build.go:44","func":"func1","level":"error","message":"build failed","serviceContext":{"service":"bob","version":""},"severity":"ERROR","time":"2023-02-03T22:21:30.807197907Z"}
exit
headless task failed: exit status 1
If I try and Continue with the Default Image I get this in the console in Gitpod
HISTFILE=/workspace/.gitpod/cmd-0 history -r; {
cargo fetch
make build test
} && {
gp ports await 23000
gp open README.md
gp open increment/src/lib.rs
gp open increment/src/test.rs
gp open README.md
soroban invoke --id 1 --wasm target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm --fn increment
}
gitpod /workspace/soroban-examples (main) $ HISTFILE=/workspace/.gitpod/cmd-0 history -r; {
> cargo fetch
> make build test
>
> } && {
> gp ports await 23000
> gp open README.md
> gp open increment/src/lib.rs
> gp open increment/src/test.rs
> gp open README.md
> soroban invoke --id 1 --wasm target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm --fn increment
>
> }
info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
info: latest update on 2023-01-10, rust version 1.66.1 (90743e729 2023-01-10)
info: downloading component 'cargo'
info: downloading component 'clippy'
info: downloading component 'rust-src'
info: downloading component 'rust-std' for 'wasm32-unknown-unknown'
info: downloading component 'rustc'
info: downloading component 'rustfmt'
info: downloading component 'rls'
info: downloading component 'rust-analysis'
info: downloading component 'rust-std'
info: removing previous version of component 'cargo'
info: rolling back changes
error: could not rename component file from '/home/gitpod/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/etc/bash_completion.d' to '/home/gitpod/.rustup/tmp/ojn2k3qp55an_9t6_dir/bk': Invalid cross-device link (os error 18)
cargo build --target wasm32-unknown-unknown --release -p soroban-token-contract
info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
info: latest update on 2023-01-10, rust version 1.66.1 (90743e729 2023-01-10)
info: downloading component 'cargo'
info: downloading component 'clippy'
info: downloading component 'rust-src'
info: downloading component 'rust-std' for 'wasm32-unknown-unknown'
info: downloading component 'rustc'
info: downloading component 'rustfmt'
info: downloading component 'rls'
info: downloading component 'rust-analysis'
info: downloading component 'rust-std'
info: removing previous version of component 'cargo'
info: rolling back changes
error: could not rename component file from '/home/gitpod/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/etc/bash_completion.d' to '/home/gitpod/.rustup/tmp/89ua23syzap5peox_dir/bk': Invalid cross-device link (os error 18)
make: *** [Makefile:10: build] Error 1
gitpod /workspace/soroban-examples (main) $
See the first commit in stellar-deprecated/soroban-token-contract#38 for a pattern to follow
soroban-examples
: 0.8.4
soroban-SDK
: 0.8.4
soroban-cli
: v0.7.0 (this is in the makefile. Shouldn't this be v0.7.1?)
Navigate to the Gitpod demo: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.8.4
Create a new Gitpod Workspace
Wait for Build to finish
A finished message similar to the following:
Finished release [optimized] target(s) in 23.44s
Error regarding Cargo.toml
file
error: could not find `Cargo.toml` in `/workspace/soroban-examples` or any parent directory
Error regarding rustc Version
error: package `soroban-sdk v0.8.4` cannot be built because it requires rustc 1.69 or newer, while the currently active rustc version is 1.68.2
Either upgrade to rustc 1.69 or newer, or use
cargo update -p [email protected] --precise ver
where `ver` is the latest version of `soroban-sdk` supporting rustc 1.68.2
make[1]: *** [Makefile:9: build] Error 101
make[1]: Leaving directory '/workspace/soroban-examples/account'
make: *** [Makefile:9: build] Error 1
Was able to successfully run make
After manually running the following:
rustup self uninstall -y
rm -rf .rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
rustup update stable
rustup target add --toolchain stable wasm32-unknown-unknown
rustup component add --toolchain stable rust-src
rustup update nightly
rustup target add --toolchain nightly wasm32-unknown-unknown
rustup component add --toolchain nightly rust-src
rustup default stable
sudo apt-get update && sudo apt-get install -y binaryen
Bug Report:
Summary:
The user is attempting to invoke a contract called "soroban_events_contract" but encounters an error while executing the command. The error message states that there is an issue with the input arguments provided to the host function, which results in a "HostError". The debug events indicate that an unexpected environment interface version was encountered, and a backtrace is provided. Additionally, to fix the issue, the user made some changes to the cargo.toml
file of the project.
Steps to Reproduce:
Build the "soroban_events_contract" using cargo build --target wasm32-unknown-unknown --release
.
Invoke the "soroban_events_contract" using soroban contract invoke
with the following arguments:
a. --wasm pointing to the path of the built wasm file.
b. --id argument set to 1.
c. -- followed by the function name "increment".
soroban contract invoke --wasm target/wasm32-unknown-unknown/release/soroban_events_contract.wasm --id 1 -- increment
Expected Results:
The contract should be successfully invoked, and the function increment
should be executed. Event should be displayed in terminal
soroban contract invoke \
--wasm target/wasm32-unknown-unknown/release/soroban_events_contract.wasm \
--id 1 \
-- \
increment
#0: event: {"ext":"v0","contract_id":"0000000000000000000000000000000000000000000000000000000000000001","type_":"contract","body":{"v0":{"topics":[{"symbol":"COUNTER"},{"symbol":"increment"}],"data":{"u32":1}}}}
1
Actual Results:
Upon executing the soroban contract invoke command, the following error is encountered:
error: HostError
Value: Status(HostFunctionError(InputArgsInvalid))
Debug events (newest first):
0: "Debug unexpected environment interface version"
Backtrace (newest first):
0: backtrace::capture::Backtrace::new_unresolved
1: soroban_env_host::host::err_helper::<impl soroban_env_host::host::Host>::err
2: soroban_env_host::host::err_helper::<impl soroban_env_host::host::Host>::err_status_msg
3: soroban_env_host::vm::Vm::new
4: soroban_env_host::host::Host::call_n_internal
5: soroban_env_host::host::Host::invoke_function
6: soroban_cli::commands::contract::invoke::Cmd::run_in_sandbox
7: soroban_cli::commands::contract::Cmd::run::{{closure}}
8: soroban_cli::commands::Root::run::{{closure}}
9: tokio::runtime::park::CachedParkThread::block_on
10: tokio::runtime::scheduler::multi_thread::MultiThread::block_on
11: tokio::runtime::runtime::Runtime::block_on
12: soroban::main
The debug events indicate that there was an unexpected environment interface version, and the backtrace suggests that there was an error with the host function.
Environment:
The error occurred on a MacBook Pro. The user attempted invoking the contract using both soroban version 0.7.0 and soroban version 0.7.1.
Additional Information:
To solve the issue, the user made changes to the cargo.toml
file of the project and then used cargo build --target wasm32-unknown-unknown --release
to rebuild the .wasm
file for the increment contract
. Specifically, they removed the git
and rev
fields from the soroban-sdk dependencies
, which were pointing to a specific commit on the Stellar Soroban SDK
repository. Instead, they included only the version field.
old cargo.toml
:
[package]
name = "soroban-events-contract"
version = "0.0.0"
authors = ["Stellar Development Foundation <[email protected]>"]
license = "Apache-2.0"
edition = "2021"
publish = false
[lib]
crate-type = ["cdylib"]
doctest = false
[dependencies]
soroban-sdk = { version = "0.7.0", git = "https://github.com/stellar/rs-soroban-sdk", rev = "9bbac60c25cee9aa995025db5af828c243d15690"}
[dev_dependencies]
soroban-sdk = { version = "0.7.0", git = "https://github.com/stellar/rs-soroban-sdk", rev = "9bbac60c25cee9aa995025db5af828c243d15690", features = ["testutils"] }
[profile.release]
opt-level = "z"
overflow-checks = true
debug = 0
strip = "symbols"
debug-assertions = false
panic = "abort"
codegen-units = 1
lto = true
[profile.release-with-logs]
inherits = "release"
debug-assertions = true
new cargo.toml
[package]
name = "soroban-events-contract"
version = "0.0.0"
authors = ["Stellar Development Foundation <[email protected]>"]
license = "Apache-2.0"
edition = "2021"
publish = false
[lib]
crate-type = ["cdylib"]
doctest = false
[dependencies]
soroban-sdk = { version = "0.7.0" }
[dev_dependencies]
soroban-sdk = { version = "0.7.0", features = ["testutils"] }
[profile.release]
opt-level = "z"
overflow-checks = true
debug = 0
strip = "symbols"
debug-assertions = false
panic = "abort"
codegen-units = 1
lto = true
[profile.release-with-logs]
inherits = "release"
debug-assertions = true
Right now we are only testing the happy path. Related to stellar-deprecated/soroban-token-contract#34
We should make sure the failure cases actually fail as expected.
None
Related issue - stellar/rs-soroban-env#634.
During the hackathon, a couple users ran into issues where their contract hit an error in the token example, but the error didn't propagate up, making it difficult to debug simple issues like insufficient allowances. We should update all contracts (but especially the token contract) to call panic_with_error!
on errors that we expect users to hit due to incorrect usage of a contract.
Blocked by stellar/rs-soroban-sdk#247
Right now the token contract is the standard entry-point for learning about auth, but it has a lot of complexity to make it appropriate for production.
We should add an example that makes several simplifying assumptions to help people learn the basics.
TODO
Use invoker()
auth exclusively
#62 updated the liquidity pool contract to use the native token contract, but this was reverted in #76 to make authorization changes easier (the native token contract doesn't have access to the auth code, so we'd have to copy it in).
Once the native token contract can do authorization, the examples should be updated to use the native token contract.
The current token example fully implements the token interface. This includes "advanced" topics such as allowances and admin functions that might be a bit confusing for new contract devs. It can be beneficial to add a simple token contract with a finite supply, simple transfer functionality and no allowances to demonstrate basic soroban concepts.
Originally suggested by @wildework
Although smart wallets aren't widely used, they are a possible construction on Soroban and it would be good to know how they fit into the system.
A simple smart wallet example. The most basic would be just an on-chain multi-signature configuration analogous to classic Stellar accounts.
N/A
Right now, tests never run the WASM. That makes it hard to know if the WASM is up to date and actually works.
Add a feature to run with the actual WASM.
TODO
Users should be able to run make
after cloning the repository. I found I needed a few additional steps beyond the Getting Started
instructions in the Soroban docs:
cargo install --locked --version 0.5.14 cargo-hack
rustup install nightly
rustup target add --toolchain nightly wasm32-unknown-unknown
rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
Probably just some instructions in the README.md
for now?
N/A
I can make a PR if this seems like the right approach.
Use invoker() auth exclusively
main
make build
soroban-examples/liquidity_pool/src/token_contract.rs
Lines 16 to 19 in cad5400
That line uses target instead, which means the liquidity pool contract is huge even when built for target-tiny. Liquidity pool contract is enormous (62k) as a consequence. Liquidity pool router makes the same error (147k). I'm guessing other examples make that error too.
When verifying multiple parameters, the verification call would look something like check_auth(&e, auth, Domain::Freeze, (a, b).into_val(&e));
. One would naturally assume that verification for a single parameter would look like check_auth(&e, auth, Domain::Freeze, (a).into_val(&e));
, but that will fail with a ConversionError
, because a vector is expected instead of the single value a
. The right way to do this would be to use (a,).into_val(&e)
(notice the comma) or (vec![&e, a]).into_val(&e)
.
The error does point you to where the conversion error occurs, but it could take some time for someone to understand what went wrong. Ideally, this issue would be caught at compile time.
In the examples we have multiple places where we have written code to pre-calculate the contract ID of a deployment. We plan to add this functionality to the SDK and host functions. Once it is there, we should remove it in the examples.
Dependent on stellar/rs-soroban-sdk#730
There are no automatically called constructors, so we should present an example of how constructors can be safely handled.
A simple contract with a function deploy
that takes a binary blob, a function name, and a list of arguments. The contract creates a contract from the binary blob then calls the specified function with the provided arguments.
In the long run we should evaluate whether to provide a native constructor functionality.
After we remove BigInt from the examples, we should make sure the arithmetic is safe.
Access to time and ledger sequence were added in stellar/rs-soroban-env#330 and stellar/rs-soroban-sdk#455 but we aren't exercising this functionality at all.
A simple timelock contract. One version of this would be analogous to a claimable balance with just one claimant and one time predicate, but I'm open to other ideas.
N/A
This came out of a discussion with @leighmcculloch. We want to make message generation extremely uniform, so every argument to a contract function should appear in the message. Currently, we are entirely excluding the Signature
type (which includes more than just a signature) from the message.
It's not possible to include the signature itself (because you can't produce the signature without the message), so we should convert the Signature
to an Identifier
and include that Identifier
in the message.
It would also be reasonable to include a ()
in the message.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
š Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ššš
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ā¤ļø Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.