stacks-network / docs

Unleash Bitcoin's full potential with decentralized apps and smart contracts. The documentation covers key aspects of the Stacks network and technology and provides tutorials and other helpful content for developers.
https://docs.stacks.co
Creative Commons Zero v1.0 Universal
156 stars 235 forks source link

Stacking: Reward bitcoin address format #817

Closed agraebe closed 3 years ago

agraebe commented 3 years ago

The reward bitcoin address needs to be in a specific format, currently not documented:

(pox-addr (tuple (version (buff 1)) (hashbytes (buff 20))))

Here's an example when the address is derived from an STX address:

const hashbytes = bufferCV(
    Buffer.from(c32.c32addressDecode(stxAddress)[1], "hex")
  );
  const version = bufferCV(Buffer.from("01", "hex"));

const address = `0x${serializeCV(
          tupleCV({
            hashbytes,
            version,
          })
        ).toString("hex")}`;
friedger commented 3 years ago

This is described in https://github.com/blockstack/docs/blob/8da7f4f53ffe05e23c2730642bea30aec09b2daa/src/pages/stacks-blockchain/integrate-stacking.md#L245

Is this issue still valid? What should be changed?

agraebe commented 3 years ago

Basically explaining the version and hashbytes outside of the JS code (in case someone would implement in a different language). It would also make sense to explain why the version is needed. Just some more guidance on what this address format is and why it is like that

agraebe commented 3 years ago

@kantai or @lgalabru could you maybe give us a braindump of the bitcoin address format? why versions? why is it 0, etc? Would love to document this so that anyone can implement, even if they're not using JS/TS

kantai commented 3 years ago

The version bytes are one of the following:

    SerializeP2PKH = 0x00,  // hash160(public-key), same as bitcoin's p2pkh
    SerializeP2SH = 0x01,   // hash160(multisig-redeem-script), same as bitcoin's multisig p2sh
    SerializeP2WPKH = 0x02, // hash160(segwit-program-00(p2pkh)), same as bitcoin's p2sh-p2wpkh
    SerializeP2WSH = 0x03,  // hash160(segwit-program-00(public-keys)), same as bitcoin's p2sh-p2wsh

Indicating what kind of Bitcoin address it is being submitted.

The hash bytes are the 20 hash bytes of the Bitcoin address, you can get that from a normal Bitcoin library, e.g.

$ node -e "const btc = require('bitcoinjs-lib'); console.log('0x' +  btc.address.fromBase58Check('1C56LYirKa3PFXFsvhSESgDy2acEHVAEt6').hash.toString('hex'))"

The reason that the PoX contract needs this special format is that it needs to ensure that miners will be able to correctly construct the Bitcoin transaction containing the reward address. An invalid reward address could cause miners to be unable to mine a block.