In my app, Blockusign, I am trying to prove two parties signed a copy of a document (hash).
I am a noobie to bitcoin programming and read you can accomplish this using a multi-sig and pass data into a transaction using the OP_RETURN.
I would prefer to use the bitcoin public keys that have the user’s blockstack id and attestations associated to it for proof that a “real” user signed the transaction.
Is there an easy way to do this with blockstack.js? Or do you suggest a better/different architecture?
You can do this with bitcoinjs-lib All you need to do is create a transaction where each party signs an input, and sends themselves back their change. The OP_RETURN would encode the document hash. The nice thing about this approach over multisig is that you don’t have to first create a multisig output to spend.
Is it possible in blockstack.js to sign the transaction with the users bitcoin private key, similar to in the Blockstack Browser Wallet but with the ability to add the OP_RETURN hash data? I noticed it was sort of answered here but i could not find a concrete code example in the docs: Add blockstack transaction generation support to blockstack.js #382
Also, I was doing research on alternative approaches and noticed a forum post on immutable data storage using atlas. Would this approach make sense for my use-case? If so, does anybody have a some sample javascript code? Immutable data
blockstack.js will help you a little bit – the function blockstack.hexStringToECPair() will convert a private key string (like the app-private key) into an ECPair object, which can be used to sign bitcoinjs-lib transactions. For actually creating the transaction with the OP_RETURN, etc., I recommend looking at the test cases for the TransactionBuilder object in bitcoinjs-lib, but the general idea would be something like this:
const tx = new TransactionBuilder()
tx.addInput(user1UTXO, 0)
tx.addInput(user2UTXO, 2) // 2 is the vout of the UTXO
tx.addInput(user3UTXO, 1)
// store the data hash in a buffer `opReturnBuffer`
const nullOutput = bitcoin.payments.embed({ data: [opReturnBuffer] }).output
tx.addOutput(nullOutput, 0)
// add any change outputs -- you will have to compute the change amount yourself.
tx.addOutput(change1, changeAmount)
// sign
tx.sign(0, user1ECPair)
tx.sign(1, user2ECPair)
tx.sign(2, user3ECPair)
// return the built transaction as a hex string
return tx.build().toHex()
Per our discussion at the meetup, do you have the code to map the app key with the user’s blockstack ID, so I can prove the user signed the transaction with his associated attestations?