@xhliu From my understanding of what you wrote I don't think this will scale....
If you are passing the previous transaction into the next transaction you're going to accumulate every single past token transaction since the issuance transaction in the ScriptSig.
To illustrate, here's the following chain of token transactions: Tx1 -> Tx2 -> Tx3 -> Tx4 -> Tx5 -> Tx6 ...:
Tx1 -> Issuance
Tx2 = (ScriptSig(Tx2PreImage, Tx1), ScriptPubKeyTx2)
Tx3 = (ScriptSig(Tx3PreImage, Tx2), ScriptPubKeyTx2)
= (ScriptSig(Tx3PreImage, (ScriptSig(Tx2PreImage, Tx1), ScriptPubKeyTx2)), ScriptPubKeyTx2)
Tx4 = (ScriptSig(Tx4PreImage, Tx3), ScriptPubKeyTx4)
= (ScriptSig(Tx4PreImage, (ScriptSig(Tx3PreImage, (ScriptSig(Tx2PreImage, Tx1), ScriptPubKeyTx2)), ScriptPubKeyTx2)), ScriptPubKeyTx4)
Tx5 = (ScriptSig(Tx5PreImage, Tx4), ScriptPubKeyTx5)
= (ScriptSig(T5PreImage, (ScriptSig(Tx4PreImage, (ScriptSig(Tx3PreImage, (ScriptSig(Tx2PreImage, Tx1), ScriptPubKeyTx2)), ScriptPubKeyTx2)), ScriptPubKeyTx4)), ScriptPubKeyTx5)
Tx6 = (ScriptSig(Tx6PreImage, Tx4), ScriptPubKeyTx6)
= (ScriptSig(Tx6PreImage, (ScriptSig(T5PreImage, (ScriptSig(Tx4PreImage, (ScriptSig(Tx3PreImage, (ScriptSig(Tx2PreImage, Tx1), ScriptPubKeyTx2)), ScriptPubKeyTx2)), ScriptPubKeyTx4)), ScriptPubKeyTx5)), ScriptPubKeyTx6)
.
.
.
Tx50 = (ScriptSig(Tx50PreImage, (ScriptSig(Tx49PreImage, (ScriptSig(Tx48PreImage, (ScriptSig(Tx47PreImage, (ScriptSig(Tx46PreImage, (ScriptSig(Tx45PreImage, (ScriptSig(Tx44PreImage, (ScriptSig(Tx43PreImage, (ScriptSig(Tx42PreImage, (ScriptSig(Tx41PreImage, (ScriptSig(Tx40PreImage, (ScriptSig(Tx39PreImage, (ScriptSig(Tx38PreImage, (ScriptSig(Tx37PreImage, (ScriptSig(Tx36PreImage, (ScriptSig(Tx35PreImage, (ScriptSig(Tx34PreImage, (ScriptSig(Tx33PreImage, (ScriptSig(Tx32PreImage, (ScriptSig(Tx31PreImage, (ScriptSig(Tx30PreImage, (ScriptSig(Tx29PreImage, (ScriptSig(Tx28PreImage, (ScriptSig(Tx27PreImage, (ScriptSig(Tx26PreImage, (ScriptSig(Tx25PreImage, (ScriptSig(Tx24PreImage, (ScriptSig(Tx23PreImage, (ScriptSig(Tx22PreImage, (ScriptSig(Tx21PreImage, (ScriptSig(Tx20PreImage, (ScriptSig(Tx19PreImage, (ScriptSig(Tx18PreImage, (ScriptSig(Tx17PreImage, (ScriptSig(Tx16PreImage, (ScriptSig(Tx15PreImage, (ScriptSig(Tx14PreImage, (ScriptSig(Tx13PreImage, (ScriptSig(Tx12PreImage, (ScriptSig(Tx11PreImage, (ScriptSig(Tx10PreImage, (ScriptSig(Tx9PreImage, (ScriptSig(Tx8PreImage, (ScriptSig(Tx7PreImage, (ScriptSig(Tx6PreImage, (ScriptSig(Tx5PreImage, (ScriptSig(Tx4PreImage, (ScriptSig(Tx3PreImage, (ScriptSig(Tx2PreImage, Issuance), ScriptPubKeyTx2)), ScriptPubKeyTx3)), ScriptPubKeyTx4)), ScriptPubKeyTx5)), ScriptPubKeyTx6)), ScriptPubKeyTx7)), ScriptPubKeyTx8)), ScriptPubKeyTx9)), ScriptPubKeyTx10)), ScriptPubKeyTx11)), ScriptPubKeyTx12)), ScriptPubKeyTx13)), ScriptPubKeyTx14)), ScriptPubKeyTx15)), ScriptPubKeyTx16)), ScriptPubKeyTx17)), ScriptPubKeyTx18)), ScriptPubKeyTx19)), ScriptPubKeyTx20)), ScriptPubKeyTx21)), ScriptPubKeyTx22)), ScriptPubKeyTx23)), ScriptPubKeyTx24)), ScriptPubKeyTx25)), ScriptPubKeyTx26)), ScriptPubKeyTx27)), ScriptPubKeyTx28)), ScriptPubKeyTx29)), ScriptPubKeyTx30)), ScriptPubKeyTx31)), ScriptPubKeyTx32)), ScriptPubKeyTx33)), ScriptPubKeyTx34)), ScriptPubKeyTx35)), ScriptPubKeyTx36)), ScriptPubKeyTx37)), ScriptPubKeyTx38)), ScriptPubKeyTx39)), ScriptPubKeyTx40)), ScriptPubKeyTx41)), ScriptPubKeyTx42)), ScriptPubKeyTx43)), ScriptPubKeyTx44)), ScriptPubKeyTx45)), ScriptPubKeyTx46)), ScriptPubKeyTx47)), ScriptPubKeyTx48)), ScriptPubKeyTx49)), ScriptPubKeyTx50)
Since in each ScriptSig contains the previous transaction, the previous transaction's ScriptSig contains the transaction before that, and so on and so forth to the issuance transaction. This end up just accumulating all the transactions that have been done in the past.
In terms of scalability this seems worse than the receiver doing all the validation themselves by fetching each individual transaction in the past. The person sending the token will have to pay to store the entire history of the UTXO on the blockchain when sending the token forward.
What are your thoughts? Am I missing something?
@joe@musiq I don't think that's correct. The only trace of tx1 inside of tx2 is tx1's txid.
Here is tx2:
inputs: [
input {
input_output_point {
tx1_txid,
tx1_output_index
}
input_unlock_script [
push reduced tx2 // tx1 unlock "script" is part of tx2 and contains reduced version of tx2. tx1 lock script enforces constraints on this (tx2) transaction by examining the reduced tx2
]
}
]
outputs: [
output {
unlock script [
verify_sig_for_tx3 // tx2 lock script is part of tx2 and contains logic to verify validity of tx3 meta-evaluation
]
}
]
The only blowup I see is if you want to spend multiple outputs using this trick in one transaction, each unlock script could contain n-1 copies of the reduced tx. I think this can be mitigated with the correct choice of SIGHASH_NONE/ONE/ALL.
Ok I see I haven't really addressed the issue when you are validating two UTXO's back in L1, so you do put the entire preimage. I think it is actually still possible to "chop off" because inputs and outputs are hashed separately as part of sighash, so perhaps it's possible to check outputs and only carry the one input back. So in this case N and N+1 would both appear in N+2, but N would not appear in N+3.
I hope OP can shed some light.
@mr_word yeah i went through the same thought process. To be able to say it's "complete" we need all transactions IMO, which I interpreted was the point of the article. But looking forward to learn more as well...