P2SH assurance contract

@bitcoincashautist reviewed the contract and agrees it would work as intended! :grinning_face_with_smiling_eyes:
He catched a few sloppy mistakes I made so I just fixed them in the Cashscript code, thanks @bitcoincashautist ! :pray:

One mistake he found was non-obvious to me from the Cashtokens spec, that OP_UTXOTOKENCATEGORY doesn’t push any capability for an immutable NFT. Whereas I had assumed (and interpreted from the spec) that it would push a 0 :sweat_smile:

1 Like

I was reviewing and rewriting it in Script Assembly using BitAuthIDE, finished just now, here it is:

Flipstarter v2

Script assembly version of Flipstarter v2 contract from here:
www.github.com/mr-zwets/p2shAssuranceContract
Note: upon loading this template, you must edit scenarios and manually replace the bytecode stored pledge receipt NFTs with bytecode matching the temporary keys generated by your browser.
For this, z_helper script is provided, from where you can copy & paste the hex

1 Like

With the Cashscript v0.8.0 prerelease and the publication of cashc@next it’s now possible to compile the cashscript assurance contract upgraded with the CashTokens functionality down to bytecode!

They are just slightly bigger than their v1 counterparts with all the new cancel-any-time functionality.
v2 is 101 opcodes and 165 bytes (without constructor arguments) in size, compared to the 95 opcodes and 150 bytes of v1.

Next up is upgrading the Cashscript SDK so you can easily make transactions with the new token-features on chipnet.

2 Likes

With the proper Cashscript v0.8.0 release it’s now possible to use the CashTokens version of this contract on the Bitcoin Cash mainchain! With the upgraded SDK and the upgraded Cashscript-Playground it’s now easy to make transactions using the smart contracts functions.

There could be a non-custodial webapp for this that connects to the Paytaca browser extension for the smart contract functionality.

1 Like

So I’m using a p2sh contract utilizing the new TransactionBuilder class in Cashscript v0.8.0 on BCHouse based on the v2 p2shAssuranceContract.

Overview

The main difference from the v2 assurance contract is that I’m using several variations of the contract to allow deposits from non-WalletConnect wallets. This makes it:

  1. extremely simple to pledge to a campaign without connecting a wallet or using a web wallet.
  2. effectively “multi-threaded” (really queuing) so that multiple users can pledge at the same time without conflict.

The design of the contract is tailored more for platform usage though, since the address the user pays to is a covenant that requires the transaction spending the deposit to pledge the funds with the campaign utxo and output an NFT receipt (exactly like Mathieu’s v2 assurance contract) OR return the funds immediately.

So due to this covenant design, either the user’s wallet, the web browser, a platform like BCHouse, or an independent 3rd party (like unspent-phi) must execute the transaction. The web browser and the platform are in the best position to do that given the contract parameters.

Payment Requests

I go through the extra step of using BIP70, JPP, and JPPv2 on BCHouse to provide the contract parameters both in the memo field and url for users - allowing them in the worst case to recover from any potential issues with the platform. Some wallets like Bitcoin.com only provide the payment url to users after the fact while others give access to both the url and memo, so I had to use both unfortunately which can be a problem with legacy QR code readers.

Future work

Either way, a simple link to a 3rd party before payment can provide the contract parameters, for example, a separate site on IPFS like this implementation. An even better solution, is using a CashRPC implementation with the same parameters to store and verify the contract and destination address before funding, as well as act on the contract/utxos.

Additionally, the design of both v2 assurance contract and the BCHouse contract don’t allow for compatibility with anyonecanpay type of pledges. This is something that could be fixed by requiring any “over-pledging” to be returned to the pledger immediately and allowing payouts IFF the outputs match the campaign goal as opposed to the campaign utxo value being >= the campaign goal:

So: require(output[0].value === fundingGoal) not require(input[0].value >= fundingGoal)

Anyways, there’s a lot to be desired from my implementation for both wallet connect and non-walletconnect users. I haven’t really made this contract available for users on mainnet (minus my own tests and campaigns) for these reasons.

2 Likes