Skip to content

Dice example implemented with a new scripting opcode

dimxy edited this page Aug 16, 2021 · 9 revisions

Concept of script extension with a new txrules opcode

Version: 0.2

In komodo we have been developing custom consensus (CC, aka Antara) modules. They were actually chain c++ core code extension modules which were implementing smart contract logic in komodo assets chains. Examples of such modules are 'tokens cc', 'asset cc', 'dice cc', 'channels cc' etc. The problem with such approach was that to upgrade a cc module a modification of the chain code and a hardfork were needed.
There has been brought up an idea to put CC validation code on chain, in transactions, as some kind of a rule language to be interpreted by a virtual machine added to the chain core code. This would allow to add new consensus rules without core code change.
Such a rule language should be rich enough to provide access to various chain objects (like they were also accessible in C++ custom consensus modules), including properties of the validated transaction, ability to load transactions from the chain and access them too and get access to general chain data, like the current chain height. There could be different approaches where to put validation code made in this rule language, one of those might be a standard script extended with a new opcode. So a rule expression is placed in the output scriptPubKey marked with the new opcode (OP_EVALTXRULES).
As a proof of concept, we have added this OP_EVALTXRULES opcode and a couple script templates to use it in the CHIPS code and started a CHIPS test chain with this.
As an example of the new opcode usage, a dice betting RPC has been added.

Improvements in version 0.2

In the initial version we simply put a OP_EVALTXRULES rule script into the scriptPubKey and a script also could have some parameters inside. This created a problem that it is hard for anyone to verify that the script validity and authenticity. In the version 0.2 this was improved so the script content is fixed and maybe verified by checking its hash value. Yet another improvement is prevention of reuse of entropy value (if a participant tries to reuse a revealed others person's entropy in another bet by attacking the chain with a reorg and recerating the bet taking advantage of knowing other's revealed value). For this hashed entropies are signed by both participants so any of them might ensure their entropy is not reused in another bet (they should track bet history for this however).

Dice RPC v0.2 description

The dice sample with OP_EVALTXRULES opcode allows to make bets against the house with specified odds and claim the win. To randomise the bet both the house and bettor should provide hashed entropies (which when combined will create the random). Later both should reveal the original entropy values which will be checked by the validation code.
The validation for wins/loss is actually placed into dicefund and dicebet transactions outputs.
The dice v0.2 rpc methods are:

  • dicecreatebettxproposal mypk housepk amount win:loss my-entropy-hash - this rpc creates a bet proposal signed by the bettor, it locks the bet amount and adds bettor's win:loss value and entropy hash in the opreturn. The tx vins must be signed with 2of2 keys. This partially signed tx is sent to the house (off-chain).
  • diceacceptbettxproposal mypk txhex my-entropy-hash - with this rpc the house accepts the proposal tx, adds his entropy hash and signs the tx. This 2of2 signed tx is sent to the chain.
  • diceclaim2 mypk entropy-house entropy-bet utxo-house utxo-bet - the bettor or house can claim the win, for that both need to reveal entropies first.
  • dicedecodebettx txhex - this is a helper rpc for decoding bet tx data like opreturn content, output amounts and also validating rule script hash value in the tx scriptPubKeys.

For compatibility: dice RPC v0.1 description

The initial version dice rpc calls description:

  • dicefund mypk bettorpk hentropy amount - house initially funds a bet
  • dicebet mypk housepk hentropy amount win:loss - bettor makes her bet and sets win:loss ratio. hentropy must be a uint256 value as hex string (64 hex chars)
  • diceclaim h|b mypk entropy-house entropy-bet utxo-house utxo-bet - house or bettor claims the win and should receive back their own funds and the partner's funds in win/loss ratio (if he has won indeed). To claim as the house pass 'h', to claim as the bettor pass 'b' char. If you are not the winner diceclaim would return error
  • dicehentropy entropy-hex helper to get hash from an entropy value. Entropy value must be uint256 in hex (64 hex chars)

Running CHIPS testnet node and using dice RPC

Steps:

  • Build a node for this repository: https://github.com/dimxy/chips3/tree/txrule-poc
  • Start a node with this command: ./chipsd -testnet -addressindex=1 -txindex=1 -addnode=3.136.47.223
  • Mine some coins with generate 1 100000000 (note, you need at least 2 blocks after the mined coinbases to use your mined coins because of coinbase maturity set to 2 for the testnet chain)
  • Send some coins to yet another address in your wallet (you need two accounts with some coins for a house and bettor)
  • Use dice rpcs described above. Instead you may also use the testdice.py python script (see below).

Running testdice.py

You need python3 package and python json lib installed to run the test.
Steps:

  • Obtain two pubkeys from the addresses in your node wallet with command chips-cli -testnet validadateaddress address.
  • Open test/testdice.py with a editor and change variables housepk and bettorpk to your pubkeys.
  • Save and run the test with command python3 ./testdice.py.

A good return of the testdice.py looks like claimed from bettor: 1.9999 claimed from house: 0.02. You may play with other params like odds in the test code.

Also, more info about the consensus on-chain code ideas and implementation is here Extension of consensus with DSL language.