CashScript / cashscript

⚖️ Easily write and interact with Bitcoin Cash smart contracts
https://cashscript.org
MIT License
112 stars 79 forks source link

Allow to spend P2SH inputs from different contracts #126

Closed mr-zwets closed 9 months ago

mr-zwets commented 2 years ago

With native introspection it is possible to add a tracking contract contract which does not change addresses to a simulated state contract which does. Getting the latest state of a simulated state contract then doesn't require replaying the whole history but instead only look at the UTXO on the tracking contract address and query the other output in the transaction that created the tracking UTXO. The cashscript contract of the tracking contract would look like this:

contract TrackingContract() {
    function SpendBoth() {
        // static contract lives on index 0
        require(this.activeInputIndex == 0);
        //  and lived on index 0 before
        require(tx.inputs[0].outpointIndex == 0);
        //  second input lived on index 1 before
        require(tx.inputs[1].outpointIndex == 1);
        bytes32 outpoint0 = tx.inputs[0].outpointTransactionHash;
        bytes32 outpoint1 = tx.inputs[1].outpointTransactionHash;
        // inputs must be created by the same transaction
        require( outpoint0 == outpoint1);
        bytes utxobytecode0 = tx.inputs[0].lockingBytecode;
        bytes outputbytecode0 = tx.outputs[0].lockingBytecode;
        // bytecode of first input should not change across iterations
        require(utxobytecode0 == outputbytecode0);
    }
}

Unfortunately such tracking contract can not be used with the current cashscript SDK as it is made with the idea of spending from a single contract function at a time.

Besides the tracking contract, I'm not aware of other usecases of spending from mutiple different contracts at a time so maybe a simple .experimentalFromP2SH(TrackingContract.functions.SpendBoth()) would be a good solution.

Alternatively a more conceptual solution would be to make .from() .to() and .send() methods on a transaction object and the .from() would require either a P2PKH unlock or a contract object with a spending function and the unlocking arguments.

Apdlrcjafg19 commented 1 year ago

Avance

rkalis commented 10 months ago

We made some progress on this today.

What we still need to do:

rkalis commented 10 months ago

We need to provide a way for developers to generate signatures for their CashScript transactions without needing to pass in the private key, such as through WalletConnect. For this we should talk to some developers that have created CashScript dapps that people can interact with without having a built-in web wallet on the website. Perhaps it makes sense for us to already make the bytecodeGenerator functions async in anticipation of it.

rkalis commented 10 months ago

Today we added the automatic "bytecode generator" generator generation (working title) for contracts and P2PKH and we addedd some tests. So we are mostly feature complete for this, but we still need to make some fixes, change some namings, and add more tests and docs. We've updated the checklist above.

rkalis commented 9 months ago

We've added all the tests we wanted to add and made a start with the docs.

mr-zwets commented 9 months ago

We finished work on the advanced transaction builder and released it with version 0.9.0 🥳