diff --git a/nix/pkgs/haskell/materialized-darwin/.plan.nix/plutus-contract.nix b/nix/pkgs/haskell/materialized-darwin/.plan.nix/plutus-contract.nix index 459c17bb0b0..9f8c091591f 100644 --- a/nix/pkgs/haskell/materialized-darwin/.plan.nix/plutus-contract.nix +++ b/nix/pkgs/haskell/materialized-darwin/.plan.nix/plutus-contract.nix @@ -181,6 +181,7 @@ "Spec/Emulator" "Spec/Rows" "Spec/State" + "Spec/ThreadToken" ]; hsSourceDirs = [ "test" ]; mainPath = [ "Spec.hs" ]; diff --git a/nix/pkgs/haskell/materialized-linux/.plan.nix/plutus-contract.nix b/nix/pkgs/haskell/materialized-linux/.plan.nix/plutus-contract.nix index 459c17bb0b0..9f8c091591f 100644 --- a/nix/pkgs/haskell/materialized-linux/.plan.nix/plutus-contract.nix +++ b/nix/pkgs/haskell/materialized-linux/.plan.nix/plutus-contract.nix @@ -181,6 +181,7 @@ "Spec/Emulator" "Spec/Rows" "Spec/State" + "Spec/ThreadToken" ]; hsSourceDirs = [ "test" ]; mainPath = [ "Spec.hs" ]; diff --git a/plutus-contract/plutus-contract.cabal b/plutus-contract/plutus-contract.cabal index 76ec11dc0ae..09bfe09e419 100644 --- a/plutus-contract/plutus-contract.cabal +++ b/plutus-contract/plutus-contract.cabal @@ -172,6 +172,7 @@ test-suite plutus-contract-test Spec.Emulator Spec.Rows Spec.State + Spec.ThreadToken build-depends: base >=4.9 && <5, bytestring -any, diff --git a/plutus-contract/src/Plutus/Contract/StateMachine.hs b/plutus-contract/src/Plutus/Contract/StateMachine.hs index 934a9555376..d96276ca8bb 100644 --- a/plutus-contract/src/Plutus/Contract/StateMachine.hs +++ b/plutus-contract/src/Plutus/Contract/StateMachine.hs @@ -462,7 +462,11 @@ mkStep client@StateMachineClient{scInstance} input = do Nothing -> pure $ Left $ InvalidTransition Nothing input Just (onChainState, utxo) -> do let (TypedScriptTxOut{tyTxOutData=currentState, tyTxOutTxOut}, txOutRef) = onChainState - oldState = State{stateData = currentState, stateValue = Ledger.txOutValue tyTxOutTxOut} + oldState = State + { stateData = currentState + -- Hide the thread token value from the client code + , stateValue = Ledger.txOutValue tyTxOutTxOut <> inv (SM.threadTokenValueOrZero scInstance) + } inputConstraints = [InputConstraint{icRedeemer=input, icTxOutRef = Typed.tyTxOutRefRef txOutRef }] case smTransition oldState input of @@ -475,7 +479,11 @@ mkStep client@StateMachineClient{scInstance} input = do red = Ledger.Redeemer (PlutusTx.toBuiltinData (Scripts.validatorHash typedValidator, Burn)) unmint = if isFinal then mustMintValueWithRedeemer red (inv $ SM.threadTokenValueOrZero scInstance) else mempty outputConstraints = - [ OutputConstraint{ocDatum = stateData newState, ocValue = stateValue newState <> SM.threadTokenValueOrZero scInstance } + [ OutputConstraint + { ocDatum = stateData newState + -- Add the thread token value back to the output + , ocValue = stateValue newState <> SM.threadTokenValueOrZero scInstance + } | not isFinal ] in pure $ Right diff --git a/plutus-contract/src/Plutus/Contract/StateMachine/OnChain.hs b/plutus-contract/src/Plutus/Contract/StateMachine/OnChain.hs index 9348c5a14cf..030548d6383 100644 --- a/plutus-contract/src/Plutus/Contract/StateMachine/OnChain.hs +++ b/plutus-contract/src/Plutus/Contract/StateMachine/OnChain.hs @@ -115,7 +115,11 @@ mkValidator (StateMachine step isFinal check threadToken) currentState input ptx checkOk = traceIfFalse "State transition invalid - checks failed" (check currentState input ptx) && traceIfFalse "Thread token not found" (TT.checkThreadToken threadToken (ownHash ptx) vl 1) - oldState = State{stateData=currentState, stateValue=vl} + oldState = State + { stateData = currentState + -- The thread token value is hidden from the client code + , stateValue = vl <> inv (threadTokenValueInner threadToken (ownHash ptx)) + } stateAndOutputsOk = case step oldState input of Just (newConstraints, State{stateData=newData, stateValue=newValue}) | isFinal newData -> @@ -127,6 +131,7 @@ mkValidator (StateMachine step isFinal check threadToken) currentState input ptx { txOwnOutputs= [ OutputConstraint { ocDatum = newData + -- Check that the thread token value is still there , ocValue = newValue <> threadTokenValueInner threadToken (ownHash ptx) } ] diff --git a/plutus-contract/test/Spec.hs b/plutus-contract/test/Spec.hs index f3a401a4a23..e9f78a0b0e6 100644 --- a/plutus-contract/test/Spec.hs +++ b/plutus-contract/test/Spec.hs @@ -5,6 +5,7 @@ import qualified Spec.Contract import qualified Spec.Emulator import qualified Spec.Rows import qualified Spec.State +import qualified Spec.ThreadToken import Test.Tasty main :: IO () @@ -15,5 +16,6 @@ tests = testGroup "plutus-contract" [ Spec.Contract.tests, Spec.Emulator.tests, Spec.State.tests, - Spec.Rows.tests + Spec.Rows.tests, + Spec.ThreadToken.tests ] diff --git a/plutus-contract/test/Spec/ThreadToken.hs b/plutus-contract/test/Spec/ThreadToken.hs new file mode 100644 index 00000000000..9003fbcd989 --- /dev/null +++ b/plutus-contract/test/Spec/ThreadToken.hs @@ -0,0 +1,98 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeApplications #-} + +-- | Reduced example of the SM contract to reproduce the token handling in and around 'runStep'. +module Spec.ThreadToken where + +import PlutusTx.Prelude hiding (Eq) +import Prelude (Show, String, show) + +import Control.Monad (void) +import GHC.Generics (Generic) +import Ledger.Typed.Scripts (TypedValidator, mkTypedValidator) +import qualified Ledger.Typed.Scripts as Scripts +import Plutus.Contract (Contract, EmptySchema, logError, mapError) +import Plutus.Contract.StateMachine (StateMachine, StateMachineClient, ThreadToken, mkStateMachine, stateData) +import qualified Plutus.Contract.StateMachine as SM +import Plutus.Contract.Test +import Plutus.Trace (EmulatorTrace, activateContractWallet) +import qualified Plutus.Trace as Trace +import qualified PlutusTx + +import Test.Tasty + +-- * Very simple plutus state machine using a thread token + +data State + = First + | Second + deriving (Generic, Show) + +PlutusTx.makeLift ''State +PlutusTx.unstableMakeIsData ''State + +data Input + = Step + deriving (Generic, Show) +PlutusTx.makeLift ''Input +PlutusTx.unstableMakeIsData ''Input + +{-# INLINEABLE transition #-} +transition :: SM.State State -> Input -> Maybe (SM.TxConstraints SM.Void SM.Void, SM.State State) +transition oldState _ = Just (mempty, oldState{stateData = Second}) + +{-# INLINEABLE stateMachine #-} +stateMachine :: ThreadToken -> StateMachine State Input +stateMachine threadToken = + mkStateMachine (Just threadToken) transition isFinal + where + isFinal = const False + +typedValidator :: ThreadToken -> TypedValidator (StateMachine State Input) +typedValidator threadToken = + mkTypedValidator @(StateMachine State Input) + ($$(PlutusTx.compile [||validator||]) `PlutusTx.applyCode` PlutusTx.liftCode threadToken) + $$(PlutusTx.compile [||wrap||]) + where + validator c = SM.mkValidator (stateMachine c) + wrap = Scripts.wrapValidator @State @Input + +stateMachineClient :: ThreadToken -> StateMachineClient State Input +stateMachineClient threadToken = + let machine = stateMachine threadToken + inst = typedValidator threadToken + in SM.mkStateMachineClient (SM.StateMachineInstance machine inst) +-- * Minimal test runner for repro + +contract :: Contract () EmptySchema String () +contract = do + threadToken <- mapSMError SM.getThreadToken + logError @String $ "Forged thread token: " <> show threadToken + + let client = stateMachineClient threadToken + void $ mapSMError $ SM.runInitialise client First mempty + logError @String $ "Initialized state machine" + + res <- mapSMError $ SM.runStep client Step + case res of + SM.TransitionFailure (SM.InvalidTransition os i) -> logError @String $ "Invalid transition: " <> show (os, i) + SM.TransitionSuccess s -> logError @String $ "Transition success: " <> show s + where + mapSMError = mapError (show @SM.SMContractError) + +testTrace :: EmulatorTrace () +testTrace = do + void $ activateContractWallet (Wallet 1) contract + void $ Trace.waitNSlots 10 + +tests :: TestTree +tests = testGroup "Thread Token" + [ checkPredicate "Runs successfully" + (assertDone contract (Trace.walletInstanceTag (Wallet 1)) (const True) "No errors" + .&&. assertNoFailedTransactions) + testTrace + ] diff --git a/plutus-use-cases/test/Spec/gameStateMachine.pir b/plutus-use-cases/test/Spec/gameStateMachine.pir index 1e1bc61d745..f0901c32ada 100644 --- a/plutus-use-cases/test/Spec/gameStateMachine.pir +++ b/plutus-use-cases/test/Spec/gameStateMachine.pir @@ -10290,7 +10290,31 @@ [ ww [ - [ { State s } w ] vl + [ { State s } w ] + [ + [ + [ + unionWith + addInteger + ] + vl + ] + [ + [ + fAdditiveGroupValue_cscale + (con + integer -1 + ) + ] + [ + [ + threadTokenValueInner + ww + ] + [ ownHash w ] + ] + ] + ] ] ] w diff --git a/plutus-use-cases/test/Spec/governance.pir b/plutus-use-cases/test/Spec/governance.pir index 0da37e9dcba..c4ac0ce0848 100644 --- a/plutus-use-cases/test/Spec/governance.pir +++ b/plutus-use-cases/test/Spec/governance.pir @@ -13309,6 +13309,225 @@ ) ) ) + (termbind + (strict) + (vardecl + fAdditiveGroupValue_cscale + (fun (con integer) (fun [[(lam k (type) (lam v (type) [List [[Tuple2 k] v]])) (con bytestring)] [[(lam k (type) (lam v (type) [List [[Tuple2 k] v]])) (con bytestring)] (con integer)]] [[(lam k (type) (lam v (type) [List [[Tuple2 k] v]])) (con bytestring)] [[(lam k (type) (lam v (type) [List [[Tuple2 k] v]])) (con bytestring)] (con integer)]])) + ) + (lam + i + (con integer) + (lam + ds + [[(lam k (type) (lam v (type) [List [[Tuple2 k] v]])) (con bytestring)] [[(lam k (type) (lam v (type) [List [[Tuple2 k] v]])) (con bytestring)] (con integer)]] + (let + (rec) + (termbind + (strict) + (vardecl + go + (fun [List [[Tuple2 (con bytestring)] [[(lam k (type) (lam v (type) [List [[Tuple2 k] v]])) (con bytestring)] (con integer)]]] [List [[Tuple2 (con bytestring)] [[(lam k (type) (lam v (type) [List [[Tuple2 k] v]])) (con bytestring)] (con integer)]]]) + ) + (lam + ds + [List [[Tuple2 (con bytestring)] [[(lam k (type) (lam v (type) [List [[Tuple2 k] v]])) (con bytestring)] (con integer)]]] + [ + [ + [ + { + [ + { + Nil_match + [[Tuple2 (con bytestring)] [[(lam k (type) (lam v (type) [List [[Tuple2 k] v]])) (con bytestring)] (con integer)]] + } + ds + ] + (fun Unit [List [[Tuple2 (con bytestring)] [[(lam k (type) (lam v (type) [List [[Tuple2 k] v]])) (con bytestring)] (con integer)]]]) + } + (lam + thunk + Unit + { + Nil + [[Tuple2 (con bytestring)] [[(lam k (type) (lam v (type) [List [[Tuple2 k] v]])) (con bytestring)] (con integer)]] + } + ) + ] + (lam + ds + [[Tuple2 (con bytestring)] [[(lam k (type) (lam v (type) [List [[Tuple2 k] v]])) (con bytestring)] (con integer)]] + (lam + xs + [List [[Tuple2 (con bytestring)] [[(lam k (type) (lam v (type) [List [[Tuple2 k] v]])) (con bytestring)] (con integer)]]] + (lam + thunk + Unit + [ + { + [ + { + { + Tuple2_match + (con bytestring) + } + [[(lam k (type) (lam v (type) [List [[Tuple2 k] v]])) (con bytestring)] (con integer)] + } + ds + ] + [List [[Tuple2 (con bytestring)] [[(lam k (type) (lam v (type) [List [[Tuple2 k] v]])) (con bytestring)] (con integer)]]] + } + (lam + c + (con bytestring) + (lam + i + [[(lam k (type) (lam v (type) [List [[Tuple2 k] v]])) (con bytestring)] (con integer)] + (let + (rec) + (termbind + (strict) + (vardecl + go + (fun [List [[Tuple2 (con bytestring)] (con integer)]] [List [[Tuple2 (con bytestring)] (con integer)]]) + ) + (lam + ds + [List [[Tuple2 (con bytestring)] (con integer)]] + [ + [ + [ + { + [ + { + Nil_match + [[Tuple2 (con bytestring)] (con integer)] + } + ds + ] + (fun Unit [List [[Tuple2 (con bytestring)] (con integer)]]) + } + (lam + thunk + Unit + { + Nil + [[Tuple2 (con bytestring)] (con integer)] + } + ) + ] + (lam + ds + [[Tuple2 (con bytestring)] (con integer)] + (lam + xs + [List [[Tuple2 (con bytestring)] (con integer)]] + (lam + thunk + Unit + [ + { + [ + { + { + Tuple2_match + (con bytestring) + } + (con integer) + } + ds + ] + [List [[Tuple2 (con bytestring)] (con integer)]] + } + (lam + c + (con bytestring) + (lam + i + (con integer) + [ + [ + { + Cons + [[Tuple2 (con bytestring)] (con integer)] + } + [ + [ + { + { + Tuple2 + (con bytestring) + } + (con integer) + } + c + ] + [ + [ + (builtin + multiplyInteger + ) + i + ] + i + ] + ] + ] + [ + go + xs + ] + ] + ) + ) + ] + ) + ) + ) + ] + Unit + ] + ) + ) + [ + [ + { + Cons + [[Tuple2 (con bytestring)] [[(lam k (type) (lam v (type) [List [[Tuple2 k] v]])) (con bytestring)] (con integer)]] + } + [ + [ + { + { + Tuple2 + (con bytestring) + } + [[(lam k (type) (lam v (type) [List [[Tuple2 k] v]])) (con bytestring)] (con integer)] + } + c + ] + [ go i ] + ] + ] + [ go xs ] + ] + ) + ) + ) + ] + ) + ) + ) + ] + Unit + ] + ) + ) + [ go ds ] + ) + ) + ) + ) (termbind (strict) (vardecl @@ -14014,7 +14233,34 @@ [ { State s } w ] - vl + [ + [ + [ + unionWith + addInteger + ] + vl + ] + [ + [ + fAdditiveGroupValue_cscale + (con + integer + -1 + ) + ] + [ + [ + threadTokenValueInner + ww + ] + [ + ownHash + w + ] + ] + ] + ] ] ] w diff --git a/plutus-use-cases/test/Spec/multisigStateMachine.pir b/plutus-use-cases/test/Spec/multisigStateMachine.pir index 3cb8d9f6cb5..aba68c5ed06 100644 --- a/plutus-use-cases/test/Spec/multisigStateMachine.pir +++ b/plutus-use-cases/test/Spec/multisigStateMachine.pir @@ -11254,7 +11254,31 @@ [ ww [ - [ { State s } w ] vl + [ { State s } w ] + [ + [ + [ + unionWith + addInteger + ] + vl + ] + [ + [ + fAdditiveGroupValue_cscale + (con + integer -1 + ) + ] + [ + [ + threadTokenValueInner + ww + ] + [ ownHash w ] + ] + ] + ] ] ] w diff --git a/plutus-use-cases/test/Spec/renderGuess.txt b/plutus-use-cases/test/Spec/renderGuess.txt index 44d841fe3b2..f20e50a2f9c 100644 --- a/plutus-use-cases/test/Spec/renderGuess.txt +++ b/plutus-use-cases/test/Spec/renderGuess.txt @@ -101,11 +101,11 @@ Balances Carried Forward: Ada: Lovelace: 100000000 ==== Slot #1, Tx #0 ==== -TxId: 0ca3f41c3b91e289db67f0138392d25b72b288c74e7b610dd806195377a67357 +TxId: ef534dc4e569338abf987f63aba13741a1288f064cb36ed252000c65a9a08050 Fee: Ada: Lovelace: 10 Mint: - Signatures PubKey: d75a980182b10ab7d54bfed3c964073a0ee172f3... - Signature: 584019b3c789578619a3d52987b7c5096232b7e6... + Signature: 5840329c846018b835d4561c7a5ef1a624701fe7... Inputs: ---- Input 0 ---- Destination: PubKeyHash: 35dedd2982a03cf39e7dce03c839994ffdec2ec6... (Wallet 1) @@ -124,7 +124,7 @@ Outputs: Ada: Lovelace: 99999982 ---- Output 1 ---- - Destination: Script: eb7796ad89166e4ab0609bf888884add7afe686627a9164c1d592deb + Destination: Script: 90f63a2b24cff4164e3be17fc7025bf697524be03e26dec3db407f51 Value: Ada: Lovelace: 8 @@ -170,51 +170,51 @@ Balances Carried Forward: Value: Ada: Lovelace: 100000000 - Script: eb7796ad89166e4ab0609bf888884add7afe686627a9164c1d592deb + Script: 90f63a2b24cff4164e3be17fc7025bf697524be03e26dec3db407f51 Value: Ada: Lovelace: 8 ==== Slot #2, Tx #0 ==== -TxId: 3add3e5c66f46db1208215b2f69196feb752aa0532a7560b45bc6c46710566fb -Fee: Ada: Lovelace: 15131 -Mint: 649bab82fd01224574f2b80618e9c0dd8094dd9d2e8a24e7bddc0c07: guess: 1 +TxId: 67909a81653821c034d28eac1025c78e7d2bf3e47ca5879888f2b6981b272098 +Fee: Ada: Lovelace: 15151 +Mint: ba38019d8b9d17ad351b9a3145370a55767cbf338242336ef019e32b: guess: 1 Signatures PubKey: d75a980182b10ab7d54bfed3c964073a0ee172f3... - Signature: 584028e26394a09b641a1b91424dc0280e9e598c... + Signature: 584092dd3e1677a93726deb79011d7bf8221adb2... Inputs: ---- Input 0 ---- Destination: PubKeyHash: 35dedd2982a03cf39e7dce03c839994ffdec2ec6... (Wallet 1) Value: Ada: Lovelace: 99999982 Source: - Tx: 0ca3f41c3b91e289db67f0138392d25b72b288c74e7b610dd806195377a67357 + Tx: ef534dc4e569338abf987f63aba13741a1288f064cb36ed252000c65a9a08050 Output #0 ---- Input 1 ---- - Destination: Script: eb7796ad89166e4ab0609bf888884add7afe686627a9164c1d592deb + Destination: Script: 90f63a2b24cff4164e3be17fc7025bf697524be03e26dec3db407f51 Value: Ada: Lovelace: 8 Source: - Tx: 0ca3f41c3b91e289db67f0138392d25b72b288c74e7b610dd806195377a67357 + Tx: ef534dc4e569338abf987f63aba13741a1288f064cb36ed252000c65a9a08050 Output #1 - Script: 5927660100003323322333222333222323322323... + Script: 59277a0100003323322333222333222323322323... Outputs: ---- Output 0 ---- Destination: PubKeyHash: 35dedd2982a03cf39e7dce03c839994ffdec2ec6... (Wallet 1) Value: - Ada: Lovelace: 99984851 - 649bab82fd01224574f2b80618e9c0dd8094dd9d2e8a24e7bddc0c07: - + Ada: Lovelace: 99984831 + ba38019d8b9d17ad351b9a3145370a55767cbf338242336ef019e32b: - ---- Output 1 ---- Destination: PubKeyHash: 35dedd2982a03cf39e7dce03c839994ffdec2ec6... (Wallet 1) Value: - 649bab82fd01224574f2b80618e9c0dd8094dd9d2e8a24e7bddc0c07: guess: 1 + ba38019d8b9d17ad351b9a3145370a55767cbf338242336ef019e32b: guess: 1 Ada: - ---- Output 2 ---- - Destination: Script: eb7796ad89166e4ab0609bf888884add7afe686627a9164c1d592deb + Destination: Script: 90f63a2b24cff4164e3be17fc7025bf697524be03e26dec3db407f51 Value: Ada: Lovelace: 8 @@ -222,8 +222,8 @@ Outputs: Balances Carried Forward: PubKeyHash: 35dedd2982a03cf39e7dce03c839994ffdec2ec6... (Wallet 1) Value: - Ada: Lovelace: 99984851 - 649bab82fd01224574f2b80618e9c0dd8094dd9d2e8a24e7bddc0c07: guess: 1 + Ada: Lovelace: 99984831 + ba38019d8b9d17ad351b9a3145370a55767cbf338242336ef019e32b: guess: 1 PubKeyHash: 3c88c96ed5ab14b16a32771bcfcb49928a5557fc... (Wallet 10) Value: @@ -261,34 +261,34 @@ Balances Carried Forward: Value: Ada: Lovelace: 100000000 - Script: eb7796ad89166e4ab0609bf888884add7afe686627a9164c1d592deb + Script: 90f63a2b24cff4164e3be17fc7025bf697524be03e26dec3db407f51 Value: Ada: Lovelace: 8 ==== Slot #3, Tx #0 ==== -TxId: 3fc15d5d6d9cc38ccf7bda153c4a546eb0c0dcd3f1e95dd16b5c6213c3e84bf8 +TxId: 732636905d23d96d6fd8f48f0aea2fab1bb479d7a4ea59d1673e298aa3d23feb Fee: Ada: Lovelace: 10 Mint: - Signatures PubKey: d75a980182b10ab7d54bfed3c964073a0ee172f3... - Signature: 58400a58e543ee1ac7afcee8adee3cfa9be7aa17... + Signature: 58407b4ceeb3ad5e7b23ec1886cac105b4d70de8... Inputs: ---- Input 0 ---- Destination: PubKeyHash: 35dedd2982a03cf39e7dce03c839994ffdec2ec6... (Wallet 1) Value: - Ada: Lovelace: 99984851 - 649bab82fd01224574f2b80618e9c0dd8094dd9d2e8a24e7bddc0c07: - + Ada: Lovelace: 99984831 + ba38019d8b9d17ad351b9a3145370a55767cbf338242336ef019e32b: - Source: - Tx: 3add3e5c66f46db1208215b2f69196feb752aa0532a7560b45bc6c46710566fb + Tx: 67909a81653821c034d28eac1025c78e7d2bf3e47ca5879888f2b6981b272098 Output #0 ---- Input 1 ---- Destination: PubKeyHash: 35dedd2982a03cf39e7dce03c839994ffdec2ec6... (Wallet 1) Value: - 649bab82fd01224574f2b80618e9c0dd8094dd9d2e8a24e7bddc0c07: guess: 1 + ba38019d8b9d17ad351b9a3145370a55767cbf338242336ef019e32b: guess: 1 Ada: - Source: - Tx: 3add3e5c66f46db1208215b2f69196feb752aa0532a7560b45bc6c46710566fb + Tx: 67909a81653821c034d28eac1025c78e7d2bf3e47ca5879888f2b6981b272098 Output #1 @@ -297,20 +297,20 @@ Outputs: ---- Output 0 ---- Destination: PubKeyHash: 35dedd2982a03cf39e7dce03c839994ffdec2ec6... (Wallet 1) Value: - Ada: Lovelace: 99984841 - 649bab82fd01224574f2b80618e9c0dd8094dd9d2e8a24e7bddc0c07: guess: 0 + Ada: Lovelace: 99984821 + ba38019d8b9d17ad351b9a3145370a55767cbf338242336ef019e32b: guess: 0 ---- Output 1 ---- Destination: PubKeyHash: 977efb35ab621d39dbeb7274ec7795a34708ff4d... (Wallet 2) Value: - 649bab82fd01224574f2b80618e9c0dd8094dd9d2e8a24e7bddc0c07: guess: 1 + ba38019d8b9d17ad351b9a3145370a55767cbf338242336ef019e32b: guess: 1 Balances Carried Forward: PubKeyHash: 35dedd2982a03cf39e7dce03c839994ffdec2ec6... (Wallet 1) Value: - Ada: Lovelace: 99984841 - 649bab82fd01224574f2b80618e9c0dd8094dd9d2e8a24e7bddc0c07: guess: 0 + Ada: Lovelace: 99984821 + ba38019d8b9d17ad351b9a3145370a55767cbf338242336ef019e32b: guess: 0 PubKeyHash: 3c88c96ed5ab14b16a32771bcfcb49928a5557fc... (Wallet 10) Value: @@ -335,7 +335,7 @@ Balances Carried Forward: PubKeyHash: 977efb35ab621d39dbeb7274ec7795a34708ff4d... (Wallet 2) Value: Ada: Lovelace: 100000000 - 649bab82fd01224574f2b80618e9c0dd8094dd9d2e8a24e7bddc0c07: guess: 1 + ba38019d8b9d17ad351b9a3145370a55767cbf338242336ef019e32b: guess: 1 PubKeyHash: b1fd7c427a17e57c112473449d8b237484c5ebf6... (Wallet 7) Value: @@ -349,16 +349,16 @@ Balances Carried Forward: Value: Ada: Lovelace: 100000000 - Script: eb7796ad89166e4ab0609bf888884add7afe686627a9164c1d592deb + Script: 90f63a2b24cff4164e3be17fc7025bf697524be03e26dec3db407f51 Value: Ada: Lovelace: 8 ==== Slot #4, Tx #0 ==== -TxId: 3c4e25461a5bd63648758383f52f207bc8b2df77b66a1e4c3eb26d6882d48392 -Fee: Ada: Lovelace: 15131 -Mint: 649bab82fd01224574f2b80618e9c0dd8094dd9d2e8a24e7bddc0c07: guess: 0 +TxId: cfe96d0e5006f3243da02a81c56c2db75acd0e3900565ada21fbcd0664c99f68 +Fee: Ada: Lovelace: 15151 +Mint: ba38019d8b9d17ad351b9a3145370a55767cbf338242336ef019e32b: guess: 0 Signatures PubKey: 3d4017c3e843895a92b70aa74d1b7ebc9c982ccf... - Signature: 5840294b04b2d2427660ba2f5fe6dcb2aa12e9df... + Signature: 58405c7d00ac66190910294d5c45ddfd58b64554... Inputs: ---- Input 0 ---- Destination: PubKeyHash: 977efb35ab621d39dbeb7274ec7795a34708ff4d... (Wallet 2) @@ -370,20 +370,20 @@ Inputs: ---- Input 1 ---- - Destination: Script: eb7796ad89166e4ab0609bf888884add7afe686627a9164c1d592deb + Destination: Script: 90f63a2b24cff4164e3be17fc7025bf697524be03e26dec3db407f51 Value: Ada: Lovelace: 8 Source: - Tx: 3add3e5c66f46db1208215b2f69196feb752aa0532a7560b45bc6c46710566fb + Tx: 67909a81653821c034d28eac1025c78e7d2bf3e47ca5879888f2b6981b272098 Output #2 - Script: 5927660100003323322333222333222323322323... + Script: 59277a0100003323322333222333222323322323... ---- Input 2 ---- Destination: PubKeyHash: 977efb35ab621d39dbeb7274ec7795a34708ff4d... (Wallet 2) Value: - 649bab82fd01224574f2b80618e9c0dd8094dd9d2e8a24e7bddc0c07: guess: 1 + ba38019d8b9d17ad351b9a3145370a55767cbf338242336ef019e32b: guess: 1 Source: - Tx: 3fc15d5d6d9cc38ccf7bda153c4a546eb0c0dcd3f1e95dd16b5c6213c3e84bf8 + Tx: 732636905d23d96d6fd8f48f0aea2fab1bb479d7a4ea59d1673e298aa3d23feb Output #1 @@ -392,17 +392,17 @@ Outputs: ---- Output 0 ---- Destination: PubKeyHash: 977efb35ab621d39dbeb7274ec7795a34708ff4d... (Wallet 2) Value: - Ada: Lovelace: 99984872 - 649bab82fd01224574f2b80618e9c0dd8094dd9d2e8a24e7bddc0c07: guess: 0 + Ada: Lovelace: 99984852 + ba38019d8b9d17ad351b9a3145370a55767cbf338242336ef019e32b: guess: 0 ---- Output 1 ---- Destination: PubKeyHash: 977efb35ab621d39dbeb7274ec7795a34708ff4d... (Wallet 2) Value: - 649bab82fd01224574f2b80618e9c0dd8094dd9d2e8a24e7bddc0c07: guess: 1 + ba38019d8b9d17ad351b9a3145370a55767cbf338242336ef019e32b: guess: 1 Ada: - ---- Output 2 ---- - Destination: Script: eb7796ad89166e4ab0609bf888884add7afe686627a9164c1d592deb + Destination: Script: 90f63a2b24cff4164e3be17fc7025bf697524be03e26dec3db407f51 Value: Ada: Lovelace: 5 @@ -410,8 +410,8 @@ Outputs: Balances Carried Forward: PubKeyHash: 35dedd2982a03cf39e7dce03c839994ffdec2ec6... (Wallet 1) Value: - Ada: Lovelace: 99984841 - 649bab82fd01224574f2b80618e9c0dd8094dd9d2e8a24e7bddc0c07: guess: 0 + Ada: Lovelace: 99984821 + ba38019d8b9d17ad351b9a3145370a55767cbf338242336ef019e32b: guess: 0 PubKeyHash: 3c88c96ed5ab14b16a32771bcfcb49928a5557fc... (Wallet 10) Value: @@ -435,8 +435,8 @@ Balances Carried Forward: PubKeyHash: 977efb35ab621d39dbeb7274ec7795a34708ff4d... (Wallet 2) Value: - Ada: Lovelace: 99984872 - 649bab82fd01224574f2b80618e9c0dd8094dd9d2e8a24e7bddc0c07: guess: 1 + Ada: Lovelace: 99984852 + ba38019d8b9d17ad351b9a3145370a55767cbf338242336ef019e32b: guess: 1 PubKeyHash: b1fd7c427a17e57c112473449d8b237484c5ebf6... (Wallet 7) Value: @@ -450,6 +450,6 @@ Balances Carried Forward: Value: Ada: Lovelace: 100000000 - Script: eb7796ad89166e4ab0609bf888884add7afe686627a9164c1d592deb + Script: 90f63a2b24cff4164e3be17fc7025bf697524be03e26dec3db407f51 Value: Ada: Lovelace: 5 \ No newline at end of file