bitshares / bitshares-core

BitShares Blockchain node and command-line wallet
https://bitshares.github.io/
Other
1.17k stars 643 forks source link

On-chain user scripts ("dumb" contracts) #1182

Open clockworkgr opened 5 years ago

clockworkgr commented 5 years ago

THIS IS FOR VERY PRELIMINARY DISCUSSION ONLY

As a user I want the ability to install scripts on-chain (let's call them "dumb" contracts) so that I can automate sequences of operations on-chain.

Additional Context (optional)

Ideally we would have the ability to write small scripts (turing-completeness not necessary) that leverage conditionals, loops (bounded) the ability to store (a limited amount of) data on-chain and call BitShares platform ops.

Scripts would be installed as sub-accounts under the account creating them and accessed with a sort of name-spacing mechanism for user-friendliness (e.g. account name: clockwork::dividend-script)

Scripts can have different entry points depending on the operation that impacts them to allow for complete functionalities and better performance while we also allow owner accounts to explicitly call methods on them via a new op i.e. call_script_method(script_account,method_name,[params]).

e.g. in pseudocode

script some_simple_script {   

     init() {
         // state loaded, common housekeeping when ran
     }

     chain_callable function onTransferIn(from, amount,asset) {
        // do stuff when a transfer comes in
     }

     user_callable function setSomeData(data) {
        // update state based on owner input
     }

    etc...
}

The main issue I see here is that the block-producing nodes don't have access to the full database which severely limits functionality. E.g. I can't query the list of holders of a certain asset inside a script for example.

Still there are use cases I can see this kind of functionality being helpful.

CORE TEAM TASK LIST

cogutvalera commented 5 years ago

Nice !

xeroc commented 5 years ago

Maybe we should distinguish

A stateless contract just consists of an instruction set with certain inputs. Think sharedrop or dividends. Those are automated transfers to multiple/all accounts. No state is required, all incoming tokens are distributed. Another example is Bitcoin's Script.

A stateful contract, in contrast, is much more difficult I think. Mostly because the block producers would need to validate state consistently as well. I would argue that this is out of scope for BitShares.

cogutvalera commented 5 years ago

NOTE INFO

  1. https://github.com/HcashOrg/HyperExchange they support smart contract
  2. https://github.com/gxchain/gxb-core GXChain supports not only smart contract, blockchain as a service (BaaS) but also provides many unique services, including ID verification, multi-dimensional data, KYC, and swift login
oxarbitrage commented 5 years ago

I did some brief research a while ago looking into the possibilities of supporting some scripting language inside the core. I think the solution could be done in the form of a plugin and do not modify the core logic at all unless really needed.

Plugin should expose an API to upload script file and plugin will process it. On my research i found that LUA plays nice with c++ and it seems easy to get started and build some sort of prototype. LUA is MIT(https://www.lua.org/license.html), LUA was(maybe still is) used in some well known trading platforms like Trade Station among other reasons i don't remember now, LUA was the best candidate of that moment IMHO. An embedded scripting language will avoid us to parse all the statements a scripting language should need to make something useful, no need to reinvent the wheel there.

I can do some more research on this now that it is posted here. Whatever path we follow, effort to make this well will be huge as a lot of details need to be considered but as an optional plugin it haves more possibilities to be done and adopted and scaled.

clockworkgr commented 5 years ago

In regards to @cogutvalera 's comment. HyperExchange uses LUA and GXB uses WASM.

I have no experience when it comes to scripting language integration so I can't comment on specifics. I assume LUA (with its huge ecosystem) would be easiest.

My concerns are regarding performance which is why I was suggesting a minimal solution by keeping the featureset small.

Also, considering this suggestion is about ON-chain scripts, which would need to be ran deterministically when the "account" object holding them is impacted and consensus reached, how is it possible to run this as a plugin?

cogutvalera commented 5 years ago

absolutely agree with @clockworkgr about performance concerns, but also I've concerns about security issues for such smart contract feature

oxarbitrage commented 5 years ago

I was thinking on something here, correct me if i am wrong.

If we want to be adding scripting i suppose one of the goals will be to be able to make trading strategies with some logic in the node with this capability enabled. Objects change in our blockchain by operation, we cant for example just change the price of a limit order in 1 node directly in the object as the others will never understand if this is not included in an operation -> transaction -> block.

So, a program can at most check object state from a script instead of using an API but to change the database it needs to execute an operation and follow the normal path. (this probably mean we need to send private key in the script?)

Will this bring real benefit ? I am trying to find the use cases mostly from trader perspective before further research.

abitmore commented 5 years ago

@oxarbitrage basically you're talking about bot logic but not on-chain logic. "Sending private key" is actually done by signing a transaction.

clockworkgr commented 5 years ago

Just to clarify,

My initial suggestion was to treat those "contract"/script accounts as special and have them produce ops that are included(or at least derived) but need not be signed in a way. similar to virtual ops.

For example, If I send 10 BTS to my "dividend" script, the chain would run through the "script" and end up creating 2x 5BTS transfers out to two different accounts. Those 2 transfer ops, seeing as the script's balance is enough and can not be created any other way then via the chain interpreting the script in a deterministic way, would not have to be signed.

Only my initial transfer of 10 BTS would have to be checked as usual. The rest is derived by that tx combined with the (deterministic) script execution.

Does that make sense?

To be honest I would like to see some degree of statefulness to the scripts. However I can see that for example historical lookups would not be possible (witness nodes carry no history) but certain actions could be taken based on current db state and perhaps keep a "contract" state (of limited size) somehow.

clockworkgr commented 5 years ago

Thinking about it further, I think my initial suggestion to treat them as accounts is probably best.

Essentially, it's a "special" account that can do anything a normal account can do except it has no keys and the ops it performs need not be signed as long as they are ops that would need its own authority.

For example, assume my script lives at 1.2.3456789.

Any op the script produces that would require the authority of 1.2.3456789 is considered signed seeing as there is no other way for those ops to be entered into the chain then via the script output.

That's the output side done.

On the other side we need to figure out the input side and when the script needs to be ran and evaluated.

Here we have 2 cases.

a) Either the script account is impacted by another chain operation (say someone sends funds to 1.2.3456789) in which case we run the script via the appropriate handler. We could also have the script "list" its used handlers on creation so we can quickly ignore ops that it's not supposed to handle without interpreting it for better performance.

b) Or a specific method in the script is called (this would require a new op_type call_script_method).... This would have to be signed by the script "owner" for security reasons. We could always have the script check the method caller (similar to what ethereum does) but that would incur a performance hit as the script would have to be interpreted first. Instead, we could leverage upcoming custom authority options to secure access (even on a per method basis).

Putting this altogether:

I , clockwork, (1.2.711128) create a new 'contract'/'script' at 1.2.999999. I am now the owner of that script. The script creation operation also takes a list of 'impacts' this script is equipped to handle. For simplicity's sake, let's say I list only 'BalanceChanged'.

This means that the script will be interpreted and executed via the onBalanceChanged handler whenever an operation (any operation) changes the script account's balances.

So for example if a 3rd party sends it an asset...or a gateway issues an asset to it.

Any resulting operations from the script's execution would be handled like virtual ops, deterministically changing the db state as long as it's something the script is allowed to do (like for example transferring part of its own balances out).

Let's also assume that I have a 'public" method in the script. Staying with the dividend simplistic example, we call it setMinimumBalanceForDividends().

This method can be called via a new op_type call_script_method that takes as params the script account id, the method name and an array of parameters.

The script would be interpreted and executed IFF the call_script_method was signed by the script account owner. Or , assuming custom authority BSIP gets implemented by someone listed in the custom authority for that op_type. In that case , the original owner could set asserts for the script_account and the method_name thus allowing me to do stuff like:

Active authority is K if script_account = 1.2.99999 and method_name = xxxxxx

Thus making different parts of the script "controllable" by different entities.

Moving onwards. Let's assume the script can store some state data (extension of account statistics object perhaps?) then the setMinimumBalanceForDividends updates a state variable store with the new minimum balance.

Going back to my original pseudocode example:

script DividendScript {   

     constructor() {
          this.CreateState('MinBalance',100);
          this.CreateState('Beneficiaries',[]);
     }
     init() {
          var minBalanceForDividends=this.state.MinBalance;
          var beneficiaries = this.state.Beneficiaries;
     }
     onBalanceChanged {
           if (this.Balances['BTS'] >minBalanceForDividends) {
                      if (beneficiaries.length>0) {
                            let dividend=this.Balance['BTS'] / beneficiaries.length;
                            for (i=0;i++; i<beneficiaries.length) {
                                  this.sendAsset(dividend,'BTS',beneficiaries[i]);
                            }
                      }
           }
     }

     setMinimumBalanceForDividends(amount) {
             this.UpdateState('MinBalance',amount);
     }
     addBeneficiary(account_id) {
           beneficiaries.push(account_id);
             this.UpdateState('Beneficiaries'beneficiaries);        
     }
}

Let's call this script payload.

Account clockwork calls create_script_operation with params: name="dividendScript",script=payload,handlers=['BalanceChanged']

The new 'special' account clockwork::dividendScript is created with id 1.2.345678 , the script is "installed" there and interpreted once running it's constructor() method setting its initial state (possibly as extension in 2.6.345678)

Now account clockwork can use call_script_method_operation on 1.2.345678 to call either setMinimumBalanceForDividends or addBeneficiary to change the script's state.

Using custom_authority (if implemented) and the required asserts he could also delegate access to these methods to one or more other accounts as required.

Whenever the script account's balance is changed, the script is interpreted and the onBalanceChanged method executed. If impacted by any other op, it is ignored (since we have not registered any other handlers on creation).

If any of the methods (in our case, onBalanceChanged) result in new operations being created/db state being changed, we update state accordingly essentially treating the output of the script as 'signed'.

Obviously it can only do the ops its allowed but at least we shouldn't have to worry about sig verification.

I'll stop here but please consider also the case where the script account itself is added as a custom authority to another (non-script) account.

We could have very flexible scenarios this way.

grctest commented 5 years ago

Could a script perform an ES lookup, for say distributing an asset's collected market fees to users who traded the most (for a single trading pair) during a set period of time? The balance redistribution idea is good, but could you provide weights for different users (ie user A gets 1, user B gets 2) based on a Bitshares blockchain query?

How would cost of computation and flexible target user size factor in? Would a simple script that splits income between 2 users cost the same as someone targeting the whole BTS holder's list for a regular UIA issuance distribution?

clockworkgr commented 5 years ago

Balance redistribution was just an example.

Consensus using external data would be impossible (unless some kind of oracle setup was added) and ES data is external.

The data that a script could access , would be whatever is in the consensus DB state. this excludes account history/market history etc.

I guess we could move some potentially interesting useful data to statistics objects but I believe we already have a decent base to cover quite a few use cases as it is.

As far as costs/fees are concerned, I haven't got that far yet.

grctest commented 5 years ago

Consensus using external data would be impossible (unless some kind of oracle setup was added) and ES data is external.

OK, so if we can get targets but we cannot assign weight due to requiring external factors, could a group of (asset owner defined) users provide weights against the retrieved targets with a new op? This way price feed publishers could be performing complex external computations then providing a list of weights which the script would take the median of to provide the weight-applied asset-issuance | fee-redistribution?

clockworkgr commented 5 years ago

Using witnesses for Oracle type work is what we already do for pricefeeds... I guess we could do the same

charyury commented 5 years ago

@clockworkgr , @ryanRfox , what is the status of this issue? Is there a BSIP for it? We in OpenLedger have played with Ethereum VM and managed to integrate it with Bitshares core, so I wonder if this is something that may be interesting to the community. Please advise)

clockworkgr commented 5 years ago

@charyury I've been slowly piecing together the steps that need to be taken for this to work properly in discussions with @oxarbitrage .

In fact, yesterday we were discussing how our biggest issue is finding the right VM/scripting interpreter that will allow us to calculate script usage/metrics so we can set fees appropriately. Seeing as EVM is one of the few VMs that already implement this I was toying around with taht idea myself (although I'm worried about its performance)

Is there somewhere I can read more about or see your implementation?

oxarbitrage commented 5 years ago

I had been testing in the last few days 2 different languages approach that are lua and wren.

they both have active and similar binding libraries:

My original plan was not the same as what is discussed here but related and at the end they should be joined.

I have in mind a plugin that will accept scripts(lua and wren are where i have some code done) that will be able to get some data from the blockchain (onBlock, getBalance(), ...) and execute some operations (Transfer).

To make it the private key will need to be present in the script or similar(insecure). Custom authorities can bring another level of security to the script by using the trading auth.

At the end the client will have to trust the node where script are being executed, can be his own node with the smart_contracts plugin loaded.

Then, to make it in the consensus level(signatures will not be needed) the witness need to execute loaded scripts on each block, get the same results and execute trades without the need of signing.

@clockworkgr haves a process for it but i was not able to fully understand it, the hardfork part should be small and easy. Need to formalize.

@charyury will be great to hear more about your testing and how that part was solved specifically, maybe we can work together if we want to change the vm, i am not sure if ethereum will be ideal.

charyury commented 5 years ago

Here is a short instructions how to reach the testnet and run a smart contract. You may load any Solidity contract from Ethereum. You may also operate Bitshares objects. Enhanced CLI also provided. Will post more documentation later. OpenLedger Bitshares VM Testent 20180829.pdf

clockworkgr commented 5 years ago

After numerous discussions with @oxarbitrage, @zapata et al, I'll try and go back to basics and spec out/explain a possible implementation strategy trying to piece together the previous conversations.

WHAT WE WANT

Essentially we want the script to function as a normal user account.

Just like I as a person would monitor stuff on the chain, react to a state change on the chain, perform some logic in my head and then possibly broascast some transactions in reaction to that, we want the contract to do the same.

The only difference is that instead of a person thinking, it's the script being evaluated and deterministically reaching a result in an expected and trustless way.

With that in mind, script/contract objects SHOULD be the same as account objects, they have the exact same capabilities/feature/data + a few extra things.

We can either use a new space for them such as 1.16.XXX which seems to be the way OL implemented it, but that would lead to duplicate code and extra changes in clients. Hence why my intital suggestion was for scripts/contracts to live as normal account objects (1.2.XXX).

NEXT STEPS

The following is a suggested path for implementation that borrows heavily from ethereum concepts.

As a first step, we want a way to "create" and "store" those script accounts.

Storing is 'easy' as we can simply add additional data fields to the relevant script-account object or its associated statistics object.

When creating however, we have an added requirement. We need to store the "owning" account. By default, this is the only account/authority that can call methods on the script. Again, this could also be an additional field.

Therefore, let's assume the new operation: create_script_account_operation.

If my account (clockwork) signs and broadcasts create_script_account_operation(script_name,script_code), a new script account object is created which is exactly the same as a normal account with the following 3 differences:

  1. It has NO keys since we don't expect or want anyone to submit normal, signed transactions on behalf of the contract/script. We only want the contract evaluation by a witness on block production to produce virtual ops (if needed)
  2. It has a flag identifying it as a script/contract.
  3. It has a field that holds the script code/bytecode.

Now, going back to the Ethereum metaphor, ETH only evaluates the contract if

a) a method is called

or

b) a transfer to the contract address is made.

In our case we have more possibilities to identify WHEN to evaluate a script.

First of all, a script method being called. For this, we create a second op: call_script_method_operation(script_id, method_name, [params])

By default, we have this locked down with its evaluator require active permissions of the script owner (as defined in the field mentioned previously). So only the script creator/owner can call a script method.

Assuming implementation of BSIP40, we can open up those permissions as needed via custom_authorities.

Our second case is evaluating the script if it's state has been changed. In Ethereum we only have a transfer (i.e. balance change) but in BitShares, an account may be impacted by other ops too. The good thing is we already monitor for those in -core to handle object subscriptions. Thus, apart from our custom script methods (callable by the owner) we can have multiple event handlers such as on(<impact-type>).

In order to avoid unnecessarily evaluating a script or running unnecessary code, we should force scripts/contracts to declare their USED handlers on creation.

So going back, our create_script_account_operation now has a signature of create_script_account_operation(script_name,script_code,[handlers]).

This concludes our first step. We now have a script on-chain, with a defined owner and defined entry points for evaluation (either via method call or via other chain op impact) that has all the properties and capabilities of an account but cannot perform ANY ops through tx broadacsting due to lack of keys.

The second step is evaluating the script/contract while retaining consensus.

For this, and in order to limit the impact on the existing consensus code, I propose that block production is split into 3 stages.

First, we evaluate and apply all existing ops as we do right now. If any of them 'impact' an account object that is flagged as script and THAT script-account lists that impact-type as one that it handles, we put an 'impact-type','script_id' data-pair into a queue for processing.

Once this is completed, we take all our call_script_method_ops to be included in that block (if any) and if they are signed properly (by the script owner, or an authority the owner has delegated to via BSIP40) we evaluate the script accordingly via the relevant method entry point.

Finally, we take our queue from the first step and evaluate the scripts using the relevant handlers as entry points.

Same input data -> Same scripts -> Same order => Same Output and thus consensus.

Now, the final step is that in the process of evaluating the script, the script is freely capable of producing ANY bitshares operation as a "virtual" operation. It being a product of valid inputs and consensus, we don't require keys for it in the sense that we assume the script-account's active authority as a given. So the script can create ANY operation that would normally require the script-account's active or owner authority. We are thus able to use the existing evaluation code for the validity of those ops with hardly any changes.

ECONOMICS & DoS PROTECTION

Whatever VM/script interpreter we choose, should provide metrics (similar to the EVM) and opcode count. Just like ethereum, we should extend the fee-schedule to have an opcode/fee table and calculate fees used as the script is evaluated. If the script opcode count exceeds fees paid by the relevant method call (or in remaining balance of the contract for impact handlers) we stop execution and no state change has taken place. Otherwise, the evaluation completes successfully. This means that the relevant UI should be able to evaluate the script off-chain and suggest the appropriate fee (UI pulls script state, script code, suggested TX and calculates the resulting opcode count & associated fee)

We should also set limits on the total number of opcode calls and script state storage.

I also suggest that a percentage of script-related fees is paid directly to witnesses.

charyury commented 5 years ago

@clockworkgr , it seems that starting from some kind of simple scripting solution, the issue is moving towards powerful and protected business logic processing mechanism, executed on consensus level, which is very close to our solution. I think the best way to proceed is describe our solution in details and see how it is compared to the requirements proposed by you. This is in progress already, I expect to share the information by the end of the week.

oxarbitrage commented 5 years ago

i also have some work in progress with a plugin that i will share more in details as soon as i have something decent to present as a proof of concept.

pmconrad commented 5 years ago

Essentially we want the script to function as a normal user account.

Then why not implement it client-side?

IMO before speccing out a major change like this we should answer the question - do we want on-chain scripting AT ALL?

clockworkgr commented 5 years ago

@pmconrad client-side is essentially what @oxarbitrage 's solution is tackling.

Whether we want on-chain scripting is the big question. Personally I would as I see many advantages , as long as it doesn't come with a huge performance hit.

The discussion is not so much about speccing it out but (at least on my side) to simply explore possible implementation paths in order to better evaluate if it's worth it. Hence my request for comments was simply to see if this proposed architecture even makes sense at all.

oxarbitrage commented 5 years ago

my approach is client side with the help of a bitshares plugin that will execute client scripts in a VM created by the plugin on every block. among other benefits i think this can bring in new businesses creation i also think it will help us explore a possible on chain smart contract support in the future, at least put us a bit closer.

charyury commented 5 years ago

Our approach is all about on-chain. We believe smart contract is something that modern blockchain must have. Bitshares is perfect blockchain for business solutions, smart contracts is just one last thing still missing. Regarding performance, it is more a matter of correct pricing model. More paid transactions means more activity in the ecosystem, this is what all stakeholders are looking for. At this time Bitshares is definitely underutilized, there is huge space for transactions count increase.

sschiessl-bcp commented 5 years ago
  1. It has NO keys since we don't expect or want anyone to submit normal, signed transactions on behalf of the contract/script. We only want the contract evaluation by a witness on block production to produce virtual ops (if needed)

What is the difference to having the owner permission of the new script account to be the creating account?

owner authority

I suggest not allowing anything that has to do with owner authority.

I also suggest that a percentage of script-related fees is paid directly to witnesses.

Witnesses have their pay already, what is reasoning here?

ECONOMICS

For my clarification:

My 2 cents on economics: Script account creation should have similar economics to the custom authority. By that I mean to include enabled/disabled (also good if it misbehaves and needs adjustment) and have a set time period in which it is active, and connect the fee to that period. This is done to be able to remove legacy scripts as it otherwise will blow up the chain over time. If owner still uses it, he/she wont mind paying the additional fee

charyury commented 5 years ago

More details about our solution in the attachment. Looking forward to the core team members feedback! It looks like we have to decide first, if on-chain script processing is required for Bitshares at all. Maybe this is something to be discussed with the whole community? A poll worker request may be created for this purpose. OpenLedger Bitshares VM Solution.pdf

oxarbitrage commented 5 years ago

@charyury i think the document looks great.

I had to change my solution from pure plugin to execute the scripts in the chain as i found no way to make it secure without consensus.

The solution is similar to the one you are providing in the high level, probably different internally as it use wren as vm instead of ethereum. solution could be adapted also to lua and luajit if wren is not good enough.

It was not my intention to make the 2 solutions to compete, if i knew openledger was working on something similar before starting i will be probably on something else.

The problem i see is that having both vm in the consensus running will be unlikely. Opinions welcome. Should we work together ?

charyury commented 5 years ago

@oxarbitrage, how far are you with you solution? Do you have something tangible already? As you can see, we have quite a big progress, so it is a good time to test our solution and decide if this approach fits the network. If you are somehow close to the same level of readiness, probably we shall compare both solutions in more details to decide which one is better and then go for it. Speaking frankly, we are not much aware of wren and lua, so we might miss some big advantages those have. Could you share your vision on pros and contras? In our opinion Ethereum VM has two big advantages: it is well known and has big developers community behind it, and there are tons of smart contracts already implemented that can be ported to Bitshares w/o any updates, so any business solution that uses Ethereum at this time can migrate to cheaper and faster environment immediately, and benefit from using DEX and MPAs that Bitshares has at the same time. Anyhow, we would be happy to collaborate!

oxarbitrage commented 5 years ago

The process is similar. Users upload scripts to the chain with operation. On each block bitshares-core will execute each active script in a wren VM and do the needed operations. It can currently only do transfers but can do other core operations. It haves similar functions to get data from the network, a simple script may look:

if(Bitshares.getBalance("my-acccount") > 100)
   Bitshares.transfer("some-account", 1)

or

user_bitrhday = "2018-10-10"
if(now > user_birthday )
   Bitshares.transfer("some-account", 10)

etc.

It is not developed as much as your pdf but it is most likely going after a very similar output.

As a pro of your system i agree with the 2 main advantages of ethereum however not sure if the community/stakeholders will agree on that. In my opinion i don't see anything wrong with that if it works for our needs.

In regards to how far, i have some code already that i will share in the next few days as i need to do some cleanup and changes. I cant leave it incomplete at this point but i will not advance much more after that unless the solution is considered. That will be good enough as a proof of concept. We can make some comparisons then, an alternative. It will be a good idea to make tests on both and see what we get from there.

I will not try to stop you to get my idea on front, in the contrary, i respect the work you had done until now, will help in what i can. Also mine is actually just 1 week of work at this moment.

Zapata commented 5 years ago

@oxarbitrage how do you imagine solve the economic part with wren/lua solution? One of the advantage of EVM it's that it computes the fees required to process the transaction, which is the harder part imho. Nice work @charyury !

oxarbitrage commented 5 years ago

You cant know upfront how many transfers a contract will end up executing as it will depend on conditions, can be 1 , 100 or none. To start, fees are charged by upload , starting, stopping contracts as this can be normal bitshares operations. Next, each time the VM executes a transfer it will execute the fee for it normally.

For usage, as a simple example we can count space in RAM, number of instructions, whatever your VM uses every time is executed, save this number and add as fee to next operation the script executes so for example in the next transfer fee will be:

fee_of_transfer + consumed_ram_since_last_time

So account will need to have enough token in his account for this transfer to succeed.

This is of course very very briefly, i didn't checked anything related to it yet in wren or lua and probably will not explore it either now as the solution at least by now will not be pushed to more than just a small proof of concept.

It also sounds like will be reinventing the wheel as ethereum VM already handle this in a more natural way from design.

sschiessl-bcp commented 5 years ago

For the economic question: Adding history to the scripting engine for the fees seems inappropriate imo.

Every operation that the script triggers must pay the normal BTS fee involved. The creation fee of the script should account for its complexity and duration of being enabled (similar to custom active authority). The script account itself should have BTS balance to pay for the fees of all triggered operations. The script itself could employ a manual check initially if the balance is sufficient, i.e. give the responsibility of atomicity to the script creator.

abitmore commented 5 years ago

Steem is making a feature named "automated actions", I'm not sure what it is:

OpenLedgerApp commented 5 years ago

@Zapata Thanks a lot for evaluation of our work! @oxarbitrage your idea is good and challenging for the economic part. You are right we have decided to develop the required functionality without reinventing the wheel. Ethereum VM already handles all necessary calculations. Our economics is simple: Payment Contract Call Fees = Contract Operation Fee + Gas*Gas Price. Contract Operation Fee is a payment (BTS) that must be charged for operation call of the contract the same as any operation fees. Since we have DPOS, Gas Price is set by the Committee. Gas Price is an amount of fee, that must be paid for 1 Gas. Gas is a measurement unit of computational effort that is needed to be paid to commit the transaction to the blockchain network. The caller of the contract pays this cost. At the very high level, Gas is the number of instructions used to execute a transaction in the EVM. It ensures that an appropriate fee is being paid by transactions submitted to the network. By requiring that a transaction pays for each operation it performs, it ensures that the network doesn’t get misused. In our current demo, Gas metrics for all computation efforts are identical with Ethereum metrics. @sschiessl-bcp, it can be adapted specifically for Bitshares on the further steps of development and testing as well as we can create a calculator for checking of BTS balance for paying the fees of all operations of selected contract. Payment Contract Call Fees for calling contracts will be distributed like fees for any other operations in BitShares. Looking forward to furthering discussion!

sschiessl-bcp commented 5 years ago

I am wondering if adoption of Ethereum VM is the right way politically. IMO the EOSIO implementation will receive more adoption due to the massive amount of money floating around. This would allow BitShares to adopt any of the new EOSIO contracts.

I have no clue how much more difficult that implemenation is, just wanted to mention it.

In general I would prefer to stick to the existing fee schedule, meaning that the script needs to execute any of the existing operations to manipulate chain state, and in that matter also the transaction fee for that. That might be unsuitable for adopting any of the existing virtual machines though.

Did you checkout what Steem is doing @OpenLedgerApp ?

cogutvalera commented 5 years ago

Have the same feelings like @sschiessl-bcp has about Ethereum VM, it is buggy and has big disadvantages also as discussed here https://bitcoin.stackexchange.com/questions/40389/what-advantages-and-disadvantages-does-ethereum-have-over-bitcoin/40735

OpenLedgerApp commented 5 years ago

@sschiessl-bcp, @cogutvalera Steem: We have evaluated Steem - there is no any mechanism for on-chain scripts execution. Steem is uniquely designed for their specific business. EOS: EOS claims that it could support different VM versions including the Ethereum EVM. There are two options for a virtual machine mentioned in the technical whitepaper: Web Assembly VM – it could enable smart contract development in C/C++ The Ethereum EVM – EOS could modify and implement the Ethereum Virtual Machine The first option was chosen https://github.com/EOSIO/WAVM. However, it goes slowly and there are no plenty of EOS contracts now. It is wiser to think what we have at the current moment than in the obscure future. This is why we have decided to go with Ethereum EVM. Our logic is simple:

  1. We can support existing ERC contracts and we can migrate business solutions to faster and cheaper Bitshares environment
  2. EVM is widely working smart contract engine for operating various processes. If the smart contract is well-written and tested in depth – it works
  3. EVM has a well-defined documentation
  4. EVM has a big community of developers All these advantages can be delivered fast to Bitshares users if we have a green light from the community.
sschiessl-bcp commented 5 years ago

Hm, I see. I guess I don't have a strict personal preference for the used VM, I leave that discussion to others.

Is an implementation possible that does not require a separate GAS, but uses existing fee schedule?

Furthermore, have you already tried porting existing scripts? What are the normal use cases of such scripts? Are typically all consensus changing operations reflected with one of the BitShares operations?

OpenLedgerApp commented 5 years ago

@sschiessl-bcp 1) Gas is the name for the execution fee that senders of transactions need to pay for every operation made on a blockchain. Gas Price is an amount of fee, that must be paid for 1 Gas. It was introduced as the separate thing since if we take the existing fee schedule, it can be an issue with BTS fees precision. GAS is a small number – it will be not enough 5 digits in the precision as in the current fees. 2) We have successfully ported EOS contract. Most of the operations available in ETH smart contracts can be migrated without any problem. 3) The solution allows executing smart contracts on the Bitshares blockchain (Any smart contracts that can be executed using the Ethereum Virtual Machine). Smart contracts can execute Bitshares operations using Bitshares system contracts. System contract allows getting access to blockchain functionality from the Solidity code. System contract has an address and can be called using this address. For example, we can create an asset in Bitshares directly from a contract.

froooze commented 5 years ago

@OpenLedgerApp : We should not introduce a new currency, because BTS fees have only 5 digits. Instead we could add some extra figures to the core?