示例#1
0
func (b *blockchain) verifyTransaction(m message.NamecoinTransaction) bool {
	blck, ok := b.Direct[m.BlockId]
	if !ok {
		fmt.Println(m.BlockId, "not in blockchain.")
		return false
	}

	var hashes []wire.ShaHash
	for _, v := range m.VerificationHashes {
		temp, err := wire.NewShaHash(v)
		if err != nil {
			fmt.Println("Unable to create Verification Sha hash", err)
			return false
		}

		hashes = append(hashes, *temp)
	}

	txHash, err := wire.NewShaHashFromStr(m.TxId)
	if err != nil {
		fmt.Println("Cannot make TX Sha Hash", err)
		return false
	}

	_, err = VerifyMerkleBranch(wire.MerkleBranch{
		BranchSideMask: m.Branch,
		BranchHash:     hashes,
	}, &blck.MerkleRoot, txHash)
	if err != nil {
		fmt.Println("Error verifying Merkle Branch", err)
	}

	return err == nil
}
示例#2
0
func (u *UTXO) ToWire() (*wire.TxIn, error) {
	hash, err := wire.NewShaHashFromStr(u.TxID)
	if err != nil {
		return nil, err
	}

	return wire.NewTxIn(
		wire.NewOutPoint(hash, u.Output), nil,
	), nil
}
示例#3
0
// constructMerkleTree will create a wire.MerkleBranch object that places the
// transaction in the block Merkle Tree.
func constructMerkleTree(transactions []string, root string, transaction string) (wire.MerkleBranch, error) {
	workingRow := make([]*wire.ShaHash, len(transactions))

	// Used to build the Merkle Branch
	var (
		currentTransaction int
		verificationHashes []wire.ShaHash
		height             uint32
		merkleBitmask      int32
	)

	var err error

	for i, v := range transactions {
		if v == transaction {
			currentTransaction = i
		}

		if workingRow[i], err = wire.NewShaHashFromStr(v); err != nil {
			return wire.MerkleBranch{}, err
		}
	}

	for {
		// We double the last entry if the row has an odd number of
		if len(workingRow)%2 == 1 {
			workingRow = append(workingRow, workingRow[len(workingRow)-1])
		}

		// Hash into the Next Row
		var nextRow []*wire.ShaHash
		for i := 0; i < len(workingRow); i += 2 {
			left := workingRow[i]
			right := workingRow[i+1]

			if currentTransaction == i {
				// We need to add the right hash to the merkle branch.
				verificationHashes = append(verificationHashes, *right)
				currentTransaction = len(nextRow)
				merkleBitmask = merkleBitmask | (0 << height)
			} else if currentTransaction == i+1 {
				// We need to add the left hash to the merkle branch.
				verificationHashes = append(verificationHashes, *left)
				currentTransaction = len(nextRow)
				merkleBitmask = merkleBitmask | (1 << height)
			}

			hash, err := wire.NewShaHash(wire.DoubleSha256(
				append(left.Bytes(), right.Bytes()...),
			))
			if err != nil {
				return wire.MerkleBranch{}, err
			}

			nextRow = append(nextRow, hash)
		}

		if len(nextRow) == 1 {
			if nextRow[0].String() != root {
				return wire.MerkleBranch{}, errors.New("Cannot validate MerkleTree.")
			}

			break
		}

		workingRow = nextRow
		height++
	}

	return wire.MerkleBranch{
		BranchHash:     verificationHashes,
		BranchSideMask: merkleBitmask,
	}, nil
}
示例#4
0
func (server *ZookoServer) CreateTransactionListForName(name string, excludeExpired bool) ([]message.NamecoinTransaction, error) {
	nhistory, err := btcjson.NewNameHistoryCmd(nil, name)
	if err != nil {
		return nil, err
	}

	reply, err := server.Send(nhistory)
	if err != nil {
		return nil, err
	}

	result := reply.Result.([]btcjson.NameInfoResult)

	// Go through each history and extract the transaction information.
	var transactions []message.NamecoinTransaction
	for _, entry := range result {
		// Get the Raw Transaction Associated with the Name Operation
		getRaw, err := btcjson.NewGetRawTransactionCmd(nil, entry.TX, 1)
		if err != nil {
			return nil, err
		}

		reply, err := server.Send(getRaw)
		if err != nil {
			return nil, err
		}

		transactionResult := reply.Result.(*btcjson.TxRawResult)
		// fmt.Println("Found entry at block", transactionResult.BlockHash, transactionResult.Confirmations)

		// Get the Block Associated with the Name Operation
		getBlock, err := btcjson.NewGetBlockCmd(nil, transactionResult.BlockHash)
		if err != nil {
			return nil, err
		}

		reply, err = server.Send(getBlock)
		if err != nil {
			return nil, err
		}

		block := reply.Result.(*btcjson.BlockResult)
		fmt.Println("Block has", len(block.Tx), "transactions.")

		// Create the Merkle Branch
		branch, err := constructMerkleTree(block.Tx, block.MerkleRoot, transactionResult.Txid)
		if err != nil {
			return nil, err
		}

		root, _ := wire.NewShaHashFromStr(block.MerkleRoot)
		txid, _ := wire.NewShaHashFromStr(transactionResult.Txid)
		if _, err = proof.VerifyMerkleBranch(branch, root, txid); err != nil {
			return nil, errors.New("unable to verify new merkle branch")
		}

		bytesTxResult, err := json.Marshal(transactionResult)
		if err != nil {
			return nil, err
		}

		var outHashes [][]byte
		for _, v := range branch.BranchHash {
			outHashes = append(outHashes, v.Bytes())
		}

		transactions = append(transactions, message.NamecoinTransaction{
			TxId:               transactionResult.Txid,
			Branch:             branch.BranchSideMask,
			VerificationHashes: outHashes,
			Raw:                bytesTxResult,
			BlockId:            transactionResult.BlockHash,
		})
	}

	return transactions, nil
}