Code example

Explained code snippet

Open source repository donation scheme design

Prerequisites

Create and initialize the token contract

// CREATE TOKEN CONTRACT
let (token_id, token_client) = create_and_init_token_contract(&env, &admin_id);

Valid accounts for the individuals

Let's create some test accounts

// Admin for the Token Contract init. 
let admin = env.accounts().generate(); let admin_id = Identifier::Account(admin.clone());

// Account that will donate to the parent project
let donor = env.accounts().generate();
let donor_id = Identifier::Account(donor.clone());

// PARENT CONTRACT (PARENT PROJECT)
let contract_id = env.register_contract(None, CascadeDonationContract);
let contract_client = CascadeDonationContractClient::new(&env, &contract_id);

// PARENT PROJECT CHILDREN ACCOUNTS
let dependency_1 = env.accounts().generate();
let dependency1_id = Identifier::Account(dependencie_1.clone());

//CHILD PARENT PROJECT (CHILD CONTRACT)
let child_contract_id = env.register_contract_wasm(None, cascade_donation_contract::WASM);
let child_contract_client = CascadeDonationContractClient::new(&env, &child_contract_id);

// CHILD PARENT PROJECT CHILDREN
let sub_dependency_1 = env.accounts().generate();
let sub_dependency_1_id = Identifier::Account(sub_dependencie_1.clone());

let sub_dependency_2 = env.accounts().generate();
let sub_dependency_2_id = Identifier::Account(sub_dependencie_2.clone());

Define distribution rules

// CHILD PARENT CHILDREN
let mut parent1_children: Vec<Node> = vec![&env];
let parent_1_child_1 =
    Recipient {
        address: soroban_sdk::Address::Account(sub_dependency_1.clone()),
        name: symbol!("subdep_1"),
        percentage: 20
    };

let parent_1_child_2 =
    Recipient {
        address: soroban_sdk::Address::Account(sub_dependency_2.clone()),
        name: symbol!("subdep_2"),
        percentage: 20
    };

parent1_children.push_back(parent_1_child_1);
parent1_children.push_back(parent_1_child_2);
// END CHILD PARENT CHILDREN

//PARENT CHILDREN
let child_parent_1 =
    Recipient {
        address: soroban_sdk::Address::Contract(child_contract_id.clone()),
        name: symbol!("c_parent_1"),
        percentage: 20
    };

let child_1 =
    Recipient {
        address: soroban_sdk::Address::Account(dependency_1.clone()),
        name: symbol!("dep_1"),
        percentage: 20
    };
// END CHILDREN

let mut children: Vec<Node> = vec![&env];
children.push_back(child_1);
children.push_back(child_parent_1);

Initialize the CascadeDonation contract

We need to initialize the second one too for the purpose of the test.

// Child contract
child_contract_client.initialize(&token_id, &parent1_children);

// Root contract
contract_client.initialize(&token_id, &children);

Mint donor account

token_client.with_source_account(&admin).mint(
    &Signature::Invoker,
    &BigInt::zero(&env),
    &donator_id,
    &BigInt::from_u32(&env, 2000)
);

Approve donation from donor

token_client.with_source_account(&donor).approve(
    &Signature::Invoker,
    &BigInt::zero(&env),
    &Identifier::Contract(contract_id.clone()),
    &BigInt::from_u32(&env, 1000)
);
contract_client.with_source_account(&donor).donate(&BigInt::from_u32(&env, 1000), &donator_id);

Expected result

Main Contract balance -> 600 Recipient 1 balance -> 200 Recipient 2 balance -> 120 Recipient 3 balance -> 40 Recipient 4 balance -> 40

Last updated