bitgo & securing bitcoin with p2sh

31
Securing Bitcoin With P2SH

Upload: mike-belshe

Post on 17-Aug-2014

1.708 views

Category:

Economy & Finance


2 download

DESCRIPTION

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.

TRANSCRIPT

Page 1: BitGo & Securing Bitcoin with P2SH

Securing Bitcoin With P2SH

Page 2: BitGo & Securing Bitcoin with P2SH

● 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.

Who Am I?

Page 3: BitGo & Securing Bitcoin with P2SH

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

Page 4: BitGo & Securing Bitcoin with P2SH

Part 1: The Theory

Page 5: BitGo & Securing Bitcoin with P2SH

Anatomy of a Transaction

Transaction

● Version● # of Inputs● List of inputs● # of Outputs● List of outputs● Lock time

Input #2

Input #1

Output #1

Page 6: BitGo & Securing Bitcoin with P2SH

Anatomy of An Output

Output

● Value (in Satoshis)● ScriptPub

½ of the Script“Deposit Script”

Page 7: BitGo & Securing Bitcoin with P2SH

Anatomy of An Input

Input

● txHash of input● Output index● Script Signature

½ of the Script“Withdrawal Script”

Page 8: BitGo & Securing Bitcoin with P2SH

Transaction Chain

Transaction #a1111

Inputs: None

Output #0: 50 BTC

Transaction #b2222

Input #0: #a1111:0

Output #0: 25 BTCOutput #1: 25 BTC

Transaction #c3333

Input #0: #b2222:1

Output #0: 5 BTCOutput #1: 20 BTC

Transaction #d4444

Input #0: #b2222:0Input #1: #c3333:1

Output #0: 35 BTCOutput #1: 10 BTC

Unspents

Page 9: BitGo & Securing Bitcoin with P2SH

Anatomy of A Transaction Script

Script Signature (from the new transaction)

Script Pub Key(from the old transaction)

Transaction #a1111

Inputs: None

Output #0: 50 BTC

Transaction #b2222

Input #0: #a1111:0

Output #0: 25 BTCOutput #1: 25 BTC

Script

1. Take Script Pub Key from the output to spend

2. Append it to Script Signature from input in spending transaction

3. Use this as a stack of commands to run as a script

Page 10: BitGo & Securing Bitcoin with P2SH

What Does A Script Look Like?● 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”

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

Page 11: BitGo & Securing Bitcoin with P2SH

Standard Transaction Types & ScriptPub

Pay to PubKey● old● used in coinbase.<PubKey>OP_CHECKSIG

Pay to PubKey Hash● Common form

OP_DUP

OP_HASH160

<PubKeyHash>

OP_EQUALVERIFY

OP_CHECKSIG

MultiSig M of N● (BIP 11)

<m>

<PubKey>

<PubKey>

<n>

<OP_CHECKMULTISIG>

Page 12: BitGo & Securing Bitcoin with P2SH

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

Page 13: BitGo & Securing Bitcoin with P2SH

Welcome Pay-to-Script-Hash (BIP16)

Deposit Script (ScriptPub) is a Fixed Format:

OP_HASH160

<ScriptHash>

OP_EQUAL

Withdrawal Script (ScriptSig) contains a new Script:

<Signature>

<Serialized Script>

Page 14: BitGo & Securing Bitcoin with P2SH

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

Page 15: BitGo & Securing Bitcoin with P2SH

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

Page 16: BitGo & Securing Bitcoin with P2SH

Part 2: The Code

Page 17: BitGo & Securing Bitcoin with P2SH

● Of course we’re using BitGo APIs!

● BitGo APIs are still evolving, version 0.9

● If you want to use these APIs contact me.

Disclosures and Disclaimers

Page 18: BitGo & Securing Bitcoin with P2SH

2-Part SDK: Service + Browser

● Browser API is Javascript○ Other client-side APIs will work

● Service API is HTTP

Page 19: BitGo & Securing Bitcoin with P2SH

JavaScript API

● Modified Bitcoinjs-lib w/ Multi-Sig support

● https://github.com/BitGo/bitcoinjs-lib

Bitcoin. Address ECKey Transaction

Page 20: BitGo & Securing Bitcoin with P2SH

Bitcoin.Addressvar 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);}

Page 21: BitGo & Securing Bitcoin with P2SH

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()

Page 22: BitGo & Securing Bitcoin with P2SH

Bitcoin.ECKeyvar 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();

Page 23: BitGo & Securing Bitcoin with P2SH

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;

}

Page 24: BitGo & Securing Bitcoin with P2SH

Bitcoin.Transaction - Sign// Sign a transaction

function signTx(tx, redeemScript, signingKey) {

var key = new Bitcoin.ECKey(signingKey);

try {

tx.signWithMultiSigScript(

[key],

Crypto.util.hexToBytes(redeemScript)

);

} catch (e) {

// deal with error ... }

return tx;

}

Simple enough.

But what the heck is a redeemScript?

We’ll come back to this after we checkout the service APIs.

Page 25: BitGo & Securing Bitcoin with P2SH

Service API

● Authenticate User

● Create Multi-Sig Wallets

● Find Unspents

● Sign & Send Transactions

Page 26: BitGo & Securing Bitcoin with P2SH

Basics

URL: https://www.bitgo.com/REST-fulAll data is JSON

Page 27: BitGo & Securing Bitcoin with P2SH

User LoginMethod: POST

URL: api/v1/user/login/local

curl --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data-binary '{"email": "[email protected]", "password": "<redacted>"}' https://www.bitgo.com/api/v1/user/signup/local

{"user":

{"id":"5314b981196d448052000088",

"name":{

"first":"",

"last":"",

"full":"[email protected]"

},

// etc

}

Page 28: BitGo & Securing Bitcoin with P2SH

Create Multi-Sig WalletMethod: POST

URL: /api/v1/addresses/bitcoin

curl --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data-binary '{"private": {"m":2, "n":3, "userPubKey": "[insert key here]", "backupPubKey": "[insert key here]", "userPrivKey": "x"}}' https://www.bitgo.com/api/v1/addresses/bitcoin

{"id":"2Mx7XSW3s36Em89jCegL75AZ3iDRLKMFXi6",

"type":"bitcoin",

"watch":true,

"private":{

"userPrivKey":"x",

"redeemScript":"5241045ccd… … … "

},

"spendingAccount":true,

"isActive":true,

"accountType":"safe",

"pendingBalance":0,

"availableBalance":0,

"balance":0,

"unconfirmedTransactions":[]

}

Page 29: BitGo & Securing Bitcoin with P2SH

UnspentsMethod: GET

URL: /api/v1/transactions/unspents/bitcoin/<address>

curl --cookie cookies.txt --cookie-jar cookies.txt https://www.bitgo.com/api/v1/transactions/unspents/bitcoin/3LbPcRnHdGHqQnhjc2VMGZVbh8LfrGQCy6

{

"unspents":[

{

"tx_hash": "e6f8057a1693b58101… … … ",

"tx_output_n":0,

"value":9005778,

"raw":"0100000001bfe62… … … "

}

]

}

Page 30: BitGo & Securing Bitcoin with P2SH

Sign TransactionMethod: POST

URL: /api/v1/transactions/bitcoin

curl --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data-binary '{"tx":"<hex encoded transaction here"}' https://www.bitgo.com/api/v1/transaction/bitcoin

{

transaction: “<hex encoded, fully signed transaction”

}

Page 31: BitGo & Securing Bitcoin with P2SH

finem