wavesplatform / Waves

⛓️ Reference Waves Blockchain Node (client) implementation on Scala
https://wavesplatform.com/
MIT License
1.17k stars 417 forks source link

[Proposal] Waves trigger #2758

Open vlzhr opened 4 years ago

vlzhr commented 4 years ago

Blockchain trigger proposal

There are many requests for adding a functionality of auto-running callable functions in Ride. An example would be a simple DeFi application that takes X WAVES from you and payouts Y WAVES back at time T automatically. Now it's only possible to allow user call payout() after T by himself. How could we design the functionality of running payout automatically?

My proposal is not to try change something in Node. Easier would be creating a Smart Contracts standard and an independent Waves Trigger tool.

SC standard

Assume there is a script containing simple payout function that decides if Alice could withdraw her balance from dApp:

@Callable(i)
func payout() = {
    let lockedTill = 1575515393
    let alicePubKey = base58'5AzfA9UfpWVYiwFwvdr77k6LWupSTGLb14b24oVdEpMM'
    let lockedAmount = getIntegerValue(this, alicePubKey.toBase58String())
    let wasCalled = getBoolean(this, alicePubKey.toBase58String()+"_payed_out")

    if (lockedTill > lastBlock.timestamp) 
        then throw("Your cash is still locked")
    else if (wasCalled != unit)
        then throw("Pyaout already completed")
    else ScriptResult(
            WriteSet([DataEntry(alicePubKey.toBase58String()+"_payed_out", true)]),
            TransferSet([ScriptTransfer(alicePubKey.addressFromPublicKey(), lockedAmount, unit)])
        )
}

To complete the payout Alice needs to wait till the time comes and call the function by herself. Better and more user-friendly would be to make the smart contract send money to her automatically at 1575515393 (Unix-time). Assume there is a trigging standard presenting function like this:

@Callable(i)
func standardpayout() = {
    let CALLAT = 1575515393  # please, call this at 1575515393
    let alicePubKey = base58'5AzfA9UfpWVYiwFwvdr77k6LWupSTGLb14b24oVdEpMM'
    let lockedAmount = getIntegerValue(this, alicePubKey.toBase58String())
    let wasCalled = getBoolean(this, CALLAT.toString()+"_payout_WAS_CALLED")

    if (CALLAT > lastBlock.timestamp) 
        then throw("Your cash is still locked")
    else if (wasCalled != unit)
        then throw("Function already called")
    else ScriptResult(
            WriteSet([DataEntry(CALLAT.toString()+"_payout_WAS_CALLED", true)]),
            TransferSet([
                ScriptTransfer(alicePubKey.addressFromPublicKey(), lockedAmount, unit),
                ScriptTransfer(i.caller, 500000, unit) # TRIGGING REWARD
            ])
        )
}

There are 3 main standard properties: 1) variable CALLAT containing UNIX-time: when to call function? 2) TRIGGING REWARD transfer - reward for calling a function being payed by dApp 3) <CALLAT>_<function name>_WAS_CALLED - dApp state value equals to true after the function call that prevents re-calling and double spending of trigging reward

Trigger tool

The trigging standard for SC makes it possible to create a tool that finds and calls functions that are expected to be automatically called.

The trigger tool is an open source app that: 1) checks every set script transaction and if the script contains "trigging standard" function adds it to the "to-do-list" 2) checks every time gap if any function in "to-do-list" is ready to be called (CALLAT is less than current time), invokes the script and gets trigging reward

The key point is that anyone can run trigger tool and earn trigger reward by calling functions faster than competitors. Moreover, this tool could be designed to be run together with the main node and add new profit to the miners.

Do you find the idea of implementing triggers to the blockchain interesting? Would like to hear any additions, remarks or hates to this Waves trigger proposal. Thank you!

pivoo81 commented 4 years ago

I like the idea to have trigger separately from the blockchain and use economic incentive to run it. Need to analize more real use-cases which need these functionality to see if the proposed solution suits all of them. But also it looks now too tightly connected to the code of the smart-contract.

PyWaves commented 4 years ago

I'm not really sure if we should add it as an extension to the node. Why not publish it open source and let the community run it, independently of nodes: first come, first serve. :)

vlzhr commented 4 years ago

@PyWaves, makes sense. But, this tool needs to check every SetScript transaction: this is what the Node actually does. So, connecting Trigger to the Node application would be a significant optimization.

ghost commented 4 years ago

I could think of several use cases for this blockchain trigger. However, it would require re-evaluation of the conditions at trigger time. For example, if a script has the following form:

triggerTime = lastTx + someInterval;

if ( currentTime >= triggerTime )
{
    // Do some stuff…
}

At the time the script is set, it is added to the “to-do-list” to be executed at a certain time. When the script is triggered the conditions are re-evaluated as the lastTx + someInterval value may have shifted due to newer transactions. The trigger is then rescheduled.

To avoid abuse/overloading, the someInterval value can be translated to script complexity. A higher value leads to a lower complexity, while a lower value leads to a high complexity. The minimum time interval between triggers can be limited in this way.

mychaint commented 2 years ago

it s been a while, any outcome?