A crowdfunding smart contract built on the Stellar network using Soroban.
Stellar Raise lets anyone create a crowdfunding campaign on-chain. Contributors pledge tokens toward a goal before a deadline. If the goal is met, the creator withdraws the funds. If not, contributors are refunded automatically.
| Feature | Description |
|---|---|
| Initialize | Create a campaign with a goal, deadline, and token |
| Contribute | Pledge tokens before the deadline |
| Withdraw | Creator claims funds after a successful campaign |
| Refund | Contributors individually reclaim tokens if the goal is missed (pull-based) |
stellar-raise-contracts/
├── .github/workflows/rust_ci.yml # CI pipeline
├── contracts/crowdfund/
│ ├── src/
│ │ ├── lib.rs # Smart contract logic
│ │ └── test.rs # Unit tests
│ └── Cargo.toml # Contract dependencies
├── Cargo.toml # Workspace config
├── CONTRIBUTING.md
├── README.md
└── LICENSE
| Requirement | Minimum | Notes |
|---|---|---|
| OS | Linux x86-64 or macOS 12+ | WSL2 on Windows |
| RAM | 4 GB | 8 GB recommended for --release builds |
| Rust | stable ≥ 1.74 | rustup update stable |
| Stellar CLI | ≥ 20.0.0 | Renamed from soroban in v20 |
| Node.js | ≥ 18 | Required for frontend UI and JS tests |
# Install Rust via rustup (https://rustup.rs)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
# Add the WASM compilation target
rustup target add wasm32-unknown-unknown
# Verify
rustc --version
rustup target list --installed | grep wasm32curl -Ls https://soroban.stellar.org/install-soroban.sh | sh
source ~/.bashrc # or ~/.zshrc
stellar --version # should print stellar-cli x.y.zNode.js ≥ 18 is required to run the frontend and its test suite.
# Using nvm (recommended)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.bashrc
nvm install 18
nvm use 18
node --version # v18.x.x
npm --versionAlternatively, download directly from nodejs.org.
# Clone the repo
git clone https://github.com/<your-org>/stellar-raise-contracts.git
cd stellar-raise-contracts
# Build the contract
cargo build --release --target wasm32-unknown-unknown
# Run contract tests
cargo test --workspace
# Install frontend dependencies
cd frontend
npm install
# Run frontend tests (single pass, no watch)
npm test -- --run
# Start the frontend dev server (run manually in your terminal)
# npm run devSee
docs/readme_md_installation.mdfor edge cases, automated environment verification, and frontend-specific troubleshooting.
// Create a new campaign
fn initialize(env, creator, token, goal, deadline, min_contribution);
// Pledge tokens to the campaign
fn contribute(env, contributor, amount);
// Creator withdraws after successful campaign
fn withdraw(env);
// Individual contributor claims refund if goal not met (pull-based)
fn refund_single(env, contributor);
// View functions
fn total_raised(env) -> i128;
fn goal(env) -> i128;
fn deadline(env) -> u64;
fn contribution(env, contributor) -> i128;
fn min_contribution(env) -> i128;This contract uses a pull-based refund pattern for scalability and gas efficiency.
A traditional "push" refund (where one transaction refunds all contributors) would:
- Fail with thousands of contributors due to resource limits
- Be expensive and unpredictable in cost
- Create a single point of failure
If the campaign goal is not met by the deadline:
- Each contributor must claim their own refund by calling
refund_single - Contributors can claim at any time after the deadline
- The refund is processed immediately and securely
stellar contract invoke \
--id <CONTRACT_ID> \
--network testnet \
--source <YOUR_SECRET_KEY> \
-- refund_single \
--contributor <YOUR_ADDRESS>Once deployed, the contract can be upgraded to a new WASM implementation without changing its address or losing stored data. This allows the project to ship fixes and improvements without redeploying.
-
Build the new WASM binary:
cargo build --release --target wasm32-unknown-unknown
-
Upload the new WASM to the network:
stellar contract install \ --wasm target/wasm32-unknown-unknown/release/crowdfund.wasm \ --network testnet \ --source <YOUR_SECRET_KEY>
This returns the WASM hash (SHA-256).
-
Invoke the upgrade function:
stellar contract invoke \ --id <CONTRACT_ADDRESS> \ --fn upgrade \ --arg <WASM_HASH> \ --network testnet \ --source <YOUR_SECRET_KEY>
- Only the admin (set to the campaign creator at initialization) can call the upgrade function.
- The upgrade is irreversible — ensure the new WASM is thoroughly tested before upgrading.
- All contract storage and state persist across upgrades.
- The contract address remains the same after an upgrade.
- Recommendation: Have at least two reviewers approve upgrade PRs before merging to production.
We provide automated scripts to simplify deploying and interacting with the crowdfund contract on testnet.
-
Install Stellar CLI (v20+):
curl -Ls https://soroban.stellar.org/install-soroban.sh | sh source ~/.bashrc # or ~/.zshrc stellar --version # should print stellar-cli x.y.z
-
Configure your Stellar identity:
stellar keys generate --global alice
-
Add the testnet network:
stellar network add testnet \ --rpc-url https://soroban-testnet.stellar.org:443 \ --network-passphrase "Test SDF Network ; September 2015"
The deploy script builds the WASM, deploys to testnet, and initializes a campaign.
./scripts/deploy.sh <creator> <token> <goal> <deadline> <min_contribution>Parameters:
| Parameter | Description |
|---|---|
creator |
Stellar address of the campaign creator |
token |
Stellar address of the token contract |
goal |
Funding goal (in stroops/lumens) |
deadline |
Unix timestamp for campaign end |
min_contribution |
Minimum contribution amount (default: 1) |
Example:
# Example: Deploy a campaign with 1000 XLM goal, 30-day deadline
DEADLINE=$(date -d "+30 days" +%s)
./scripts/deploy.sh GAAAAH4D... GAAAAH4D... 1000 $DEADLINE 10Output:
Building WASM...
Deploying contract to testnet...
Contract deployed: C...
Campaign initialized successfully.
Contract ID: C...
Save this Contract ID for interacting with the campaign.
After deployment, use the interact script for common actions:
./scripts/interact.sh <contract_id> <action> [args...]Actions:
| Action | Description | Arguments |
|---|---|---|
contribute |
Contribute tokens to campaign | contributor (address), amount |
withdraw |
Creator withdraws funds (after success) | creator (address) |
refund |
Contributor requests refund (if goal not met) | caller (address) |
Examples:
# Contribute 100 tokens to the campaign
./scripts/interact.sh C... contribute GCCCC... 100
# Creator withdraws funds after successful campaign
./scripts/interact.sh C... withdraw GAAAAH4D...
# Contributor requests refund if goal not met
./scripts/interact.sh C... refund GCCCC...If you prefer manual deployment:
# Build the optimized WASM
cargo build --release --target wasm32-unknown-unknown
# Deploy using Stellar CLI
stellar contract deploy \
--wasm target/wasm32-unknown-unknown/release/crowdfund.wasm \
--network testnet \
--source <YOUR_SECRET_KEY>
# Initialize the campaign
stellar contract invoke \
--id <CONTRACT_ADDRESS> \
--network testnet \
--source <YOUR_SECRET_KEY> \
-- initialize \
--creator <CREATOR> \
--token <TOKEN> \
--goal <GOAL> \
--deadline <DEADLINE> \
--min_contribution <MIN>Please read our Code of Conduct before contributing.
# Symptom: error[E0463]: can't find crate for `std`
rustup target add wasm32-unknown-unknown
rustup target list --installed | grep wasm32# Symptom: stellar: command not found OR unexpected argument '--source-account'
# The CLI was renamed from `soroban` to `stellar` in v20. Install the latest:
curl -Ls https://soroban.stellar.org/install-soroban.sh | sh
source ~/.bashrc # or ~/.zshrc
stellar --version # should print stellar-cli x.y.z# Generate a funded testnet identity (friendbot auto-funds on testnet)
stellar keys generate --global alice --network testnet
stellar keys address alice
# For Futurenet (manual funding required):
stellar network add futurenet \
--rpc-url https://rpc-futurenet.stellar.org:443 \
--network-passphrase "Test SDF Future Network ; October 2022"
stellar keys generate --global alice-futurenet --network futurenetSecurity: Never commit
.soroban/or~/.config/stellar/directories. They contain plaintext secret keys. Add.soroban/to.gitignore.
rustup update stable
rustup target add wasm32-unknown-unknown # re-add after toolchain update
cargo clean && cargo build --release --target wasm32-unknown-unknownSoroban tests spin up an in-process ledger. On machines with limited RAM, running all tests in parallel can exhaust memory.
# Limit test thread parallelism
cargo test --workspace -- --test-threads=2# Symptom: SyntaxError or "engine" warning during npm install
node --version # must be >= 18
nvm install 18 && nvm use 18
npm install# Use legacy peer deps flag if needed (Node 18+)
npm install --legacy-peer-deps# Symptom: EADDRINUSE: address already in use :::3000
# Kill the process on port 3000 and restart
lsof -ti:3000 | xargs kill -9
npm run devFor a full edge-case checklist and automated environment verification, see
docs/readme_md_installation.md and run:
./scripts/verify_env.shSee CHANGELOG.md for a full history of notable changes.
Please review our Security Policy for responsible disclosure guidelines.
See CONTRIBUTING.md for guidelines.
This project is licensed under the MIT License — see the LICENSE file for details.