Skip to content

Commit e4f1f5c

Browse files
authored
Merge pull request #107 from kcalvinalvin/2024-01-07-full-taproot-support
txscript, main, blockchain, indexers, chaincfg: full taproot support
2 parents 69a9e5f + f71e9e7 commit e4f1f5c

File tree

2,798 files changed

+6890
-688
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

2,798 files changed

+6890
-688
lines changed

blockchain/indexers/addrindex.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ const (
6363
// script template, as well as a 32-byte data push.
6464
addrKeyTypeWitnessScriptHash = 3
6565

66+
// addrKeyTypeTaprootPubKey is the address type in an address key that
67+
// represnts a pay-to-taproot adress. We use this to denote addresses
68+
// related to the segwit v1 that are encoded in the bech32m format.
69+
addrKeyTypeTaprootPubKey = 4
70+
6671
// Size of a transaction entry. It consists of 4 bytes block id + 4
6772
// bytes offset + 4 bytes length.
6873
txEntrySize = 4 + 4 + 4
@@ -573,6 +578,16 @@ func addrToKey(addr btcutil.Address) ([addrKeySize]byte, error) {
573578
result[0] = addrKeyTypeWitnessPubKeyHash
574579
copy(result[1:], addr.Hash160()[:])
575580
return result, nil
581+
582+
case *btcutil.AddressTaproot:
583+
var result [addrKeySize]byte
584+
result[0] = addrKeyTypeTaprootPubKey
585+
586+
// Taproot outputs are actually just the 32-byte public key.
587+
// Similar to the P2WSH outputs, we'll map these to 20-bytes
588+
// via the hash160.
589+
copy(result[1:], btcutil.Hash160(addr.ScriptAddress()))
590+
return result, nil
576591
}
577592

578593
return [addrKeySize]byte{}, errUnsupportedAddressType

blockchain/scriptval.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,11 @@ out:
7474
witness := txIn.Witness
7575
pkScript := utxo.PkScript()
7676
inputAmount := utxo.Amount()
77-
vm, err := txscript.NewEngine(pkScript, txVI.tx.MsgTx(),
78-
txVI.txInIndex, v.flags, v.sigCache, txVI.sigHashes,
79-
inputAmount)
77+
vm, err := txscript.NewEngine(
78+
pkScript, txVI.tx.MsgTx(), txVI.txInIndex,
79+
v.flags, v.sigCache, txVI.sigHashes,
80+
inputAmount, v.utxoView,
81+
)
8082
if err != nil {
8183
str := fmt.Sprintf("failed to parse input "+
8284
"%s:%d which references output %v - "+
@@ -201,7 +203,7 @@ func ValidateTransactionScripts(tx *btcutil.Tx, utxoView *UtxoViewpoint,
201203
// amongst all worker validation goroutines.
202204
if segwitActive && tx.MsgTx().HasWitness() &&
203205
!hashCache.ContainsHashes(tx.Hash()) {
204-
hashCache.AddSigHashes(tx.MsgTx())
206+
hashCache.AddSigHashes(tx.MsgTx(), utxoView)
205207
}
206208

207209
var cachedHashes *txscript.TxSigHashes
@@ -266,15 +268,17 @@ func checkBlockScripts(block *btcutil.Block, utxoView *UtxoViewpoint,
266268
if segwitActive && tx.HasWitness() && hashCache != nil &&
267269
!hashCache.ContainsHashes(hash) {
268270

269-
hashCache.AddSigHashes(tx.MsgTx())
271+
hashCache.AddSigHashes(tx.MsgTx(), utxoView)
270272
}
271273

272274
var cachedHashes *txscript.TxSigHashes
273275
if segwitActive && tx.HasWitness() {
274276
if hashCache != nil {
275277
cachedHashes, _ = hashCache.GetSigHashes(hash)
276278
} else {
277-
cachedHashes = txscript.NewTxSigHashes(tx.MsgTx())
279+
cachedHashes = txscript.NewTxSigHashes(
280+
tx.MsgTx(), utxoView,
281+
)
278282
}
279283
}
280284

blockchain/thresholdstate.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ func thresholdStateTransition(state ThresholdState, prevNode *blockNode,
171171
// speed deployments can only transition to failed
172172
// after a confirmation window.
173173
if !checker.IsSpeedy() && checker.HasEnded(prevNode) {
174+
log.Debugf("Moving from state=%v, to state=%v", state,
175+
ThresholdFailed)
176+
174177
state = ThresholdFailed
175178
break
176179
}
@@ -179,6 +182,9 @@ func thresholdStateTransition(state ThresholdState, prevNode *blockNode,
179182
// once its start time has been reached (and it hasn't
180183
// already expired per the above).
181184
if checker.HasStarted(prevNode) {
185+
log.Debugf("Moving from state=%v, to state=%v", state,
186+
ThresholdStarted)
187+
182188
state = ThresholdStarted
183189
}
184190

@@ -187,6 +193,9 @@ func thresholdStateTransition(state ThresholdState, prevNode *blockNode,
187193
// expires before it is accepted and locked in, but
188194
// only if this deployment isn't speedy.
189195
if !checker.IsSpeedy() && checker.HasEnded(prevNode) {
196+
log.Debugf("Moving from state=%v, to state=%v", state,
197+
ThresholdFailed)
198+
190199
state = ThresholdFailed
191200
break
192201
}
@@ -214,13 +223,23 @@ func thresholdStateTransition(state ThresholdState, prevNode *blockNode,
214223
// period that voted for the rule change meets the
215224
// activation threshold.
216225
case count >= checker.RuleChangeActivationThreshold():
226+
log.Debugf("Moving from state=%v, to state=%v", state,
227+
ThresholdLockedIn)
228+
217229
state = ThresholdLockedIn
218230

219231
// If this is a speedy deployment, we didn't meet the
220232
// threshold above, and the deployment has expired, then
221233
// we transition to failed.
222234
case checker.IsSpeedy() && checker.HasEnded(prevNode):
235+
log.Debugf("Moving from state=%v, to state=%v", state,
236+
ThresholdFailed)
237+
223238
state = ThresholdFailed
239+
240+
default:
241+
log.Tracef("Still at state=%v, threshold=%v", state,
242+
float64(count)/float64(checker.RuleChangeActivationThreshold()))
224243
}
225244

226245
case ThresholdLockedIn:
@@ -232,8 +251,14 @@ func thresholdStateTransition(state ThresholdState, prevNode *blockNode,
232251
// If we aren't eligible to active yet, then we'll just
233252
// stay in the locked in position.
234253
if !checker.EligibleToActivate(prevNode) {
254+
log.Debugf("Moving from state=%v, to state=%v", state,
255+
ThresholdLockedIn)
256+
235257
state = ThresholdLockedIn
236258
} else {
259+
log.Debugf("Moving from state=%v, to state=%v", state,
260+
ThresholdActive)
261+
237262
// The new rule becomes active when its
238263
// previous state was locked in assuming it's
239264
// now eligible to activate.

blockchain/validate.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,18 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block,
12401240
scriptFlags |= txscript.ScriptStrictMultiSig
12411241
}
12421242

1243+
// Before we execute the main scripts, we'll also check to see if
1244+
// taproot is active or not.
1245+
taprootState, err := b.deploymentState(
1246+
node.parent, chaincfg.DeploymentTaproot,
1247+
)
1248+
if err != nil {
1249+
return err
1250+
}
1251+
if taprootState == ThresholdActive {
1252+
scriptFlags |= txscript.ScriptVerifyTaproot
1253+
}
1254+
12431255
// Now that the inexpensive checks are done and have passed, verify the
12441256
// transactions are actually allowed to spend the coins by running the
12451257
// expensive ECDSA signature check scripts. Doing this last helps

blockchain/versionbits.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ func (c deploymentChecker) HasEnded(blkNode *blockNode) bool {
187187
// This is part of the thresholdConditionChecker interface implementation.
188188
func (c deploymentChecker) RuleChangeActivationThreshold() uint32 {
189189
// Some deployments like taproot used a custom activation threshold
190-
// that ovverides the network level threshold.
190+
// that overrides the network level threshold.
191191
if c.deployment.CustomActivationThreshold != 0 {
192192
return c.deployment.CustomActivationThreshold
193193
}
@@ -234,7 +234,8 @@ func (c deploymentChecker) EligibleToActivate(blkNode *blockNode) bool {
234234
//
235235
// This is part of the thresholdConditionChecker interface implementation.
236236
func (c deploymentChecker) IsSpeedy() bool {
237-
return c.deployment.MinActivationHeight != 0
237+
return (c.deployment.MinActivationHeight != 0 ||
238+
c.deployment.CustomActivationThreshold != 0)
238239
}
239240

240241
// Condition returns true when the specific bit defined by the deployment

chaincfg/chainhash/hash.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,33 @@ var (
3030
// TagBIP0340Nonce is the BIP-0340 tag for nonces.
3131
TagBIP0340Nonce = []byte("BIP0340/nonce")
3232

33+
// TagTapSighash is the tag used by BIP 341 to generate the sighash
34+
// flags.
35+
TagTapSighash = []byte("TapSighash")
36+
37+
// TagTagTapLeaf is the message tag prefix used to compute the hash
38+
// digest of a tapscript leaf.
39+
TagTapLeaf = []byte("TapLeaf")
40+
41+
// TagTapBranch is the message tag prefix used to compute the
42+
// hash digest of two tap leaves into a taproot branch node.
43+
TagTapBranch = []byte("TapBranch")
44+
45+
// TagTapTweak is the message tag prefix used to compute the hash tweak
46+
// used to enable a public key to commit to the taproot branch root
47+
// for the witness program.
48+
TagTapTweak = []byte("TapTweak")
49+
3350
// precomputedTags is a map containing the SHA-256 hash of the BIP-0340
3451
// tags.
3552
precomputedTags = map[string]Hash{
3653
string(TagBIP0340Challenge): sha256.Sum256(TagBIP0340Challenge),
3754
string(TagBIP0340Aux): sha256.Sum256(TagBIP0340Aux),
3855
string(TagBIP0340Nonce): sha256.Sum256(TagBIP0340Nonce),
56+
string(TagTapSighash): sha256.Sum256(TagTapSighash),
57+
string(TagTapLeaf): sha256.Sum256(TagTapLeaf),
58+
string(TagTapBranch): sha256.Sum256(TagTapBranch),
59+
string(TagTapTweak): sha256.Sum256(TagTapTweak),
3960
}
4061
)
4162

chaincfg/params.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,11 @@ const (
141141
// includes the deployment of BIPS 141, 142, 144, 145, 147 and 173.
142142
DeploymentSegwit
143143

144+
// DeploymentTaproot defines the rule change deployment ID for the
145+
// Taproot (+Schnorr) soft-fork package. The taproot package includes
146+
// the deployment of BIPS 340, 341 and 342.
147+
DeploymentTaproot
148+
144149
// NOTE: DefinedDeployments must always come last since it is used to
145150
// determine how many defined deployments there currently are.
146151

@@ -378,6 +383,17 @@ var MainNetParams = Params{
378383
time.Unix(1510704000, 0), // November 15, 2017 UTC.
379384
),
380385
},
386+
DeploymentTaproot: {
387+
BitNumber: 2,
388+
DeploymentStarter: NewMedianTimeDeploymentStarter(
389+
time.Unix(1619222400, 0), // April 24th, 2021 UTC.
390+
),
391+
DeploymentEnder: NewMedianTimeDeploymentEnder(
392+
time.Unix(1628640000, 0), // August 11th, 2021 UTC.
393+
),
394+
CustomActivationThreshold: 1815, // 90%
395+
MinActivationHeight: 709_632,
396+
},
381397
},
382398

383399
// Mempool parameters
@@ -477,6 +493,16 @@ var RegressionNetParams = Params{
477493
time.Time{}, // Never expires.
478494
),
479495
},
496+
DeploymentTaproot: {
497+
BitNumber: 2,
498+
DeploymentStarter: NewMedianTimeDeploymentStarter(
499+
time.Time{}, // Always available for vote
500+
),
501+
DeploymentEnder: NewMedianTimeDeploymentEnder(
502+
time.Time{}, // Never expires.
503+
),
504+
CustomActivationThreshold: 1512, // 75%
505+
},
480506
},
481507

482508
// Mempool parameters
@@ -601,6 +627,16 @@ var TestNet3Params = Params{
601627
time.Unix(1493596800, 0), // May 1, 2017 UTC.
602628
),
603629
},
630+
DeploymentTaproot: {
631+
BitNumber: 2,
632+
DeploymentStarter: NewMedianTimeDeploymentStarter(
633+
time.Unix(1619222400, 0), // April 24th, 2021 UTC.
634+
),
635+
DeploymentEnder: NewMedianTimeDeploymentEnder(
636+
time.Unix(1628640000, 0), // August 11th, 2021 UTC
637+
),
638+
CustomActivationThreshold: 1512, // 75%
639+
},
604640
},
605641

606642
// Mempool parameters
@@ -704,6 +740,16 @@ var SimNetParams = Params{
704740
time.Time{}, // Never expires.
705741
),
706742
},
743+
DeploymentTaproot: {
744+
BitNumber: 2,
745+
DeploymentStarter: NewMedianTimeDeploymentStarter(
746+
time.Time{}, // Always available for vote
747+
),
748+
DeploymentEnder: NewMedianTimeDeploymentEnder(
749+
time.Time{}, // Never expires.
750+
),
751+
CustomActivationThreshold: 1815, // 90%
752+
},
707753
},
708754

709755
// Mempool parameters
@@ -822,6 +868,15 @@ func CustomSignetParams(challenge []byte, dnsSeeds []DNSSeed) Params {
822868
time.Time{}, // Never expires
823869
),
824870
},
871+
DeploymentTaproot: {
872+
BitNumber: 29,
873+
DeploymentStarter: NewMedianTimeDeploymentStarter(
874+
time.Time{}, // Always available for vote
875+
),
876+
DeploymentEnder: NewMedianTimeDeploymentEnder(
877+
time.Time{}, // Never expires
878+
),
879+
},
825880
},
826881

827882
// Mempool parameters

go.mod

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,35 @@ module github.com/utreexo/utreexod
33
require (
44
github.com/aead/siphash v1.0.1
55
github.com/btcsuite/btcd v0.24.0
6+
github.com/btcsuite/btcd/btcec/v2 v2.1.3
67
github.com/btcsuite/btcd/btcutil v1.1.5
8+
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0
79
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f
810
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd
911
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792
1012
github.com/btcsuite/winsvc v1.0.0
1113
github.com/davecgh/go-spew v1.1.1
14+
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1
1215
github.com/decred/dcrd/lru v1.0.0
1316
github.com/jessevdk/go-flags v1.4.0
1417
github.com/jrick/logrotate v1.0.0
1518
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23
19+
github.com/stretchr/testify v1.7.0
1620
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
1721
github.com/utreexo/utreexo v0.0.0-20240107135703-1173e8c06c0a
1822
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
1923
)
2024

2125
require (
22-
github.com/btcsuite/btcd/btcec/v2 v2.1.3 // indirect
23-
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect
2426
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce // indirect
2527
github.com/btcsuite/goleveldb v1.0.0 // indirect
2628
github.com/btcsuite/snappy-go v1.0.0 // indirect
2729
github.com/decred/dcrd/crypto/blake256 v1.0.0 // indirect
28-
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
2930
github.com/golang/snappy v0.0.4 // indirect
31+
github.com/pmezard/go-difflib v1.0.0 // indirect
3032
golang.org/x/exp v0.0.0-20220414153411-bcd21879b8fd // indirect
3133
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 // indirect
34+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
3235
)
3336

3437
go 1.18

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,10 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
9191
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
9292
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
9393
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
94+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
9495
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
9596
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
97+
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
9698
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
9799
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM=
98100
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
@@ -158,6 +160,7 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ
158160
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
159161
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
160162
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
163+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
161164
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
162165
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
163166
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
@@ -166,4 +169,5 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
166169
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
167170
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
168171
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
172+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
169173
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

rpcserver.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,6 +1274,9 @@ func handleGetBlockChainInfo(s *rpcServer, cmd interface{}, closeChan <-chan str
12741274
case chaincfg.DeploymentSegwit:
12751275
forkName = "segwit"
12761276

1277+
case chaincfg.DeploymentTaproot:
1278+
forkName = "taproot"
1279+
12771280
default:
12781281
return nil, &btcjson.RPCError{
12791282
Code: btcjson.ErrRPCInternal.Code,

txscript/bench_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ func BenchmarkCalcSigHash(b *testing.B) {
5555
// BenchmarkCalcWitnessSigHash benchmarks how long it takes to calculate the
5656
// witness signature hashes for all inputs of a transaction with many inputs.
5757
func BenchmarkCalcWitnessSigHash(b *testing.B) {
58-
sigHashes := NewTxSigHashes(&manyInputsBenchTx)
58+
prevOutFetcher := NewCannedPrevOutputFetcher(prevOutScript, 5)
59+
sigHashes := NewTxSigHashes(&manyInputsBenchTx, prevOutFetcher)
5960

6061
b.ResetTimer()
6162
b.ReportAllocs()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"tx": "0100000003bcb2054607a921b3c6df992a9486776863b28485e731a805931b6feb14221acff2000000001c75619cdff9d694a434b13abfbbd618e2ece4460f24b4821cf47d5afc481a386c59565c4900000000cff75994dceb5f5568f8ada45d428630f512fb8efacd46682b4367b4edaf1985c5e4af4b07010000003c029216047236f3000000000017a9141d5a2c690c3e2dacb3cead240f0ce4a273b9d0e48758020000000000001600149d38710eb90e420b159c7a9263994c88e6810bc758020000000000001976a91490770ceff2b1c32e9dbf952fbe65b04a54d1949388ac580200000000000017a914f017945d4d088c7d42ab3bcbc1adce51d74fbd9f8784d7ee4b", "prevouts": ["ac7783000000000017a91408247b8d3db4e641d0be1ff23f14280256870a5187", "06404d000000000017a914b60a534933f6e50f3846e396b9868efc9e681f4187", "4408250000000000225120103e7c2917eb37935b19ad951dd63925690af67710d97c5b32ba23098190dae6"], "index": 1, "flags": "P2SH,DERSIG,CHECKLOCKTIMEVERIFY,CHECKSEQUENCEVERIFY,WITNESS,NULLDUMMY,TAPROOT", "comment": "applic/scriptpath", "success": {"scriptSig": "225c202540f27e90740933c99d4f17ab2dfc6c82951cfb0b8674c83ad179cfbc247b89", "witness": ["b51b9ccaaea9fd42c652f402c720f9204800e00b2f8ae4766b7fcfa164231fc81d8a8900ca86e7a871b94e86ceded7cff43db52b7ae760520079a117b3a2a562", "207d732801de7e0c866f2462f29c14b63e555159b62ba93a5d5963d1c04795f936ac", "c0871bf677dcc1eeea213f60505c1c9f1695f8b7d2ee8bbacb3ba246e9f1e57e2046c7eccffefd2d573ec014130e508f0c9963ccebd7830409f7b1b1301725e9fa"]}},
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"tx": "010000000260f8b8616e71e7ed05613145ce7cda782ac9861e64f9ce24e333ca1e91d912708900000000676b3469dceb5f5568f8ada45d428630f512fb8efacd46682b4367b4edaf1985c5e4af4b2101000000e54ad34c04af0b30000000000017a914719f78084af863e000acd618ba76df979722368987580200000000000017a9141d5a2c690c3e2dacb3cead240f0ce4a273b9d0e487580200000000000017a914f017945d4d088c7d42ab3bcbc1adce51d74fbd9f8758020000000000001976a91401f109af244d8c7f2563284ac2d2ba7d6323a75e88ac6f000000", "prevouts": ["d015120000000000225120eeb645229ded9c683f00135b937b2e4e86df68d251777aa040a582f59863bb1e", "65ee200000000000225120d822e1bd1f5ea10d0aa44b8067d00045600d13617c1c35db91f3c0990a68d49e"], "index": 0, "flags": "P2SH,DERSIG,CHECKLOCKTIMEVERIFY,CHECKSEQUENCEVERIFY,WITNESS,NULLDUMMY,TAPROOT", "comment": "opsuccess/undecodable", "success": {"scriptSig": "", "witness": ["d14c", "c07d732801de7e0c866f2462f29c14b63e555159b62ba93a5d5963d1c04795f93699aaf103cceb41d9bc37ec231aca89b984b5fd3c65977ce764d51033ac65adb4595f1c75585029ef5fafe40c7b455be7b6317879deb123e683907f6588babc52172c8da9bdd43b70cbab8912ef1aa7926e5ad7e47a4f7b71ac936200cc947dd0f9b27230787fc79bd718ce7ac07558dd4f31dfc3ae0570acbd1df01407b1d4ec"]}, "failure": {"scriptSig": "", "witness": ["614c", "c07d732801de7e0c866f2462f29c14b63e555159b62ba93a5d5963d1c04795f93657385cfb449c384dd2171856b934522ab5b17115bbddd9e3700a77caba093451595f1c75585029ef5fafe40c7b455be7b6317879deb123e683907f6588babc52172c8da9bdd43b70cbab8912ef1aa7926e5ad7e47a4f7b71ac936200cc947dd0f9b27230787fc79bd718ce7ac07558dd4f31dfc3ae0570acbd1df01407b1d4ec"]}},

0 commit comments

Comments
 (0)