Ejemplo n.º 1
0
func (h *BlockHeader) Hash() []byte {
	if h.hash == nil {
		var b bytes.Buffer
		h.Serialize(&b)
		h.hash = utils.DoubleHash(b.Bytes())
	}
	return h.hash
}
Ejemplo n.º 2
0
func TestPayments(t *testing.T) {
	seed := "xprv9z29aRLQo4Gkn2z7XczXBDup2Nig8EvDCXV7wub6FnSe36UkakkEfTN4TZH9obaPj" +
		"7yn4Zh5P1JSRvnfXAi6riG9g8WqrZjzenkU9MHxy6g"
	account, err := NewAccount(seed)
	if err != nil {
		t.Fatalf("Failed to set up account", err)
	}

	mock := NewMockInventory()
	account.SetTxInventory(mock)

	pay := account.NewPayment()
	decoded, _, _ := base58.BitcoinCheckDecode("1QAsw4fsfq3MJdgiEGod3MxY9BY2EnTWEU")
	pay.AddOutput(decoded, 50000)
	err = pay.AddInputsAndFee(10000)
	if err != nil {
		t.Fatalf("Failed to add inputs to payment: %v", err)
	}
	err = pay.Sign()
	if err != nil {
		t.Fatalf("Failed to sign payment: %v", err)
	}
	transactions := pay.Transactions()
	if len(transactions) != 1 {
		t.Errorf("Bad number of transactions, got %d expected 1.",
			len(transactions))
	}
	tx := transactions[0]

	for index, input := range tx.Inputs {
		stack := script.Stack{}
		err = stack.Execute(input.Signature, nil)
		if err != nil {
			t.Fatalf("Failed to push signature: %v", err)
		}
		prev := input.PreviousOutput
		inputTx, found := mock.inv[string(prev.Hash)]
		if !found {
			t.Fatalf("Input tx %x not found in map.", prev.Hash)
		}
		subscript := inputTx.Outputs[prev.Index].Script

		data := &script.Data{
			Hasher: func(c uint32) []byte {
				return utils.DoubleHash(tx.SignSerialize(
					index, subscript, c))
			}}
		err = stack.Execute(inputTx.Outputs[prev.Index].Script, data)
		if err != nil {
			t.Fatalf("Failed to execute script: %v", err)
		}
		if !stack.CheckSuccess() {
			t.Errorf("Signature on input %d not valid.", index)
		}
	}
}
Ejemplo n.º 3
0
func ParseTransaction(data []byte) (*Transaction, error) {
	b := bytes.NewBuffer(data)
	t, err := parseTransactionFromStreamWithoutHash(b)
	if err != nil {
		return nil, err
	}
	t.data = data
	t.hash = utils.DoubleHash(data)
	return t, nil
}
Ejemplo n.º 4
0
func ParseTransactionFromStream(input io.Reader) (*Transaction, error) {
	// Tee stream to save the raw data.
	data := new(bytes.Buffer)
	b := io.TeeReader(input, data)

	t, err := parseTransactionFromStreamWithoutHash(b)
	if err != nil {
		return nil, err
	}

	t.data = data.Bytes()
	t.hash = utils.DoubleHash(t.data)
	return t, nil
}
Ejemplo n.º 5
0
func (n *MerkleNode) Process(hashes *HashStack, bits *BitStack, levels int) error {
	flag := bits.Pop()
	if n.level < levels-1 {
		// non-txid
		if !flag {
			// Hash will be nil once we're out of hashes. nils will
			// be replaced by copies from their sibling.
			n.Hash = hashes.Pop()
			return nil
		}
	} else {
		// txid
		n.Hash = hashes.Pop()
		n.match = flag
		return nil
	}

	// non-txid and flag==1: Append child and compute hash from them.
	n.Left = &MerkleNode{
		level: n.level + 1,
		rank:  n.rank * 2,
	}
	err := n.Left.Process(hashes, bits, levels)
	if err != nil {
		return err
	}
	n.Right = &MerkleNode{
		level: n.level + 1,
		rank:  n.rank*2 + 1,
	}
	err = n.Right.Process(hashes, bits, levels)
	if err != nil {
		return err
	}
	if n.Left.Hash != nil {
		var hash []byte
		if n.Right.Hash != nil {
			hash = append(n.Left.Hash, n.Right.Hash...)
		} else {
			// Take left hash twice.
			hash = append(n.Left.Hash, n.Left.Hash...)
		}
		n.Hash = utils.DoubleHash(hash)
	} else {
		return fmt.Errorf("Left child (%d,%d) has nil hash.",
			n.Left.level, n.Left.rank)
	}
	return nil
}
Ejemplo n.º 6
0
func ParseBlock(data []byte) (*Block, error) {
	var err error
	block := Block{
		Hash: utils.DoubleHash(data[0:80]),
	}
	b := bytes.NewBuffer(data)
	block.BlockHeader, err = parseBlockHeader(b)
	if err != nil {
		return nil, err
	}
	block.Transactions, err = parseTransactions(b)
	if err != nil {
		return nil, fmt.Errorf("Could not parse transactions: %v", err)
	}
	if b.Len() != 0 {
		return nil, fmt.Errorf("Excess data: %x", b.Bytes())
	}
	return &block, nil
}
Ejemplo n.º 7
0
// Sign all the inputs of the payment transaction.
func (p *Payment) Sign() error {
	j := 0
	for _, tx := range p.transactions {
		for i, input := range tx.Inputs {
			// These keys were appended in the order of the
			// transactions and inputs, so they should correspond
			// to the addresses of the inputs.
			key := p.keys[j]
			hashCode := messages.SigTypeAll

			// Subscript is temporarily stored in signature field.
			data := utils.DoubleHash(tx.SignSerialize(
				i, input.Signature, uint32(hashCode)))
			r, s := key.Sign(data)
			input.Signature = script.SigScriptEncode(
				append(utils.DEREncode(r, s), byte(hashCode)), key.PublicKey())
			j++
		}
	}
	return nil
}
Ejemplo n.º 8
0
func (inv *Inventory) VerifyTransaction(tx *messages.Transaction) (bool, error) {
	var inputValue, outputValue uint64
	for index, input := range tx.Inputs {
		stack := script.Stack{}
		err := stack.Execute(input.Signature, nil)
		if err != nil {
			return false, fmt.Errorf("Failed to push signature: %v", err)
		}
		prev := input.PreviousOutput
		d, found := inv.txHashes[string(prev.Hash)]
		if !found {
			return false, fmt.Errorf("Input tx %x not found in map.", prev.Hash)
		}
		inputTx := d.tx
		output := inputTx.Outputs[prev.Index]
		inputValue += output.Value

		data := &script.Data{
			Hasher: func(c uint32) []byte {
				return utils.DoubleHash(tx.SignSerialize(
					index, output.Script, c))
			}}
		err = stack.Execute(output.Script, data)
		if err != nil {
			return false, fmt.Errorf("Failed to execute script: %v", err)
		}
		if !stack.CheckSuccess() {
			return false, fmt.Errorf("Signature on input %d not valid.", index)
		}
	}
	for _, output := range tx.Outputs {
		outputValue += output.Value
	}
	if outputValue > inputValue {
		return false, fmt.Errorf("Outputs have higher value (%d) than inputs (%d).",
			outputValue, inputValue)
	}
	return true, nil
}
Ejemplo n.º 9
0
func (t *Transaction) Hash() []byte {
	if t.hash == nil {
		t.hash = utils.DoubleHash(t.Data())
	}
	return t.hash
}
Ejemplo n.º 10
0
// Fingerprint returns a fingerprint that is unique for each tx but doen't
// include the signatures (or other things that can be changed after broadcast).
func (t *Transaction) Fingerprint() []byte {
	if t.fingerprint == nil {
		t.fingerprint = utils.DoubleHash(t.SerializeWithoutSignature())
	}
	return t.fingerprint
}