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 }
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) } } }
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 }
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 }
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 }
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 }
// 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 }
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 }
func (t *Transaction) Hash() []byte { if t.hash == nil { t.hash = utils.DoubleHash(t.Data()) } return t.hash }
// 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 }