New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Basic contracts library for AssemblyScript #3204

Open
toonsevrin opened this Issue May 18, 2018 · 22 comments

Comments

Projects
None yet
@toonsevrin
Contributor

toonsevrin commented May 18, 2018

EDIT: You can join the discussion in the telegram group and start contributing here!

Motivation

C++ is a barrier for the younger (or less experienced) under us. I think supporting a simpler language will enable a lot of these developers to start playing with eos as well.

Description

AssemblyScript allows the compilation of strictly typed TypeScript to WebAssembly with Binaryen. It's still in active development but I'm pretty sure the basic stuff is already in place.

I propose an AssemblyScript library containing the essential components from eosiolib to begin with and over time introduce better database support and all that.

Developing this minimal library should not be that difficult (especially compared to the benefits that come from it).

Questions

The answers to the following problems are useful for supporting any language.

What parts of the eosiolib are essential?

Serialization
Stuff like action arguments have to be deserialized from a standard format to an internal representation (for example, a struct). The deserialization and serialization library should eventually cover all datatypes (structs, ints, strings, names..).

How is context related stuff done, like print.h?

All functions are imported from a webassembly module called "env". These functions only support fixed size parameters, so you have to pass memory pointers.

Printing
Uses the import env.prints(pointer: i32): void. The referenced string should be utf-8 encoded with null termination. There are also other functions for printing numbers..

Entrypoint
Every contract must export the apply(receiver: u64, code: u64, action: u64): void function.

To fetch the actual action data, you need to use a combination of the following imports:

  • env.action_data_size(): i32 fetches the byte length of the action data
  • env.read_action_data(msg: i32, len: i32) i32 stores len bytes of the action data to the msg pointer. Returns the number of bytes copied?
    To serialize/deserialize the action data, see serialisation.

You can fetch the actual contract account through the current_receiver(): u64 call. Comparing this to the apply receiver ensures that you're handling the right actions.

Database
The database functions which can be imported are listed here or/and here.

Time
The import current_time(): u64 returns the timestamp of the current block. (I'm uncertain about the freedom producers have in deviating from the real time when they set this timestamp)

Inline transactions
send_inline(serialized_action: u32, size: u32): void sends an inline action in the same context as the parent transaction. The serialized_action is a memory pointer to the start of the serialized action.

@toonsevrin toonsevrin changed the title from Proposal: Basic library for AssemblyScript to Proposal: Basic contracts library for AssemblyScript May 18, 2018

@SonicAgamemnon

This comment has been minimized.

SonicAgamemnon commented May 18, 2018

This is wonderful: Enabling even partial access for TypeScript developers opens up a significant market.

@toonsevrin

This comment has been minimized.

Contributor

toonsevrin commented May 18, 2018

I'd be glad to implement this myself if there's a team member who can address questions when they come up!

@dax-l

This comment has been minimized.

dax-l commented May 18, 2018

Typescript has C# like syntax (khm khm... Anders Hejlsberg) so you could potentially catch two big areas of industry here... web programming (Javascript guys) and .NET folks.

@kesar

This comment has been minimized.

Contributor

kesar commented May 21, 2018

@toonsevrin love this idea. I think it will be a great project to fund with the Worker Proposals as soon as they are available 👏

@toonsevrin

This comment has been minimized.

Contributor

toonsevrin commented May 21, 2018

Hi everyone!

It took about 40 lines to write a working Hello World contract in AssemblyScript! The contract could be written in 4 lines if the redundant stuff is extracted into a library. All though this contract is extremely simple (without any persistence), it proves that supporting assemblyscript is doable!

That said, there are a few issues:

  • AssemblyScript strings are utf-16 encoded. This means that conversion was required to print them.
  • The binary size was large (6000bytes compared to 3000 bytes for the c++ helloworld) and the execution was slow (3-6ms compared to 1ms in c++)
  • The AssemblyScript standard library prints its errors to an env.abort function, which does not exist in the eos runtime. This means that this function had to be implemented manually after compilation (as there's no way to do it beforehand).

This makes AssemblyScript less attractive compared to c++ right now, but, in my opinion, all of these issues can be resolved by working together with the AssemblyScript team.

@learnforpractice

This comment has been minimized.

Contributor

learnforpractice commented May 21, 2018

@toonsevrin

This comment has been minimized.

Contributor

toonsevrin commented May 21, 2018

UPDATE
The AssemblyScript team has jumped on the issues mentioned above, big thanks to them! Two of the issues are now resolved:

  • Changing to a simpler memory allocator (one which does not deallocate memory) dropped the size to 4100 bytes and the execution time to 0.7ms! Changing to a smaller toUTF8 function dropped the size down to 950 bytes.
  • The env.abort issue is resolved (you can map it to an internal function with the compiler)

Up next: Database, arguments and inline contract call support

@metrue

This comment has been minimized.

metrue commented May 23, 2018

@toonsevrin

This experiment is so cool, I just asked a related question "is it possible to write a contractor in Go/Rust in eos" in EOS telegram channel a few days ago, and I got response from @abourget .

The go toolchain is not ready and contracts would be over 9M, which wouldn't fit in a transaction. Too much runtime stuff, which makes C++ (and eventually Rust) a better fit.

not totally understand what he said, but technically we can do it I think.

@toonsevrin

This comment has been minimized.

Contributor

toonsevrin commented May 23, 2018

@metrue the way golang targets webassembly is very interesting, but it does create a heavy binary (1MB+).

First of all: AssemblyScript does not have this problem, our test contract was under 1KB.

Secondly: golang may eventually split the binary up into two: One containing the runtime, the other one containing the actual program. That could make golang a viable language for contract development as well. I'd love to chat with @abourget about the feasability of this.

@metrue

This comment has been minimized.

metrue commented May 23, 2018

@toonsevrin awesome.

just checked out your project https://github.com/toonsevrin/eos-assemblyscript-api, found no 'How To' in README, add some usage stuff would be helpful for someone not that familiar with it like me. ):

@toonsevrin

This comment has been minimized.

Contributor

toonsevrin commented May 23, 2018

@metrue that repo is not in use yet. I'll place a message here once it is.

@metrue

This comment has been minimized.

metrue commented May 23, 2018

@toonsevrin I see, how about this gist you listed above https://gist.github.com/toonsevrin/94734d39f7ee9441159ddcd7a844837a, is it a workable one? and how to get it up and run?

@toonsevrin

This comment has been minimized.

Contributor

toonsevrin commented May 23, 2018

Hi Metrue, here's a much simpler version of that contract (4 lines of code): https://gist.github.com/toonsevrin/26498311ee024afbca0d890badf5f4f8

My apologies for the worst build instructions ever written ;)

@metrue

This comment has been minimized.

metrue commented May 23, 2018

@toonsevrin awesome, thanks.

@gustavomick

This comment has been minimized.

gustavomick commented May 23, 2018

fyi https://steemit.com/eosio/@eosargentina/developing-typescript-javascript-on-eos you use this to accelerate your research :)

@toonsevrin

This comment has been minimized.

Contributor

toonsevrin commented May 23, 2018

Hi everyone!

Time to get the ball rolling! The development of the assemblyscript library will take place here and once the library becomes more stable it's likely to be moved to the eosio organization.

If you're interested in contributing, learning, discussing..., a telegram group has just been created for this project. You are all invited to join in!

@Hodles

This comment has been minimized.

Hodles commented Jun 1, 2018

Absolutely support for higher level languages would greatly accelerate the adoption of EOS as a DAPP platform. When the worker proposal system is in place, it's def something I will personally be voting for.

@ellipticasec

This comment has been minimized.

ellipticasec commented Jun 2, 2018

That is very very exciting =)

@Hodles

This comment has been minimized.

Hodles commented Jun 4, 2018

FYI, zilliqa block chain have proposed a smart contract specific language, which would also be a nice to have

https://arxiv.org/pdf/1801.00687.pdf

@MaxGraey

This comment has been minimized.

MaxGraey commented Jun 5, 2018

AssemblyScript now support full set of operator overloading. So just imagine how looks like contracts will be:

@action
@onlyOwner
export function transfer(from: AccountName, to: AccountName, quantity: u64): void {
  Account.get(from) >> quantity >> Account.get(to);
}

[edit] or better:

  Account.get(to) << quantity << Account.get(from);

which provide right order: firstly decrease balance from and only after that increase balance for to account.

More implementation details with some limitation (which resolve in future) you can find here:
https://webassembly.studio/?f=tz9pgrvb7u

@toonsevrin

This comment has been minimized.

Contributor

toonsevrin commented Jun 6, 2018

@MaxGraey that's awesome! Not sure if this would simplify things for developers though (because there's more syntax they have to learn).

Btw let's keep the syntax discussion going here 👍

@7flash

This comment has been minimized.

7flash commented Jun 29, 2018

How could one contract in AssemblyScript call method from another contract?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment