Skip to main content

Setting up the Donation Contract

The first step is setting up the basic structure of our donation contract. We'll define the contract state, initialization method, and basic beneficiary management.

Contract State Structure

The donation contract needs to track two key pieces of data: who receives the donations (beneficiary) and how much each donor has contributed.

use near_sdk::store::IterableMap;
use near_sdk::{near, AccountId, NearToken, PanicOnDefault};

#[near(contract_state)]
#[derive(PanicOnDefault)]
pub struct Contract {
pub beneficiary: AccountId,
pub donations: IterableMap<AccountId, NearToken>,
}

Contract Initialization

Every NEAR contract needs an initialization method to set up the initial state. Our contract requires a beneficiary to be specified during deployment.

#[near]
impl Contract {
#[init]
#[private] // only callable by the contract's account
pub fn init(beneficiary: AccountId) -> Self {
Self {
beneficiary,
donations: IterableMap::new(b"d"),
}
}
}
tip

The #[private] decorator in Rust and privateFunction: true in TypeScript ensure only the contract account can call the initialization method.

Beneficiary Management

Add methods to view and update the beneficiary. The update method should be restricted to the contract owner for security.

impl Contract {
pub fn get_beneficiary(&self) -> &AccountId {
&self.beneficiary
}

#[private] // only callable by the contract's account
pub fn change_beneficiary(&mut self, new_beneficiary: AccountId) {
self.beneficiary = new_beneficiary;
}
}

Building the Contract

Now let's build the contract to ensure our setup is correct.

First, create your Cargo.toml:

Build the contract:

cargo near build

Basic Unit Test

Let's add a simple test to verify our initialization works correctly.

#[cfg(test)]
mod tests {
use super::*;

const BENEFICIARY: &str = "beneficiary.testnet";

#[test]
fn initializes() {
let contract = Contract::init(BENEFICIARY.parse().unwrap());
assert_eq!(contract.beneficiary, BENEFICIARY.parse::<AccountId>().unwrap());
}
}

Run the test:

cargo test

Next Steps

With the basic contract structure in place, you're ready to implement the core donation functionality. The next chapter will cover how to handle token transfers using payable methods.

Continue to Handle Donations to learn about accepting NEAR token payments.