How to Deploy Smart Contract to the Casper Network

How to Deploy Smart Contract to the Casper Network

GET ACCESS TO CASPER

If you are the type of person or developer that aims to run their own decentralized applications (dApps) or do any kind of procedure on top of a specific blockchain network, you need to take advantage of the smart contract functionality that the network has to offer.

How to Deploy Smart Contract to the Casper Network

Casper is a blockchain platform that allows any developer to build on top of it and is designed for real-world application development without putting a sacrifice on usability, cost, and decentralization.

Today, we are going to go over everything you need to know when it comes to deploying smart contracts on top of the Casper network.

Key Points:

  • Casper Network is a Proof-of-Stake (PoS) based network that is specifically designed to help enterprises begin their journey towards the process of building blockchain-enabled products as well as services in a way that is quick and efficient. 

  • The specific capabilities which make the network stand out include security, minimal risk, flexibility, a low cost associated with its usage as well as future-proofing due to its modular architecture. 

  • CSPR is the native utility token used across the Casper ecosystem, and the cryptocurrency has multiple roles within the network, such as being used as a reward for PoS validators and for regular users to interact with the services and features on the network.

  • You can easily deploy smart contracts on top of the Casper network, but if you want to keep track of everything that occurs on top of the network, you need to run a node or connect to a node, something that can be easily accomplished through the utilization of NOWNodes. 

Why Use Smart Contracts?

The Casper network does indeed support smart contracts, and there are numerous reasons why you might be interested in utilizing them.

Why Use Smart Contracts for Casper?

On a blockchain network, the main role a smart contract plays is to simplify business and trades between anonymous and identified parties, which can be achieved without the requirement for a middleman to get involved.

A smart contract can essentially scale down on formality and costs associated with traditional methods, and they are fully programmable. Smart contracts get executed only when predetermined conditions are met.

Advantages of Casper Network

There are numerous advantages that the Casper network has an offer for developers that decide to build their smart contracts or decentralized applications (dApps) on top of it.

For example, the Casper Network features a development ecosystem, one specifically designed to support WebAssembly. This means that developers aren’t required to learn a proprietary language to begin work on top of it, such as Ethereum and its Solidity language.

This simplifies the overall development process. Furthermore, the basic functions include an account permission model, which is given the ability to recover lost keys, and a permission model that can securely share the state between accounts and contracts. Furthermore, the fees which occur on top of the network are predictable, and as such, the Casper Network aims to eliminate any volatility and improve the overall development and business experience due to its transparent, consistent, and fully predictable gas prices. 

Advantages of Casper Network

These are just some factors and advantages that make the overall Casper network a worthwhile network to build on top of.

Deploying Smart Contracts to the Casper Network

GET ACCESS TO CASPER

Casper provides you with a contract API within the casper_contract crate. We will be going over how you can create simple, smart contracts, which allow callers to donate funds, for example, to a purse owned by the contract, and one that can track the total funds received alongside the number of individual contributors.

  • Step 1: Create a Directory Structure

First, you will need to create a proper directory. This folder will have two sub-directories, called contract and test.

cargo new [CONTRACT_NAME]
  • Step 2: Configuring The Right Files

You will now need to remove the auto-generated main functions and configure the Main.rs File.

  • #![no_main] tells the program not to use the standard main functions as the entry point.
  • #![no_std] tells the program not to import the standard libraries.

You can add these dependencies to the Cargo.toml file:

[dependencies]
// A library for developing Casper network smart contracts.
casper-contract = “1.4.4”
// Types shared by many Casper crates for use on a Casper Network.
casper-types = “1.4.6”

Then, you can add the imports in the main.rs file.

extern crate alloc;


// Importing Rust types.

use alloc::string::{String, ToString};

use alloc::vec;

// Importing aspects of the Casper platform.

use casper_contract::contract_api::storage::dictionary_get;

use casper_contract::contract_api::{runtime, storage, system};

use casper_contract::unwrap_or_revert::UnwrapOrRevert;

// Importing specific Casper types.

use casper_types::account::AccountHash;

use casper_types::contracts::NamedKeys;

use casper_types::{runtime_args, CLType, CLValue, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, ApiError, RuntimeArgs};
  • Step 3: Defining the Global Constants

Once you’ve imported all of the required dependencies, you need to define the constants that you will use within the contracts, such as the entry points and values.

// Creating constants for the various contract entry points.

const ENTRY_POINT_INIT: &str = “init”;

const ENTRY_POINT_DONATE: &str = “donate”;

const ENTRY_POINT_GET_DONATION_COUNT: &str = “get_donation_count”;

const ENTRY_POINT_GET_FUNDS_RAISED: &str = “get_funds_raised”;

// Creating constants for values within the contract.

const DONATING_ACCOUNT_KEY: &str = “donating_account_key”;

const LEDGER: &str = “ledger”;

const FUNDRAISING_PURSE: &str = “fundraising_purse”;
  • Step 4: Defining the Contract Entry Points

These entry points will be the way through which you can access the contract code installed on the global state.

When defining them, begin with a #[no_mangle], as this will ensure that the system doesn’t really change any critical syntax within the method names.

#[no_mangle]

pub extern “C” fn init() {    

let fundraising_purse = system::create_purse();    

runtime::put_key(FUNDRAISING_PURSE, fundraising_purse.into());    

// Create a dictionary to track the mapping of account hashes to number of donations made.    

storage::new_dictionary(LEDGER).unwrap_or_revert();

}


// This is the donation entry point. When called, it records the caller’s account
// hash and returns the donation purse, with add access, to the immediate caller.

#[no_mangle]
pub extern “C” fn donate() {    
let donating_account_key: Key = runtime::get_named_arg(DONATING_ACCOUNT_KEY);    if let Key::Account(donating_account_hash) = donating_account_key {        

update_ledger_record(donating_account_hash.to_string())   

 } else {        

runtime::revert(FundRaisingError::InvalidKeyVariant)    

}    let donation_purse = *runtime::get_key(FUNDRAISING_PURSE)        

.unwrap_or_revert_with(FundRaisingError::MissingFundRaisingPurseURef)        

.as_uref()       

.unwrap_or_revert();    

// The return value is the donation_purse URef with `add` access only. As a result    

// the entity receiving this purse URef may only add to the purse, and cannot remove    

// funds.    

let value = CLValue::from_t(donation_purse.into_add()).unwrap_or_revert();    runtime::ret(value)

}

// This entry point returns the amount of donations from the caller.

#[no_mangle]

pub extern “C” fn get_donation_count() {   

let donating_account_key: Key = runtime::get_named_arg(DONATING_ACCOUNT_KEY);    

if let Key::Account(donating_account_hash) = donating_account_key {       

let ledger_seed_uref = *runtime::get_key(LEDGER)            .unwrap_or_revert_with(FundRaisingError::MissingLedgerSeedURef)            .as_uref()            .unwrap_or_revert();        

let donation_count = if let Some(donation_count) =            

storage::dictionary_get::<u64>(ledger_seed_uref, &donating_account_hash.to_string())                

.unwrap_or_revert()    

    {       

     donation_count    

    } else {       

     0u64    

    };    

    runtime::ret(CLValue::from_t(donation_count).unwrap_or_revert())  

  } else {     

   runtime::revert(FundRaisingError::InvalidKeyVariant)    

}

}

// This entry point returns the total funds raised.

#[no_mangle]

pub extern “C” fn get_funds_raised() {  

  let donation_purse = *runtime::get_key(FUNDRAISING_PURSE)        

.unwrap_or_revert_with(FundRaisingError::MissingFundRaisingPurseURef)      

  .as_uref()   

  .unwrap_or_revert();  

  let funds_raised = system::get_purse_balance(donation_purse)      

  .unwrap_or_revert();   

 runtime::ret(CLValue::from_t(funds_raised).unwrap_or_revert())

}
  • Step 5: Defining the Call Function

This call function will start the code execution, and is responsible for installing the contract.

Here, you will need to define the runtime arguments, insert the function entry points into the call function, and add entry points.

#[no_mangle]

pub extern “C” fn call() {  

  // This establishes the `init` entry point for initializing the contract’s infrastructure.   

 let init_entry_point = EntryPoint::new(     

   ENTRY_POINT_INIT,     

   vec![],     

   CLType::Unit,      

  EntryPointAccess::Public,      

  EntryPointType::Contract,  

  );
   
 // This establishes the `donate` entry point for callers looking to donate.  

  let donate_entry_point = EntryPoint::new(     

   ENTRY_POINT_DONATE,     

   vec![Parameter::new(DONATING_ACCOUNT_KEY, CLType::Key)],      

  CLType::URef,     

   EntryPointAccess::Public,    

   EntryPointType::Contract,    );
    
// This establishes an entry point called `donation_count` that returns the amount of   

 // donations from a specific account.   

 let get_donation_count_entry_point = EntryPoint::new(       

 ENTRY_POINT_GET_DONATION_COUNT,      

  vec![Parameter::new(DONATING_ACCOUNT_KEY, CLType::Key)],       

 CLType::U64,       

 EntryPointAccess::Public,        

EntryPointType::Contract,  

  );
    

// This establishes an entry point called `funds_raised` that returns the total amount   

 // donated by all participants.   

 let funds_raised_entry_point = EntryPoint::new(       

 ENTRY_POINT_GET_FUNDS_RAISED,       

 vec![],        

CLType::U512,     

 EntryPointAccess::Public,       

 EntryPointType::Contract,   

 );

}

This step will add the individual entry points through the add_entry_point method to one object, and return it to the new_contract method.

    let mut entry_points = EntryPoints::new();    

entry_points.add_entry_point(init_entry_point);    

entry_points.add_entry_point(donate_entry_point);    

entry_points.add_entry_point(get_donation_count_entry_point);   

entry_points.add_entry_point(funds_raised_entry_point);

All that’s left for you to do is to create the new contract by using the new_contract method to create it, with its named keys and entry points.

let (contract_hash, _contract_version) = storage::new_contract(       

 entry_points,        

None,        

Some(“fundraiser_package_hash”.to_string()),        

Some(“fundraiser_access_uref”.to_string()),   

 );
    

runtime::put_key(“fundraiser_contract_hash”, contract_hash.into());    

// Call the init entry point to setup and create the fundraising purse    
// and the ledger to track donations made.    

runtime::call_contract::<()>(contract_hash, ENTRY_POINT_INIT, runtime_args! {})

Conclusion

We have gone over just about everything you need to know when it comes to deploying smart contracts on top of the Casper network.

Note that if you are interested in learning as much about the blockchain as possible and keeping track of everything that occurs with your smart contracts, you can connect to a node through the utilization of the blockchain-as-a-service provider NOWNodes.

With the data you can gain from this process, you can ensure that your smart contracts are properly operating on top of the network.

GET ACCESS TO CASPER