Esempio n. 1
0
// Returns the sha256^2 of serialized Tx
func (t *Tx) Hash() *klib.Hash256 {
	return klib.Sha256Sha256(t.Bytes())
}
Esempio n. 2
0
func (h *Header) Hash() *klib.Hash256 {
	p := new(bytes.Buffer)
	binary.Write(p, binary.LittleEndian, h)
	return klib.Sha256Sha256(p.Bytes())
}
Esempio n. 3
0
func (t *Tx) HashToSign(subScript []byte, ii int, hashType byte) (*klib.Hash256, error) {
	if ii >= len(t.TxIns) {
		return nil, errors.New("Tx.StringToSign invalid index")
	}
	anyoneCanPay := (hashType & SIGHASH_ANYONECANPAY) != 0
	htype := hashType & numbers.HashTypeMask
	p := new(bytes.Buffer)

	// STEP0: version
	binary.Write(p, binary.LittleEndian, t.Version)
	// STEP1: inputs
	if anyoneCanPay {
		// If SIGHASH_ANYONECANPAY is set, only current input is written,
		// and subScipt is used as SigScript
		p.Write(klib.VarUint(1).Bytes())                                 // inputs count
		binary.Write(p, binary.LittleEndian, t.TxIns[ii].PreviousOutput) // PreviousOutput
		p.Write(((klib.VarString)(subScript)).Bytes())                   // subScript
		binary.Write(p, binary.LittleEndian, t.TxIns[ii].Sequence)       // Sequence
	} else {
		// Else write all the inputs with modifications
		p.Write(klib.VarUint(len(t.TxIns)).Bytes())
		for i, txin := range t.TxIns {
			binary.Write(p, binary.LittleEndian, txin.PreviousOutput)
			if i == ii { // If this is current input, write subScript
				p.Write(((klib.VarString)(subScript)).Bytes())
			} else { // Else write an empty VarString
				p.Write((klib.VarString{}).Bytes())
			}
			sequence := txin.Sequence
			if i != ii && (htype == SIGHASH_NONE || htype == SIGHASH_SINGLE) {
				// If not current input, and of type SIGHASH_NONE || SIGHASH_SINGLE,
				// set sequence to 0
				sequence = 0
			}
			binary.Write(p, binary.LittleEndian, sequence)
		}
	}
	// STEP3: outputs
	switch htype {
	case SIGHASH_NONE:
		p.Write((klib.VarString{}).Bytes())
	case SIGHASH_SINGLE:
		if ii >= len(t.TxOuts) {
			// This is actually allowed due to a Satoshi Bug, right thing to do:
			// panic("Tx.StringToSign invalid index with type SIGHASH_SINGLE")
			return new(klib.Hash256).SetUint64(1), nil
		}
		p.Write(klib.VarUint(ii + 1).Bytes()) // output count
		for i := 0; i < ii; i++ {             // All outputs except the last one are written as blank
			binary.Write(p, binary.LittleEndian, int64(-1)) // value
			p.Write((klib.VarString{}).Bytes())             // script
		}
		txout := t.TxOuts[ii]
		binary.Write(p, binary.LittleEndian, txout.Value)
		p.Write(((klib.VarString)(txout.PKScript)).Bytes())
	default:
		// Another Satoshi Bug: any other hashtype are considered as SIGHASH_ALL
		p.Write(klib.VarUint(len(t.TxOuts)).Bytes())
		for _, txout := range t.TxOuts {
			binary.Write(p, binary.LittleEndian, txout.Value)
			p.Write(((klib.VarString)(txout.PKScript)).Bytes())
		}
	}
	// STEP4: LockTime and HashType
	binary.Write(p, binary.LittleEndian, t.LockTime)
	// Notice hashTypes needs to take 4 bytes
	binary.Write(p, binary.LittleEndian, uint32(hashType))
	return klib.Sha256Sha256(p.Bytes()), nil
}
Esempio n. 4
0
// checksum is the first 4 bytes of sha256(payload)
func getChecksumForPayload(payload []byte) uint32 {
	hash := klib.Sha256Sha256(payload)
	return binary.LittleEndian.Uint32(hash[:4])
}