txscript: code cleanup

- switch if-else to switch/case for readability
- remove unused params
This commit is contained in:
David Hill 2019-01-30 16:38:16 -05:00
parent 457a797a03
commit b1bbf8091b
8 changed files with 90 additions and 84 deletions

View File

@ -1,5 +1,5 @@
// Copyright (c) 2013-2017 The btcsuite developers
// Copyright (c) 2015-2018 The Decred developers
// Copyright (c) 2015-2019 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -302,10 +302,11 @@ func (vm *Engine) Step() (done bool, err error) {
vm.numOps = 0 // number of ops is per script.
vm.scriptOff = 0
if vm.scriptIdx == 0 && vm.bip16 {
switch {
case vm.scriptIdx == 0 && vm.bip16:
vm.scriptIdx++
vm.savedFirstStack = vm.GetStack()
} else if vm.scriptIdx == 1 && vm.bip16 {
case vm.scriptIdx == 1 && vm.bip16:
// Put us past the end for CheckErrorCondition()
vm.scriptIdx++
// Check script ran successfully and pull the script
@ -325,7 +326,7 @@ func (vm *Engine) Step() (done bool, err error) {
// Set stack to be the stack from first script minus the
// script itself
vm.SetStack(vm.savedFirstStack[:len(vm.savedFirstStack)-1])
} else {
default:
vm.scriptIdx++
}
// there are zero length scripts in the wild

View File

@ -1,5 +1,5 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Copyright (c) 2015-2017 The Decred developers
// Copyright (c) 2015-2019 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -684,11 +684,12 @@ func (pop *parsedOpcode) checkMinimalDataPush() error {
dataLen := len(data)
opcode := pop.opcode.value
if dataLen == 0 && opcode != OP_0 {
switch {
case dataLen == 0 && opcode != OP_0:
str := fmt.Sprintf("zero length data push is encoded with "+
"opcode %s instead of OP_0", pop.opcode.name)
return scriptError(ErrMinimalData, str)
} else if dataLen == 1 && data[0] >= 1 && data[0] <= 16 {
case dataLen == 1 && data[0] >= 1 && data[0] <= 16:
if opcode != OP_1+data[0]-1 {
// Should have used OP_1 .. OP_16
str := fmt.Sprintf("data push of the value %d encoded "+
@ -696,14 +697,14 @@ func (pop *parsedOpcode) checkMinimalDataPush() error {
pop.opcode.name, data[0])
return scriptError(ErrMinimalData, str)
}
} else if dataLen == 1 && data[0] == 0x81 {
case dataLen == 1 && data[0] == 0x81:
if opcode != OP_1NEGATE {
str := fmt.Sprintf("data push of the value -1 encoded "+
"with opcode %s instead of OP_1NEGATE",
pop.opcode.name)
return scriptError(ErrMinimalData, str)
}
} else if dataLen <= 75 {
case dataLen <= 75:
if int(opcode) != dataLen {
// Should have used a direct push
str := fmt.Sprintf("data push of %d bytes encoded "+
@ -711,14 +712,14 @@ func (pop *parsedOpcode) checkMinimalDataPush() error {
pop.opcode.name, dataLen)
return scriptError(ErrMinimalData, str)
}
} else if dataLen <= 255 {
case dataLen <= 255:
if opcode != OP_PUSHDATA1 {
str := fmt.Sprintf("data push of %d bytes encoded "+
"with opcode %s instead of OP_PUSHDATA1",
dataLen, pop.opcode.name)
return scriptError(ErrMinimalData, str)
}
} else if dataLen <= 65535 {
case dataLen <= 65535:
if opcode != OP_PUSHDATA2 {
str := fmt.Sprintf("data push of %d bytes encoded "+
"with opcode %s instead of OP_PUSHDATA2",
@ -2501,7 +2502,7 @@ func opcodeBlake256(op *parsedOpcode, vm *Engine) error {
}
hash := chainhash.HashB(buf)
vm.dstack.PushByteArray(hash[:])
vm.dstack.PushByteArray(hash)
return nil
}
@ -2541,7 +2542,7 @@ func opcodeHash160(op *parsedOpcode, vm *Engine) error {
}
hash := chainhash.HashB(buf)
vm.dstack.PushByteArray(calcHash(hash[:], ripemd160.New()))
vm.dstack.PushByteArray(calcHash(hash, ripemd160.New()))
return nil
}

View File

@ -1,5 +1,5 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Copyright (c) 2015-2018 The Decred developers
// Copyright (c) 2015-2019 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -103,19 +103,19 @@ func CanonicalDataSize(data []byte) int {
// When the data consists of a single number that can be represented
// by one of the "small integer" opcodes, that opcode will be instead
// of a data push opcode followed by the number.
if dataLen == 0 {
return 1
} else if dataLen == 1 && data[0] <= 16 {
return 1
} else if dataLen == 1 && data[0] == 0x81 {
switch {
case dataLen == 0,
dataLen == 1 && data[0] <= 16,
dataLen == 1 && data[0] == 0x81:
return 1
}
if dataLen < OP_PUSHDATA1 {
switch {
case dataLen < OP_PUSHDATA1:
return 1 + dataLen
} else if dataLen <= 0xff {
case dataLen <= 0xff:
return 2 + dataLen
} else if dataLen <= 0xffff {
case dataLen <= 0xffff:
return 3 + dataLen
}
@ -132,13 +132,14 @@ func (b *ScriptBuilder) addData(data []byte) *ScriptBuilder {
// When the data consists of a single number that can be represented
// by one of the "small integer" opcodes, use that opcode instead of
// a data push opcode followed by the number.
if dataLen == 0 || dataLen == 1 && data[0] == 0 {
switch {
case dataLen == 0 || dataLen == 1 && data[0] == 0:
b.script = append(b.script, OP_0)
return b
} else if dataLen == 1 && data[0] <= 16 {
case dataLen == 1 && data[0] <= 16:
b.script = append(b.script, OP_1-1+data[0])
return b
} else if dataLen == 1 && data[0] == 0x81 {
case dataLen == 1 && data[0] == 0x81:
b.script = append(b.script, byte(OP_1NEGATE))
return b
}
@ -147,16 +148,17 @@ func (b *ScriptBuilder) addData(data []byte) *ScriptBuilder {
// enough so the data push instruction is only a single byte.
// Otherwise, choose the smallest possible OP_PUSHDATA# opcode that
// can represent the length of the data.
if dataLen < OP_PUSHDATA1 {
switch {
case dataLen < OP_PUSHDATA1:
b.script = append(b.script, byte((OP_DATA_1-1)+dataLen))
} else if dataLen <= 0xff {
case dataLen <= 0xff:
b.script = append(b.script, OP_PUSHDATA1, byte(dataLen))
} else if dataLen <= 0xffff {
case dataLen <= 0xffff:
buf := make([]byte, 2)
binary.LittleEndian.PutUint16(buf, uint16(dataLen))
b.script = append(b.script, OP_PUSHDATA2)
b.script = append(b.script, buf...)
} else {
default:
buf := make([]byte, 4)
binary.LittleEndian.PutUint32(buf, uint32(dataLen))
b.script = append(b.script, OP_PUSHDATA4)

View File

@ -1,5 +1,5 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Copyright (c) 2015-2018 The Decred developers
// Copyright (c) 2015-2019 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -202,7 +202,7 @@ func sigHashPrefixSerializeSize(hashType SigHashType, txIns []*wire.TxIn, txOuts
// sigHashWitnessSerializeSize returns the number of bytes the passed parameters
// would take when encoded with the format used by the witness hash portion of
// the overall signature hash.
func sigHashWitnessSerializeSize(hashType SigHashType, txIns []*wire.TxIn, signScript []byte) int {
func sigHashWitnessSerializeSize(txIns []*wire.TxIn, signScript []byte) int {
// 1) 4 bytes version/serialization type
// 2) number of inputs varint
// 3) per input:
@ -411,7 +411,7 @@ func calcSignatureHash(prevOutScript []parsedOpcode, hashType SigHashType, tx *w
// a) length of prevout pkscript (as varint)
// b) prevout pkscript (as unmodified bytes)
size := sigHashWitnessSerializeSize(hashType, txIns, signScript)
size := sigHashWitnessSerializeSize(txIns, signScript)
witnessBuf := make([]byte, size)
// Commit to the version and hash serialization type.

View File

@ -1,5 +1,5 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Copyright (c) 2015-2016 The Decred developers
// Copyright (c) 2015-2019 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -191,8 +191,8 @@ func signMultiSig(tx *wire.MsgTx, idx int, subScript []byte, hashType SigHashTyp
// handleStakeOutSign is a convenience function for reducing code clutter in
// sign. It handles the signing of stake outputs.
func handleStakeOutSign(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int,
subScript []byte, hashType SigHashType, kdb KeyDB, sdb ScriptDB,
func handleStakeOutSign(tx *wire.MsgTx, idx int, subScript []byte,
hashType SigHashType, kdb KeyDB, sdb ScriptDB,
addresses []dcrutil.Address, class ScriptClass, subClass ScriptClass,
nrequired int) ([]byte, ScriptClass, []dcrutil.Address, int, error) {
@ -325,19 +325,19 @@ func sign(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int,
return script, class, addresses, nrequired, nil
case StakeSubmissionTy:
return handleStakeOutSign(chainParams, tx, idx, subScript, hashType, kdb,
return handleStakeOutSign(tx, idx, subScript, hashType, kdb,
sdb, addresses, class, subClass, nrequired)
case StakeGenTy:
return handleStakeOutSign(chainParams, tx, idx, subScript, hashType, kdb,
return handleStakeOutSign(tx, idx, subScript, hashType, kdb,
sdb, addresses, class, subClass, nrequired)
case StakeRevocationTy:
return handleStakeOutSign(chainParams, tx, idx, subScript, hashType, kdb,
return handleStakeOutSign(tx, idx, subScript, hashType, kdb,
sdb, addresses, class, subClass, nrequired)
case StakeSubChangeTy:
return handleStakeOutSign(chainParams, tx, idx, subScript, hashType, kdb,
return handleStakeOutSign(tx, idx, subScript, hashType, kdb,
sdb, addresses, class, subClass, nrequired)
case NullDataTy:

View File

@ -1,5 +1,5 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Copyright (c) 2015-2018 The Decred developers
// Copyright (c) 2015-2019 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -102,7 +102,7 @@ func checkScripts(msg string, tx *wire.MsgTx, idx int, sigScript, pkScript []byt
func signAndCheck(msg string, tx *wire.MsgTx, idx int, pkScript []byte,
hashType SigHashType, kdb KeyDB, sdb ScriptDB,
previousScript []byte, suite dcrec.SignatureType) error {
suite dcrec.SignatureType) error {
sigScript, err := SignTxOutput(testingParams, tx, idx, pkScript,
hashType, kdb, sdb, nil, suite)
@ -115,7 +115,7 @@ func signAndCheck(msg string, tx *wire.MsgTx, idx int, pkScript []byte,
func signBadAndCheck(msg string, tx *wire.MsgTx, idx int, pkScript []byte,
hashType SigHashType, kdb KeyDB, sdb ScriptDB,
previousScript []byte, suite dcrec.SignatureType) error {
suite dcrec.SignatureType) error {
// Setup a PRNG.
randScriptHash := chainhash.HashB(pkScript)
tRand := mrand.New(mrand.NewSource(int64(randScriptHash[0])))
@ -259,7 +259,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {&key, false},
}), mkGetScript(nil), nil, suite); err != nil {
}), mkGetScript(nil), suite); err != nil {
t.Error(err)
break
}
@ -267,7 +267,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signBadAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {&key, false},
}), mkGetScript(nil), nil, suite); err == nil {
}), mkGetScript(nil), suite); err == nil {
t.Errorf("corrupted signature validated %s: %v",
msg, err)
break
@ -393,7 +393,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {&key, true},
}), mkGetScript(nil), nil, suite); err != nil {
}), mkGetScript(nil), suite); err != nil {
t.Error(err)
break
}
@ -401,7 +401,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signBadAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {&key, true},
}), mkGetScript(nil), nil, suite); err == nil {
}), mkGetScript(nil), suite); err == nil {
t.Errorf("corrupted signature validated %s: %v",
msg, err)
break
@ -515,7 +515,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {&key, true},
}), mkGetScript(nil), nil,
}), mkGetScript(nil),
dcrec.STEcdsaSecp256k1); err != nil {
t.Error(err)
break
@ -524,7 +524,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signBadAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {&key, true},
}), mkGetScript(nil), nil,
}), mkGetScript(nil),
dcrec.STEcdsaSecp256k1); err == nil {
t.Errorf("corrupted signature validated %s: %v",
msg, err)
@ -564,7 +564,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {&key, true},
}), mkGetScript(nil), nil,
}), mkGetScript(nil),
dcrec.STEcdsaSecp256k1); err != nil {
t.Error(err)
break
@ -573,7 +573,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signBadAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {&key, true},
}), mkGetScript(nil), nil,
}), mkGetScript(nil),
dcrec.STEcdsaSecp256k1); err == nil {
t.Errorf("corrupted signature validated %s: %v",
msg, err)
@ -613,7 +613,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {&key, true},
}), mkGetScript(nil), nil,
}), mkGetScript(nil),
dcrec.STEcdsaSecp256k1); err != nil {
t.Error(err)
break
@ -622,7 +622,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signBadAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {&key, true},
}), mkGetScript(nil), nil,
}), mkGetScript(nil),
dcrec.STEcdsaSecp256k1); err == nil {
t.Errorf("corrupted signature validated %s: %v",
msg, err)
@ -662,7 +662,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {&key, true},
}), mkGetScript(nil), nil,
}), mkGetScript(nil),
dcrec.STEcdsaSecp256k1); err != nil {
t.Error(err)
break
@ -671,7 +671,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signBadAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {&key, true},
}), mkGetScript(nil), nil,
}), mkGetScript(nil),
dcrec.STEcdsaSecp256k1); err == nil {
t.Errorf("corrupted signature validated %s: %v",
msg, err)
@ -712,7 +712,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {&key, false},
}), mkGetScript(nil), nil, suite); err != nil {
}), mkGetScript(nil), suite); err != nil {
t.Error(err)
break
}
@ -720,7 +720,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signBadAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {&key, false},
}), mkGetScript(nil), nil, suite); err == nil {
}), mkGetScript(nil), suite); err == nil {
t.Errorf("corrupted signature validated %s: %v",
msg, err)
break
@ -873,7 +873,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signAndCheck(msg, tx, i, pkScript, hashType,
mkGetKeyPub(map[string]addressToKey{
address.String(): {&key, true},
}), mkGetScript(nil), nil, suite); err != nil {
}), mkGetScript(nil), suite); err != nil {
t.Error(err)
break
}
@ -881,7 +881,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signBadAndCheck(msg, tx, i, pkScript, hashType,
mkGetKeyPub(map[string]addressToKey{
address.String(): {&key, true},
}), mkGetScript(nil), nil, suite); err == nil {
}), mkGetScript(nil), suite); err == nil {
t.Errorf("corrupted signature validated %s: %v",
msg, err)
break
@ -1039,7 +1039,7 @@ func TestSignTxOutput(t *testing.T) {
address.EncodeAddress(): {&key, false},
}), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript,
}), nil, suite); err != nil {
}), suite); err != nil {
t.Error(err)
break
}
@ -1047,7 +1047,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signBadAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {&key, false},
}), mkGetScript(nil), nil, suite); err == nil {
}), mkGetScript(nil), suite); err == nil {
t.Errorf("corrupted signature validated %s: %v",
msg, err)
break
@ -1211,7 +1211,7 @@ func TestSignTxOutput(t *testing.T) {
address.EncodeAddress(): {&key, true},
}), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript,
}), nil, suite); err != nil {
}), suite); err != nil {
t.Error(err)
break
}
@ -1219,7 +1219,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signBadAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {&key, true},
}), mkGetScript(nil), nil, suite); err == nil {
}), mkGetScript(nil), suite); err == nil {
t.Errorf("corrupted signature validated %s: %v",
msg, err)
break
@ -1396,14 +1396,14 @@ func TestSignTxOutput(t *testing.T) {
address.EncodeAddress(): {&key, false},
}), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript,
}), nil, suite); err != nil {
}), suite); err != nil {
t.Error(err)
}
if err := signBadAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {&key, false},
}), mkGetScript(nil), nil, suite); err == nil {
}), mkGetScript(nil), suite); err == nil {
t.Errorf("corrupted signature validated %s: %v",
msg, err)
break
@ -1593,7 +1593,7 @@ func TestSignTxOutput(t *testing.T) {
address.EncodeAddress(): {&key, true},
}), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript,
}), nil, suite); err != nil {
}), suite); err != nil {
t.Error(err)
break
}
@ -1601,7 +1601,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signBadAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {&key, false},
}), mkGetScript(nil), nil, suite); err == nil {
}), mkGetScript(nil), suite); err == nil {
t.Errorf("corrupted signature validated %s: %v",
msg, err)
break
@ -1781,7 +1781,7 @@ func TestSignTxOutput(t *testing.T) {
address2.EncodeAddress(): {&key2, true},
}), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript,
}), nil, dcrec.STEcdsaSecp256k1); err != nil {
}), dcrec.STEcdsaSecp256k1); err != nil {
t.Error(err)
break
}
@ -1790,7 +1790,7 @@ func TestSignTxOutput(t *testing.T) {
mkGetKey(map[string]addressToKey{
address1.EncodeAddress(): {&key1, true},
address2.EncodeAddress(): {&key2, true},
}), mkGetScript(nil), nil,
}), mkGetScript(nil),
dcrec.STEcdsaSecp256k1); err == nil {
t.Errorf("corrupted signature validated %s: %v",
msg, err)

View File

@ -1,5 +1,5 @@
// Copyright (c) 2013-2017 The btcsuite developers
// Copyright (c) 2015-2018 The Decred developers
// Copyright (c) 2015-2019 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -152,13 +152,14 @@ func (s *stack) nipN(idx int32) ([]byte, error) {
}
so := s.stk[sz-idx-1]
if idx == 0 {
switch {
case idx == 0:
s.stk = s.stk[:sz-1]
} else if idx == sz-1 {
case idx == sz-1:
s1 := make([][]byte, sz-1)
copy(s1, s.stk[1:])
s.stk = s1
} else {
default:
s1 := s.stk[sz-idx : sz]
s.stk = s.stk[:sz-idx-1]
s.stk = append(s.stk, s1...)

View File

@ -1,5 +1,5 @@
// Copyright (c) 2013-2017 The btcsuite developers
// Copyright (c) 2015-2018 The Decred developers
// Copyright (c) 2015-2019 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -316,27 +316,28 @@ func isSStxChange(pops []parsedOpcode) bool {
// scriptType returns the type of the script being inspected from the known
// standard types.
func typeOfScript(pops []parsedOpcode) ScriptClass {
if isPubkey(pops) {
switch {
case isPubkey(pops):
return PubKeyTy
} else if isPubkeyAlt(pops) {
case isPubkeyAlt(pops):
return PubkeyAltTy
} else if isPubkeyHash(pops) {
case isPubkeyHash(pops):
return PubKeyHashTy
} else if isPubkeyHashAlt(pops) {
case isPubkeyHashAlt(pops):
return PubkeyHashAltTy
} else if isScriptHash(pops) {
case isScriptHash(pops):
return ScriptHashTy
} else if isMultiSig(pops) {
case isMultiSig(pops):
return MultiSigTy
} else if isNullData(pops) {
case isNullData(pops):
return NullDataTy
} else if isStakeSubmission(pops) {
case isStakeSubmission(pops):
return StakeSubmissionTy
} else if isStakeGen(pops) {
case isStakeGen(pops):
return StakeGenTy
} else if isStakeRevocation(pops) {
case isStakeRevocation(pops):
return StakeRevocationTy
} else if isSStxChange(pops) {
case isSStxChange(pops):
return StakeSubChangeTy
}