Mission Impossible III — Distributed Payments on NEO platform

By: Igor M. Coelho and Vitor N. Coelho

First of all, nice to meet you! :) This is our first post, what justifies the introduction, and a bit long post… but it will be interesting (we hope) ;)

Vitor and I are part of a NEO development group called NeoResearch, focused on open-source tools for the community and new amazing projects for NEO Ecosystem. Our main projects so far are: (1) Eco platform: an online platform (https://neocompiler.io) for writing, deploying and testing smart contracts; (2) Advances on consensus networks by optimization and high-performance computing tools (+ data analysis on current projects); and (3) porting Solidity language for NEO.

As you may know, Solidity is currently the most used language for prototyping smart contracts, and it was born for Ethereum network. We also believed we could bring it to NEO, but many people thought that was impossible because of things that may lack in NEO… So we went to look for those things, and found out the first challenge was to put onchain asset transfer on NEO (for NEO/GAS/etc). We consulted many experts, and all of them believed it was not possible or it could be possible, but they didn’t know how to do that on NEO.

Hopefully, we passed by two amazing post of NEL group, the Mission Impossible I and II, what helped us a lot to better understand how NEO network works, and finally to help us create a coding pattern on Distributed Payments for UTXO Assets (what we needed to start Solidity afterall…). We recently created a NEP that will (hopefully) be discussed by NEO community: https://github.com/neo-project/proposals/pull/45

Ok, this post will have two (long) parts. The first, we will remake the Mission Impossible I using our Eco platform instead on ThinSDK from NEL group. I believe that’s important because Eco is online (neocompiler.io) and accessible to everyone, while some of us have issues with running Windows .NET systems (most of us only have Mac or Linux). In the second step, we will demonstrate how our proposed NEP works (again on Eco platform, as example).

================= PART I ==================

The challenge put by Li Jianyang on February was to “steal” some GAS from this TestNet address: APBUyZNkemciUQurabSQBnnma7kGGhUPPL

This address represents the following contract:

public static object Main(string method, object[] args) {
 if (Runtime.Trigger == TriggerType.Verification) {
 if (method == “0214”) return true;
 }
 return false;
 }

55c56b6c766b00527ac46c766b51527ac4616168164e656f2e52756e74696d652e47657454726967676572009c6c766b52527ac46c766b52c3642a00616c766b00c30430323134876c766b53527ac46c766b53c3640e00516c766b54527ac4620f0061006c766b54527ac46203006c766b54c3616c7566

ScriptHash:0x86cf7371f5511257f682cc47be48563a3ff03f51

As himself described in the post, nobody took the prize, so he named it “Mission Impossible”. How to take it?

In simple words, this Verification contract returns True only if the passed string is “0214”, otherwise it returns False. The Verification phase on NEO verifies if a given transaction is valid, so we need to create a transaction taking GAS from this contract address and transfering it to our own wallet.

The neocompiler.io has an embedded Ecosystem Laboratory (EcoLab) to perform such experiments: https://neocompiler.io/#/ecolab

In Transaction Build tab, you can find a box with everything you will need, called “Create TX: Withdraw UTXO Assets from Contract”.

Put the contract AVM in the first box (it will calculate the scripthash and address, make sure Address is correct: APBUyZNkemciUQurabSQBnnma7kGGhUPPL.

Now we need an invocation script to load the desired string (code in C#):

public static string Main() {
 return “0214”;
 }

The AVM is 00c56b0430323134616c7566, but we need to remove the unnecessary c5 (create array), 6b/6c (altstack), 61 (nop) and 75/66(drop/ret), leaving us with: 000430323134

Okay, select NEO TestNet on top of the page:

Now you can select Asset (GAS) and the UTXO available will be displayed on the box. Put your own TestNet Address in scripthash format (you can use our converters in EcoLab to do that if you need to), then take how much you want :) (please leave some for the next learners…)

Example, taking 2.5 GAS for scripthash address 0FA8B54D1AF130E2E515D5FEDA31D4C423C5754E

It was amazing to discover that the private key is not necessary for this kind of “withdraw”, and this showed us that it was possible to implement different transfer methods on NEO that could be easily integrated to smart contracts.

=============== PART II ===================

Using this precious knowledge, we started to develop a prototype that could allow automatic (or semi-automatic) asset transfers on NEO smart contracts. There are some challenges we faced such as:

(1) Dealing with fragmented UTXO on scripthash account. For example, when many people participate in ICO, the assets will be made available in many different “units”, so in order to simplify further methods, we propose the JoinAsset (or JoinUTXO) method. The idea is to use the Verification trigger to validate transactions that group several UTXO in a single one, what will keep the balance of the scripthash account, but will reduce the number of operations in further methods. This operation can be called by anyone on the network, not only the contract “owner”, so even if the proprietary offchain mechanism is on vacation, assets can still be grouped and withdrawn.

(2) Creating a method for sending assets, called SendAsset (or SendUTXO). This method uses contract storage to inform that a given asset transaction must be allowed for a given address (in a given asset and specific value). This information goes to a storage called “PendingSendAsset”. It is possible to finish the process here and automatically schedule the transfers, but for now we are using a separated scheduling method.

(3) These transfers must be scheduled by ScheduleUTXO method, that receives a UTXO as parameter and verifies it has enough assets to perform at least one transfer in pending list. All possible transfers will be scheduled (until a maximum limit B, to avoid too much gas spending in a single operation). After scheduling, it is not possible to unschedule, and only after Verification step is called and assets are transfered, another scheduling can occur. The next scheduling will validate that the previous has been performed, it will clear the current scheduling storage and allow another scheduling to occur on the pending list.

Using this process, any payment can occur in a distributed process, meaning that no centralization (or authority trust) is needed. Anyone on the network can claim the payments, and it is on the best interest on the involved parties that they actually perform the claims, so it is expected that the process will go on naturally without the intervenction of any central structure. Obviously, this whole process can work better if people can just hit a “Claim Payment” button on a lightwallet, and that’s why we are aiming to put standards on the function names and the whole process (in a proposed NEP for Distributed Payments).

Finally, we developed a prototype of the functions that can be tested using Eco platform. Tutorial is available here: https://github.com/NeoResearch/nep-distributed-payments/blob/master/simplePrototype/simplePrototype.md

======

We would like to thank NEO, and personally Peter Lin for all support regarding the ideas that came to be this NEP. We believe this can be very useful for future smart contracts, ICOs and all related to future DEX. Thanks Fabio Cardoso for the amazing job with the implementation of transaction validation for Eco platform.

Many thanks to NEL team for the inspiring two posts:

If you are interested, please follow our discussion towards a NEP standard on Distributed Payments for UTXO Assets:

Implementations in C#:
https://github.com/NeoResearch/nep-distributed-payments/blob/master/simplePrototype/simplePrototype.cs

See you next time ;)

Igor and Vitor