Welcome to VoteChain! This guide will help you set up your development environment and make your first contribution.
Before you begin, ensure you have the following installed on your system:
| Tool | Minimum Version | Purpose |
|---|---|---|
| Rust | 1.75.0+ | Core language for smart contracts |
| Cargo | 1.75.0+ | Rust package manager (comes with Rust) |
| Stellar CLI | Latest | Build and deploy Soroban contracts |
| Git | 2.0+ | Version control |
| Tool | Purpose |
|---|---|
| VS Code | IDE with Rust extensions |
| rust-analyzer | Rust language server for IDE support |
Install Rust using rustup (the official Rust installer):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shFollow the on-screen instructions. After installation, restart your terminal and verify:
rustc --version
cargo --versionSoroban contracts compile to WebAssembly. Add the wasm32 target:
rustup target add wasm32-unknown-unknownThe Stellar CLI is required to build and deploy Soroban contracts:
cargo install --locked stellar-cli --features optVerify the installation:
stellar --versionClone the VoteChain repository and navigate to the project directory:
git clone https://github.com/Vera3289/votechain-contracts.git
cd votechain-contractsBuild both contracts (governance and token):
make buildThis compiles the contracts to .wasm files in the target/wasm32-unknown-unknown/release/ directory.
Run the full test suite to ensure everything is working:
make testYou should see output indicating all tests passed:
running 45 tests
test test_create_proposal ... ok
test test_cast_vote_and_finalise_passed ... ok
...
test result: ok. 45 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
make test# Governance contract only
cargo test -p votechain-governance
# Token contract only
cargo test -p votechain-tokencargo test test_create_proposalBy default, Rust captures test output. To see println! statements:
cargo test -- --nocapturecargo test -- --test-threads=1 --nocaptureBefore submitting a pull request, ensure your code passes all quality checks:
make fmt-checkIf formatting issues are found, auto-fix them:
make fmtRun Clippy (Rust's linter) to catch common mistakes:
make lintFix any warnings or errors before committing.
Ensure you have a Stellar testnet account with XLM for fees. You can get testnet XLM from the Stellar Laboratory.
Create a .env file in the project root (this file is gitignored):
# Stellar testnet configuration
STELLAR_NETWORK=testnet
STELLAR_RPC_URL=https://soroban-testnet.stellar.org
STELLAR_NETWORK_PASSPHRASE="Test SDF Network ; September 2015"
# Your testnet account secret key (NEVER commit this!)
STELLAR_SECRET_KEY=S...Deploy the token contract first, then the governance contract:
NETWORK=testnet ./scripts/deploy.shThe script will:
- Build both contracts
- Deploy the token contract
- Deploy the governance contract
- Initialize both contracts
- Output the deployed contract addresses
Check the deployment on Stellar Expert by searching for your contract addresses.
Create a new branch for your feature or bug fix:
git checkout -b feature/my-new-featureUse descriptive branch names:
feature/add-delegationfix/double-vote-bugtest/quorum-edge-casesdocs/update-readme
Edit the relevant files. Common areas:
| Area | Files |
|---|---|
| Governance logic | contracts/governance/src/lib.rs |
| Token logic | contracts/token/src/lib.rs |
| Events | contracts/*/src/events.rs |
| Tests | contracts/*/src/test.rs |
| Documentation | README.md, docs/ |
Every new function or bug fix should include tests. Add tests to the appropriate test.rs file:
#[test]
fn test_my_new_feature() {
let t = setup_env();
// Your test code here
assert_eq!(expected, actual);
}Before committing, ensure all checks pass:
make test
make fmt
make lintFollow Conventional Commits format:
git add .
git commit -m "feat: add delegation support to governance contract"Commit message prefixes:
feat:- New featurefix:- Bug fixtest:- Adding or updating testsdocs:- Documentation changesrefactor:- Code refactoringchore:- Maintenance tasks
Push your branch to GitHub:
git push origin feature/my-new-featureThen create a pull request on GitHub with:
- Clear title describing the change
- Description of what was changed and why
- Reference to any related issues (e.g., "Closes #42")
- Screenshots or examples if applicable
Solution: Ensure you're using Rust 1.75.0 or later:
rustup updateSolution: Reinstall the Stellar CLI:
cargo install --locked stellar-cli --features optEnsure ~/.cargo/bin is in your PATH.
Solution: Add the WebAssembly target:
rustup target add wasm32-unknown-unknownSolution: This is expected behavior for re-initialization tests. If other tests fail, ensure you're running the latest code:
git pull origin main
cargo clean
make build
make testSolution: Ensure your testnet account has XLM. Get testnet XLM from:
Solution: Ensure you have the correct Rust toolchain:
rustup default stable
rustup target add wasm32-unknown-unknownSolution: Remove unused imports or allow them temporarily:
#[allow(unused_imports)]
use soroban_sdk::...;Solution: Auto-format your code:
make fmtUnderstanding the project layout:
votechain-contracts/
├── contracts/
│ ├── governance/ # Governance contract
│ │ ├── src/
│ │ │ ├── lib.rs # Main contract logic
│ │ │ ├── storage.rs # Storage helpers
│ │ │ ├── events.rs # Event emissions
│ │ │ ├── types.rs # Type definitions
│ │ │ └── test.rs # Unit tests
│ │ └── Cargo.toml # Contract dependencies
│ └── token/ # Token contract (similar structure)
├── docs/ # Documentation
│ ├── adr/ # Architecture Decision Records
│ ├── examples/ # Usage examples
│ └── security/ # Security documentation
├── scripts/ # Deployment scripts
├── config/ # Network configurations
├── Cargo.toml # Workspace configuration
├── Makefile # Build commands
└── README.md # Project overview
- Pick an issue from the GitHub issues page or create a new one
- Create a branch with a descriptive name
- Write code following the project's style and conventions
- Write tests for your changes
- Run quality checks (test, fmt, lint)
- Commit with a conventional commit message
- Push and create a pull request
- Respond to feedback from maintainers
- Merge once approved
- No
std: All contracts use#![no_std] - Error handling: Use
Result<T, ContractError>for fallible operations - Events: Emit events for all state-changing operations
- Documentation: Add
///doc comments to all public functions - Testing: Every function needs at least one test
- No floating-point: Use
i128for all numeric values - Formatting: Run
make fmtbefore committing - Linting: Fix all Clippy warnings
- GitHub Issues: github.com/Vera3289/votechain-contracts/issues
- Stellar Discord: discord.gg/stellar - #soroban channel
- Stellar Docs: developers.stellar.org/docs/smart-contracts
- Soroban Examples: github.com/stellar/soroban-examples
Now that you're set up:
- Read the CONTRIBUTING.md for contribution guidelines
- Review the Architecture Decision Records to understand design choices
- Check the FAQ for common questions
- Browse open issues to find something to work on
- Join the Stellar Discord to connect with the community
Happy coding! 🚀