mlabs-haskell / TuxedoDapp

Cryptokitties on Polkadot using UTXO
Apache License 2.0
2 stars 1 forks source link

FE-JS : Integration between Talisman Wallet and DApp #35

Open NadigerAmit opened 4 months ago

NadigerAmit commented 4 months ago

Please see this link for detailed analysis of Talisman : https://github.com/Off-Narrative-Labs/Tuxedo/issues/167

Please see the link here : https://github.com/TalismanSociety/talisman-connect/tree/master/packages/connect-wallets

NadigerAmit commented 4 months ago

Hi

Below is the link for blind signing in Talisman Connect:

(https://github.com/TalismanSociety/talisman/blob/2570f7367dd386bd16f5517d805e490b615f3f32/apps/playground/src/components/Substrate/sign/SignMessage.tsx#L51)

NadigerAmit commented 3 months ago

Spilt the current rest API in 2 steps

  1. Provide the transaction to FE i.e signing .
  2. Provide the rest API sending the signed transaction to Blockchain.
NadigerAmit commented 3 months ago

@AltiMario @Winni- ,

Please confirm below for Talisman Integration :

You need to implement the below logic in JA or TS with the help of Talisman wallet.

Step 1. JS app will request GET/ REST API to get the Transaction for any of the operations such as (listKityForSale,Delist*,BuyKitty,BrteedKitty,etc )

Step2: JS will get the transactions which is defined in the https://github.com/mlabs-haskell/Tuxedo/blob/d35d28a1cee7af47d26d56fca2833516bf4a2ffa/tuxedo-core/src/types.rs#L34-L46

Note: JS app need to refer to Tuxedo core in the code for referring to these structs. I am not sure if Js/Ts app can do it or not since the structures are defined in the Rust . Please check the feasiablity .

pub struct Transaction<V, C> {
    /// Existing pieces of state to be read and consumed from storage
    pub inputs: Vec<Input>,
    /// Existing state to be read, but not consumed, from storage
    pub peeks: Vec<OutputRef>,
    /// New state to be placed into storage
    pub outputs: Vec<Output<V>>,
    /// Which piece of constraint checking logic is used to determine whether this transaction is valid
    pub checker: C,
}

Step3 :Input Preparation:: Clone the transaction object received in step 2 to create a copy. Encode the cloned transaction object to get its stripped encoded version. Lets call this as stripped_encoded_transaction See the details of Transaction encoding : https://off-narrative-labs.github.io/Tuxedo/tuxedo_core/types/struct.Transaction.html

Step4 :Construct Redeemer:

Depending on the type of verifier associated with the output UTXO , you'll need to construct a redeemer. If the verifier is of type OuterVerifier::Sr25519Signature, you'll need to sign the stripped_encoded_transaction using the Talisman wallet. You should leverage the Talisman wallet to sign the transaction data. I think this involves creating a cryptographic signature using the private key associated with the public key stored in the output.

If the verifier is of type OuterVerifier::UpForGrabs, no action is needed as it doesn't require a specific redeemer.

If the verifier is of type OuterVerifier::ThresholdMultiSignature, you'll need to handle this case according to your application logic. Note : Currently only OuterVerifier::Sr25519Signature is used with respect to kitty and money.

FYI Input structure below :

/// A reference the a utxo that will be consumed along with proof that it may be consumed
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
pub struct Input {
    /// a reference to the output being consumed
    pub output_ref: OutputRef,
    // Eg the signature
    pub redeemer: Vec<u8>,
}

Step 5: Add Redeemer to Input:

Once you've constructed the redeemer, you need to add it to the corresponding input. redeemer is nothing but the signature obtained in step 4.

Step 6: Repeat for Each Input: Repeat the above steps for each input in the transaction.

Step 7: After signing and adding the redeemer , Send the signed transaction to webserver operation.

JFYI Below is the code which is implemented in the rust , which need to be done exactly same in JS code with help of Talisman wallet.

image

NadigerAmit commented 3 months ago

How to create the redeemer: Redeemer is required only in case of UTXO-based transactions and since Tuxedo is UTXO-based they are using the Redeemer for each input as prof that UTXO belongs to the user who has signed it. It will be used within the blockchain core to verify the authenticity of the ownership of resource.

. Input is for redeemer : Input1:
Clone/Copy the unsigned Transactionobject received .
Encode the above cloned Transactionobject to get its stripped encoded version. Let's call this as stripped_encoded_transaction

Input2:: Utxo.verifier for each input in the Transaction objects. utxo.verifier: This variable represents the type of verifier associated with the output being consumed. It's of type OuterVerifier which is defined in the Tuxedo core. Depending on the type of OuterVerifier, the redeemer creation logic varies: If OuterVerifier is Sr25519Signature, it expects a Sr25519Signature structure containing owner_pubkey. If OuterVerifier is UpForGrabs, no specific input is required.It is free. If OuterVerifier is ThresholdMultiSignature, multiple signatures are required. Now you can ignore this as it is not used in the current code.

Expected Output: The redeemer is expected to be a Vec, which represents the proof that the input can be consumed. The content of the redeemer varies depending on the type of OuterVerifier: If OuterVerifier is Sr25519Signature, the redeemer is created by signing stripped_encoded_transaction instance using the private key and public key derived from owner_pubkey.

algorithm to create the redeemer based on the code is :

  1. Clone/Copy the unsigned Transactionobject received and encode it. and call it as stripped_encoded_transaction
  2. Extract the public key from the owner_pubkey field of the Sr25519Signature structure.
  3. Sign Transaction: Sign the stripped_encoded_transaction data using the private key associated with the extracted public key.
  4. Creating Redeemer: Encode the signature obtained from the signing process into a byte array (Vec), which serves as the redeemer.
NadigerAmit commented 3 months ago

Below is the Example sequence dig for list-kitty-for-sale transaction

TransactionFlow-withTalisman

NadigerAmit commented 3 months ago

Below is my testing result ;

  1. Create the kitty : curl -X POST -H "Content-Type: application/json" -d '{"name": "amit","owner_public_key":"d2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67"}' http://localhost:3000/create-kitty

Test result

amit@DESKTOP-TF687VE:/tmp/tuxedo-wallet$ curl -X POST -H "Content-Type: application/json" -d '{"name": "amit","owner_public_key":"d2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67"}' http://localhost:3000/create-kitty
{"message":"Kitty created successfully","kitty":{"parent":{"Mom":"RearinToGo"},"free_breedings":2,"dna":"0x7ea2b1a369895189984f11d392c0ac390e3209978c854c19e0b7aa6aaf44d2f6","num_breedings":3,"name":[97,109,105,116]}}
  1. Get the Transaction and inpututxo list : Curl command : curl -X GET -H "Content-Type: application/json" -H "kitty-name: amit" -H "kitty-price: 100" -H "owner_public_key: d2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67" http://localhost:3000/get-txn-and-inpututxolist-for-listkitty-forsale

Test results ;

amit@DESKTOP-TF687VE:/tmp/tuxedo-wallet$ curl -X GET -H "Content-Type: application/json" -H "kitty-name: amit" -H "kitty-price: 100" -H "owner_public_key: d2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67" http://localhost:3000/get-txn-and-inpututxolist-for-listkitty-forsale
{"message":"Kitty listed for sale successfully","transaction":{"inputs":[{"output_ref":{"tx_hash":"0xb8edce97d1175407251cb770af8ed4e74afe03d1f5196723ff8dd3244fde8216","index":0},"redeemer":[]}],"peeks":[],"outputs":[{"payload":{"data":[0,0,2,0,0,0,0,0,0,0,126,162,177,163,105,137,81,137,152,79,17,211,146,192,172,57,14,50,9,151,140,133,76,25,224,183,170,106,175,68,210,246,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,109,105,116,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"type_id":[116,100,107,116]},"verifier":{"Sr25519Signature":{"owner_pubkey":"0xd2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67"}}}],"checker":{"TradableKitty":"ListKittiesForSale"}},"input_utxo_list":[{"payload":{"data":[0,0,2,0,0,0,0,0,0,0,126,162,177,163,105,137,81,137,152,79,17,211,146,192,172,57,14,50,9,151,140,133,76,25,224,183,170,106,175,68,210,246,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,109,105,116],"type_id":[75,105,116,116]},"verifier":{"Sr25519Signature":{"owner_pubkey":"0xd2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67"}}}]}

Now follow the redeemer creation algorithm: Please see this https://github.com/mlabs-haskell/TuxedoDapp/issues/35#issuecomment-2015171702

  1. Send the signed transaction to Blockchain via webserver using below post REST API

Below is the curl command : Please note the redeemer is added to below for each inputs:

curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "signed_transaction": {
      "inputs": [
        {
          "output_ref": {
            "tx_hash": "0x87f523f282d756034c394d48af33b3237bbdf119d9a71807dadf1f10b45bc41d",
            "index": 0
          },
          "redeemer": [
            246,122,39,210,41,196,61,160,188,241,189,117,234,107,94,18,145,189,241,154,92,104,221,171,184,8,83,224,22,3,236,26,86,86,181,226,164,154,132,4,156,205,199,5,148,215,17,177,63,62,228,218,243,171,229,153,167,162,254,14,6,247,31,140
          ]
        }
      ],
      "peeks": [],
      "outputs": [
        {
          "payload": {
            "data": [
              1,0,2,0,0,0,0,0,0,0,86,157,216,52,66,246,237,71,48,132,154,23,14,7,58,192,28,198,29,218,252,173,67,169,138,249,210,103,246,178,134,32,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,109,105,116,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
            ],
            "type_id": [116,100,107,116]
          },
          "verifier": {
            "Sr25519Signature": {
              "owner_pubkey": "0xd2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67"
            }
          }
        }
      ],
      "checker": {
        "TradableKitty": "ListKittiesForSale"
      }
    }
  }' \
  http://localhost:3000/listkitty-for-sale

Below is the test result:

{"message":"Kitty listed for sale successfully","td_kitty":{"kitty_basic_data":{"parent":{"Dad":"RearinToGo"},"free_breedings":2,"dna":"0x569dd83442f6ed4730849a170e073ac01cc61ddafcad43a98af9d267f6b28620","num_breedings":3,"name":[97,109,105,116]},"price":100}}
amit@DESKTOP-TF687VE:/tmp/tuxedo-wallet$
NadigerAmit commented 3 months ago

Note the difference between signed and unsigned transactions is just redeemer in the input:

The unsigned Transaction looks like the below ;

curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "signed_transaction": {
      "inputs": [
        {
          "output_ref": {
            "tx_hash": "0x87f523f282d756034c394d48af33b3237bbdf119d9a71807dadf1f10b45bc41d",
            "index": 0
          },
          "redeemer": []
        }
      ],
      "peeks": [],
      "outputs": [
        {
          "payload": {
            "data": [
              1,0,2,0,0,0,0,0,0,0,86,157,216,52,66,246,237,71,48,132,154,23,14,7,58,192,28,198,29,218,252,173,67,169,138,249,210,103,246,178,134,32,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,109,105,116,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"type_id":[116,100,107,116]
          },
          "verifier": {
            "Sr25519Signature": {
              "owner_pubkey": "0xd2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67"
            }
          }
        }
      ],
      "checker": {
        "TradableKitty": "ListKittiesForSale"
      }
    }
  }' \
  http://localhost:3000/listkitty-for-sale

The signed transaction looks like below ;

curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "signed_transaction": {
      "inputs": [
        {
          "output_ref": {
            "tx_hash": "0x87f523f282d756034c394d48af33b3237bbdf119d9a71807dadf1f10b45bc41d",
            "index": 0
          },
          "redeemer": [
            246,122,39,210,41,196,61,160,188,241,189,117,234,107,94,18,145,189,241,154,92,104,221,171,184,8,83,224,22,3,236,26,86,86,181,226,164,154,132,4,156,205,199,5,148,215,17,177,63,62,228,218,243,171,229,153,167,162,254,14,6,247,31,140
          ]
        }
      ],
      "peeks": [],
      "outputs": [
        {
          "payload": {
            "data": [
              1,0,2,0,0,0,0,0,0,0,86,157,216,52,66,246,237,71,48,132,154,23,14,7,58,192,28,198,29,218,252,173,67,169,138,249,210,103,246,178,134,32,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,109,105,116,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
            ],
            "type_id": [116,100,107,116]
          },
          "verifier": {
            "Sr25519Signature": {
              "owner_pubkey": "0xd2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67"
            }
          }
        }
      ],
      "checker": {
        "TradableKitty": "ListKittiesForSale"
      }
    }
  }' \
  http://localhost:3000/listkitty-for-sale

If I send the unsigned transaction to blockchain for list-kitty I will get the below kind of error

2024-03-26 12:27:17.094  INFO tokio-runtime-worker tuxedo_template_runtime: runtime-> validate_transaction
            TransactionSource = TransactionSource::External
            tx = Transaction { inputs: [Input { output_ref: OutputRef { tx_hash: 0x87f523f282d756034c394d48af33b3237bbdf119d9a71807dadf1f10b45bc41d, index: 0 }, redeemer: [] }], peeks: [], outputs: [Output { payload: DynamicallyTypedData { data: [1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 86, 157, 216, 52, 66, 246, 237, 71, 48, 132, 154, 23, 14, 7, 58, 192, 28, 198, 29, 218, 252, 173, 67, 169, 138, 249, 210, 103, 246, 178, 134, 32, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 109, 105, 116, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], type_id: [116, 100, 107, 116] }, verifier: Sr25519Signature(Sr25519Signature { owner_pubkey: 0xd2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67 }) }], checker: TradableKitty(ListKittiesForSale) }
            block_hash = 0x73241ee9114673ca3c4a12b214cce4c0665a6ae47fc0230b412e6e5f18daaaac
2024-03-26 12:27:17.094  INFO tokio-runtime-worker tuxedo-core: validating tuxedo transaction
2024-03-26 12:27:17.094  INFO tokio-runtime-worker tuxedo-core: input_set.len() 1 and transaction.inputs.len()  1
2024-03-26 12:27:17.094  WARN tokio-runtime-worker tuxedo-core: Tuxedo Transaction did not validate (in the pool): VerifierError
2024-03-26 12:27:17.094  INFO tokio-runtime-worker tuxedo-core: Validation result: **Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(0)))**
NadigerAmit commented 2 months ago

I think we cant decode the signature in the Tuxedo core source code also . Please see the below explanation.

The actual verification of redeemer is done by sp_io::crypto::sr25519_verify() i.e https://crates.parity.io/sp_io/crypto/fn.sr25519_verify.html

The code in Tuxedo core is below where redeemer is sent to sp_io::crypto::sr25519_verify() in below : https://github.com/mlabs-haskell/Tuxedo/blob/636f473e8b2afcaa52772f3d3f59d6f32ade8bbc/tuxedo-core/src/verifier.rs#L40-L49

Testing details of today: Below is my test env:

  1. I used the Rust's local key store in CLI-wallet to generate the redeemer :

Below are the logs from curl command :

amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$
amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$ curl -X POST -H "Content-Type: application/json" -d '{"name": "amit","owner_public_key":"d2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67"}' http://localhost:3000/post-create-kitty
{"message":"Kitty created successfully","kitty":{"parent":{"Mom":"RearinToGo"},"free_breedings":2,"dna":"0x7773c7312ad561c5c3cc45e5a85ccebc85fa6847a4ba22d76f0f783d8f472237","num_breedings":0,"name":[97,109,105,116]}}amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$

---------------  Kitty created ---------------
amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$
amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$
amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$  curl -X GET -H "Content-Type: application/json"  http://localhost:3000/get-all-kitty-list
{"message":"Success: Found Kitties","owner_kitty_list":[{"owner_pub_key":"0xd2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67","kitty":{"parent":{"Mom":"RearinToGo"},"free_breedings":2,"dna":"0x7773c7312ad561c5c3cc45e5a85ccebc85fa6847a4ba22d76f0f783d8f472237","num_breedings":0,"name":[97,109,105,116]}}]}amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$
amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$
amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$
---------------  Kitty Retrived from sled db ---------------

amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$ curl -X GET -H "Content-Type: application/json" -H "kitty-dna: 7773c7312ad561c5c3cc45e5a85ccebc85fa6847a4ba22d76f0f783d8f472237" -H "kitty-price: 100" -H "owner_public_key: d2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67" http://localhost:3000/get-txn-and-inpututxolist-for-listkitty-forsale
{"message":"List kitty for Sale txn created successfully","transaction":{"inputs":[{"output_ref":{"tx_hash":"0xab4273dcff5c0685ff0aceeb6aeb96de9561c69a9dbfa602e1ede01e947b2b04","index":0},"redeemer":[]}],"peeks":[],"outputs":[{"payload":{"data":[0,0,2,0,0,0,0,0,0,0,119,115,199,49,42,213,97,197,195,204,69,229,168,92,206,188,133,250,104,71,164,186,34,215,111,15,120,61,143,71,34,55,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,109,105,116,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"type_id":[116,100,107,116]},"verifier":{"Sr25519Signature":{"owner_pubkey":"0xd2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67"}}}],"checker":{"TradableKitty":"ListKittiesForSale"}},"input_utxo_list":[{"payload":{"data":[0,0,2,0,0,0,0,0,0,0,119,115,199,49,42,213,97,197,195,204,69,229,168,92,206,188,133,250,104,71,164,186,34,215,111,15,120,61,143,71,34,55,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,109,105,116],"type_id":[75,105,116,116]},"verifier":{"Sr25519Signature":{"owner_pubkey":"0xd2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67"}}}]}amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$
amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$

---------------  Get  the unsigned transaction and UTXO list from the webservice ---------------

amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$
amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$
amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$ curl -X PUT \
"Conte>   -H "Content-Type: application/json" \
  -d '{>   -d '{
>     "signed_transaction": {"inputs":[{"output_ref":{"tx_hash":"0xab4273dcff5c0685ff0aceeb6aeb96de9561c69a9dbfa602e1ede01e947b2b04","index":0},"redeemer":[20, 180, 133, 20, 115, 253, 19, 253, 197, 147, 115, 107, 101, 7, 3, 254, 213, 32, 213, 21, 254, 209, 241, 85, 234, 21, 136, 118, 164, 170, 178, 70, 82, 17, 162, 37, 89, 59, 5, 64, 29, 175, 45, 184, 96, 61, 90, 113, 233, 112, 177, 150, 137, 127, 196, 228, 144, 3, 17, 79, 218, 180, 214, 133]}],"peeks":[],"outputs":[{"payload":{"data":[0,0,2,0,0,0,0,0,0,0,119,115,199,49,42,213,97,197,195,204,69,229,168,92,206,188,133,250,104,71,164,186,34,215,111,15,120,61,143,71,34,55,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,109,105,116,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"type_id":[116,100,107,116]},"verifier":{"Sr25519Signature":{"owner_pubkey":"0xd2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67"}}}],"checker":{"TradableKitty":"ListKittiesForSale"}},"input_utxo_list":[{"payload":{"data":[0,0,2,0,0,0,0,0,0,0,119,115,199,49,42,213,97,197,195,204,69,229,168,92,206,188,133,250,104,71,164,186,34,215,111,15,120,61,143,71,34,55,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,109,105,116],"type_id":[75,105,116,116]},"verifier":{"Sr25519Signature":{"owner_pubkey":"0xd2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67"}}}]}' \
p://loc>   http://localhost:3000/put-listkitty-for-sale

{"message":"Error listing forsale: Error sending transaction: Call(Custom(ErrorObject { code: ServerError(1010), message: \"Invalid Transaction\", data: Some(RawValue(\"Custom error: 0\")) }))","td_kitty":null}amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$
amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$
amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$
---------------  Sent the "put-listkitty-for-sale"  txn with wrong redeemer  txn failed with verifier error ---------------

amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$
amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$ curl -X PUT \
"Conte>   -H "Content-Type: application/json" \
>   -d '{
>     "signed_transaction": {"inputs":[{"output_ref":{"tx_hash":"0xab4273dcff5c0685ff0aceeb6aeb96de9561c69a9dbfa602e1ede01e947b2b04","index":0},"redeemer":[204, 180, 133, 20, 115, 253, 19, 253, 197, 147, 115, 107, 101, 7, 3, 254, 213, 32, 213, 21, 254, 209, 241, 85, 234, 21, 136, 118, 164, 170, 178, 70, 82, 17, 162, 37, 89, 59, 5, 64, 29, 175, 45, 184, 96, 61, 90, 113, 233, 112, 177, 150, 137, 127, 196, 228, 144, 3, 17, 79, 218, 180, 214, 133]}],"peeks":[],"outputs":[{"payload":{"data":[0,0,2,0,0,0,0,0,0,0,119,115,199,49,42,213,97,197,195,204,69,229,168,92,206,188,133,250,104,71,164,186,34,215,111,15,120,61,143,71,34,55,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,109,105,116,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"type_id":[116,100,107,116]},"verifier":{"Sr25519Signature":{"owner_pubkey":"0xd2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67"}}}],"checker":{"TradableKitty":"ListKittiesForSale"}},"input_utxo_list":[{"payload":{"data":[0,0,2,0,0,0,0,0,0,0,119,115,199,49,42,213,97,197,195,204,69,229,168,92,206,188,133,250,104,71,164,186,34,215,111,15,120,61,143,71,34,55,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,109,105,116],"type_id":[75,105,116,116]},"verifier":{"Sr25519Signature":{"owner_pubkey":"0xd2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67"}}}]}' \
tp://lo>   http://localhost:3000/put-listkitty-for-sale
{"message":"Kitty listed for sale successfully","td_kitty":{"kitty_basic_data":{"parent":{"Mom":"RearinToGo"},"free_breedings":2,"dna":"0x7773c7312ad561c5c3cc45e5a85ccebc85fa6847a4ba22d76f0f783d8f472237","num_breedings":0,"name":[97,109,105,116]},"price":100}}amit@DESKTOP-TF687VE:~/OmBlockchain/OmTest$

--------------- Sent the "put-listkitty-for-sale" txn with correct redeemer txn success --------------

Below are the logs from the blockchain

1. Wrong redeemer. Here you can see the verifier is i.e sp_io::crypto::sr25519_verify() is returning false.

---------------  Sent the "put-listkitty-for-sale"  txn with wrong redeemer---------------

2024-04-10 14:09:12.314  INFO tokio-runtime-worker substrate: šŸ’¤ Idle (0 peers), best: #140 (0xa6d8ā€¦1114), finalized #137 (0xe29cā€¦28c9), ā¬‡ 0 ā¬† 0

2024-04-10 14:09:13.243  INFO tokio-runtime-worker jsonrpsee_server::server: Accepting new connection 1/100
2024-04-10 14:09:13.243  INFO tokio-runtime-worker tuxedo_template_runtime: runtime-> validate_transaction
            TransactionSource = TransactionSource::External
            tx = Transaction { inputs: [Input { output_ref: OutputRef { tx_hash: 0xab4273dcff5c0685ff0aceeb6aeb96de9561c69a9dbfa602e1ede01e947b2b04, index: 0 }, redeemer: [20, 180, 133, 20, 115, 253, 19, 253, 197, 147, 115, 107, 101, 7, 3, 254, 213, 32, 213, 21, 254, 209, 241, 85, 234, 21, 136, 118, 164, 170, 178, 70, 82, 17, 162, 37, 89, 59, 5, 64, 29, 175, 45, 184, 96, 61, 90, 113, 233, 112, 177, 150, 137, 127, 196, 228, 144, 3, 17, 79, 218, 180, 214, 133] }], peeks: [], outputs: [Output { payload: DynamicallyTypedData { data: [0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 119, 115, 199, 49, 42, 213, 97, 197, 195, 204, 69, 229, 168, 92, 206, 188, 133, 250, 104, 71, 164, 186, 34, 215, 111, 15, 120, 61, 143, 71, 34, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 109, 105, 116, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], type_id: [116, 100, 107, 116] }, verifier: Sr25519Signature(Sr25519Signature { owner_pubkey: 0xd2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67 }) }], checker: TradableKitty(ListKittiesForSale) }
            block_hash = 0xa6d8520858e7fc1c27332425de4b8d49dd30ba29efa802d2436581b5e5a31114
2024-04-10 14:09:13.244  INFO tokio-runtime-worker tuxedo-core: validating tuxedo transaction
2024-04-10 14:09:13.244  INFO tokio-runtime-worker tuxedo-core: input_set.len() 1 and transaction.inputs.len()  1
2024-04-10 14:09:13.244  INFO tokio-runtime-worker tuxedo-core:  in Verfier simplified_tx: [125, 2, 4, 171, 66, 115, 220, 255, 92, 6, 133, 255, 10, 206, 235, 106, 235, 150, 222, 149, 97, 198, 154, 157, 191, 166, 2, 225, 237, 224, 30, 148, 123, 43, 4, 0, 0, 0, 0, 0, 0, 4, 57, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 119, 115, 199, 49, 42, 213, 97, 197, 195, 204, 69, 229, 168, 92, 206, 188, 133, 250, 104, 71, 164, 186, 34, 215, 111, 15, 120, 61, 143, 71, 34, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 109, 105, 116, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 100, 107, 116, 0, 210, 191, 75, 132, 77, 254, 253, 103, 114, 168, 132, 62, 102, 159, 148, 52, 8, 150, 106, 151, 126, 58, 226, 175, 29, 215, 142, 15, 85, 244, 223, 103, 2, 0]
2024-04-10 14:09:13.244  INFO tokio-runtime-worker tuxedo-core: Signature from redeemer:->
2024-04-10 14:09:13.244  INFO tokio-runtime-worker tuxedo-core: Owner pubkey: 0xd2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67
2024-04-10 14:09:13.244  INFO tokio-runtime-worker tuxedo-core: Owner pubkey converted from_h256:->
2024-04-10 14:09:13.244  INFO tokio-runtime-worker tuxedo-core: Verification result: false
2024-04-10 14:09:13.244  WARN tokio-runtime-worker tuxedo-core: Tuxedo Transaction did not validate (in the pool): VerifierError
2024-04-10 14:09:13.244  INFO tokio-runtime-worker tuxedo-core: Validation result: Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(0)))
2024-04-10 14:09:15.000  INFO tokio-runtime-worker sc_basic_authorship::basic_authorship: šŸ™Œ Starting consensus session on top of parent 0xa6d8520858e7fc1c27332425de4b8d49dd30ba29efa802d2436581b5e5a31114
2024-04-10 14:09:15.001  INFO tokio-runtime-worker tuxedo_template_runtime: runtime-> inherent_extrinsics
2024-04-10 14:09:15.001  INFO tokio-runtime-worker tuxedo_template_runtime: runtime-> apply_extrinsic Transaction { inputs: [], peeks: [OutputRef { tx_hash: 0x2ea416c1031b5f7c25c6e3336e739c8ba9fe945bf7d62528debb5ccdfbd7b6a6, index: 0 }], outputs: [Output { payload: DynamicallyTypedData { data: [56, 71, 41, 199, 142, 1, 0, 0, 141, 0, 0, 0], type_id: [116, 105, 109, 101] }, verifier: UpForGrabs(UpForGrabs) }], checker: SetTimestamp(SetTimestamp(PhantomData<tuxedo_template_runtime::Runtime>)) }
2024-04-10 14:09:15.001  INFO tokio-runtime-worker tuxedo-core: validating tuxedo transaction
2024-04-10 14:09:15.001  INFO tokio-runtime-worker tuxedo-core: input_set.len() 0 and transaction.inputs.len()  0
2024-04-10 14:09:15.002  INFO tokio-runtime-worker tuxedo_template_runtime: runtime-> finalize_block
2024-04-10 14:09:15.002  INFO tokio-runtime-worker sc_basic_authorship::basic_authorship: šŸŽ Prepared block for proposing at 141 (1 ms) [hash: 0xc52f4e6458d62669b2f7a197b165abf445129ec4640dca5ccadefdb132c38613; parent_hash: 0xa6d8ā€¦1114; extrinsics (1): [0x2e98ā€¦8920]
2024-04-10 14:09:15.005  INFO tokio-runtime-worker aura: šŸ”– Pre-sealed block for proposal at 141. Hash now 0x8d341650b429f0678832dd3453af5451dff74dff3a0a90f0a4b7150d61f8e292, previously 0xc52f4e6458d62669b2f7a197b165abf445129ec4640dca5ccadefdb132c38613.
2024-04-10 14:09:15.005  INFO tokio-runtime-worker substrate: āœØ Imported #141 (0x8d34ā€¦e292)

Below is the blockchain logs with correct redeemer : Here you can see the verifier is i.e sp_io::crypto::sr25519_verify() is returning TRUE.

2024-04-10 14:10:53.757  INFO tokio-runtime-worker jsonrpsee_server::server: Accepting new connection 1/100
2024-04-10 14:10:53.758  INFO tokio-runtime-worker tuxedo_template_runtime: runtime-> validate_transaction
            TransactionSource = TransactionSource::External
            tx = Transaction { inputs: [Input { output_ref: OutputRef { tx_hash: 0xab4273dcff5c0685ff0aceeb6aeb96de9561c69a9dbfa602e1ede01e947b2b04, index: 0 }, redeemer: [204, 180, 133, 20, 115, 253, 19, 253, 197, 147, 115, 107, 101, 7, 3, 254, 213, 32, 213, 21, 254, 209, 241, 85, 234, 21, 136, 118, 164, 170, 178, 70, 82, 17, 162, 37, 89, 59, 5, 64, 29, 175, 45, 184, 96, 61, 90, 113, 233, 112, 177, 150, 137, 127, 196, 228, 144, 3, 17, 79, 218, 180, 214, 133] }], peeks: [], outputs: [Output { payload: DynamicallyTypedData { data: [0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 119, 115, 199, 49, 42, 213, 97, 197, 195, 204, 69, 229, 168, 92, 206, 188, 133, 250, 104, 71, 164, 186, 34, 215, 111, 15, 120, 61, 143, 71, 34, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 109, 105, 116, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], type_id: [116, 100, 107, 116] }, verifier: Sr25519Signature(Sr25519Signature { owner_pubkey: 0xd2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67 }) }], checker: TradableKitty(ListKittiesForSale) }
            block_hash = 0x9d784b8cf17744400bd4f021573628db61edc2487b505e0cc3aa70eeed4b644a
2024-04-10 14:10:53.758  INFO tokio-runtime-worker tuxedo-core: validating tuxedo transaction
2024-04-10 14:10:53.758  INFO tokio-runtime-worker tuxedo-core: input_set.len() 1 and transaction.inputs.len()  1
2024-04-10 14:10:53.758  INFO tokio-runtime-worker tuxedo-core:  in Verfier simplified_tx: [125, 2, 4, 171, 66, 115, 220, 255, 92, 6, 133, 255, 10, 206, 235, 106, 235, 150, 222, 149, 97, 198, 154, 157, 191, 166, 2, 225, 237, 224, 30, 148, 123, 43, 4, 0, 0, 0, 0, 0, 0, 4, 57, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 119, 115, 199, 49, 42, 213, 97, 197, 195, 204, 69, 229, 168, 92, 206, 188, 133, 250, 104, 71, 164, 186, 34, 215, 111, 15, 120, 61, 143, 71, 34, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 109, 105, 116, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 100, 107, 116, 0, 210, 191, 75, 132, 77, 254, 253, 103, 114, 168, 132, 62, 102, 159, 148, 52, 8, 150, 106, 151, 126, 58, 226, 175, 29, 215, 142, 15, 85, 244, 223, 103, 2, 0]
2024-04-10 14:10:53.758  INFO tokio-runtime-worker tuxedo-core: Signature from redeemer:->
2024-04-10 14:10:53.758  INFO tokio-runtime-worker tuxedo-core: Owner pubkey: 0xd2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67
2024-04-10 14:10:53.758  INFO tokio-runtime-worker tuxedo-core: Owner pubkey converted from_h256:->
2024-04-10 14:10:53.759  INFO tokio-runtime-worker tuxedo-core: Verification result: true
2024-04-10 14:10:53.759  INFO tokio-runtime-worker tuxedo-core: Validation result: Ok(ValidTransaction { priority: 0, requires: [], provides: [[189, 73, 196, 252, 176, 84, 27, 163, 243, 19, 255, 219, 200, 61, 3, 209, 113, 105, 30, 11, 57, 99, 135, 143, 167, 184, 40, 166, 41, 85, 198, 223, 0, 0, 0, 0]], longevity: 18446744073709551615, propagate: true })
2024-04-10 14:10:54.002  INFO tokio-runtime-worker sc_basic_authorship::basic_authorship: šŸ™Œ Starting consensus session on top of parent 0x9d784b8cf17744400bd4f021573628db61edc2487b505e0cc3aa70eeed4b644a
2024-04-10 14:10:54.004  INFO tokio-runtime-worker tuxedo_template_runtime: runtime-> inherent_extrinsics
2024-04-10 14:10:54.005  INFO tokio-runtime-worker tuxedo_template_runtime: runtime-> apply_extrinsic Transaction { inputs: [], peeks: [OutputRef { tx_hash: 0x43f7a91380b4dbc5d6cbda1c91b4787bfc44fee03c0ff74da003ecfe96725135, index: 0 }], outputs: [Output { payload: DynamicallyTypedData { data: [241, 201, 42, 199, 142, 1, 0, 0, 174, 0, 0, 0], type_id: [116, 105, 109, 101] }, verifier: UpForGrabs(UpForGrabs) }], checker: SetTimestamp(SetTimestamp(PhantomData<tuxedo_template_runtime::Runtime>)) }
2024-04-10 14:10:54.005  INFO tokio-runtime-worker tuxedo-core: validating tuxedo transaction
2024-04-10 14:10:54.005  INFO tokio-runtime-worker tuxedo-core: input_set.len() 0 and transaction.inputs.len()  0
2024-04-10 14:10:54.006  INFO tokio-runtime-worker tuxedo_template_runtime: runtime-> apply_extrinsic Transaction { inputs: [Input { output_ref: OutputRef { tx_hash: 0xab4273dcff5c0685ff0aceeb6aeb96de9561c69a9dbfa602e1ede01e947b2b04, index: 0 }, redeemer: [204, 180, 133, 20, 115, 253, 19, 253, 197, 147, 115, 107, 101, 7, 3, 254, 213, 32, 213, 21, 254, 209, 241, 85, 234, 21, 136, 118, 164, 170, 178, 70, 82, 17, 162, 37, 89, 59, 5, 64, 29, 175, 45, 184, 96, 61, 90, 113, 233, 112, 177, 150, 137, 127, 196, 228, 144, 3, 17, 79, 218, 180, 214, 133] }], peeks: [], outputs: [Output { payload: DynamicallyTypedData { data: [0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 119, 115, 199, 49, 42, 213, 97, 197, 195, 204, 69, 229, 168, 92, 206, 188, 133, 250, 104, 71, 164, 186, 34, 215, 111, 15, 120, 61, 143, 71, 34, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 109, 105, 116, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], type_id: [116, 100, 107, 116] }, verifier: Sr25519Signature(Sr25519Signature { owner_pubkey: 0xd2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67 }) }], checker: TradableKitty(ListKittiesForSale) }
2024-04-10 14:10:54.007  INFO tokio-runtime-worker tuxedo-core: validating tuxedo transaction
2024-04-10 14:10:54.007  INFO tokio-runtime-worker tuxedo-core: input_set.len() 1 and transaction.inputs.len()  1
2024-04-10 14:10:54.007  INFO tokio-runtime-worker tuxedo-core:  in Verfier simplified_tx: [125, 2, 4, 171, 66, 115, 220, 255, 92, 6, 133, 255, 10, 206, 235, 106, 235, 150, 222, 149, 97, 198, 154, 157, 191, 166, 2, 225, 237, 224, 30, 148, 123, 43, 4, 0, 0, 0, 0, 0, 0, 4, 57, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 119, 115, 199, 49, 42, 213, 97, 197, 195, 204, 69, 229, 168, 92, 206, 188, 133, 250, 104, 71, 164, 186, 34, 215, 111, 15, 120, 61, 143, 71, 34, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 109, 105, 116, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 100, 107, 116, 0, 210, 191, 75, 132, 77, 254, 253, 103, 114, 168, 132, 62, 102, 159, 148, 52, 8, 150, 106, 151, 126, 58, 226, 175, 29, 215, 142, 15, 85, 244, 223, 103, 2, 0]
2024-04-10 14:10:54.007  INFO tokio-runtime-worker tuxedo-core: Signature from redeemer:->
2024-04-10 14:10:54.007  INFO tokio-runtime-worker tuxedo-core: Owner pubkey: 0xd2bf4b844dfefd6772a8843e669f943408966a977e3ae2af1dd78e0f55f4df67
2024-04-10 14:10:54.007  INFO tokio-runtime-worker tuxedo-core: Owner pubkey converted from_h256:->
2024-04-10 14:10:54.007  INFO tokio-runtime-worker tuxedo-core: Verification result: true
2024-04-10 14:10:54.008  INFO tokio-runtime-worker tuxedo_template_runtime: runtime-> finalize_block