BitGo & Securing Bitcoin with P2SH

3,674 views

Published on

This talk was presented at the SF Bitcoin Dev meetup on March 3, 2014. It's a pretty low level talk, and we covered many topics from how transaction signing works, how scripts work, how multi-signature transactions work, what are standard transactions, what are P2SH transactions, and finally, how to use the early BitGo APIs to do your own P2SH wallet creation and transaction signing.

If you wish to use the BitGo APIs, please contact me.

Published in: Economy & Finance

BitGo & Securing Bitcoin with P2SH

  1. 1. Securing Bitcoin With P2SH
  2. 2. Who Am I? ● ● ● ● ● Mike Belshe CTO / Co-Founder of BitGo. Startup Addict. Early Chrome Engineer Co-creator of SPDY, becoming HTTP/2.0 Co-founder of Lookout Software, email search.
  3. 3. Agenda Part 1: The Theory ● Signatures - how do they work? ○ Inputs & Outputs ○ Script Pub Key ○ Script Signature ● The P2SH Overlay Part 2: The Code ● BitGo APIs ○ HTTP Service ○ JavaScript library ● Let’s create a P2SH address! ● Let’s create a transaction
  4. 4. Part 1: The Theory
  5. 5. Anatomy of a Transaction Input #1 Transaction Input #2 ● ● ● ● ● ● Version # of Inputs List of inputs # of Outputs List of outputs Lock time Output #1
  6. 6. Anatomy of An Output Output ● Value (in Satoshis) ● ScriptPub ½ of the Script “Deposit Script”
  7. 7. Anatomy of An Input Input ● txHash of input ● Output index ● Script Signature ½ of the Script “Withdrawal Script”
  8. 8. Transaction Chain Transaction #d4444 Transaction #a1111 Transaction #b2222 Inputs: None Input #0: #a1111:0 Output #0: 50 BTC Input #0: #b2222:0 Input #1: #c3333:1 Output #0: 25 BTC Output #1: 25 BTC Output #0: 35 BTC Output #1: 10 BTC Transaction #c3333 Input #0: #b2222:1 Output #0: 5 BTC Output #1: 20 BTC Unspents
  9. 9. Anatomy of A Transaction Script Transaction #b2222 1. Take Script Pub Key from the output to spend Input #0: #a1111:0 Output #0: 25 BTC Output #1: 25 BTC Script Signature (from the new transaction) Script Pub Key (from the old transaction) Transaction #a1111 Inputs: None Output #0: 50 BTC Script 2. Append it to Script Signature from input in spending transaction 3. Use this as a stack of commands to run as a script
  10. 10. What Does A Script Look Like? Sampling of Script OP CODES OP_0, OP_FALSE Push 0 onto stack OP_PUSHDATA[1-4] Push a number of bytes on stack OP_DUP Duplicate top of stack OP_IFDUP If top of stack is not zero, duplicate it OP_NUMEQUAL Returns 1 if the numbers are equal OP_SHA256 Hash the contents of the stack with SHA-256 OP_RIPEMD160 Hash the contents of the stack with RIPEMD-160 OP_CHECKSIG Hash the transaction inputs/outputs; the sig must be a valid for the given pub key etc Overall, there are < 100 op codes ● Scripting language is complicated ● Scripts can be large and expensive to run ● Not turing complete ● bitcoind does not implement the full language ○ Rely on “standard transactions”
  11. 11. Standard Transaction Types & ScriptPub Pay to PubKey Pay to PubKey Hash MultiSig M of N ● old ● used in coinbase. ● Common form ● (BIP 11) <PubKey> OP_CHECKSIG OP_DUP <m> OP_HASH160 <PubKey> <PubKeyHash> … OP_EQUALVERIFY <PubKey> OP_CHECKSIG <n> <OP_CHECKMULTISIG>
  12. 12. The Need For P2SH ● Existing “Standard Transactions” require the transaction creator to specify the ScriptPub portion of the script ● Wanted a way to let the receiver specify the script. ○ Faster adoption of new formats (like BIP11: M of N) ○ Applies to all transactions at an address
  13. 13. Welcome Pay-to-Script-Hash (BIP16) Deposit Script (ScriptPub) is a Fixed Format: Withdrawal Script (ScriptSig) contains a new Script: OP_HASH160 <Signature> <ScriptHash> <Serialized Script> OP_EQUAL
  14. 14. P2SH Details ● Adoption accepted in April 2012. ● Was controversial because the script is a bit of a “bolt on” ○ New address type (BIP13): 32JnPkrXfNZByp5tgi4YxAVMi649Cjfnds ● Provided simple, 20-byte addresses like our existing ones
  15. 15. BitGo: P2SH & M-of-N magic ● P2SH gives the “Withdrawal Script” back to the receiver, rather than the sender. ● Multi-Sig gives us multi-factor bitcoin ● Now we can create a safe storage for bitcoin using the web: https://www.bitgo.com/p2sh_safe_address
  16. 16. Part 2: The Code
  17. 17. Disclosures and Disclaimers ● Of course we’re using BitGo APIs! ● BitGo APIs are still evolving, version 0.9 ● If you want to use these APIs contact me.
  18. 18. 2-Part SDK: Service + Browser ● Browser API is Javascript ○ Other client-side APIs will work ● Service API is HTTP
  19. 19. JavaScript API ● Modified Bitcoinjslib w/ Multi-Sig support ● https://github. com/BitGo/bitcoinjs -lib Bitcoin. Address ECKey Transaction
  20. 20. Bitcoin.Address var stdAddress = ‘1MyxBcAfzNze2aY3ggLEvroKJBZXDgAmc’; var p2shAddress = ‘32JnPkrXfNZByp5tgi4YxAVMi649Cjfnds’; assert(Bitcoin.Address.verify(stdAddress), true); assert(Bitcoin.Address.verify(p2shAddress), true); var address; try { address = new Bitcoin.Address(stdAddress); assert(address.isP2SHAddress() === false); } catch (e) { console.log(‘Invalid Address: ‘ + e); }
  21. 21. Bitcoin.Util // Arrays to/from Hex Strings Bitcoin.Util.bytesToHex() / hexToBytes() // double-SHA256 Bitcoin.Util.dsha() // A solid PRNG; with browser entropy from mouse/keyboard Bitcoin.Util.randomBytes()
  22. 22. Bitcoin.ECKey var key = new Bitcoin.ECKey(); // Get the bitcoin address for this key key.getBitcoinAddress().toString() // Get the public key key.getPub(); // as a byte array key.getPubKeyHex(); // as a hex string // Get string format for private key key.getWalletImportFormat();
  23. 23. Bitcoin.Transaction - Create // Create a transaction // Input is the outputIndex of inputTx // Output is valueInSatoshis to outputAddress. function createTx(inputTx, outputIndex, valueInSatoshis, outputAddress) { var tx = new Bitcoin.Transaction(); tx.addInput(new Bitcoin.TransactionIn( { outpoint: { hash: inputTx.getHash(), index: outputIndex script: inputTx.script, sequence: 4294967295 }) ); tx.addOuput(outputAddress, valueInSatoshis); return tx; } },
  24. 24. Bitcoin.Transaction - Sign // Sign a transaction function signTx(tx, redeemScript, signingKey) { var key = new Bitcoin.ECKey(signingKey); Simple enough. try { tx.signWithMultiSigScript( But what the heck is a redeemScript? [key], Crypto.util.hexToBytes(redeemScript) ); } catch (e) { // deal with error ... } return tx; } We’ll come back to this after we checkout the service APIs.
  25. 25. Service API ● Authenticate User ● Create Multi-Sig Wallets ● Find Unspents ● Sign & Send Transactions
  26. 26. Basics URL: https://www.bitgo.com/ REST-ful All data is JSON
  27. 27. User Login Method: POST {"user": {"id":"5314b981196d448052000088", URL: api/v1/user/login/local "name":{ "first":"", "last":"", curl --cookie cookies.txt --cookie-jar cookies.txt -header 'Content-Type: application/json' --databinary '{"email": "mike+auto@belshe.com", "password": "<redacted>"}' https://www.bitgo. com/api/v1/user/signup/loca "full":"mike+auto@belshe.com" }, // etc }
  28. 28. Create Multi-Sig Wallet Method: POST {"id":"2Mx7XSW3s36Em89jCegL75AZ3iDRLKMFXi6", "type":"bitcoin", URL: /api/v1/addresses/bitcoin "watch":true, "private":{ "userPrivKey":"x", "redeemScript":"5241045ccd… … … " curl --cookie cookies.txt --cookiejar cookies.txt --header 'ContentType: application/json' --databinary '{"private": {"m":2, "n":3, "userPubKey": "[insert key here]", "backupPubKey": "[insert key here]", "userPrivKey": "x"}}' https://www.bitgo. com/api/v1/addresses/bitcoin }, "spendingAccount":true, "isActive":true, "accountType":"safe", "pendingBalance":0, "availableBalance":0, "balance":0, "unconfirmedTransactions":[] }
  29. 29. Unspents Method: GET { "unspents":[ URL: /api/v1/transactions/unspen ts/bitcoin/<address> { "tx_hash": "e6f8057a1693b58101… … … ", "tx_output_n":0, "value":9005778, "raw":"0100000001bfe62… … … " curl --cookie cookies.txt --cookie-jar cookies.txt https://www.bitgo. com/api/v1/transactions/uns pents/bitcoin/3LbPcRnHdGHqQ nhjc2VMGZVbh8LfrGQCy6 } ] }
  30. 30. Sign Transaction Method: POST URL: /api/v1/transactions/bitcoi n curl --cookie cookies.txt --cookiejar cookies.txt --header 'ContentType: application/json' --databinary '{"tx":"<hex encoded transaction here"}' https://www. bitgo. com/api/v1/transaction/bitcoin { transaction: “<hex encoded, fully signed transaction” }
  31. 31. finem

×