DEV Community 👩‍💻👨‍💻

Harish
Harish

Posted on

Beginner's guide to deploy smart contract with an example

This guide tries to explain how to write and deploy smart contracts to Arweave using Javascript.

Table Of Contents

Fundamentals

What is a smart contract?

Smart contracts are digital substitutes of real world contracts. Once its coded and pushed to the chain, its immuatable, hence cannot be changed!

How to write one?

There are plenty of networks out there. I deployed my contract to Arweave. Unlike many other networks, the smart contracts on Arweave can be written in JavaScript. The process to write and deploy one is fairly straight forward.

PreRequisites

  1. Install Arweave CLI
  2. Install Smartweave CLI
  3. Get Arweave wallet or Finnie wallet

Complete the above steps before moving ahead.

Introduction

There are two steps to deploying Smart Contracts on Arweave once the prerequisites are completed.

  1. Write the smart contracts Go through the Contract writing guide by Arweave Team. It contains an example of Hello World that should set your fundamentals straight.
  2. Deploy them via CLI Once the contract files are ready. To deploy it via the CLI, you would need to export the private key of your Arweave/Finnie Wallet which you must have created earlier. Here is the CLI Usage guide.

Setting up initial state

Please go through the introduction section and explore the attached resources before moving ahead.

Example Contract description : Set up a Decentralised marketplace where people can donate to crowdsource fundraiser listings.

Time to build our Crowdsource App 🥳🥳🥳

In order to do that, we need two contracts to make it work.

A Collection contract that would contain all the information regarding the listing in its state

{
  "owner": "6Jfg5shIvbAcgoD04mOppSxL6LAqx6IfjL0JexxpmFQ",
  "name": "Tabs over Spaces",
  "description":"This is my first petition. Please vote this petition to make spaces illegal",
  "funds":{
    "raised":0,
    "goal":100,
    "records":{

    }
  }  
}
Enter fullscreen mode Exit fullscreen mode

A Parent Crowdsource contract that would contain references to the above created collection contracts in its state

{
    "owner": "6Jfg5shIvbAcgoD04mOppSxL6LAqx6IfjL0JexxpmFQ",
    "name": "CrowdSource | PeopleHelpPeople",
    "collections":{}
  }
Enter fullscreen mode Exit fullscreen mode

Updating state

There are two operations that could happen:

  1. Users enlist a new crowdsource collection
  2. Users donate funds to the collection

NOTE: These actions are basic and preliminary. Since I didnt have much time during the hackathon, this was all I could build. But obviously it could be expanded to make the system more usable and robust.

Enlisting a Collection Contract

Lets take a look at the enlist function on the Parent Contract

export function handle(state, action) {

    if (action.input.function === 'enlist') {
        if (typeof action.input.listingId === 'undefined') {
            throw new ContractError(`PetitionId cant be null`)
        }
        if (state.collections.hasOwnProperty(action.input.listingId)) {
            throw new ContractError(`PetitionId already exists`)
        }
        state.collections[action.input.listingId] = 1
        return { state }
    }

    throw new ContractError('Invalid input')
}
Enter fullscreen mode Exit fullscreen mode

The enlist function performs the essential checks firstly, then adds the reference to the collections object of the state. This serves as a means to keep track of all the crowdsource contracts on the chain.

After enlisting a collection contract, the parent contract state should like this:

{
  "owner": "6Jfg5shIvbAcgoD04mOppSxL6LAqx6IfjL0JexxpmFQ",
  "name": "CrowdSource | PeopleHelpPeople",
  "collections": {
    "Ji6MP-Wt_LYk6yaTsxEnhlpbRpAu08248PUTxnp2qOU": 1
  }
}
Enter fullscreen mode Exit fullscreen mode

Donating to a Collection Contract

Once the collection is enlisted, users could transfer funds to the collection. Feel free to use any wallet services to transfer tokens. But make sure you got the correct address on the owner field.

Since I used Finnie wallet, I put my Finnie address inside the owner field.

Here is the Collection Contract

export function handle(state, action) {

    if (action.input.function === 'donate') {
        if (typeof action.input.donorId === 'undefined') {
            throw new ContractError(`DonorId cant be null`)
        }
        if (typeof action.input.amount === 'undefined') {
            throw new ContractError(`amount cant be null`)
        }

        if (typeof action.input.amount !== 'number') {
            throw new ContractError(`amount must be a number`)
        }

        state.funds.records[action.input.donorId] = action.input.amount;
        state.funds.raised += action.input.amount;
        return { state }
    }
    throw new ContractError('Invalid input')
}
Enter fullscreen mode Exit fullscreen mode

After performing essential checks, the contracts state is updated with the donor payment ID(address) and the amount of funds they have contributed.

The default currency is assumed to be KOII. Again a place for improvement. To support various currencies, currency field could be added to the record.

This is how the collection contract would look like once users have donated some funds.

{
  "owner": "6Jfg5shIvbAcgoD04mOppSxL6LAqx6IfjL0JexxpmFQ",
  "name": "Tabs over Spaces",
  "description": "This is my first petition. Please vote this petition to make spaces illegal",
  "funds": {
    "raised": 1.2109999999999999,
    "goal": 100,
    "records": {
      "Ji6MP-Wt_LYk6yaTsxEnhlpbRpAu0824": 1.21,
      "6Jfg5shIvbAcgoD04mOppSxL6LAqx6IfjL0JexxpmFQ": 0.001
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Deployment

To deploy the contracts, use the Smartweave create command:

smartweave create [SRC LOCATION] [INITIAL STATE FILE] --key-file [YOUR KEYFILE]
Enter fullscreen mode Exit fullscreen mode

It takes around 10-15 minutes for the contract to be deployed. Note that you would have to spend some AR in order to deploy the contract.
Once the create command completes, the CLI will output a unique transaction ID for the transaction. This ID is essential to proceed forward.

To check the status of the transaction

arweave status [CONTRACT TXID]
Enter fullscreen mode Exit fullscreen mode

To read the state of the contract

smartweave read [CONTRACT TXID]
Enter fullscreen mode Exit fullscreen mode

For a web GUI experience, check out Viewblock.io. Its a handy website to check all the information about your contracts state, tags and transactions.

Interacting with the contract

It is time to send payloads to interact with the contract i.e. update the state. We would be using the enlist and donate functions that we set up earlier on the contracts.

To interact with the transaction:

smartweave write [CONTRACT TXID] --key-file [YOUR KEYFILE] \
  --input "[CONTRACT INPUT STRING HERE]"
Enter fullscreen mode Exit fullscreen mode

For enlisting a contract

smartweave write [Parent Crowdsource Contract TXID] --key-file [YOUR KEYFILE] --input "{"function":"enlist","listingId":"<Collection contract TXID>"}"
Enter fullscreen mode Exit fullscreen mode

For donating tokens to a collection

smartweave write [Collection Contract] --key-file [YOUR KEYFILE] --input '{"function":"donate","donorId":"<Donor wallet address>","amount":<number of tokens>}'
Enter fullscreen mode Exit fullscreen mode

Summary

Congratulations 🥳🥳🥳

Hope you liked reading through the article. To summarise the learnings, you should have understood:

  1. What are smart contracts
  2. How to write and deploy one on Arweave
  3. How to Interact with them

Read about my project I built for the hackathon if you're interested below 🙂

Bonus Tip

All of these are done via CLI, but to scale it to a real world application. You would need to the Arweave SDKs and APIs.

Happy Exploring 😉

About my project

Its called People Help People, the origin of the name comes from the idea of a society where people are not dependent on middle men or central systems to help each other. One can find more information about the Aim and Goals on the Pitch Deck.

This is a blockchain based project. It has two parts to it. The smart contracts and the web client interface.

The project presently consists of two prototypes

  1. Petitions
  2. Crowdsource

Both of these prototypes inherits the idea of PHP, i.e. to defeat the intervention of a central system. Hence I covered only one of them in the article. Once I learnt the basic fundamentals of how smart contracts work and how to write one, giving life to these two ideas was plain sailing.

Devfolio Submission link: https://devfolio.co/submissions/people-help-people-a3c8

GitHub Repo link: https://github.com/HarishTeens/PeopleHelpPeople

I had to struggle a lot to walk through the right steps in order to learn this. So I tried my best to make the learning smooth for a beginner. Please share your feedbacks in the comments.

Join the Movement

If you're interested in joining the movement, dm me on Twitter so I could add you to the organisation People Help People on GitHub. It's a very recent org, so it appears to be blank at the moment. But definitely planning to work on it in the future ✨

Follow me on Twitter @HarishTeens

Top comments (0)

Classic DEV Post:

caching

Web Caching Explained by Buying Milk at the Supermarket