bitgo & securing bitcoin with p2sh

Post on 17-Aug-2014

1.708 Views

Category:

Economy & Finance

2 Downloads

Preview:

Click to see full reader

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

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?

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

Part 1: The Theory

Anatomy of a Transaction

Transaction

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

Input #2

Input #1

Output #1

Anatomy of An Output

Output

● Value (in Satoshis)● ScriptPub

½ of the Script“Deposit Script”

Anatomy of An Input

Input

● txHash of input● Output index● Script Signature

½ of the Script“Withdrawal Script”

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

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

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

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>

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

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>

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

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

Part 2: The Code

● 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

2-Part SDK: Service + Browser

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

● Service API is HTTP

JavaScript API

● Modified Bitcoinjs-lib w/ Multi-Sig support

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

Bitcoin. Address ECKey Transaction

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);}

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

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

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;

}

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.

Service API

● Authenticate User

● Create Multi-Sig Wallets

● Find Unspents

● Sign & Send Transactions

Basics

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

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": "mike+auto@belshe.com", "password": "<redacted>"}' https://www.bitgo.com/api/v1/user/signup/local

{"user":

{"id":"5314b981196d448052000088",

"name":{

"first":"",

"last":"",

"full":"mike+auto@belshe.com"

},

// etc

}

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":[]

}

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… … … "

}

]

}

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”

}

finem

top related