Skip to content

Commit e37a7a8

Browse files
committed
V2.1.0
fix issue #5
1 parent 4f24072 commit e37a7a8

17 files changed

+418
-282
lines changed

CHANGELOG.md

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
## 2.1.0
2+
3+
* fix issue [#5](https://github.com/mrtnetwork/bitcoin/issues/5)
4+
15
## 2.0.0
2-
- Updated golang.org/x/crypto to the latest version v0.18.0
3-
- Resolved issue with Multisignature address
6+
7+
* Updated golang.org/x/crypto to the latest version v0.18.0
8+
* Resolved issue with Multisignature address
49

510
## 1.0.0
611

7-
* Release.
12+
* Release.

README.md

+226-195
Large diffs are not rendered by default.

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ module github.com/mrtnetwork/bitcoin
22

33
go 1.21
44

5-
require golang.org/x/crypto v0.18.0
5+
require golang.org/x/crypto v0.22.0

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
22
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
33
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
44
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
5+
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
6+
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=

provider/transction_builder.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func (builder *BitcoinTransactionBuilder) HasTaproot() bool {
8484
// It is used to make the appropriate scriptSig
8585
func buildInputScriptPubKeys(utxo UtxoWithOwner, isTaproot bool) (*scripts.Script, error) {
8686
if utxo.IsMultiSig() {
87-
script, e := scripts.ScriptFromRaw(utxo.OwnerDetails.MultiSigAddress.ScriptDetails, true)
87+
script, e := scripts.ScriptFromRaw(formating.HexToBytes(utxo.OwnerDetails.MultiSigAddress.ScriptDetails), true)
8888
if e != nil {
8989
return nil, e
9090
}
@@ -205,7 +205,7 @@ func buildP2shSegwitRedeemScriptSig(utx UtxoWithOwner) ([]string, error) {
205205
if utx.IsMultiSig() {
206206
switch utx.OwnerDetails.MultiSigAddress.Address.GetType() {
207207
case address.P2WSHInP2SH:
208-
script, e := scripts.ScriptFromRaw(utx.OwnerDetails.MultiSigAddress.ScriptDetails, true)
208+
script, e := scripts.ScriptFromRaw(formating.HexToBytes(utx.OwnerDetails.MultiSigAddress.ScriptDetails), true)
209209
if e != nil {
210210
return nil, e
211211
}

scripts/script.go

+16-20
Original file line numberDiff line numberDiff line change
@@ -52,46 +52,41 @@ func (s *Script) ToP2shScriptPubKey() *Script {
5252
}
5353

5454
// Imports a Script commands list from raw hexadecimal data
55-
func ScriptFromRaw(hexData string, hasSegwit bool) (*Script, error) {
55+
func ScriptFromRaw(scriptBytes []byte, hasSegwit bool) (*Script, error) {
5656
var commands []interface{}
5757
index := 0
58-
scriptraw, err := formating.HexToBytesCatch(hexData)
59-
if err != nil {
60-
return nil, fmt.Errorf("invalid script bytes")
61-
}
62-
63-
for index < len(scriptraw) {
64-
b := int(scriptraw[index])
58+
for index < len(scriptBytes) {
59+
b := int(scriptBytes[index])
6560
if constant.CODE_OPS[b] != "" {
6661
commands = append(commands, constant.CODE_OPS[b])
6762
index++
6863
} else if !hasSegwit && b == 0x4c {
69-
bytesToRead := int(scriptraw[index+1])
64+
bytesToRead := int(scriptBytes[index+1])
7065
index++
71-
data := scriptraw[index : index+bytesToRead]
66+
data := scriptBytes[index : index+bytesToRead]
7267
commands = append(commands, hex.EncodeToString(data))
7368
index += bytesToRead
7469
} else if !hasSegwit && b == 0x4d {
75-
bytesToRead := int(binary.LittleEndian.Uint16(scriptraw[index+1 : index+3]))
70+
bytesToRead := int(binary.LittleEndian.Uint16(scriptBytes[index+1 : index+3]))
7671
index += 3
77-
data := scriptraw[index : index+bytesToRead]
72+
data := scriptBytes[index : index+bytesToRead]
7873
commands = append(commands, hex.EncodeToString(data))
7974
index += bytesToRead
8075
} else if !hasSegwit && b == 0x4e {
81-
bytesToRead := int(binary.LittleEndian.Uint32(scriptraw[index+1 : index+5]))
76+
bytesToRead := int(binary.LittleEndian.Uint32(scriptBytes[index+1 : index+5]))
8277
index += 5
83-
data := scriptraw[index : index+bytesToRead]
78+
data := scriptBytes[index : index+bytesToRead]
8479
commands = append(commands, hex.EncodeToString(data))
8580
index += bytesToRead
8681
} else {
87-
vi, size := formating.ViToInt(scriptraw[index:])
82+
vi, size := formating.ViToInt(scriptBytes[index:])
8883
dataSize := vi
8984
// size := size
9085
lastIndex := index + size + dataSize
91-
if lastIndex > len(scriptraw) {
92-
lastIndex = len(scriptraw)
86+
if lastIndex > len(scriptBytes) {
87+
lastIndex = len(scriptBytes)
9388
}
94-
commands = append(commands, hex.EncodeToString(scriptraw[index+size:lastIndex]))
89+
commands = append(commands, hex.EncodeToString(scriptBytes[index+size:lastIndex]))
9590
index += dataSize + size
9691
}
9792
}
@@ -100,8 +95,9 @@ func ScriptFromRaw(hexData string, hasSegwit bool) (*Script, error) {
10095

10196
// GetScriptType determines the script type based on the provided hash and whether it has
10297
// SegWit data. It returns the identified ScriptType.
103-
func GetScriptType(hash string, hasSegwit bool) (ScriptType, error) {
104-
s, err := ScriptFromRaw(hash, hasSegwit)
98+
func GetScriptType(scriptBytes []byte, hasSegwit bool) (ScriptType, error) {
99+
100+
s, err := ScriptFromRaw(scriptBytes, hasSegwit)
105101
if err != nil {
106102
return -1, err
107103
}

scripts/transaction.go

+12-11
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package scripts
22

33
import (
4+
"math/big"
5+
46
"github.com/mrtnetwork/bitcoin/constant"
57
"github.com/mrtnetwork/bitcoin/digest"
68
"github.com/mrtnetwork/bitcoin/formating"
7-
"math/big"
89
)
910

1011
// Define BtcTransaction struct
@@ -95,37 +96,37 @@ func (tx *BtcTransaction) Copy() *BtcTransaction {
9596
}
9697
}
9798
func BtcTransactionFromRaw(raw string) (*BtcTransaction, error) {
98-
rawtx := formating.HexToBytes(raw)
99+
txBytes := formating.HexToBytes(raw)
99100
cursor := 4
100101
var flag []byte
101102
hasSegwit := false
102103

103-
if rawtx[4] == 0 {
104-
flag = rawtx[5:6]
104+
if txBytes[4] == 0 {
105+
flag = txBytes[5:6]
105106
if flag[0] == 1 {
106107
hasSegwit = true
107108
}
108109
cursor += 2
109110
}
110111

111-
vi, viCursor := formating.ViToInt(rawtx[cursor:])
112+
vi, viCursor := formating.ViToInt(txBytes[cursor:])
112113
cursor += viCursor
113114

114115
inputs := make([]*TxInput, vi)
115116
for index := 0; index < len(inputs); index++ {
116-
inp, inpCursor, err := TxInputFromRaw(raw, cursor, hasSegwit)
117+
inp, inpCursor, err := TxInputFromRaw(txBytes, cursor, hasSegwit)
117118
if err != nil {
118119
return nil, err
119120
}
120121
inputs[index] = inp
121122
cursor = inpCursor
122123
}
123-
viOut, viOutCursor := formating.ViToInt(rawtx[cursor:])
124+
viOut, viOutCursor := formating.ViToInt(txBytes[cursor:])
124125
cursor += viOutCursor
125126

126127
outputs := make([]*TxOutput, viOut)
127128
for index := 0; index < len(outputs); index++ {
128-
out, outCursor, err := TxOutputFromRaw(raw, cursor, hasSegwit)
129+
out, outCursor, err := TxOutputFromRaw(txBytes, cursor, hasSegwit)
129130
if err != nil {
130131
return nil, err
131132
}
@@ -135,14 +136,14 @@ func BtcTransactionFromRaw(raw string) (*BtcTransaction, error) {
135136
witnesses := make([]TxWitnessInput, len(inputs))
136137
if hasSegwit {
137138
for n := 0; n < len(inputs); n++ {
138-
wVi, wViCursor := formating.ViToInt(rawtx[cursor:])
139+
wVi, wViCursor := formating.ViToInt(txBytes[cursor:])
139140
cursor += wViCursor
140141
witnessesTmp := make([]string, wVi)
141142
for m := 0; m < len(witnessesTmp); m++ {
142143
var witness []byte
143-
wtVi, wtViCursor := formating.ViToInt(rawtx[cursor:])
144+
wtVi, wtViCursor := formating.ViToInt(txBytes[cursor:])
144145
if wtVi != 0 {
145-
witness = rawtx[cursor+wtViCursor : cursor+wtViCursor+wtVi]
146+
witness = txBytes[cursor+wtViCursor : cursor+wtViCursor+wtVi]
146147
}
147148
cursor += wtViCursor + wtVi
148149
witnessesTmp[m] = formating.BytesToHex(witness)

scripts/tx_input.go

+12-15
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/binary"
55
"encoding/hex"
66
"fmt"
7+
78
"github.com/mrtnetwork/bitcoin/constant"
89
"github.com/mrtnetwork/bitcoin/formating"
910
)
@@ -81,45 +82,41 @@ func (ti *TxInput) ToBytes() []byte {
8182
}
8283

8384
// FromRaw parses a raw transaction input string into a TxInput
84-
func TxInputFromRaw(raw string, cursor int, hasSegwit bool) (*TxInput, int, error) {
85-
txInputRaw, err := formating.HexToBytesCatch(raw)
86-
if err != nil {
87-
return nil, cursor, err
88-
}
85+
func TxInputFromRaw(inputBytes []byte, cursor int, hasSegwit bool) (*TxInput, int, error) {
8986

90-
if cursor+32 >= len(txInputRaw) {
87+
if cursor+32 >= len(inputBytes) {
9188
return nil, cursor, fmt.Errorf("input transaction hash not found. Probably malformed raw transaction")
9289
}
9390

9491
inpHash := make([]byte, 32)
95-
copy(inpHash, formating.ReverseBytes(txInputRaw[cursor:cursor+32]))
92+
copy(inpHash, formating.ReverseBytes(inputBytes[cursor:cursor+32]))
9693
cursor += 32
9794

98-
if cursor+4 >= len(txInputRaw) {
95+
if cursor+4 >= len(inputBytes) {
9996
return nil, cursor, fmt.Errorf("output number not found. Probably malformed raw transaction")
10097
}
10198

102-
outputN := binary.LittleEndian.Uint32(formating.ReverseBytes(txInputRaw[cursor : cursor+4]))
99+
outputN := binary.LittleEndian.Uint32(inputBytes[cursor : cursor+4])
103100
cursor += 4
104101

105-
vi, viSize := formating.ViToInt(txInputRaw[cursor:])
102+
vi, viSize := formating.ViToInt(inputBytes[cursor:])
106103
cursor += viSize
107104

108-
if cursor+vi > len(txInputRaw) {
105+
if cursor+vi > len(inputBytes) {
109106
return nil, cursor, fmt.Errorf("unlocking script length exceeds available data. Probably malformed raw transaction")
110107
}
111108

112-
unlockingScript := txInputRaw[cursor : cursor+vi]
109+
unlockingScript := inputBytes[cursor : cursor+vi]
113110
cursor += vi
114111

115-
if cursor+4 > len(txInputRaw) {
112+
if cursor+4 > len(inputBytes) {
116113
return nil, cursor, fmt.Errorf("Sequence number not found. Probably malformed raw transaction")
117114
}
118115

119-
sequenceNumberData := txInputRaw[cursor : cursor+4]
116+
sequenceNumberData := inputBytes[cursor : cursor+4]
120117
cursor += 4
121118

122-
script, err := ScriptFromRaw(formating.BytesToHex(unlockingScript), hasSegwit)
119+
script, err := ScriptFromRaw(unlockingScript, hasSegwit)
123120
if err != nil {
124121
return nil, cursor, err
125122
}

scripts/tx_output.go

+8-7
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ package scripts
22

33
import (
44
"encoding/binary"
5-
"github.com/mrtnetwork/bitcoin/formating"
65
"math/big"
6+
7+
"github.com/mrtnetwork/bitcoin/formating"
78
)
89

910
type TxOutput struct {
@@ -42,19 +43,19 @@ func (txOutput *TxOutput) ToBytes() []byte {
4243
// raw The hexadecimal raw string of the Transaction
4344
// The cursor of which the algorithm will start to read the data
4445
// hasSegwit Is the Tx Output segwit or not
45-
func TxOutputFromRaw(raw string, cursor int, hasSegwit bool) (*TxOutput, int, error) {
46-
rawBytes := formating.HexToBytes(raw)
46+
func TxOutputFromRaw(outputBytes []byte, cursor int, hasSegwit bool) (*TxOutput, int, error) {
47+
4748
// Parse TxOutput from raw bytes
48-
value := int64(binary.LittleEndian.Uint64(rawBytes[cursor : cursor+8]))
49+
value := int64(binary.LittleEndian.Uint64(outputBytes[cursor : cursor+8]))
4950
cursor += 8
5051

51-
vi, viSize := formating.ViToInt(rawBytes[cursor:])
52+
vi, viSize := formating.ViToInt(outputBytes[cursor:])
5253
cursor += viSize
5354

54-
lockScript := rawBytes[cursor : cursor+vi]
55+
lockScript := outputBytes[cursor : cursor+vi]
5556
cursor += vi
5657

57-
scriptPubKey, err := ScriptFromRaw(formating.BytesToHex(lockScript), hasSegwit)
58+
scriptPubKey, err := ScriptFromRaw(lockScript, hasSegwit)
5859
if err != nil {
5960
return nil, cursor, err
6061
}

test/bip_39_test.go

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package test
22

33
import (
4-
"fmt"
5-
"github.com/mrtnetwork/bitcoin/bip39"
6-
"github.com/mrtnetwork/bitcoin/formating"
74
"testing"
5+
6+
"github.com/mrtnetwork/bitcoin/bip39"
87
)
98

109
func TestBip39(t *testing.T) {
@@ -26,13 +25,11 @@ func TestBip39(t *testing.T) {
2625

2726
// Select the desired number of words. 12(Words12), 15(Words15), 18(Words18), 21(Words21) or 24(Words24) words
2827
mnemonic, err := bip.GenerateMnemonic(bip39.Words24)
29-
fmt.Println("mnemonic: ", mnemonic)
3028
if err != nil {
3129
t.Errorf(err.Error())
3230
}
3331
// passphrase: An optional passphrase used for seed derivation. Can be an empty string.
34-
toSeed := bip39.ToSeed(mnemonic, "PASSPHRASE")
35-
fmt.Println("seed: ", formating.BytesToHex(toSeed))
32+
_ = bip39.ToSeed(mnemonic, "PASSPHRASE")
3633

3734
toEntropy, err := bip.MnemonicToEntropy(mnemonic)
3835
if err != nil {

test/hd_wallet_test.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package test
22

33
import (
4-
"fmt"
4+
"testing"
5+
56
"github.com/mrtnetwork/bitcoin/address"
67
hdwallet "github.com/mrtnetwork/bitcoin/hd_wallet"
7-
"testing"
88
)
99

1010
func TestHDWallet(t *testing.T) {
@@ -72,7 +72,6 @@ func TestHDWallet(t *testing.T) {
7272
}
7373

7474
p2wsh := publicKey.ToP2WSHAddress().Show(network)
75-
fmt.Println("p2wsh: ", p2wsh)
7675
if p2wsh != p2wshPublicWallet {
7776
t.Errorf("Expected %v, but got %v", p2wshPublicWallet, p2wsh)
7877
}

test/keys_test.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func TestP2pkhAddresses(t *testing.T) {
102102
if err == nil {
103103
fmt.Println(tx.Program().Hash160 == hash160)
104104
} else {
105-
print(err.Error())
105+
t.Errorf(err.Error())
106106
}
107107

108108
})
@@ -234,7 +234,6 @@ func TestP2trAddresses(t *testing.T) {
234234
t.Run("t7", func(t *testing.T) {
235235
pub := privOdd.GetPublic()
236236
program := pub.ToTaprootAddress().Program().Program
237-
fmt.Println("program: ", program)
238237
if !strings.EqualFold(program, correctOddTweakedPk) {
239238
t.Errorf("Expected %v, but got %v", correctOddTweakedPk, program)
240239
}

0 commit comments

Comments
 (0)