Skip to content
This repository has been archived by the owner on Feb 14, 2021. It is now read-only.

Add real life example in tutorial #29

Open
Pzixel opened this issue Jun 29, 2018 · 1 comment
Open

Add real life example in tutorial #29

Pzixel opened this issue Jun 29, 2018 · 1 comment

Comments

@Pzixel
Copy link
Contributor

Pzixel commented Jun 29, 2018

I'm currently trying to port some Solidity code into wasm using pwasm. But I have a problem that I don't see enough examples or documentation to perform such a transform. For example, here is a simple Solidity contract:

contract Example {    
    string[] values;

    function addValue(string value) public onlyOwner {
        values.push(value);
    }

    function getValue(uint i) public returns(string) {
        return values[i];
    }
	
    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }
}

it's very simple but it shows all properties that real contracts have: it has onlyOwner modifier, it works with dynamically-sized data and it push values into internal storage (which is not prealocated). Token examples are too simple and don't show how to perform such operations that are crucial for most contracts.

I'm playing with these storage_keys!/pwasm_ethereum::write and so on, but it doesn't look I'm even approaching the solution. Currently It's actually a blocker to me, without stretching storage I cannot migrate my code to wasm.


I'd appreciate any help because I'm currently stuck with that - I only see how I can write into preallocated fixed size storage, but I don't see how to dynamically increase it.

@Pzixel Pzixel changed the title Add real life example in tutorials Add real life example in tutorial Jun 29, 2018
@Pzixel
Copy link
Contributor Author

Pzixel commented Jun 29, 2018

I managed to emulate an array, but I only could save ony fixed-sizd items smaller than 32 bytes. It won't work for string or any arbitrary-sized type. Stuck with that currently Code is based on step-3 sample

pub mod token {
    use pwasm_std::Vec;
    use pwasm_ethereum;
    use parity_hash::H256;
    use bigint::U256;

    macro_rules! storage_keys {
        () => {};
        ($($name:ident),*) => {
            storage_keys!(0u8, $($name),*);
        };
        ($count:expr, $name:ident) => {
            static $name: H256 = H256([$count, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
        };
        ($count:expr, $name:ident, $($tail:ident),*) => {
            static $name: H256 = H256([$count, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
            storage_keys!($count + 1u8, $($tail),*);
        };
    }

    // eth_abi is a procedural macros https://doc.rust-lang.org/book/first-edition/procedural-macros.html
    use pwasm_abi_derive::eth_abi;

    #[eth_abi(TokenEndpoint, TokenClient)]
    pub trait TokenInterface {
        /// The constructor
        fn constructor(&mut self, _total_supply: U256);
        /// Total amount of tokens
        #[constant]
        fn totalSupply(&mut self) -> U256;

        #[constant]
        fn getNumbers(&mut self) -> Vec<U256>;

        fn addNumber(&mut self, value: U256);
    }

    storage_keys!(
        TOTAL_SUPPLY_KEY,
        DATA_LEN,
        DATA_KEY
    );

    pub struct TokenContract;

    impl TokenInterface for TokenContract {
        fn constructor(&mut self, total_supply: U256) {
            // Set up the total supply for the token
            pwasm_ethereum::write(&TOTAL_SUPPLY_KEY, &total_supply.into());
        }

        fn totalSupply(&mut self) -> U256 {
            pwasm_ethereum::read(&TOTAL_SUPPLY_KEY).into()
        }

        fn getNumbers(&mut self) -> Vec<U256> {
            let num: u8 = pwasm_ethereum::read(&DATA_LEN)[31];
            let mut result = Vec::with_capacity(num as usize);
            for i in 0..num {
                let mut key = DATA_KEY.clone();
                key[31] = i;
                result.push(pwasm_ethereum::read(&key).into())
            }
            result
        }

        fn addNumber(&mut self, value: U256) {
            let num: u8 = pwasm_ethereum::read(&DATA_LEN)[31];
            let new_num: U256 = (num + 1).into();
            pwasm_ethereum::write(&DATA_LEN, &new_num.into());

            let mut key = DATA_KEY.clone();
            key[31] = num;
            pwasm_ethereum::write(&key, &value.into());
        }
    }
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant