ava-labs / hypersdk

Opinionated Framework for Building Hyper-Scalable Blockchains on Avalanche
Other
196 stars 100 forks source link

[x/programs] Mechanism for calling other public functions within a program #982

Open dboehm-avalabs opened 3 months ago

dboehm-avalabs commented 3 months ago

Currently calling other public functions from within a public function causes borrowing issues around the Context. You can get around this by having an "inner" copy of the public function that takes in the deconstructed components of the Context, but it would be cleaner to not have to do this.


#[public]
pub fn transfer_from(
    context: Context<StateKey>,
    sender: Address,
    recipient: Address,
    amount: u64,
) -> bool {
    let Context {program, actor } = context;
    let total_allowance = allowance(context, sender, actor); 
    // the above call is not valid, have to call inner_allowance instead.

    assert!(total_allowance>amount);
    program
        .state()
        .store(StateKey::Allowance(sender, actor), &(total_allowance - amount))
        .expect("failed to store allowance");
    transfer(context, recipient, amount)
}

#[public]
pub fn allowance(context: Context<StateKey>, owner: Address, spender: Address) -> u64 {
    let Context { program, .. } = context;
    inner_allowance(&program, owner, spender)
}

pub fn inner_allowance(program:&Program<StateKey>, owner: Address, spender: Address) -> u64 {
    program
        .state()
        .get::<u64>(StateKey::Allowance(owner, spender))
        .expect("failure")
        .unwrap_or_default()
}
github-actions[bot] commented 1 month ago

This issue has become stale because it has been open 60 days with no activity. Adding the lifecycle/frozen label will exempt this issue from future lifecycle events.