Ejemplo n.º 1
0
func (u *UTXO) Execute(txData []byte) (*ExecResult, error) {
	newTX := ParseUTXOBytes(txData)
	txHash := u.GetTransactionHash(txData)
	execResult := &ExecResult{}
	// Loop through outputs first
	for index, output := range newTX.Txout {
		currKey := &Key{TxHashAsHex: hex.EncodeToString(txHash[:]), TxIndex: uint32(index)}
		_, ok, err := u.Store.GetState(*currKey)
		if err != nil {
			return nil, fmt.Errorf("Error getting state from store:  %s", err)
		}
		if ok == true {
			// COLLISION
			return nil, fmt.Errorf("COLLISION detected for key = %v, with output script length = ", currKey, len(output.Script))
		}
		// Store the ouput in utxo
		u.Store.PutState(*currKey, &TX_TXOUT{Script: output.Script, Value: output.Value})
		execResult.SumCurrentOutputs += output.Value
	}
	// Now loop over inputs,
	for index, input := range newTX.Txin {
		prevTxHash := input.SourceHash
		prevOutputIx := input.Ix
		if u.IsCoinbase(prevOutputIx) {
			execResult.IsCoinbase = true
			//fmt.Println("COINBASE!!")
		} else {
			//fmt.Println("NOT COINBASE!!")
			// NOT coinbase, need to verify
			keyToPrevOutput := &Key{TxHashAsHex: hex.EncodeToString(prevTxHash), TxIndex: prevOutputIx}
			value, ok, err := u.Store.GetState(*keyToPrevOutput)
			if err != nil {
				return nil, fmt.Errorf("Error getting state from store:  %s", err)
			}
			if !ok {
				// Previous output not fouund,
				return nil, fmt.Errorf("Could not find previous transaction output with key = %v", keyToPrevOutput)
			}
			// Call Verify_script
			tx_input_index := uint(index)
			result := consensus.Verify_script(&txData[0], int64(len(txData)), &value.Script[0], int64(len(value.Script)), tx_input_index, uint(standardFlags))
			if result != consensus.Verify_result_eval_true {
				result = consensus.Verify_script(&txData[0], int64(len(txData)), &value.Script[0], int64(len(value.Script)), tx_input_index, uint(mandatoryFlags))
				if result != consensus.Verify_result_eval_true {
					return nil, fmt.Errorf("Unexpected result from verify_script, expected %d, got %d, perhaps it is %d", consensus.Verify_result_eval_true, result, consensus.Verify_result_invalid_stack_operation)
				}
			}
			// Verified, now remove prior outputs
			u.Store.DelState(*keyToPrevOutput)
			execResult.SumPriorOutputs += value.Value
		}

		hex := hex.EncodeToString(txHash[:])
		fmt.Printf("PUT TRAN %s", hex)
		u.Store.PutTran(hex, txData)
	}
	return execResult, nil
}
Ejemplo n.º 2
0
func TestParse_LibbitconTX(t *testing.T) {
	txData, err := hex.DecodeString(consensusScriptVerifyTx)
	if err != nil {
		t.Fatalf("Error decoding HEX tx from libbitcoin:  %s", err)
		return
	}

	prevTxScript, err := hex.DecodeString(consensusScriptVerifyPreviousOutputScript)
	if err != nil {
		t.Fatalf("Error decoding HEX tx from libbitcoin:  %s", err)
		return
	}

	t.Logf("TX data from libbitcoin: %v", txData)

	tx := ParseUTXOBytes(txData)

	// Call Verify_script
	txInputIndex := uint(0)
	result := consensus.Verify_script(&txData[0], int64(len(txData)), &prevTxScript[0], int64(len(prevTxScript)), txInputIndex, uint(consensus.Verify_flags_p2sh))
	if result != consensus.Verify_result_eval_true {
		t.Fatalf("Unexpected result from verify_script, expected %d, got %d", consensus.Verify_result_eval_true, result)
	}
	t.Log(result)
	t.Log(consensus.Verify_result_eval_true)
	t.Logf("TX from %v", tx)
}
Ejemplo n.º 3
0
func TestVerifyScript_InvalidTranscation(t *testing.T) {
	arg1 := []byte("arg1")
	arg2 := int64(4)
	arg3 := []byte("arg2")
	arg4 := int64(4)
	arg5 := uint(100)
	arg6 := uint(1)
	//func Verify_script(arg1 *byte, arg2 int64, arg3 *byte, arg4 int64, arg5 uint, arg6 uint) (_swig_ret LibbitcoinConsensusVerify_result_type)
	result := consensus.Verify_script(&arg1[0], arg2, &arg3[0], arg4, arg5, arg6)
	t.Log(result)
	t.Log(consensus.Verify_result_tx_invalid)
	if result != consensus.Verify_result_tx_invalid {
		t.Fatalf("Should have failed to verify transaction")
	}
}