bitgo & securing bitcoin with p2sh
Post on 17-Aug-2014
1.708 Views
Preview:
DESCRIPTION
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
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