Git Product home page Git Product logo

Comments (4)

Robbepop avatar Robbepop commented on June 30, 2024

In a discussion about a future look'and'feel for the upcoming pDSL there were some remarks that I wanted to memorize in this issue for the future implementation.

The following are some notes for the unfinished ERC-20 token implementation using the pdsl_core library as of 15-01-2019 that can be found here.

Contract Definition

/// The storage data that is hold by the ERC-20 token.
#[derive(Debug, Encode, Decode)]
pub struct Erc20Token {
	/// All peeps done by all users.
	balances: storage::HashMap<Address, Balance>,
	/// Balances that are spendable by non-owners.
	allowances: storage::HashMap<AllowancePair, Balance>,
	/// The total supply.
	total_supply: storage::Value<Balance>,
	/// The allocator for newly allocated entities.
	alloc: storage::alloc::CellChunkAlloc,
}

should become similar or equal to

/// The storage data that is hold by the ERC-20 token.
#[derive(Contract)]
pub struct Erc20Token {
	/// All peeps done by all users.
	balances: storage::HashMap<Address, Balance>,
	/// Balances that are spendable by non-owners.
	allowances: storage::HashMap<AllowancePair, Balance>,
	/// The total supply.
	total_supply: Balance,
}

First-Class Environmentals

ContractEnv::caller() should be just caller.

Mutation Wrappers

self.balances.mutate_with(&from, |from| *from -= value)

Is jargony and difficult to understand, especially for people that are not using Rust on a regular basis.
It should become something similar or equal to

self.balances[from] -= value

Streamlined Derives

Derives for auxiliary structs should be straight forward and streamlined to contract usage.

#[derive(Debug, Hash, PartialEq, Eq, Encode, Decode)]

should become similar or equal to

#[derive(Debug, HashStorage)]

Also the entire dispatch of functions still has to be implemented in the upcoming pDSL.

from ink.

Robbepop avatar Robbepop commented on June 30, 2024

The current state and initial goal is to be able to write a simple smart contract like this:

use pdsl_lang::contract;
use pdsl_core::storage;

contract! {
    /// A simple contract that has a value that can be
    /// incremented, returned and compared.
    struct Incrementer {
        /// The internal value.
        value: storage::Value<u32>,
    }

    impl Incrementer {
        /// Automatically called when the contract is deployed.
        pub(external) fn on_deploy(&mut self, init_value: u32) {
            self.value.set(init_value);
        }

        /// Increments the internal counter.
        pub(external) fn inc(&mut self, by: u32) {
            self.value += by
        }

        /// Returns the internal counter.
        pub(external) fn get(&self) -> u32 {
            *self.value
        }

        /// Returns `true` if `x` is greater than the internal value.
        pub(external) fn compare(&self, x: u32) -> bool {
            x > *self.value
        }
    }
}

The generated code for the above smart contract should look approximately like the following:

use pdsl_core::storage;

pdsl_model::state! {
    /// A simple contract that has a value that can be
    /// incremented, returned and compared.
    struct Incrementer {
        /// The internal value.
        value: storage::Value<u32>
    }
}

pdsl_model::messages! {
    /// Increments the internal counter.
    0 => Inc(by: u32);
    /// Returns the internal counter.
    1 => Get() -> u32;
    /// Returns `true` if `x` is greater than the internal value.
    2 => Compare(with: u32) -> bool;
}

impl Adder {
    /// Automatically called when the contract is deployed.
    pub fn on_deploy(&mut self, env: &mut pdsl_model::EnvHandler, init_val: u32) {
        self.value.set(init_val)
    }

    /// Increments the internal counter.
    pub fn inc(&mut self, env: &mut pdsl_model::EnvHandler, by: u32) {
        self.value += by
    }

    /// Returns the internal counter.
    pub fn get(&self, env: &pdsl_model::EnvHandler) -> u32 {
        *self.value
    }

    /// Returns `true` if `x` is greater than the internal value.
    pub fn compare(&self, env: &pdsl_model::EnvHandler, x: u32) -> bool {
        x > *self.value
    }
}

fn instantiate() -> impl pdsl_model::Contract {
    pdsl_model::ContractDecl::using::<Adder>()
        .on_deploy(|env, init_val: u32| {
            let (handler, state) = env.split_mut();
            state.on_deploy(handler, init_val)
        })
        .on_msg_mut::<Inc>(|env, by: u32| {
        	let (handler, state) = env.split_mut();
        	state.inc(handler, by)
        })
        .on_msg::<Get>(|env, _| {
        	let (handler, state) = env.split();
        	state.get(handler)
        })
        .on_msg::<Compare>(|env, x: u32| {
        	let (handler, state) = env.split();
        	state.compare(handler, x)
        })
        .instantiate()
}

#[no_mangle]
fn deploy() {
    instantiate().deploy()
}

#[no_mangle]
fn call() {
    instantiate().dispatch()
}

from ink.

Robbepop avatar Robbepop commented on June 30, 2024

As of 589210f this is the actual generated code from the simple.rs example above.

#![feature(prelude_import)]
#![no_std]
#[prelude_import]
use ::std::prelude::v1::*;
#[macro_use]
extern crate std as std;
use pdsl_core::storage;
use pdsl_lang::contract;

#[doc = " A simple contract that has a value that can be"]
#[doc = " incremented, returned and compared."]
struct Incrementer {
    #[doc = " The internal value."]
    value: storage::Value<u32>,
}
impl pdsl_core::storage::Flush for Incrementer {
    fn flush(&mut self) {
        self.value.flush()
    }
}
impl pdsl_core::storage::alloc::AllocateUsing for Incrementer {
    unsafe fn allocate_using<A>(alloc: &mut A) -> Self
    where
        A: pdsl_core::storage::alloc::Allocate,
    {
        use pdsl_core::storage::alloc::AllocateUsing;
        Self {
            value: AllocateUsing::allocate_using(alloc),
        }
    }
}
impl ::pdsl_model::ContractState for Incrementer {
    const NAME: &'static [u8] = "Incrementer".as_bytes();
}
use pdsl_model::messages;
#[doc = " Returns `true` if `x` is greater than the internal value."]
#[rustc_copy_clone_marker]
struct Compare;
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::std::marker::Copy for Compare {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::std::clone::Clone for Compare {
    #[inline]
    fn clone(&self) -> Compare {
        {
            *self
        }
    }
}
impl ::pdsl_model::Message for Compare {
    type Input = (u32);
    type Output = bool;
    const ID: ::pdsl_model::MessageHandlerSelector =
        ::pdsl_model::MessageHandlerSelector::new(0);
    const NAME: &'static [u8] = "Compare".as_bytes();
}
#[doc = " Increments the internal counter."]
#[rustc_copy_clone_marker]
struct Inc;
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::std::marker::Copy for Inc {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::std::clone::Clone for Inc {
    #[inline]
    fn clone(&self) -> Inc {
        {
            *self
        }
    }
}
impl ::pdsl_model::Message for Inc {
    type Input = (u32);
    type Output = ();
    const ID: ::pdsl_model::MessageHandlerSelector =
        ::pdsl_model::MessageHandlerSelector::new(1);
    const NAME: &'static [u8] = "Inc".as_bytes();
}
#[doc = " Returns the internal counter."]
#[rustc_copy_clone_marker]
struct Get;
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::std::marker::Copy for Get {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::std::clone::Clone for Get {
    #[inline]
    fn clone(&self) -> Get {
        {
            *self
        }
    }
}
impl ::pdsl_model::Message for Get {
    type Input = ();
    type Output = u32;
    const ID: ::pdsl_model::MessageHandlerSelector =
        ::pdsl_model::MessageHandlerSelector::new(2);
    const NAME: &'static [u8] = "Get".as_bytes();
}
impl Incrementer {
    #[doc = " Automatically called when the contract is deployed."]
    pub fn on_deploy(&mut self, env: &mut pdsl_model::EnvHandler, init_value: u32) {
        self.value.set(init_value);
    }
    #[doc = " Returns `true` if `x` is greater than the internal value."]
    pub fn compare(&self, env: &pdsl_model::EnvHandler, x: u32) -> bool {
        x > *self.value
    }
    #[doc = " Increments the internal counter."]
    pub fn inc(&mut self, env: &mut pdsl_model::EnvHandler, by: u32) {
        self.value += by
    }
    #[doc = " Returns the internal counter."]
    pub fn get(&self, env: &pdsl_model::EnvHandler) -> u32 {
        *self.value
    }
}
fn instantiate() -> impl pdsl_model::Contract {
    pdsl_model::ContractDecl::using::<Incrementer>()
        .on_deploy(|env, init_value: u32| {
            let (handler, state) = env.split_mut();
            state.on_deploy(handler, init_value)
        })
        .on_msg::<Compare>(|env, x: u32| {
            let (handler, state) = env.split();
            state.compare(handler, x)
        })
        .on_msg_mut::<Inc>(|env, by: u32| {
            let (handler, state) = env.split_mut();
            state.inc(handler, by)
        })
        .on_msg::<Get>(|env, _| {
            let (handler, state) = env.split();
            state.get(handler)
        })
        .instantiate()
}
#[no_mangle]
fn deploy() {
    instantiate().deploy()
}
#[no_mangle]
fn call() {
    instantiate().dispatch()
}

from ink.

Robbepop avatar Robbepop commented on June 30, 2024

I am closing this since it has obviously reached a state that satisfies this issue.

from ink.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.