Skip to content

Commit

Permalink
fix tx bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
danielsuo committed Dec 18, 2014
1 parent c14fe6a commit 49d54ed
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 63 deletions.
5 changes: 5 additions & 0 deletions src/Coin.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module Coin

export
# keys.jl
Keys,
generate_keys,
get_pub_key,

Expand All @@ -24,6 +25,10 @@ export
OutPoint,
Tx_Output,

# tx.jl
create_tx,
get_tx,

# utils.jl
reverse_endian,
get_checksum,
Expand Down
2 changes: 1 addition & 1 deletion src/base58.jl
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ function decode58_to_array(n::String)

# TODO: this isn't correct in the case of general # of 0s
# Capture 2 leading 0s
if n[1:2] == repeat(base58[1], 2) # Get the zero element
if n[1] == base58[1] # Get the zero element
result = [0x00, result]
end

Expand Down
92 changes: 30 additions & 62 deletions src/tx.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
##############################################################################
##
## TODO
##
##############################################################################

# - Read raw_tx to tx

##############################################################################
##
## Resources
##
##############################################################################

# - http://bitcoin.stackexchange.com/questions/2859/how-are-transaction-hashes-calculated

using Crypto
using HTTPClient
using JSON
Expand All @@ -10,8 +26,8 @@ const SIGHASH_ANYONECANPAY = 0x00000080
# Create transaction from previous OutPoints and outputs
function create_tx(keys::Array{Keys},
outpoints::Array{OutPoint},
addresses::Array{String},
amounts::Array{Integer};
addresses::Array, # Should be array of Base58Check-encoded strings
amounts::Array; # Should be array of Integers
hash_code = SIGHASH_ALL)

if length(keys) != length(outpoints)
Expand All @@ -27,7 +43,7 @@ function create_tx(keys::Array{Keys},
for outpoint in outpoints
prev_tx = get_tx(outpoint.hash)
input = Tx_Input(outpoint, prev_tx.outputs[outpoint.index].scriptPubKey)
append!(inputs, input)
append!(inputs, [input])
end

# Build output objects
Expand All @@ -41,7 +57,7 @@ function create_tx(keys::Array{Keys},

# Create output object
output = Tx_Output(amounts[i], scriptPubKey)
append!(outputs, output)
append!(outputs, [output])
end

# Build transaction object
Expand All @@ -51,13 +67,13 @@ function create_tx(keys::Array{Keys},
raw_tx = bytearray(tx)

# Append hash code; see here: https://en.bitcoin.it/wiki/OP_CHECKSIG
append!(raw_tx, reverse(bytearray(hash_code)))
append!(raw_tx, reverse(Crypto.int2oct(hash_code)))

# Double hash the transaction
hash = Crypto.digest("SHA256", Crypto.digest("SHA256", raw_tx))

# Sign the transaction using the private key
for i in 1:length(priv)
for i in 1:length(keys)

# Sign transation using private key
signature = Crypto.ec_sign(hash, keys[i].priv_key)
Expand All @@ -72,7 +88,7 @@ function create_tx(keys::Array{Keys},
append!(scriptSig, signature)

# Append hash_code byte
append!(scriptSig, uint8(hash_code))
append!(scriptSig, [uint8(hash_code)])

# Append length of public key as little-endian varint hex
append!(scriptSig, reverse(to_varint(length(keys[i].pub_key))))
Expand All @@ -83,6 +99,7 @@ function create_tx(keys::Array{Keys},
tx.inputs[i].scriptSig = scriptSig
end

return tx
end

function get_tx(hash::Array{Uint8})
Expand Down Expand Up @@ -110,7 +127,7 @@ function get_tx(hash::String)
json_inputs = result["inputs"]
inputs = Array(Tx_Input, 0)
for input in json_inputs
outpoint = OutPoint(input["previous_transaction_hash"], input["output_index"])
outpoint = OutPoint(input["previous_transaction_hash"], input["output_index"] + 1) # Julia is 1-index
tx_input = Tx_Input(outpoint, input["script"])
append!(inputs, [tx_input])
end
Expand All @@ -130,57 +147,8 @@ function parse_tx(raw_tx::Array{Uint8})
return 0
end

# Crypto.init()

# priv_key = Crypto.random(256)
# pub_key = Crypto.ec_pub_key(priv_key)
# keys = [Keys(priv_key, pub_key)]

# outpoint = OutPoint("f2b3eb2deb76566e7324307cd47c35eeb88413f971d88519859b1834307ecfec", 1)
# address = "1runeksijzfVxyrpiyCY2LCBvYsSiFsCm"
# println(address)
# http://bitcoin.stackexchange.com/questions/2859/how-are-transaction-hashes-calculated
# outpoint = OutPoint("f2b3eb2deb76566e7324307cd47c35eeb88413f971d88519859b1834307ecfec", 1)
# input = Tx_Input(outpoint, "76a914010966776006953d5567439e5e39f86a0d273bee88ac")
# output = Tx_Output(99900000, "76a914097072524438d003d23a2f23edb65aae1bb3e46988ac")

# tx = Tx([input], [output])



# hash_code = SIGHASH_ALL

# raw_tx = bytearray(tx)
# append!(raw_tx, reverse(bytearray(hash_code)))
# hash = Crypto.digest("SHA256", Crypto.digest("SHA256", raw_tx))

# data = "0100000001eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2010000001976a914010966776006953d5567439e5e39f86a0d273bee88acffffffff01605af405000000001976a914097072524438d003d23a2f23edb65aae1bb3e46988ac0000000001000000"



# sig = Crypto.ec_sign(hash, priv_key)
# hash_code = uint8(SIGHASH_ALL)

# scriptSig = Array(Uint8, 0)

# append!(scriptSig, reverse(to_varint(length(sig))))
# append!(scriptSig, sig)
# append!(scriptSig, hash_code)

# append!(scriptSig, reverse(to_varint(length(pub_key))))
# append!(scriptSig, pub_key)

# tx.inputs[1].scriptSig = scriptSig

# send = "1KKKK6N21XKo48zWKuQKXdvSsCf95ibHFa"
# # First byte is network id, last four bytes are checksum
# addr = decode58_to_array(send)[2:end-4]

# scriptPubKey = [OP_DUP, OP_HASH160, uint8(length(addr)), addr, OP_EQUALVERIFY, OP_CHECKSIG]

# tx.outputs[1].scriptPubKey = scriptPubKey

# raw_tx = bytearray(tx)

# # TODO: Read raw_tx to Tx
# # TODO:
# https://en.bitcoin.it/wiki/OP_CHECKSIG
# https://github.com/aantonop/bitcoinbook/blob/develop/ch05.asciidoc
function verify_tx(tx::Tx)
return 0
end
9 changes: 9 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@ tx_in = Tx_Input(outpoint, scriptSig)
tx = Tx([tx_in], [tx_out])
@test bytearray(tx) == [0x01, 0x00, 0x00, 0x00, 0x01, 0x48, 0x4d, 0x40, 0xd4, 0x5b, 0x9e, 0xa0, 0xd6, 0x52, 0xfc, 0xa8, 0x25, 0x8a, 0xb7, 0xca, 0xa4, 0x25, 0x41, 0xeb, 0x52, 0x97, 0x58, 0x57, 0xf9, 0x6f, 0xb5, 0x0c, 0xd7, 0x32, 0xc8, 0xb4, 0x81, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x47, 0x30, 0x44, 0x02, 0x20, 0x2c, 0xb2, 0x65, 0xbf, 0x10, 0x70, 0x7b, 0xf4, 0x93, 0x46, 0xc3, 0x51, 0x5d, 0xd3, 0xd1, 0x6f, 0xc4, 0x54, 0x61, 0x8c, 0x58, 0xec, 0x0a, 0x0f, 0xf4, 0x48, 0xa6, 0x76, 0xc5, 0x4f, 0xf7, 0x13, 0x02, 0x20, 0x6c, 0x66, 0x24, 0xd7, 0x62, 0xa1, 0xfc, 0xef, 0x46, 0x18, 0x28, 0x4e, 0xad, 0x8f, 0x08, 0x67, 0x8a, 0xc0, 0x5b, 0x13, 0xc8, 0x42, 0x35, 0xf1, 0x65, 0x4e, 0x6a, 0xd1, 0x68, 0x23, 0x3e, 0x82, 0x01, 0x41, 0x04, 0x14, 0xe3, 0x01, 0xb2, 0x32, 0x8f, 0x17, 0x44, 0x2c, 0x0b, 0x83, 0x10, 0xd7, 0x87, 0xbf, 0x3d, 0x8a, 0x40, 0x4c, 0xfb, 0xd0, 0x70, 0x4f, 0x13, 0x5b, 0x6a, 0xd4, 0xb2, 0xd3, 0xee, 0x75, 0x13, 0x10, 0xf9, 0x81, 0x92, 0x6e, 0x53, 0xa6, 0xe8, 0xc3, 0x9b, 0xd7, 0xd3, 0xfe, 0xfd, 0x57, 0x6c, 0x54, 0x3c, 0xce, 0x49, 0x3c, 0xba, 0xc0, 0x63, 0x88, 0xf2, 0x65, 0x1d, 0x1a, 0xac, 0xbf, 0xcd, 0xff, 0xff, 0xff, 0xff, 0x01, 0x62, 0x64, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xc8, 0xe9, 0x09, 0x96, 0xc7, 0xc6, 0x08, 0x0e, 0xe0, 0x62, 0x84, 0x60, 0x0c, 0x68, 0x4e, 0xd9, 0x04, 0xd1, 0x4c, 0x5c, 0x88, 0xac, 0x00, 0x00, 0x00, 0x00]

priv_key = Crypto.random(256)
pub_key = Crypto.ec_pub_key(priv_key)
keys = [Keys(priv_key, pub_key)]

outpoints = [OutPoint("81b4c832d70cb56ff957589752eb4125a4cab78a25a8fc52d6a09e5bd4404d48", 1)]
addresses = ["1KKKK6N21XKo48zWKuQKXdvSsCf95ibHFa"]
amounts = [91234]
tx = create_tx(keys, outpoints, addresses, amounts)

##############################################################################
##
## Utility tests
Expand Down

0 comments on commit 49d54ed

Please sign in to comment.