OSDN Git Service

adjust contract
authoroys <oys@oysdeMacBook-Pro.local>
Thu, 26 Sep 2019 12:17:10 +0000 (20:17 +0800)
committeroys <oys@oysdeMacBook-Pro.local>
Thu, 26 Sep 2019 12:17:10 +0000 (20:17 +0800)
consensus/segwit/segwit.go
protocol/validation/vmcontext.go
protocol/vm/vmutil/script.go

index 8d62e9a..a2aae23 100644 (file)
@@ -105,13 +105,22 @@ func ConvertP2SHProgram(prog []byte) ([]byte, error) {
 }
 
 // ConvertP2DCProgram convert standard P2WDC program into P2DC program
-func ConvertP2DCProgram(prog []byte, lockedAssetID bc.AssetID) ([]byte, error) {
+func ConvertP2DCProgram(prog []byte, lockedAssetID bc.AssetID, args [][]byte) ([]byte, error) {
        dexContractArgs, err := DecodeP2DCProgram(prog)
        if err != nil {
                return nil, err
        }
 
-       return vmutil.P2DCProgram(*dexContractArgs, lockedAssetID)
+       if len(args) != 2 {
+               errors.New("Invalid P2DC arguments")
+       }
+
+       clauseSelector, err := vm.AsInt64(args[1])
+       if err != nil {
+               return nil, err
+       }
+
+       return vmutil.P2DCProgram(*dexContractArgs, lockedAssetID, clauseSelector)
 }
 
 // DecodeP2DCProgram parse standard P2WDC arguments to DexContractArgs
index fd84da4..1a3da84 100644 (file)
@@ -81,7 +81,7 @@ func NewTxVMContext(vs *validationState, entry bc.Entry, prog *bc.Program, args
 
        result := &vm.Context{
                VMVersion: prog.VmVersion,
-               Code:      witnessProgram(prog.Code, *assetID),
+               Code:      witnessProgram(prog.Code, *assetID, args),
                Arguments: args,
 
                EntryID: entryID.Bytes(),
@@ -101,7 +101,7 @@ func NewTxVMContext(vs *validationState, entry bc.Entry, prog *bc.Program, args
        return result
 }
 
-func witnessProgram(prog []byte, lockedAssetID bc.AssetID) []byte {
+func witnessProgram(prog []byte, lockedAssetID bc.AssetID, args [][]byte) []byte {
        if segwit.IsP2WPKHScript(prog) {
                if witnessProg, err := segwit.ConvertP2PKHSigProgram(prog); err == nil {
                        return witnessProg
@@ -111,7 +111,7 @@ func witnessProgram(prog []byte, lockedAssetID bc.AssetID) []byte {
                        return witnessProg
                }
        } else if segwit.IsP2WDCScript(prog) {
-               if witnessProg, err := segwit.ConvertP2DCProgram(prog, lockedAssetID); err == nil {
+               if witnessProg, err := segwit.ConvertP2DCProgram(prog, lockedAssetID, args); err == nil {
                        return witnessProg
                }
        }
index 32d459b..8ad2ad8 100644 (file)
@@ -9,6 +9,9 @@ import (
        "github.com/vapor/protocol/vm"
 )
 
+// DexClauseSelector is the global selector for the dex transaction
+var DexClauseSelector = 0
+
 // pre-define errors
 var (
        ErrBadValue       = errors.New("bad value")
@@ -159,13 +162,14 @@ func P2WDCProgram(dexContractArgs DexContractArgs) ([]byte, error) {
 }
 
 // P2DCProgram generates the script for control with dex contract
-func P2DCProgram(dexContractArgs DexContractArgs, lockedAssetID bc.AssetID) ([]byte, error) {
+func P2DCProgram(dexContractArgs DexContractArgs, lockedAssetID bc.AssetID, clauseSelector int64) ([]byte, error) {
        standardProgram, err := P2WDCProgram(dexContractArgs)
        if err != nil {
                return nil, err
        }
 
-       dexProgram, err := DexProgram(strings.Compare(dexContractArgs.RequestedAsset.String(), lockedAssetID.String()))
+       assetComparedResult := strings.Compare(dexContractArgs.RequestedAsset.String(), lockedAssetID.String())
+       dexProgram, err := DexProgram(assetComparedResult, clauseSelector)
        if err != nil {
                return nil, err
        }
@@ -188,165 +192,158 @@ func P2DCProgram(dexContractArgs DexContractArgs, lockedAssetID bc.AssetID) ([]b
 //
 // DexContract source code:
 // contract DexContract(requestedAsset: Asset,
-//                         ratioMolecule: Integer,
-//                             ratioDenominator: Integer,
-//                             sellerProgram: Program,
-//                             standardProgram: Program,
-//                             sellerKey: PublicKey) locks valueAmount of valueAsset {
-// clause trade(exchangeAmount: Amount) {
-//     define availableAmount: Integer = valueAmount * ratioMolecule / ratioDenominator
-//     verify exchangeAmount > 0 && exchangeAmount <= availableAmount
-//     define actualAmount: Integer = exchangeAmount * ratioDenominator / ratioMolecule
-//     verify actualAmount > 0 && actualAmount <= valueAmount
-//     if exchangeAmount < availableAmount {
-//         lock exchangeAmount of requestedAsset with sellerProgram
-//         lock valueAmount-actualAmount of valueAsset with standardProgram
-//         unlock actualAmount of valueAsset
-//     } else {
-//         lock availableAmount of requestedAsset with sellerProgram
-//         unlock valueAmount of valueAsset
-//     }
-//   }
+//                                             ratioMolecule: Integer,
+//                                             ratioDenominator: Integer,
+//                                             sellerProgram: Program,
+//                                             standardProgram: Program,
+//                                             sellerKey: PublicKey) locks valueAmount of valueAsset {
+// clause partialTrade(exchangeAmount: Amount) {
+//      define actualAmount: Integer = exchangeAmount * ratioDenominator / ratioMolecule
+//      verify actualAmount > 0 && actualAmount < valueAmount
+//   lock exchangeAmount of requestedAsset with sellerProgram
+//   lock valueAmount-actualAmount of valueAsset with standardProgram
+//   unlock actualAmount of valueAsset
+// }
+// clause fullTrade(exchangeAmount: Amount) {
+//   define actualAmount: Integer = exchangeAmount * ratioDenominator / ratioMolecule
+//   verify actualAmount > 0 && actualAmount == valueAmount
+//   lock exchangeAmount of requestedAsset with sellerProgram
+//   unlock valueAmount of valueAsset
+// }
 // clause cancel(sellerSig: Signature) {
-//     verify checkTxSig(sellerKey, sellerSig)
-//     unlock valueAmount of valueAsset
-//   }
+//   verify checkTxSig(sellerKey, sellerSig)
+//   unlock valueAmount of valueAsset
 // }
 //
 // contract stack flow:
 // 6                        [... <clause selector> sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset 6]
 // ROLL                     [... sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset <clause selector>]
-// JUMPIF:$cancel           [... sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset]
-// $trade                   [... sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset]
-// AMOUNT                   [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset valueAmount]
-// 2                        [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset valueAmount 2]
-// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset valueAmount ratioMolecule]
-// MUL                      [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset (valueAmount * ratioMolecule)]
-// 3                        [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset (valueAmount * ratioMolecule) 3]
-// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset (valueAmount * ratioMolecule) ratioDenominator]
-// DIV                      [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset availableAmount]
-// 7                        [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset availableAmount 7]
-// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset availableAmount exchangeAmount]
-// 0                        [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset availableAmount exchangeAmount 0]
-// GREATERTHAN              [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset availableAmount (exchangeAmount > 0)]
-// 8                        [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset availableAmount (exchangeAmount > 0) 8]
-// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset availableAmount (exchangeAmount > 0) exchangeAmount]
-// 2                        [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset availableAmount (exchangeAmount > 0) exchangeAmount 2]
-// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset availableAmount (exchangeAmount > 0) exchangeAmount availableAmount]
-// LESSTHANOREQUAL          [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset availableAmount (exchangeAmount > 0) (exchangeAmount <= availableAmount)]
-// BOOLAND                  [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset availableAmount ((exchangeAmount > 0) && (exchangeAmount <= availableAmount))]
-// VERIFY                   [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset availableAmount]
-// 7                        [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset availableAmount 7]
-// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset availableAmount exchangeAmount]
-// 4                        [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset availableAmount exchangeAmount 4]
-// ROLL                     [... exchangeAmount sellerKey standardProgram sellerProgram ratioMolecule requestedAsset availableAmount exchangeAmount ratioDenominator]
-// MUL                      [... exchangeAmount sellerKey standardProgram sellerProgram ratioMolecule requestedAsset availableAmount (exchangeAmount * ratioDenominator)]
-// 3                        [... exchangeAmount sellerKey standardProgram sellerProgram ratioMolecule requestedAsset availableAmount (exchangeAmount * ratioDenominator) 3]
-// ROLL                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount (exchangeAmount * ratioDenominator) ratioMolecule]
-// DIV                      [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount]
-// AMOUNT                   [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount valueAmount]
-// OVER                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount valueAmount actualAmount]
-// 0                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount valueAmount actualAmount 0]
-// GREATERTHAN              [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount valueAmount (actualAmount > 0)]
-// 2                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount valueAmount (actualAmount > 0) 2]
-// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount valueAmount (actualAmount > 0) actualAmount]
-// 2                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount valueAmount (actualAmount > 0) actualAmount 2]
-// ROLL                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount (actualAmount > 0) actualAmount valueAmount]
-// LESSTHANOREQUAL          [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount (actualAmount > 0) (actualAmount <= valueAmount)]
-// BOOLAND                  [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount ((actualAmount > 0) && (actualAmount <= valueAmount))]
-// VERIFY                   [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount]
-// 6                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 6]
-// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount exchangeAmount]
-// 2                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount exchangeAmount 2]
-// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount exchangeAmount availableAmount]
-// LESSTHAN                 [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount (exchangeAmount < availableAmount)]
-// NOT                      [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount !(exchangeAmount < availableAmount)]
-// NOP                      [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount !(exchangeAmount < availableAmount)]
-// JUMPIF:$else_1           [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount]
-// $if_1                    [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount]
-// 0                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 0]
-// 7                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 0 7]
-// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 0 exchangeAmount]
-// 4                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 0 exchangeAmount 4]
-// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 0 exchangeAmount requestedAsset]
-// 1                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 0 exchangeAmount requestedAsset 1]
-// 7                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 0 exchangeAmount requestedAsset 1 7]
-// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 0 exchangeAmount requestedAsset 1 sellerProgram]
-// CHECKOUTPUT              [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount checkOutput(exchangeAmount, requestedAsset, sellerProgram)]
-// VERIFY                   [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount]
-// 1                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 1]
-// AMOUNT                   [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 1 valueAmount]
-// 2                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 1 valueAmount 2]
-// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 1 valueAmount actualAmount]
-// SUB                      [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 1 (valueAmount - actualAmount)]
-// ASSET                    [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 1 (valueAmount - actualAmount) valueAsset]
-// 1                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 1 (valueAmount - actualAmount) valueAsset 1]
-// 8                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 1 (valueAmount - actualAmount) valueAsset 1 8]
-// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 1 (valueAmount - actualAmount) valueAsset 1 standardProgram]
-// CHECKOUTPUT              [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount checkOutput((valueAmount - actualAmount), valueAsset, standardProgram)]
-// VERIFY                   [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount]
-// JUMP:$endif_1            [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount]
-// $else_1                  [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount]
-// 0                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 0]
-// 2                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 0 2]
-// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 0 availableAmount]
-// 4                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 0 availableAmount 4]
-// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 0 availableAmount requestedAsset]
-// 1                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 0 availableAmount requestedAsset 1]
-// 7                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 0 availableAmount requestedAsset 1 7]
-// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount 0 availableAmount requestedAsset 1 sellerProgram]
-// CHECKOUTPUT              [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount checkOutput(availableAmount, requestedAsset, sellerProgram)]
-// VERIFY                   [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount]
-// $endif_1                 [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset availableAmount actualAmount]
+// DUP                      [... sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset <clause selector> <clause selector>]
+// 2                        [... sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset <clause selector> <clause selector> 2]
+// NUMEQUAL                 [... sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset <clause selector> (<clause selector> == 2)]
+// JUMPIF:$cancel           [... sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset <clause selector>]
+// JUMPIF:$fullTrade        [... sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset]
+// $partialTrade            [... sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset]
+// 6                        [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset 6]
+// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset exchangeAmount]
+// 3                        [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset exchangeAmount 3]
+// ROLL                     [... exchangeAmount sellerKey standardProgram sellerProgram ratioMolecule requestedAsset exchangeAmount ratioDenominator]
+// MUL                      [... exchangeAmount sellerKey standardProgram sellerProgram ratioMolecule requestedAsset (exchangeAmount * ratioDenominator)]
+// 2                        [... exchangeAmount sellerKey standardProgram sellerProgram ratioMolecule requestedAsset (exchangeAmount * ratioDenominator) 2]
+// ROLL                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset (exchangeAmount * ratioDenominator) ratioMolecule]
+// DIV                      [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount]
+// AMOUNT                   [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount]
+// OVER                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount actualAmount]
+// 0                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount actualAmount 0]
+// GREATERTHAN              [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount (actualAmount > 0)]
+// 2                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount (actualAmount > 0) 2]
+// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount (actualAmount > 0) actualAmount]
+// 2                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount (actualAmount > 0) actualAmount 2]
+// ROLL                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount (actualAmount > 0) actualAmount valueAmount]
+// LESSTHAN                 [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount (actualAmount > 0) (actualAmount < valueAmount)]
+// BOOLAND                  [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount ((actualAmount > 0) && (actualAmount < valueAmount))]
+// VERIFY                   [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount]
+// 0                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount 0]
+// 6                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount 0 6]
+// ROLL                     [... sellerKey standardProgram sellerProgram requestedAsset actualAmount 0 exchangeAmount]
+// 3                        [... sellerKey standardProgram sellerProgram requestedAsset actualAmount 0 exchangeAmount 3]
+// ROLL                     [... sellerKey standardProgram sellerProgram actualAmount 0 exchangeAmount requestedAsset]
+// 1                        [... sellerKey standardProgram sellerProgram actualAmount 0 exchangeAmount requestedAsset 1]
+// 5                        [... sellerKey standardProgram sellerProgram actualAmount 0 exchangeAmount requestedAsset 1 5]
+// ROLL                     [... sellerKey standardProgram actualAmount 0 exchangeAmount requestedAsset 1 sellerProgram]
+// CHECKOUTPUT              [... sellerKey standardProgram actualAmount checkOutput(exchangeAmount, requestedAsset, sellerProgram)]
+// VERIFY                   [... sellerKey standardProgram actualAmount]
+// 1                        [... sellerKey standardProgram actualAmount 1]
+// AMOUNT                   [... sellerKey standardProgram actualAmount 1 valueAmount]
+// 2                        [... sellerKey standardProgram actualAmount 1 valueAmount 2]
+// ROLL                     [... sellerKey standardProgram 1 valueAmount actualAmount]
+// SUB                      [... sellerKey standardProgram 1 (valueAmount - actualAmount)]
+// ASSET                    [... sellerKey standardProgram 1 (valueAmount - actualAmount) valueAsset]
+// 1                        [... sellerKey standardProgram 1 (valueAmount - actualAmount) valueAsset 1]
+// 4                        [... sellerKey standardProgram 1 (valueAmount - actualAmount) valueAsset 1 4]
+// ROLL                     [... sellerKey 1 (valueAmount - actualAmount) valueAsset 1 standardProgram]
+// CHECKOUTPUT              [... sellerKey checkOutput((valueAmount - actualAmount), valueAsset, standardProgram)]
 // JUMP:$_end               [... sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset]
-// $cancel                  [... sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset]
+// $fullTrade               [... sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset]
+// 6                        [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset 6]
+// PICK                     [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset exchangeAmount]
+// 3                        [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset exchangeAmount 3]
+// ROLL                     [... exchangeAmount sellerKey standardProgram sellerProgram ratioMolecule requestedAsset exchangeAmount ratioDenominator]
+// MUL                      [... exchangeAmount sellerKey standardProgram sellerProgram ratioMolecule requestedAsset (exchangeAmount * ratioDenominator)]
+// 2                        [... exchangeAmount sellerKey standardProgram sellerProgram ratioMolecule requestedAsset (exchangeAmount * ratioDenominator) 2]
+// ROLL                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset (exchangeAmount * ratioDenominator) ratioMolecule]
+// DIV                      [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount]
+// AMOUNT                   [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount]
+// OVER                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount actualAmount]
+// 0                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount actualAmount 0]
+// GREATERTHAN              [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount (actualAmount > 0)]
+// 2                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount (actualAmount > 0) 2]
+// ROLL                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset valueAmount (actualAmount > 0) actualAmount]
+// 2                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset valueAmount (actualAmount > 0) actualAmount 2]
+// ROLL                     [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset (actualAmount > 0) actualAmount valueAmount]
+// EQUAL                    [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset (actualAmount > 0) (actualAmount == valueAmount)]
+// BOOLAND                  [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset ((actualAmount > 0) && (actualAmount == valueAmount))]
+// VERIFY                   [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset]
+// 0                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset 0]
+// 5                        [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset 0 5]
+// ROLL                     [... sellerKey standardProgram sellerProgram requestedAsset 0 exchangeAmount]
+// 2                        [... sellerKey standardProgram sellerProgram requestedAsset 0 exchangeAmount 2]
+// ROLL                     [... sellerKey standardProgram sellerProgram 0 exchangeAmount requestedAsset]
+// 1                        [... sellerKey standardProgram sellerProgram 0 exchangeAmount requestedAsset 1]
+// 4                        [... sellerKey standardProgram sellerProgram 0 exchangeAmount requestedAsset 1 4]
+// ROLL                     [... sellerKey standardProgram 0 exchangeAmount requestedAsset 1 sellerProgram]
+// CHECKOUTPUT              [... sellerKey standardProgram checkOutput(exchangeAmount, requestedAsset, sellerProgram)]
+// JUMP:$_end               [... sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset]
+// $cancel                  [... sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset <clause selector>]
+// DROP                     [... sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset]
 // 6                        [... sellerSig sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset 6]
 // ROLL                     [... sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset sellerSig]
 // 6                        [... sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset sellerSig 6]
 // ROLL                     [... standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset sellerSig sellerKey]
 // TXSIGHASH SWAP CHECKSIG  [... standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset checkTxSig(sellerKey, sellerSig)]
 // $_end                    [... sellerKey standardProgram sellerProgram ratioDenominator ratioMolecule requestedAsset]
-func DexProgram(assetComparedResult int) ([]byte, error) {
+func DexProgram(assetComparedResult int, clauseSelector int64) ([]byte, error) {
        var firstPositionOP, secondPostionOP vm.Op
-       if assetComparedResult == 0 {
-               return nil, errors.WithDetail(ErrBadValue, "the requestAssetID is same as lockedAssetID")
-       } else if assetComparedResult > 0 {
+       switch {
+       case assetComparedResult > 0:
                firstPositionOP = vm.OP_0
                secondPostionOP = vm.OP_1
-       } else {
-               firstPositionOP = vm.OP_2
-               secondPostionOP = vm.OP_3
+
+               // the composition of dex transaction must comply with the rules:
+               // the first input requestAsset must greater than lockedAsset,
+               // and the second input requestAsset must less than lockedAsset
+               DexClauseSelector = 0
+               if clauseSelector == 1 {
+                       DexClauseSelector = 1
+               }
+
+       case assetComparedResult < 0:
+               if DexClauseSelector == 1 {
+                       firstPositionOP = vm.OP_1
+                       secondPostionOP = vm.OP_2
+               } else {
+                       firstPositionOP = vm.OP_2
+                       secondPostionOP = vm.OP_3
+               }
+
+       default:
+               return nil, errors.WithDetail(ErrBadValue, "the requestAssetID is same as lockedAssetID")
        }
 
        builder := NewBuilder()
        builder.AddOp(vm.OP_6)
        builder.AddOp(vm.OP_ROLL)
-       builder.AddJumpIf(0)
-       builder.AddOp(vm.OP_AMOUNT)
+       builder.AddOp(vm.OP_DUP)
        builder.AddOp(vm.OP_2)
+       builder.AddOp(vm.OP_NUMEQUAL)
+       builder.AddJumpIf(0)
+       builder.AddJumpIf(1)
+       builder.AddOp(vm.OP_6)
        builder.AddOp(vm.OP_PICK)
-       builder.AddOp(vm.OP_MUL)
        builder.AddOp(vm.OP_3)
-       builder.AddOp(vm.OP_PICK)
-       builder.AddOp(vm.OP_DIV)
-       builder.AddOp(vm.OP_7)
-       builder.AddOp(vm.OP_PICK)
-       builder.AddOp(vm.OP_0)
-       builder.AddOp(vm.OP_GREATERTHAN)
-       builder.AddOp(vm.OP_8)
-       builder.AddOp(vm.OP_PICK)
-       builder.AddOp(vm.OP_2)
-       builder.AddOp(vm.OP_PICK)
-       builder.AddOp(vm.OP_LESSTHANOREQUAL)
-       builder.AddOp(vm.OP_BOOLAND)
-       builder.AddOp(vm.OP_VERIFY)
-       builder.AddOp(vm.OP_7)
-       builder.AddOp(vm.OP_PICK)
-       builder.AddOp(vm.OP_4)
        builder.AddOp(vm.OP_ROLL)
        builder.AddOp(vm.OP_MUL)
-       builder.AddOp(vm.OP_3)
-       builder.AddOp(vm.OP_ROLL)
+       builder.AddOp(vm.OP_ROT)
        builder.AddOp(vm.OP_DIV)
        builder.AddOp(vm.OP_AMOUNT)
        builder.AddOp(vm.OP_OVER)
@@ -355,53 +352,57 @@ func DexProgram(assetComparedResult int) ([]byte, error) {
        builder.AddOp(vm.OP_2)
        builder.AddOp(vm.OP_PICK)
        builder.AddOp(vm.OP_ROT)
-       builder.AddOp(vm.OP_LESSTHANOREQUAL)
+       builder.AddOp(vm.OP_LESSTHAN)
        builder.AddOp(vm.OP_BOOLAND)
        builder.AddOp(vm.OP_VERIFY)
-       builder.AddOp(vm.OP_6)
-       builder.AddOp(vm.OP_PICK)
-       builder.AddOp(vm.OP_2)
-       builder.AddOp(vm.OP_PICK)
-       builder.AddOp(vm.OP_LESSTHAN)
-       builder.AddOp(vm.OP_NOT)
-       builder.AddOp(vm.OP_NOP)
-       builder.AddJumpIf(1)
        builder.AddOp(firstPositionOP)
-       builder.AddOp(vm.OP_7)
-       builder.AddOp(vm.OP_PICK)
-       builder.AddOp(vm.OP_4)
-       builder.AddOp(vm.OP_PICK)
+       builder.AddOp(vm.OP_6)
+       builder.AddOp(vm.OP_ROLL)
+       builder.AddOp(vm.OP_3)
+       builder.AddOp(vm.OP_ROLL)
        builder.AddOp(vm.OP_1)
-       builder.AddOp(vm.OP_7)
-       builder.AddOp(vm.OP_PICK)
+       builder.AddOp(vm.OP_5)
+       builder.AddOp(vm.OP_ROLL)
        builder.AddOp(vm.OP_CHECKOUTPUT)
        builder.AddOp(vm.OP_VERIFY)
        builder.AddOp(secondPostionOP)
        builder.AddOp(vm.OP_AMOUNT)
-       builder.AddOp(vm.OP_2)
-       builder.AddOp(vm.OP_PICK)
+       builder.AddOp(vm.OP_ROT)
        builder.AddOp(vm.OP_SUB)
        builder.AddOp(vm.OP_ASSET)
        builder.AddOp(vm.OP_1)
-       builder.AddOp(vm.OP_8)
-       builder.AddOp(vm.OP_PICK)
+       builder.AddOp(vm.OP_4)
+       builder.AddOp(vm.OP_ROLL)
        builder.AddOp(vm.OP_CHECKOUTPUT)
-       builder.AddOp(vm.OP_VERIFY)
        builder.AddJump(2)
        builder.SetJumpTarget(1)
-       builder.AddOp(firstPositionOP)
-       builder.AddOp(vm.OP_2)
-       builder.AddOp(vm.OP_PICK)
-       builder.AddOp(vm.OP_4)
+       builder.AddOp(vm.OP_6)
        builder.AddOp(vm.OP_PICK)
+       builder.AddOp(vm.OP_3)
+       builder.AddOp(vm.OP_ROLL)
+       builder.AddOp(vm.OP_MUL)
+       builder.AddOp(vm.OP_ROT)
+       builder.AddOp(vm.OP_DIV)
+       builder.AddOp(vm.OP_AMOUNT)
+       builder.AddOp(vm.OP_OVER)
+       builder.AddOp(vm.OP_0)
+       builder.AddOp(vm.OP_GREATERTHAN)
+       builder.AddOp(vm.OP_ROT)
+       builder.AddOp(vm.OP_ROT)
+       builder.AddOp(vm.OP_EQUAL)
+       builder.AddOp(vm.OP_BOOLAND)
+       builder.AddOp(vm.OP_VERIFY)
+       builder.AddOp(firstPositionOP)
+       builder.AddOp(vm.OP_5)
+       builder.AddOp(vm.OP_ROLL)
+       builder.AddOp(vm.OP_ROT)
        builder.AddOp(vm.OP_1)
-       builder.AddOp(vm.OP_7)
-       builder.AddOp(vm.OP_PICK)
+       builder.AddOp(vm.OP_4)
+       builder.AddOp(vm.OP_ROLL)
        builder.AddOp(vm.OP_CHECKOUTPUT)
-       builder.AddOp(vm.OP_VERIFY)
-       builder.SetJumpTarget(2)
        builder.AddJump(3)
        builder.SetJumpTarget(0)
+       builder.AddOp(vm.OP_DROP)
        builder.AddOp(vm.OP_6)
        builder.AddOp(vm.OP_ROLL)
        builder.AddOp(vm.OP_6)
@@ -409,6 +410,7 @@ func DexProgram(assetComparedResult int) ([]byte, error) {
        builder.AddOp(vm.OP_TXSIGHASH)
        builder.AddOp(vm.OP_SWAP)
        builder.AddOp(vm.OP_CHECKSIG)
+       builder.SetJumpTarget(2)
        builder.SetJumpTarget(3)
        return builder.Build()
 }