Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smart contract transaction hash received is the same for distinct redeemers #371

Open
leobel opened this issue Oct 17, 2024 · 2 comments
Open

Comments

@leobel
Copy link

leobel commented Oct 17, 2024

Hi, I've noticed that for slightly changes in a redeemer, I've only testes with changing some digits in a json numeric property but could be something deeper, the resulting transaction hash received by Aiken is the same.

Lucid Evolution
@lucid-evolution/lucid = "v0.3.49"

Aiken

compiler = "v1.1.3"
plutus = "v3"
aiken-lang/stdlib = "v2.1.0"

Here is the smart contract:

validator foo {
  spend(
    _datum: Option<Data>,
    _redeemer: Data,
    _self_ref: OutputReference,
    self_tx: Transaction,
  ) {
    let Transaction { id, .. } = self_tx
    trace @"tx hash": id
    fail
  }

  else(_) {
    fail
  }
}

You can reproduce the issue with this code

import { Blockfrost, Data, Lucid, SpendingValidator, UTxO } from "@lucid-evolution/lucid";
import * as fs from 'fs';

const lucid = await Lucid(
    new Blockfrost(
        "https://cardano-preview.blockfrost.io/api/v0",
        "preview..." // your key here
    ),
    "Preview"
);

// Select your wallet here
const prvKey = fs.readFileSync('./src/me.sk').toString();
lucid.selectWallet.fromPrivateKey(prvKey);
const walletAddress = await lucid.wallet().address();
console.log('Wallet Address:', walletAddress);

// compiled code for the smart contract above
const spend: SpendingValidator = {
    type: "PlutusV3",
    script: "590358590355010100323232323232323225333002323232323253330073370e900118049baa001132323253300b3372c92109747820686173683a200037326664646464646002002444a6664666603200626464646464646601800400266e2922010128000025333016337100069007099b80483c80400c54ccc058cdc4001a410004266e00cdc0241002800690068b299980c800899b8a4881035b5d2900005133714911035b5f2000333300800133714911025d2900005223330090090023006001223330090090020013758602e0046eb4c054004c8cdd81ba83015001374e602c0026ea800c4c94ccc05c0044cdc52441027b7d00003133714911037b5f200032323300100100322533301a00110031533301a301c0011323330090093019001337149101023a2000333009009301a001004301b0011323330090093019001337149101023a2000333009009301a001300633003003301d002301b0013371491102207d000033756006264a66602e002266e29221025b5d00003133714911035b5f2000333300600133714911015d000032233300700700230040012233300700700200137580066e292201022c2000133005375a0040022646466e2922010268270000132333001001337006e3400920013371491101270000322253330153371000490000800899191919980300319b8000548004cdc599b80002533301833710004900a0a40c02903719b8b33700002a66603066e2000520141481805206e0043370c004901019b8300148080cdc70020011bae002222232330010010052253330170011005153330173019001133003301800100513300430180013300200230190012232330010010032253330103370e0029000099b8a488101300000315333010337100029000099b8a489012d003300200233702900000089980299b8400148050cdc599b803370a002900a240c00066002002444a66601a66e2400920001001133300300333708004900a19b8b3370066e14009201448180004c03cc040c040c040c040c040c040c040c040c040c040c040c034dd5003a450016300e300f002300d001300a37540022c60166018004601400260140046010002600a6ea8004526153300349011856616c696461746f722072657475726e65642066616c736500136565734ae7155ceaab9e5573eae855d12ba401"
};

const spendAddress = "addr_test1xpx8w9plfr5t8zusdg8flxs6jgcl5uzhxc7nsy76vg6zz46vwu2r7j8gkw9eq6swn7dp4y33lfc9wd3a8qfa5c35y9tsjkus62";

let spendRedeemer = Data.to(Data.fromJson({
    foo: 123
}));
// let spendRedeemer = "bf43666f6f187bff"; 

// let spendRedeemer = Data.to(Data.fromJson({
//     foo: 124
// }));
// let spendRedeemer = "bf43666f6f187cff"; 

console.log('Redeemer:', spendRedeemer);

const validTo = 1729163464873 + (20 * 60 * 60 * 1000); // 20 hour

const utxo: UTxO = {
    address: spendAddress,
    txHash: "a9d1ab3e1bd3d048a149b596c6270b8aca30cf37bc2024c6de143d04835958a9",
    outputIndex: 0,
    assets: { lovelace: BigInt(5_000_000) }
}

const tx = await lucid
    .newTx()
    .collectFrom([utxo], spendRedeemer)
    // consume script
    .attach.SpendingValidator(spend)
    
    .pay.ToAddress(
        walletAddress, 
        {
            lovelace: BigInt(1_000_000),
        }
    )
    .validTo(validTo)
    .complete();

You can try with redeemers:

let spendRedeemer = Data.to(Data.fromJson({
    foo: 123
}));

and

let spendRedeemer = Data.to(Data.fromJson({
    foo: 124
}));

Transaction hash will be the same: C5863C120096F9400EBDBFE2FF58F6FA3909E770D1D990AFDF28064946FFE78E

@zachyking
Copy link

Redeemer is not a part of transaction body but the witness set, and transaction hash is a transaction body hash. So if everything else in the tx is the same it's expected behavior.

@leobel
Copy link
Author

leobel commented Oct 31, 2024

Redeemer is not a part of transaction body but the witness set, and transaction hash is a transaction body hash. So if everything else in the tx is the same it's expected behavior.

script_data_hash is part of transaction body, so changes on the redeemer should be reflected on the transaction hash: https://github.com/IntersectMBO/cardano-ledger/blob/7358718500e9bf1adc78092bdcf90ee9c2231df7/eras/conway/impl/cddl-files/conway.cddl#L359

; This is a hash of data which may affect evaluation of a script.
;     This data consists of:
;       - The redeemers from the transaction_witness_set (the value of field 5).
;       - The datums from the transaction_witness_set (the value of field 4).
;       - The value in the costmdls map corresponding to the script's language
;         (in field 18 of protocol_param_update.)
;     (In the future it may contain additional protocol parameters.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants