<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ganesh oli</title>
    <description>The latest articles on DEV Community by Ganesh oli (@ganesholi11).</description>
    <link>https://dev.to/ganesholi11</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F281516%2Fc91bbe51-79a5-494f-9b3a-a868f4e5d604.jpeg</url>
      <title>DEV Community: Ganesh oli</title>
      <link>https://dev.to/ganesholi11</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ganesholi11"/>
    <language>en</language>
    <item>
      <title>Donation ink! smart contract</title>
      <dc:creator>Ganesh oli</dc:creator>
      <pubDate>Thu, 30 Mar 2023 06:38:40 +0000</pubDate>
      <link>https://dev.to/ganesholi11/donation-ink-smart-contract-433f</link>
      <guid>https://dev.to/ganesholi11/donation-ink-smart-contract-433f</guid>
      <description>&lt;p&gt;Donation smart contract is useful when you are learning substrate based ink! smart contract. This contract is based on &lt;code&gt;ink! v4.0.0&lt;/code&gt; and use &lt;a href="https://paritytech.github.io/ink/ink_prelude/vec/struct.Vec.html"&gt;Vec&lt;/a&gt; and &lt;a href="https://paritytech.github.io/ink/ink_storage/struct.Mapping.html"&gt;Mapping&lt;/a&gt; data structure. Vec(i.e contiguous growable array type) is used to store and return Donation list and Mapping (i.e key-value pairs directly into contract storage) which is used to store Donation &lt;code&gt;(i.e value)&lt;/code&gt; with respect to donation_id &lt;code&gt;(i.e key)&lt;/code&gt;. There are also other data structure like AccountId &lt;code&gt;(i.e 32-byte type)&lt;/code&gt;, u128 (to store balance) and i32 (to store donation id).&lt;/p&gt;




&lt;p&gt;Through this contract you can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Initialize beneficiary account while contract deployment.&lt;/li&gt;
&lt;li&gt;Can change beneficiary at any time.&lt;/li&gt;
&lt;li&gt;Donate the beneficiary address.&lt;/li&gt;
&lt;li&gt;Can view donation list.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before start writing &lt;code&gt;ink! smart contract&lt;/code&gt;, you need to setup &lt;code&gt;rust&lt;/code&gt;, &lt;code&gt;cargo&lt;/code&gt; and &lt;code&gt;cargo contract&lt;/code&gt; (i.e Setup and deployment tool for developing Wasm based smart contracts via ink!). You can setup rust and cargo from &lt;a href="https://doc.rust-lang.org/cargo/getting-started/installation.html"&gt;here&lt;/a&gt; and can install latest cargo contract from &lt;a href="https://github.com/paritytech/ink#usage"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After successfully setup all requirement, you can create ink! smart contract using following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo contract new &amp;lt;contract_name&amp;gt;
contract_name must not start with alphabetic character and contains `alphanumeric characters and underscores`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Successfully create contract can be build with following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo contract build
if you wan't to build in release, then add --release flag
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace, your &lt;code&gt;#[ink(storage)]&lt;/code&gt; Macros with the below code snippet. &lt;br&gt;
&lt;code&gt;owner&lt;/code&gt;: Contract Address Owner&lt;br&gt;
&lt;code&gt;beneficiary&lt;/code&gt;: Beneficiary account where you can donate balance.&lt;br&gt;
&lt;code&gt;donations&lt;/code&gt;: mapping to storage donation data.&lt;br&gt;
&lt;code&gt;donation_id&lt;/code&gt;: id for donation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    #[ink(storage)]
    pub struct DonationContract {
        owner: AccountId,
        beneficiary: AccountId,
        donations: Mapping&amp;lt;DonationId, Donation&amp;gt;,
        donation_id: i32,
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Donation&lt;/code&gt; is Custom Data Structures, we have to define separately above the &lt;code&gt;#[ink(storage)]&lt;/code&gt; macro. Derive traits Decode and Encode provide a way to serialize and deserialize rust data type into complete binary format, you can learn more from &lt;a href="https://docs.rs/parity-scale-codec/latest/parity_scale_codec/"&gt;here&lt;/a&gt;. This data structure defines two fields:&lt;br&gt;
&lt;code&gt;account&lt;/code&gt;: AccountId, user who donate.&lt;br&gt;
&lt;code&gt;amount&lt;/code&gt;: u128, user how much he donate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    #[derive(scale::Decode, scale::Encode)]
    #[cfg_attr(
        feature = "std",
        derive(scale_info::TypeInfo, ink::storage::traits::StorageLayout)
    )]
    pub struct Donation {
        account: AccountId,
        amount: u128,
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since, &lt;code&gt;ink!v4.0.0&lt;/code&gt; remove AccountId &lt;a href="https://github.com/paritytech/ink/pull/1255"&gt;default implementation&lt;/a&gt;, we can't use &lt;code&gt;Default&lt;/code&gt; macro inside derive, So we have to define separately just below Donation struct.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Donation struct default implementations
    impl Default for Donation {
        fn default() -&amp;gt; Self {
            Self {
                account: zero_address(),
                amount: 0,
            }
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We defined &lt;code&gt;zero_address()&lt;/code&gt; function, separately, which you can define like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   /// Helper for referencing the zero address (`0x00`). Note that in practice this address should
    /// not be treated in any special way (such as a default placeholder) since it has a known
    /// private key.
    fn zero_address() -&amp;gt; AccountId {
        [0u8; 32].into()
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every ink! contract has one or more constructor. Our constructor is defined below. You can include this code in your &lt;code&gt;#[ink(constructor)]&lt;/code&gt; macro. If you want to learn more &lt;a href="https://use.ink/macros-attributes/constructor"&gt;click here&lt;/a&gt;.&lt;br&gt;
&lt;code&gt;Self::env().caller()&lt;/code&gt; gives owner of the contract. The owner will be whoever deploy the contract.&lt;br&gt;
Return all the fields from &lt;code&gt;#[ink(storage)]&lt;/code&gt; macro like:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;owner&lt;/li&gt;
&lt;li&gt;beneficiary which is provided while contract instantiation.&lt;/li&gt;
&lt;li&gt;donations mapping we can define like &lt;code&gt;Mapping::default()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;donation_id can be initialize with 1 or &lt;code&gt;Default::default()&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        #[ink(constructor)]
        pub fn new(beneficiary: AccountId) -&amp;gt; Self {
            let owner = Self::env().caller();
            Self {
                owner,
                beneficiary,
                donations: Mapping::default(),
                donation_id: 1,
            }
        }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Normal user can view beneficiary address anytime. Only owner of the contract can change the beneficiary address. These are public function which can be represent by &lt;code&gt;#[ink(message)]&lt;/code&gt; macro, then only you can view those api while interaction with frontend. Contract must contains at least one or many &lt;code&gt;#[ink(message)]&lt;/code&gt;, you can get more info from &lt;a href="https://use.ink/macros-attributes/message"&gt;here&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        #[ink(message)]
        pub fn get_beneficiary(&amp;amp;self) -&amp;gt; Option&amp;lt;AccountId&amp;gt; {
            Some(self.beneficiary)
        }

        #[ink(message)]
        pub fn change_beneficiary(&amp;amp;mut self, new_beneficiary: AccountId) {
            let caller = self.env().caller();
            assert!(
                self.owner == caller,
                "Only owner can change the beneficiary account"
            );
            self.beneficiary = new_beneficiary;
        }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;assert!()&lt;/code&gt; macro check whether caller of the function is owner or not. If not owner then, he can't change the new beneficiary address. In order to update value we call &lt;code&gt;self&lt;/code&gt; and mut so that beneficiary from storage can be updated easily, as you might be aware about rust.&lt;/p&gt;

&lt;p&gt;Add another function which is also public below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        #[ink(message, payable)]
        pub fn donation(&amp;amp;mut self) {
            // Account who is donating
            let caller = self.env().caller();
            let donation_id = self.next_donation_id();

            // Donation amount
            let donation_amount = self.env().transferred_value();
            let mut donated_so_far = self.donations.get(donation_id).unwrap_or_default();

            assert!(donation_amount &amp;gt; 0, "Cannot transfer 0 donation");

            // Total donation amount so far by caller
            donated_so_far.amount += donation_amount;
            donated_so_far.account = caller;

            // Insert total donation amount with respect to caller
            self.donations.insert(donation_id, &amp;amp;donated_so_far);

            // Send donation amount to the beneficiary account
            self.env()
                .transfer(self.beneficiary, donation_amount)
                .unwrap_or_default();
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is function is &lt;code&gt;payable&lt;/code&gt;, which means it allow receiving value. You can deep dive with this macro from &lt;a href="https://use.ink/macros-attributes/payable"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://paritytech.github.io/ink/ink_env/fn.caller.html"&gt;caller&lt;/a&gt; who is calling this function while donating amount.&lt;/li&gt;
&lt;li&gt;donation_id is local variable which store id from &lt;code&gt;next_donation_id()&lt;/code&gt; function which is private function and  defined below.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        pub fn next_donation_id(&amp;amp;mut self) -&amp;gt; DonationId {
            let id = self.donation_id;
            self.donation_id += 1;
            id
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;self.env().transferred_value()&lt;/code&gt; returns the value for contract execution more info &lt;a href="https://paritytech.github.io/ink/ink_env/fn.transferred_value.html"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;donated_so_far&lt;/code&gt; variable which storage donation so far by account.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If donation more than 0, then donation store in storage.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this way wasm based ink! smart contract can be written. This is way basic contract for beginner level. You can find all the code in my git hub account. I haven't included here but you can find unit test of this contract as well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/ganesh1233456/PortfolioDapps/tree/main/donation_ink"&gt;GitHub link&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>ink</category>
      <category>substrate</category>
      <category>polkadot</category>
    </item>
  </channel>
</rss>
