hirosystems / multisig-stx-btc

A webscript for generating, signing, decoding multisig STX operations in the STX-over-BTC wire format
4 stars 7 forks source link

Documentation on Usage #1

Open whoabuddy opened 2 years ago

whoabuddy commented 2 years ago

Now that I've used this library quite a few times I wanted to share what documentation I've built so far around the process.

There was an original issue opened in one of the docs repos but I cannot find it anymore, so I'll create the issue here then link it back in the Discord documentation channel.

Some of the information comes straight from the README and just lays it out in a new format to get from a standing start to over the finish line, including some of the additional steps required for a Trezor.


The instructions below assume you are signing with a Trezor.

Table of Contents

Setup Trezor Bridge

This software is used for the Trezor to connect to external services.

The website below will check if its installed and provide installation instructions if not.

https://suite.trezor.io/web/bridge/

Setup Trezor Device

⚠️ Be sure to have a backup of the secret key before changing the firmware on the device. ⚠️

Downgrade Firmware

  1. Download firmware version 2.0.7
  2. In Trezor Suite, click on Wallet top-left
  3. Click on Settings gear
  4. Under Settings > Device at bottom, click Install Firmware
  5. Select downloaded firmware file trezor-2.0.7.bin and click Install Firmware
  6. Confirm recovery seed phrase saved
  7. Reconnect in bootloader mode (swipe while plugging in)
  8. Confirm current firmware on Trezor
  9. Connect to Trezor Suite, click Install Firmware
  10. Confirm on Trezor (seed will be erased)
  11. Confirm when done and Trezor will automatically reboot

Confirm Trezor Config

  1. Connect Trezor to Trezor Suite
  2. Click on Setup Trezor
  3. Skip firmware update
  4. Click Recover Wallet
  5. On recover wallet from seed, click Start Recovery
  6. Confirm number of words on Trezor
  7. Type in each word on the Trezor (old school texting style)
  8. Trezor suite will confirm phrase is entered when done
  9. Click to set a pin, confirm on Trezor
  10. Trezor suite will confirm pin is entered when done
  11. Click to Continue to account screen
  12. Under activate coins, choose Bitcoin if not selected
  13. Click Complete Setup

Note: If prompted for a passphrase, do not enter anything and use the green check on the device to skip.

Create BTC Legacy Account

Note: If the account already existed, this adds it on the list again for Trezor Suite.

Note: Multiple legacy accounts can be created, but the prior account must have at least one transaction before creating a new one.

From the Trezor Suite dashboard:

  1. Click the + to add a new account
  2. Select Bitcoin
  3. Select Legacy BIP44, P2PKH, Base58
  4. Click Add Account
  5. Click on Receive and confirm on Trezor
  6. Copy and save the address for reference

Export xPub of Legacy Account

From the Trezor Suite accounts tab:

  1. Click on the Legacy Accounts header to show Legacy Account
  2. Click on the Account tab for the Legacy Account
  3. Click on show public key
  4. Copy and save the xpub for reference

Note: Before moving on to the next step, this process should be repeated for each account that represents the multsig address until all required xpubs are saved.

Setup multisig in Electrum

The Electrum wallet is used to obtain the bitcoin address and correctly formatted public keys required by the multisig-stx-btc tool.

Note: If you are using a custodial solution for any of the Bitcoin keys, try to obtain the xPub for the account through their service. If another public key format is provided (e.g. yPub or zPub), this tool can help convert it to an xPub.

Download and verify the signatures for the latest version, then open Electrum and:

  1. Create a new wallet
  2. Select multi-signature wallet
  3. Set number of cosigners (e.g. From 3 cosigners / require 2 signatures)
  4. Select Use a master key
  5. Enter xPub for Key 1
  6. Click Next to confirm public key
  7. Select Enter cosigner key
  8. Enter xPub for Key 2
  9. Select Enter cosigner key
  10. Enter xPub for Key 3
  11. Set a password to encrypt the file

Note: Pay attention to the order of the keys used above, as the multisig-stx-btc tool will expect them to be in the same order.

The electrum wallet is now operating in watch-only mode and will show the balance for the account.

The BTC address of the multisig wallet is the first address listed on the Addresses tab. (e.g. 37qEjwRbionPc9MkK8WHH8GTbj2GC8mWix)

Compressed Public Keys

By right-clicking on the first address listed on the Addresses tab, select Details to find the compressed public keys for the address, which are prefixed with 02 or 03.

Save the public keys for reference.

Convert multisig BTC to multisig STX address

The c32check allows us to convert between BTC and STX addresses.

Install and Usage

First clone the repo, then run:

npm i
npm run build
cd dist
node
.load c32check.js

Commands

Convert the BTC address to a STX address:

> c32check.b58ToC32('37qEjwRbionPc9MkK8WHH8GTbj2GC8mWix')
'SM11NXJ0RJVJ6AV9DHJJB3DS5TK7RMCZCGWPNDT2P'

Convert the STX address to a BTC address:

> c32check.c32ToB58('SM11NXJ0RJVJ6AV9DHJJB3DS5TK7RMCZCGWPNDT2P')
'37qEjwRbionPc9MkK8WHH8GTbj2GC8mWix'

Setup multisig-stx-btc tool

The Stacks Address Transaction Signing Tool tool helps build and manage Stacks operations that are sent on Bitcoin using a multisig wallet.

Installation

First clone the repo, then run:

npm i
npm run build

This will create a dist folder with the following files:

bootstrap.min.css
distribute.js
index.html
transacter.js

Open the index.html file in a browser to use the tool.

Sending a Transaction

According to SIP-007, both a STX transfer and a STX stacking operation require two Bitcoin transactions.

The first is a pre-op transaction that should receive at least 1 confirmation before sending the transfer or stacking operation.

The transaction ID of the pre-op transaction is used by the transaction for the second operation.

Fund appropriate accounts

  1. Send enough BTC to cover two transaction fees to the multisig BTC address (~$50)
  2. Send a small amount of STX to the multisig STX address (e.g. 1 STX)

Note: Do not send any other type of token to this address (e.g. SIP-009/SIP-010), only STX.

Verifying Payloads

To verify a payload generated by the tool, copy the entire paragraph of text and paste it into the "Decode/Check Partial Transaction" box under "Partial transaction:".

Click "Check/Decode" and a new field will appear validating the transaction information.

Examples:

================== Pre-STX Op =========================
STX from address: SM11NXJ0RJVJ6AV9DHJJB3DS5TK7RMCZCGWPNDT2P
partially signed: false
BTC consumed: 139192
=======================================================
================== Pre-STX Op =========================
STX from address: SM11NXJ0RJVJ6AV9DHJJB3DS5TK7RMCZCGWPNDT2P
partially signed: true
BTC consumed: 102264
=======================================================
================== STX Transfer =======================
STX from address: SM11NXJ0RJVJ6AV9DHJJB3DS5TK7RMCZCGWPNDT2P
STX to address: SPBSN61W5ADNG9VJ6AYC48QRTV4BBWVRYDZ97WFN
microstacks amount: 9000000
partially signed: false
BTC consumed: 15050
=======================================================
================== Stack STX Op =========================
STX from address: SM11NXJ0RJVJ6AV9DHJJB3DS5TK7RMCZCGWPNDT2P
PoX reward address: 37qEjwRbionPc9MkK8WHH8GTbj2GC8mWix
microstacks to stack: 1000000000000
reward cycles: 5
partially signed: false
=======================================================

Pre-STX Transfer

Setup

Fill in the first three fields below to generate the pre-stx transaction:

Click "Generate Pre-STX TX" and a new field will appear at the bottom of the screen titled "Unsigned Pre-STX Operation Transaction" with the payload below it.

Signing

To sign the payload, copy the entire paragraph of text and paste it into the "Transaction Signing" box under "Partial transaction:".

Fill in the following information based on the configuration supplied in this documentation. If you did not follow the instructions above, the Signer Path may be different.

Note: If using multiple legacy accounts on the same Trezor, increment the 3rd digit of the signer path for each account (e.g. m/44'/0'/1'/0/0 for the second account).

Click "Start Sign TX" and a new window will open to connect to the Trezor and sign the transaction.

Once complete, a new field will appear at the bottom of the screen titled "Partially Signed Pre-STX Operation Transaction" with the payload below it.

The next signer will follow the same steps above.

The last signer will follow the same steps above except click "Finish Sign TX" at the end.

Once complete, a new field will appear at the bottom of the screen titled "Signed Pre-STX Operation Transaction" with the payload below it.

Submitting

Once the fully-signed transaction is generated, it is ready to be broadcast to the Bitcoin blockchain. There are several ways to do this, and one simple approach is using BlockCypher's pushtx tool.

After pushing the transaction, allow for at least 1 confirmation before broadcasting the transaction generated in to the next step.

Also, record the Bitcoin transaction ID to be used while generating the next STX operation.

STX Transfer

Setup

Fill in the required fields below to generate the STX transfer transaction:

Click "Generate Transfer TX" and a new field will appear at the bottom of the screen titled "Unsigned STX Transfer Operation Transaction" with the payload below it.

Signing

To sign the payload, copy the entire paragraph of text and paste it into the "Transaction Signing" box under "Partial transaction:".

Fill in the following information based on the configuration supplied in this documentation. If you did not follow the instructions above, the Signer Path may be different.

Note: If using multiple legacy accounts on the same Trezor, increase the 3rd digit of the signer path for each account (e.g. m/44'/0'/1'/0/0 for the second account).

Click "Start Sign TX" and a new window will open to connect to the Trezor and sign the transaction.

Once complete, a new field will appear at the bottom of the screen titled "Partially Signed STX Transfer Operation Transaction" with the payload below it.

The next signer will follow the same steps above.

The last signer will follow the same steps above except click "Finish Sign TX" at the end.

Once complete, a new field will appear at the bottom of the screen titled "Signed STX Transfer Operation Transaction" with the payload below it.

Submitting

Once the fully-signed transaction is generated, it is ready to be broadcast to the Bitcoin blockchain. There are several ways to do this, and one simple approach is using BlockCypher's pushtx tool.

Record the Bitcoin transaction ID to be used to verify the transaction status.

Stacking STX

Setup

Fill in the required fields below to generate the STX stacking transaction:

Click "Generate Stacking TX" and a new field will appear at the bottom of the screen titled "Unsigned STX Stacking Operation Transaction" with the payload below it.

Signing

To sign the payload, copy the entire paragraph of text and paste it into the "Transaction Signing" box under "Partial transaction:".

Fill in the following information based on the configuration supplied in this documentation. If you did not follow the instructions above, the Signer Path may be different.

Note: If using multiple legacy accounts on the same Trezor, increase the 3rd digit of the signer path for each account (e.g. m/44'/0'/1'/0/0 for the second account).

Click "Start Sign TX" and a new window will open to connect to the Trezor and sign the transaction.

Once complete, a new field will appear at the bottom of the screen titled "Partially Signed STX Stacking Operation Transaction" with the payload below it.

The next signer will follow the same steps above.

The last signer will follow the same steps above except click "Finish Sign TX" at the end.

Once complete, a new field will appear at the bottom of the screen titled "Signed STX Stacking Operation Transaction" with the payload below it.

Submitting

Once the fully-signed transaction is generated, it is ready to be broadcast to the Bitcoin blockchain. There are several ways to do this, and one simple approach is using BlockCypher's pushtx tool.

Record the Bitcoin transaction ID to be used to verify the transaction status.

Verifying Status

In order for the transaction to be accepted and executed by miners, the second operation must confirm in a Bitcoin block that corresponds with a Stacks block, and the next Bitcoin block must correspond with a Stacks block as well.

If either of those blocks are missed by the Stacks chain, the operation will not be carried out and the process must be restarted.

To verify the status of a transaction:

Example (success):

Operation Bitcoin Block Stacks Block
BTC Pre-Op STX 732900 56992
BTC Send STX 732904 56996
Next block 732905 56997

In this example, Stacks block 56,997 would contain the STX transfer operation from the Stacks multisig wallet.

Example (lost):

Operation Bitcoin Block Stacks Block
BTC Pre-Op STX 732800 56892
BTC Send STX 732814 56906
Flash block 732815 none
Next block 732816 56907

In this example, the Stacks operation would not be picked up by miners, and the entire process must be started over again.

Bitcoin Transaction Fees

The fee estimation can be a bit aggressive at times, and the "Use Whole Pre-Stx UTXO" option may spend more than expected depending on the balance in the account.

If the tool is constantly returning the error below or if the fee estimates seem too high, it is possible to manually change the fee rate.

The transaction generator doesn't think the PreStxOp has enough funds to pay the transaction fees. Try to generate using the "use whole UTXO" option.

To reduce the recommended fee rate, modify the getFeeRate function in transacter.js to reduce the multiplier.

Example: default is 2.3, reduces it to 1

bsk.config.network.getFeeRate = function () {
  return fetch("https://bitcoinfees.earn.com/api/v1/fees/recommended")
    .then((resp) => resp.json())
    .then((rates) => Math.floor(1 * rates.fastestFee));
};
Hero-Gamer commented 2 years ago

Wow, amazing documentation!

markmhendrickson commented 2 years ago

@kantai Might you want to incorporate some or all of this into the repo's README, or simply link to it from there?

kantai commented 2 years ago

Yes, this is great documentation-- a PR to merge this into the repo's README or content would be awesome.