github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/portxo/fromtx.go (about) 1 package portxo 2 3 import ( 4 "fmt" 5 6 "github.com/mit-dci/lit/wire" 7 ) 8 9 // ExtractFromTx returns a portxo from a tx and index. 10 // It fills in what it can, but the keygen, sequence, and height can't 11 // be determined from just this and need to be put in separately. 12 func ExtractFromTx(tx *wire.MsgTx, idx uint32) (*PorTxo, error) { 13 if tx == nil { 14 return nil, fmt.Errorf("nil tx") 15 } 16 if int(idx) > len(tx.TxOut)-1 { 17 return nil, fmt.Errorf("extract txo %d but tx has %d outputs", 18 idx, len(tx.TxOut)) 19 } 20 21 u := new(PorTxo) 22 23 u.Op.Hash = tx.TxHash() 24 u.Op.Index = idx 25 26 u.Value = tx.TxOut[idx].Value 27 28 u.Mode = TxoUnknownMode // default to unknown mode 29 30 // check if mode can be determined from the pkscript 31 u.Mode = TxoModeFromPkScript(tx.TxOut[idx].PkScript) 32 33 // copy pkscript into portxo 34 u.PkScript = tx.TxOut[idx].PkScript 35 36 //done 37 return u, nil 38 } 39 40 func TxoModeFromPkScript(script []byte) TxoMode { 41 // start with unknown 42 var mode TxoMode 43 44 mode = TxoUnknownMode 45 46 if script == nil { 47 return mode 48 } 49 50 // check for p2pk 51 if len(script) == 35 && script[0] == 0x21 && script[34] == 0xac { 52 mode = TxoP2PKComp 53 } 54 55 // check for p2pkh 56 if len(script) == 25 && script[0] == 0x76 && script[1] == 0xa9 && 57 script[2] == 0x14 && script[23] == 0x88 && script[24] == 0xac { 58 59 mode = TxoP2PKHComp // assume compressed 60 } 61 62 // check for witness key hash 63 if len(script) == 22 && script[0] == 0x00 && script[1] == 0x14 { 64 mode = TxoP2WPKHComp // assume compressed 65 } 66 67 // check for witness script hash 68 if len(script) == 34 && script[0] == 0x00 && script[1] == 0x20 { 69 mode = TxoP2WSHComp // does compressed even mean anything for SH..? 70 } 71 72 // couldn't find anything, unknown 73 return mode 74 }