func DecodeTxSops(tx *btc.Tx) (s string, missinginp bool, totinp, totout uint64, sigops uint, e error) { s += fmt.Sprintln("Transaction details (for your information):") s += fmt.Sprintln(len(tx.TxIn), "Input(s):") sigops = btc.WITNESS_SCALE_FACTOR * tx.GetLegacySigOpCount() for i := range tx.TxIn { s += fmt.Sprintf(" %3d %s", i, tx.TxIn[i].Input.String()) var po *btc.TxOut inpid := btc.NewUint256(tx.TxIn[i].Input.Hash[:]) if txinmem, ok := network.TransactionsToSend[inpid.BIdx()]; ok { s += fmt.Sprint(" mempool") if int(tx.TxIn[i].Input.Vout) >= len(txinmem.TxOut) { s += fmt.Sprintf(" - Vout TOO BIG (%d/%d)!", int(tx.TxIn[i].Input.Vout), len(txinmem.TxOut)) } else { po = txinmem.TxOut[tx.TxIn[i].Input.Vout] } } else { po, _ = common.BlockChain.Unspent.UnspentGet(&tx.TxIn[i].Input) if po != nil { s += fmt.Sprintf("%8d", po.BlockHeight) } } if po != nil { ok := script.VerifyTxScript(po.Pk_script, po.Value, i, tx, script.VER_P2SH|script.VER_DERSIG|script.VER_CLTV) if !ok { s += fmt.Sprintln("\nERROR: The transacion does not have a valid signature.") e = errors.New("Invalid signature") return } totinp += po.Value ads := "???" if ad := btc.NewAddrFromPkScript(po.Pk_script, common.Testnet); ad != nil { ads = ad.String() } s += fmt.Sprintf(" %15.8f BTC @ %s", float64(po.Value)/1e8, ads) if btc.IsP2SH(po.Pk_script) { so := btc.WITNESS_SCALE_FACTOR * btc.GetP2SHSigOpCount(tx.TxIn[i].ScriptSig) s += fmt.Sprintf(" + %d sigops", so) sigops += so } swo := tx.CountWitnessSigOps(i, po.Pk_script) if swo > 0 { s += fmt.Sprintf(" + %d segops", swo) sigops += swo } s += "\n" } else { s += fmt.Sprintln(" - UNKNOWN INPUT") missinginp = true } } s += fmt.Sprintln(len(tx.TxOut), "Output(s):") for i := range tx.TxOut { totout += tx.TxOut[i].Value adr := btc.NewAddrFromPkScript(tx.TxOut[i].Pk_script, common.Testnet) if adr != nil { s += fmt.Sprintf(" %15.8f BTC to adr %s\n", float64(tx.TxOut[i].Value)/1e8, adr.String()) } else { s += fmt.Sprintf(" %15.8f BTC to scr %s\n", float64(tx.TxOut[i].Value)/1e8, hex.EncodeToString(tx.TxOut[i].Pk_script)) } } if missinginp { s += fmt.Sprintln("WARNING: There are missing inputs and we cannot calc input BTC amount.") s += fmt.Sprintln("If there is somethign wrong with this transaction, you can loose money...") } else { s += fmt.Sprintf("All OK: %.8f BTC in -> %.8f BTC out, with %.8f BTC fee\n", float64(totinp)/1e8, float64(totout)/1e8, float64(totinp-totout)/1e8) } s += fmt.Sprintln("ECDSA sig operations : ", sigops) return }
func output_tx_xml(w http.ResponseWriter, tx *btc.Tx) { w.Write([]byte("<input_list>")) for i := range tx.TxIn { w.Write([]byte("<input>")) w.Write([]byte("<script_sig>")) w.Write([]byte(hex.EncodeToString(tx.TxIn[i].ScriptSig))) w.Write([]byte("</script_sig>")) var po *btc.TxOut inpid := btc.NewUint256(tx.TxIn[i].Input.Hash[:]) if txinmem, ok := network.TransactionsToSend[inpid.BIdx()]; ok { if int(tx.TxIn[i].Input.Vout) < len(txinmem.TxOut) { po = txinmem.TxOut[tx.TxIn[i].Input.Vout] } } else { po, _ = common.BlockChain.Unspent.UnspentGet(&tx.TxIn[i].Input) } if po != nil { ok := script.VerifyTxScript(po.Pk_script, po.Value, i, tx, script.STANDARD_VERIFY_FLAGS) if !ok { w.Write([]byte("<status>Script FAILED</status>")) } else { w.Write([]byte("<status>OK</status>")) } fmt.Fprint(w, "<value>", po.Value, "</value>") fmt.Fprint(w, "<pkscript>", hex.EncodeToString(po.Pk_script), "</pkscript>") if ad := btc.NewAddrFromPkScript(po.Pk_script, common.Testnet); ad != nil { fmt.Fprint(w, "<addr>", ad.String(), "</addr>") } fmt.Fprint(w, "<block>", po.BlockHeight, "</block>") if btc.IsP2SH(po.Pk_script) { fmt.Fprint(w, "<input_sigops>", btc.WITNESS_SCALE_FACTOR*btc.GetP2SHSigOpCount(tx.TxIn[i].ScriptSig), "</input_sigops>") } fmt.Fprint(w, "<witness_sigops>", tx.CountWitnessSigOps(i, po.Pk_script), "</witness_sigops>") } else { w.Write([]byte("<status>UNKNOWN INPUT</status>")) } fmt.Fprint(w, "<sequence>", tx.TxIn[i].Sequence, "</sequence>") if tx.SegWit != nil { w.Write([]byte("<segwit>")) for _, wit := range tx.SegWit[i] { w.Write([]byte("<witness>")) w.Write([]byte(hex.EncodeToString(wit))) w.Write([]byte("</witness>")) } w.Write([]byte("</segwit>")) } w.Write([]byte("</input>")) } w.Write([]byte("</input_list>")) w.Write([]byte("<output_list>")) for i := range tx.TxOut { w.Write([]byte("<output>")) fmt.Fprint(w, "<value>", tx.TxOut[i].Value, "</value>") adr := btc.NewAddrFromPkScript(tx.TxOut[i].Pk_script, common.Testnet) if adr != nil { fmt.Fprint(w, "<addr>", adr.String(), "</addr>") } else { fmt.Fprint(w, "<addr>", "scr:"+hex.EncodeToString(tx.TxOut[i].Pk_script), "</addr>") } w.Write([]byte("</output>")) } w.Write([]byte("</output_list>")) }