// The purpose of this test is to directly showcase how the various // API traits are being used, without the aid of macros. // All this code is of course always macro-generated. // // Since it is more difficult to debug macros directly, // it is helpful to keep this test as a reference for macro development // and maintenance. #![allow(unused)] use dharithri_sc::{ contract_base::ProxyObjBase, types::{BigInt, ManagedAddress}, }; use dharithri_sc_scenario::api::{SingleTxApi, StaticApi}; use crate::module_1::VersionModule; mod module_1 { dharithri_sc::imports!(); ///////////////////////////////////////////////////////////////////////////////////////////////// //////// CONTRACT TRAIT ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////// pub trait VersionModule: dharithri_sc::contract_base::ContractBase + Sized { fn version(&self) -> BigInt; fn some_async(&self); fn callback(&self); } ///////////////////////////////////////////////////////////////////////////////////////////////// //////// AUTO-IMPLEMENTED METHODS /////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////// pub trait AutoImpl: dharithri_sc::contract_base::ContractBase {} impl VersionModule for C where C: AutoImpl, { fn version(&self) -> BigInt { BigInt::from(100) } fn some_async(&self) { panic!("wooo") } fn callback(&self) {} } impl AutoImpl for dharithri_sc::contract_base::UniversalContractObj where A: dharithri_sc::api::VMApi { } pub trait EndpointWrappers: VersionModule + dharithri_sc::contract_base::ContractBase { #[inline] fn call_version(&self) { dharithri_sc::io::call_value_init::not_payable::(); let result = self.version(); dharithri_sc::io::finish_multi::(&result) } fn call_some_async(&self) { self.some_async(); dharithri_sc::io::finish_multi::(&()) } fn call(&self, fn_name: &str) -> bool { if match fn_name { "callBack" => { self.callback(); return true; }, "version" => { self.call_version(); true }, _other => false, } { return true; } false } } impl EndpointWrappers for dharithri_sc::contract_base::UniversalContractObj where A: dharithri_sc::api::VMApi { } pub struct AbiProvider {} impl dharithri_sc::contract_base::ContractAbiProvider for AbiProvider { type Api = dharithri_sc::api::uncallable::UncallableApi; fn abi() -> dharithri_sc::abi::ContractAbi { dharithri_sc::abi::ContractAbi::default() } } pub trait ProxyTrait: dharithri_sc::contract_base::ProxyObjBase + Sized { fn version( &mut self, ) -> dharithri_sc::types::ContractCallNoPayment> { let ___address___ = self.extract_address(); dharithri_sc::types::ContractCallNoPayment::new(___address___, "version") } } } mod sample_adder { dharithri_sc::imports!(); ///////////////////////////////////////////////////////////////////////////////////////////////// //////// CONTRACT TRAIT ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////// pub trait Adder: super::module_1::VersionModule + dharithri_sc::contract_base::ContractBase + Sized { fn init(&self, initial_value: &BigInt) { self.set_sum(initial_value); } fn add(&self, value: BigInt) -> SCResult<()> { let mut sum = self.get_sum(); sum.add_assign(value); self.set_sum(&sum); Ok(()) } fn get_sum(&self) -> BigInt; fn set_sum(&self, sum: &BigInt); fn add_version(&self) -> SCResult<()> { self.add(self.version()) } fn callback(&self); fn callbacks(&self) -> self::CallbackProxyObj; } ///////////////////////////////////////////////////////////////////////////////////////////////// //////// AUTO-IMPLEMENTED METHODS /////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////// pub trait AutoImpl: dharithri_sc::contract_base::ContractBase {} // impl super::module_1::AutoImpl for C where C: AutoImpl {} impl Adder for C where C: AutoImpl + super::module_1::AutoImpl, { fn get_sum(&self) -> BigInt { let mut ___key___ = dharithri_sc::storage::StorageKey::::new(&b"sum"[..]); dharithri_sc::storage_get(dharithri_sc::types::ManagedRef::new(&___key___)) } fn set_sum(&self, sum: &BigInt) { let mut ___key___ = dharithri_sc::storage::StorageKey::::new(&b"sum"[..]); dharithri_sc::storage_set(dharithri_sc::types::ManagedRef::new(&___key___), &sum); } fn callback(&self) {} fn callbacks(&self) -> self::CallbackProxyObj { as dharithri_sc::contract_base::CallbackProxyObjBase>::new_cb_proxy_obj() } } impl AutoImpl for dharithri_sc::contract_base::UniversalContractObj where A: dharithri_sc::api::VMApi { } pub trait EndpointWrappers: Adder + dharithri_sc::contract_base::ContractBase + super::module_1::EndpointWrappers { #[inline] fn call_get_sum(&self) { ::init_static(); dharithri_sc::io::call_value_init::not_payable::(); let () = dharithri_sc::io::load_endpoint_args::(()); let result = self.get_sum(); dharithri_sc::io::finish_multi::(&result); } #[inline] fn call_init(&self) { ::init_static(); dharithri_sc::io::call_value_init::not_payable::(); let (initial_value, ()) = dharithri_sc::io::load_endpoint_args::< Self::Api, (dharithri_sc::types::BigInt, ()), >(("initial_value", ())); self.init(&initial_value); } #[inline] fn call_add(&self) { ::init_static(); dharithri_sc::io::call_value_init::not_payable::(); let (value, ()) = dharithri_sc::io::load_endpoint_args::< Self::Api, (dharithri_sc::types::BigInt, ()), >(("value", ())); let result = self.add(value); dharithri_sc::io::finish_multi::(&result); } fn call(&self, fn_name: &str) -> bool { if match fn_name { "callBack" => { Adder::callback(self); return true; }, "getSum" => { self.call_get_sum(); true }, "init" => { self.call_init(); true }, "add" => { self.call_add(); true }, _other => false, } { return true; } if super::module_1::EndpointWrappers::call(self, fn_name) { return true; } false } } impl EndpointWrappers for dharithri_sc::contract_base::UniversalContractObj where A: dharithri_sc::api::VMApi { } pub trait ProxyTrait: dharithri_sc::contract_base::ProxyObjBase + super::module_1::ProxyTrait { fn get_sum( &mut self, ) -> dharithri_sc::types::ContractCallNoPayment> { let ___address___ = self.extract_address(); dharithri_sc::types::ContractCallNoPayment::new(___address___, "get_sum") } fn add( &mut self, amount: &BigInt, ) -> dharithri_sc::types::ContractCallNoPayment { let ___address___ = self.extract_address(); let mut ___contract_call___ = dharithri_sc::types::ContractCallNoPayment::new(___address___, "add"); dharithri_sc::types::ContractCall::proxy_arg(&mut ___contract_call___, amount); ___contract_call___ } } ///////////////////////////////////////////////////////////////////////////////////////////////// //////// CONTRACT OBJECT //////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////// pub struct ContractObj where A: dharithri_sc::api::VMApi, { _phantom: core::marker::PhantomData, } ///////////////////////////////////////////////////////////////////////////////////////////////// //////// CONTRACT OBJECT as CONTRACT BASE /////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////// impl dharithri_sc::contract_base::ContractBase for ContractObj where A: dharithri_sc::api::VMApi, { type Api = A; } impl super::module_1::AutoImpl for ContractObj where A: dharithri_sc::api::VMApi {} impl AutoImpl for ContractObj where A: dharithri_sc::api::VMApi {} impl super::module_1::EndpointWrappers for ContractObj where A: dharithri_sc::api::VMApi {} impl EndpointWrappers for ContractObj where A: dharithri_sc::api::VMApi {} impl dharithri_sc::contract_base::CallableContract for ContractObj where A: dharithri_sc::api::VMApi, { fn call(&self, fn_name: &str) -> bool { EndpointWrappers::call( &dharithri_sc::contract_base::UniversalContractObj::::new(), fn_name, ) } } pub struct ContractBuilder; impl dharithri_sc::contract_base::CallableContractBuilder for ContractBuilder { fn new_contract_obj( &self, ) -> dharithri_sc::types::heap::Box { dharithri_sc::types::heap::Box::new(ContractObj:: { _phantom: core::marker::PhantomData, }) } } pub struct AbiProvider {} impl dharithri_sc::contract_base::ContractAbiProvider for AbiProvider { type Api = dharithri_sc::api::uncallable::UncallableApi; fn abi() -> dharithri_sc::abi::ContractAbi { dharithri_sc::abi::ContractAbi::default() } } pub fn contract_obj() -> ContractObj where A: dharithri_sc::api::VMApi, { ContractObj { _phantom: core::marker::PhantomData, } } pub struct Proxy where A: dharithri_sc::api::VMApi + 'static, { pub address: dharithri_sc::types::ManagedOption>, } impl dharithri_sc::contract_base::ProxyObjBase for Proxy where A: dharithri_sc::api::VMApi + 'static, { type Api = A; fn new_proxy_obj() -> Self { Proxy { address: dharithri_sc::types::ManagedOption::none(), } } fn contract(mut self, address: dharithri_sc::types::ManagedAddress) -> Self { self.address = dharithri_sc::types::ManagedOption::some(address); self } fn extract_opt_address( &mut self, ) -> dharithri_sc::types::ManagedOption< Self::Api, dharithri_sc::types::ManagedAddress, > { core::mem::replace( &mut self.address, dharithri_sc::types::ManagedOption::none(), ) } fn extract_address(&mut self) -> dharithri_sc::types::ManagedAddress { let address = core::mem::replace( &mut self.address, dharithri_sc::types::ManagedOption::none(), ); address.unwrap_or_sc_panic(dharithri_sc::err_msg::RECIPIENT_ADDRESS_NOT_SET) } } impl super::module_1::ProxyTrait for Proxy where A: dharithri_sc::api::VMApi {} impl ProxyTrait for Proxy where A: dharithri_sc::api::VMApi {} pub struct CallbackProxyObj where A: dharithri_sc::api::VMApi + 'static, { _phantom: core::marker::PhantomData, } impl dharithri_sc::contract_base::CallbackProxyObjBase for CallbackProxyObj where A: dharithri_sc::api::VMApi + 'static, { type Api = A; fn new_cb_proxy_obj() -> Self { CallbackProxyObj { _phantom: core::marker::PhantomData, } } } pub trait CallbackProxy: dharithri_sc::contract_base::CallbackProxyObjBase + Sized { fn my_callback(self, caller: &Address) -> dharithri_sc::types::CallbackClosure { let mut ___callback_call___ = dharithri_sc::types::new_callback_call::("my_callback"); ___callback_call___.push_endpoint_arg(caller); ___callback_call___ } } impl self::CallbackProxy for CallbackProxyObj where A: dharithri_sc::api::VMApi + 'static {} } #[test] fn contract_without_macros_basic() { use sample_adder::{Adder, EndpointWrappers, ProxyTrait}; let adder = sample_adder::contract_obj::(); adder.init(&BigInt::from(5)); assert_eq!(BigInt::from(5), adder.get_sum()); let _ = adder.add(BigInt::from(7)); assert_eq!(BigInt::from(12), adder.get_sum()); let _ = adder.add(BigInt::from(-1)); assert_eq!(BigInt::from(11), adder.get_sum()); assert_eq!(BigInt::from(100), adder.version()); let _ = adder.add_version(); assert_eq!(BigInt::from(111), adder.get_sum()); assert!(!adder.call("invalid_endpoint")); assert!(adder.call("version")); let mut own_proxy = sample_adder::Proxy::::new_proxy_obj().contract(ManagedAddress::zero()); let _ = own_proxy.get_sum(); let _ = dharithri_sc_meta::abi_json::contract_abi::(); } fn world() -> dharithri_sc_scenario::ScenarioWorld { let mut blockchain = dharithri_sc_scenario::ScenarioWorld::new(); blockchain.register_contract( "file:../../contracts/examples/adder/output/adder.wasm", sample_adder::ContractBuilder, ); blockchain } #[test] fn contract_without_macros_scenario() { world().run("../../contracts/examples/adder/scenarios/adder.scen.json"); }