func dump_raw_sigscript(d []byte) bool { ss, er := btc.ScriptToText(d) if er != nil { println(er.Error()) return false } p2sh := len(ss) >= 2 && d[0] == 0 if p2sh { ms, er := btc.NewMultiSigFromScript(d) if er == nil { fmt.Println(" Multisig script", ms.SigsNeeded, "of", len(ms.PublicKeys)) for i := range ms.PublicKeys { fmt.Printf(" pkey%d = %s\n", i+1, hex.EncodeToString(ms.PublicKeys[i])) } for i := range ms.Signatures { fmt.Printf(" R%d = %64s\n", i+1, hex.EncodeToString(ms.Signatures[i].R.Bytes())) fmt.Printf(" S%d = %64s\n", i+1, hex.EncodeToString(ms.Signatures[i].S.Bytes())) fmt.Printf(" HashType%d = %02x\n", i+1, ms.Signatures[i].HashType) } return len(ms.Signatures) >= int(ms.SigsNeeded) } else { println(er.Error()) } } fmt.Println(" SigScript:", p2sh) for i := range ss { if p2sh && i == len(ss)-1 { // Print p2sh script d, _ = hex.DecodeString(ss[i]) s2, er := btc.ScriptToText(d) if er != nil { println(er.Error()) p2sh = false fmt.Println(" ", ss[i]) continue //return } fmt.Println(" P2SH spend script:") for j := range s2 { fmt.Println(" ", s2[j]) } } else { fmt.Println(" ", ss[i]) } } return true }
// dump raw transaction func dump_raw_tx() { tx := raw_tx_from_file(*dumptxfn) if tx == nil { fmt.Println("ERROR: Cannot decode the raw transaction") return } var unsigned, totin, totout, noins uint64 fmt.Println("ID:", tx.Hash.String()) fmt.Println("Tx Version:", tx.Version) if tx.IsCoinBase() { if len(tx.TxIn[0].ScriptSig) >= 4 && tx.TxIn[0].ScriptSig[0] == 3 { fmt.Println("Coinbase TX from block height", uint(tx.TxIn[0].ScriptSig[1])| uint(tx.TxIn[0].ScriptSig[2])<<8|uint(tx.TxIn[0].ScriptSig[3])<<16) } else { fmt.Println("Coinbase TX from an unknown block") } s := hex.EncodeToString(tx.TxIn[0].ScriptSig) for len(s) > 0 { i := len(s) if i > 64 { i = 64 } fmt.Println(" ", s[:i]) s = s[i:] } //fmt.Println() } else { fmt.Println("TX IN cnt:", len(tx.TxIn)) for i := range tx.TxIn { fmt.Printf("%4d) %s sl=%d seq=%08x\n", i, tx.TxIn[i].Input.String(), len(tx.TxIn[i].ScriptSig), tx.TxIn[i].Sequence) if intx := tx_from_balance(btc.NewUint256(tx.TxIn[i].Input.Hash[:]), false); intx != nil { val := intx.TxOut[tx.TxIn[i].Input.Vout].Value totin += val fmt.Printf("%15s BTC\n", btc.UintToBtc(val)) } else { noins++ } if len(tx.TxIn[i].ScriptSig) > 0 { if !dump_sigscript(tx.TxIn[i].ScriptSig) { unsigned++ } } else { unsigned++ } } } fmt.Println("TX OUT cnt:", len(tx.TxOut)) for i := range tx.TxOut { totout += tx.TxOut[i].Value fmt.Printf("%4d) %20s BTC ", i, btc.UintToBtc(tx.TxOut[i].Value)) addr := addr_from_pkscr(tx.TxOut[i].Pk_script) if addr != nil { if addr.Version == ver_script() { fmt.Println("to scriptH", addr.String()) } else { fmt.Println("to address", addr.String()) } } else if len(tx.TxOut[i].Pk_script) == 40 && tx.TxOut[i].Pk_script[0] == 0x6a && tx.TxOut[i].Pk_script[1] == 0x26 && tx.TxOut[i].Pk_script[2] == 0x06 { sha := sha256.New() sha.Write(tx.TxOut[i].Pk_script[3:40]) fmt.Println("Stealth", hex.EncodeToString(sha.Sum(nil)[:4]), hex.EncodeToString(tx.TxOut[i].Pk_script[7:])) } else { if tx.TxOut[i].Value > 0 { fmt.Println("WARNING!!! These coins go to non-standard Pk_script:") } else { fmt.Println("NULL output to Pk_script:") } ss, er := btc.ScriptToText(tx.TxOut[i].Pk_script) if er == nil { for i := range ss { fmt.Println(" ", ss[i]) } } else { fmt.Println(hex.EncodeToString(tx.TxOut[i].Pk_script)) fmt.Println(er.Error()) } } } fmt.Println("Lock Time:", tx.Lock_time) fmt.Println("Output volume:", btc.UintToBtc(totout), "BTC") if noins == 0 { fmt.Println("Input volume :", btc.UintToBtc(totin), "BTC") fmt.Println("Transact. fee:", btc.UintToBtc(totin-totout), "BTC") } else { fmt.Println("WARNING: Unable to figure out what the fee is") } if !tx.IsCoinBase() { if unsigned > 0 { fmt.Println("WARNING:", unsigned, "out of", len(tx.TxIn), "inputs are not signed or signed only patially") } else { fmt.Println("All", len(tx.TxIn), "transaction inputs seem to be signed") } } }