// Query callback representing the query of a chaincode
// Supported functions are the following:
// "query(asset)": returns the owner of the asset.
// Anyone can invoke this function.
func (t *AssetManagementChaincode) Query(stub shim.ChaincodeStubInterface) ([]byte, error) {
	function, args := stub.GetFunctionAndParameters()
	myLogger.Debugf("Query [%s]", function)

	if function != "query" {
		return nil, errors.New("Invalid query function name. Expecting 'query' but found '" + function + "'")
	}

	var err error

	if len(args) != 1 {
		myLogger.Debug("Incorrect number of arguments. Expecting name of an asset to query")
		return nil, errors.New("Incorrect number of arguments. Expecting name of an asset to query")
	}

	// Who is the owner of the asset?
	asset := args[0]

	myLogger.Debugf("Arg [%s]", string(asset))

	var columns []shim.Column
	col1 := shim.Column{Value: &shim.Column_String_{String_: asset}}
	columns = append(columns, col1)

	row, err := stub.GetRow("AssetsOwnership", columns)
	if err != nil {
		myLogger.Debugf("Failed retriving asset [%s]: [%s]", string(asset), err)
		return nil, fmt.Errorf("Failed retriving asset [%s]: [%s]", string(asset), err)
	}

	myLogger.Debugf("Query done [% x]", row.Columns[1].GetBytes())

	return row.Columns[1].GetBytes(), nil
}
func (t *AssetManagementChaincode) query(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	var err error

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting name of an asset to query")
	}

	// Who is the owner of the asset?
	asset := args[0]

	fmt.Printf("ASSET: %v", string(asset))

	var columns []shim.Column
	col1 := shim.Column{Value: &shim.Column_String_{String_: asset}}
	columns = append(columns, col1)

	row, err := stub.GetRow("AssetsOwnership", columns)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed retrieving asset " + asset + ". Error " + err.Error() + ". \"}"
		return nil, errors.New(jsonResp)
	}

	if len(row.Columns) == 0 {
		jsonResp := "{\"Error\":\"Failed retrieving owner for " + asset + ". \"}"
		return nil, errors.New(jsonResp)
	}

	jsonResp := "{\"Owner\":\"" + string(row.Columns[1].GetBytes()) + "\"}"
	fmt.Printf("Query Response:%s\n", jsonResp)

	return row.Columns[1].GetBytes(), nil
}
// queryTable returns the record row matching a correponding account ID on the chaincode state table
// stub: chaincodestub
// accountID: account ID
func (t *depositoryHandler) queryTable(stub shim.ChaincodeStubInterface, accountID string) (shim.Row, error) {

	var columns []shim.Column
	col1 := shim.Column{Value: &shim.Column_String_{String_: accountID}}
	columns = append(columns, col1)

	return stub.GetRow(tableColumn, columns)
}
Exemple #4
0
func (t *RBACChaincode) hasInvokerRole(stub shim.ChaincodeStubInterface, role string) (bool, []byte, error) {
	// In order to enforce access control, we require that the
	// metadata contains the following items:
	// 1. a certificate Cert
	// 2. a signature Sigma under the signing key corresponding
	// to the verification key inside Cert of :
	// (a) Cert;
	// (b) The payload of the transaction (namely, function name and args) and
	// (c) the transaction binding.

	// Verify Sigma=Sign(certificate.sk, Cert||tx.Payload||tx.Binding) against Cert.vk

	// Unmarshall metadata
	metadata, err := stub.GetCallerMetadata()
	rbacMetadata := new(RBACMetadata)
	_, err = asn1.Unmarshal(metadata, rbacMetadata)
	if err != nil {
		return false, nil, fmt.Errorf("Failed unmarshalling metadata [%s]", err)
	}

	// Verify signature
	payload, err := stub.GetPayload()
	if err != nil {
		return false, nil, errors.New("Failed getting payload")
	}
	binding, err := stub.GetBinding()
	if err != nil {
		return false, nil, errors.New("Failed getting binding")
	}

	myLogger.Debug("passed certificate [% x]", rbacMetadata.Cert)
	myLogger.Debug("passed sigma [% x]", rbacMetadata.Sigma)
	myLogger.Debug("passed payload [% x]", payload)
	myLogger.Debug("passed binding [% x]", binding)

	ok, err := stub.VerifySignature(
		rbacMetadata.Cert,
		rbacMetadata.Sigma,
		append(rbacMetadata.Cert, append(payload, binding...)...),
	)
	if err != nil {
		return false, nil, fmt.Errorf("Failed verifying signature [%s]", err)
	}
	if !ok {
		return false, nil, fmt.Errorf("Signature is not valid!")
	}

	myLogger.Debug("Signature verified. Check for role...")

	myLogger.Debug("ID [% x]", rbacMetadata.Cert)

	// Check role
	var columns []shim.Column
	idCol := shim.Column{Value: &shim.Column_Bytes{Bytes: rbacMetadata.Cert}}
	columns = append(columns, idCol)
	row, err := stub.GetRow("RBAC", columns)
	if err != nil {
		return false, nil, fmt.Errorf("Failed retrieveing RBAC row [%s]", err)
	}
	if len(row.GetColumns()) == 0 {
		return false, nil, fmt.Errorf("Failed retrieveing RBAC row [%s]", err)
	}

	myLogger.Debug("#Columns: [%d]", len(row.Columns))
	roles := row.Columns[1].GetString_()

	result := strings.Split(roles, " ")
	for i := range result {
		if result[i] == role {
			myLogger.Debug("Role found.")
			return true, rbacMetadata.Cert, nil
		}
	}

	myLogger.Debug("Role not found.")

	return false, nil, nil
}
Exemple #5
0
func (t *RBACChaincode) addRole(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	if len(args) != 2 {
		return nil, errors.New("Incorrect number of arguments. Expecting 2")
	}
	id, err := base64.StdEncoding.DecodeString(args[0])
	if err != nil {
		return nil, fmt.Errorf("Failed decoding tcert:  %s", err)
	}
	//id := []byte(args[0])
	role := args[1]

	myLogger.Debug("Add role [% x][%s]", id, role)

	// Verify that the invoker has the 'admin' role
	ok, _, err := t.hasInvokerRole(stub, "admin")
	if err != nil {
		return nil, fmt.Errorf("Failed checking role [%s]", err)
	}
	if !ok {
		return nil, errors.New("The invoker does not have the required roles.")
	}

	// Add role to id
	myLogger.Debug("Permission granted to the invoker")

	// Retrieve id's row
	var columns []shim.Column
	idCol := shim.Column{Value: &shim.Column_Bytes{Bytes: id}}
	columns = append(columns, idCol)
	row, err := stub.GetRow("RBAC", columns)
	if err != nil {
		return nil, fmt.Errorf("Failed retriving associated row [%s]", err)
	}
	if len(row.Columns) == 0 {
		// Insert row
		ok, err = stub.InsertRow("RBAC", shim.Row{
			Columns: []*shim.Column{
				&shim.Column{Value: &shim.Column_Bytes{Bytes: id}},
				&shim.Column{Value: &shim.Column_String_{String_: role}},
			},
		})
		if err != nil {
			return nil, fmt.Errorf("Failed inserting row [%s]", err)
		}
		if !ok {
			return nil, errors.New("Failed inserting row.")
		}

	} else {
		// Update row
		ok, err = stub.ReplaceRow("RBAC", shim.Row{
			Columns: []*shim.Column{
				&shim.Column{Value: &shim.Column_Bytes{Bytes: id}},
				&shim.Column{Value: &shim.Column_String_{String_: row.Columns[1].GetString_() + " " + role}},
			},
		})
		if err != nil {
			return nil, fmt.Errorf("Failed replacing row [%s]", err)
		}
		if !ok {
			return nil, errors.New("Failed replacing row.")
		}
	}

	return nil, err
}
func (t *AssetManagementChaincode) transfer(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	myLogger.Debug("Transfer...")

	if len(args) != 2 {
		return nil, errors.New("Incorrect number of arguments. Expecting 2")
	}

	asset := args[0]
	newOwner, err := base64.StdEncoding.DecodeString(args[1])
	if err != nil {
		return nil, fmt.Errorf("Failed decoding owner")
	}

	// Verify the identity of the caller
	// Only the owner can transfer one of his assets
	var columns []shim.Column
	col1 := shim.Column{Value: &shim.Column_String_{String_: asset}}
	columns = append(columns, col1)

	row, err := stub.GetRow("AssetsOwnership", columns)
	if err != nil {
		return nil, fmt.Errorf("Failed retrieving asset [%s]: [%s]", asset, err)
	}

	prvOwner := row.Columns[1].GetBytes()
	myLogger.Debugf("Previous owener of [%s] is [% x]", asset, prvOwner)
	if len(prvOwner) == 0 {
		return nil, fmt.Errorf("Invalid previous owner. Nil")
	}

	// Verify ownership
	ok, err := t.isCaller(stub, prvOwner)
	if err != nil {
		return nil, errors.New("Failed checking asset owner identity")
	}
	if !ok {
		return nil, errors.New("The caller is not the owner of the asset")
	}

	// At this point, the proof of ownership is valid, then register transfer
	err = stub.DeleteRow(
		"AssetsOwnership",
		[]shim.Column{shim.Column{Value: &shim.Column_String_{String_: asset}}},
	)
	if err != nil {
		return nil, errors.New("Failed deliting row.")
	}

	_, err = stub.InsertRow(
		"AssetsOwnership",
		shim.Row{
			Columns: []*shim.Column{
				&shim.Column{Value: &shim.Column_String_{String_: asset}},
				&shim.Column{Value: &shim.Column_Bytes{Bytes: newOwner}},
			},
		})
	if err != nil {
		return nil, errors.New("Failed inserting row.")
	}

	myLogger.Debug("New owner of [%s] is [% x]", asset, newOwner)

	myLogger.Debug("Transfer...done")

	return nil, nil
}
func (t *AssetManagementChaincode) transfer(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	if len(args) != 2 {
		return nil, errors.New("Incorrect number of arguments. Expecting 2")
	}

	asset := args[0]

	newOwner, err := base64.StdEncoding.DecodeString(args[1])
	if err != nil {
		fmt.Printf("Error decoding [%v] \n", err)
		return nil, errors.New("Failed decoding owner")
	}

	// Verify the identity of the caller
	// Only the owner can transfer one of his assets
	var columns []shim.Column
	col1 := shim.Column{Value: &shim.Column_String_{String_: asset}}
	columns = append(columns, col1)

	row, err := stub.GetRow("AssetsOwnership", columns)
	if err != nil {
		return nil, fmt.Errorf("Failed retrieving asset [%s]: [%s]", asset, err)
	}

	prvOwner := row.Columns[1].GetBytes()
	myLogger.Debugf("Previous owener of [%s] is [% x]", asset, prvOwner)
	if len(prvOwner) == 0 {
		return nil, fmt.Errorf("Invalid previous owner. Nil")
	}

	// Verify ownership
	callerAccount, err := stub.ReadCertAttribute("account")
	if err != nil {
		return nil, fmt.Errorf("Failed fetching caller account. Error was [%v]", err)
	}

	if bytes.Compare(prvOwner, callerAccount) != 0 {
		return nil, fmt.Errorf("Failed verifying caller ownership.")
	}

	newOwnerAccount, err := attr.GetValueFrom("account", newOwner)
	if err != nil {
		return nil, fmt.Errorf("Failed fetching new owner account. Error was [%v]", err)
	}

	// At this point, the proof of ownership is valid, then register transfer
	err = stub.DeleteRow(
		"AssetsOwnership",
		[]shim.Column{shim.Column{Value: &shim.Column_String_{String_: asset}}},
	)
	if err != nil {
		return nil, errors.New("Failed deliting row.")
	}

	_, err = stub.InsertRow(
		"AssetsOwnership",
		shim.Row{
			Columns: []*shim.Column{
				&shim.Column{Value: &shim.Column_String_{String_: asset}},
				&shim.Column{Value: &shim.Column_Bytes{Bytes: newOwnerAccount}},
			},
		})
	if err != nil {
		return nil, errors.New("Failed inserting row.")
	}

	return nil, nil
}
Exemple #8
0
// Query callback representing the query of a chaincode
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	switch function {

	case "getRowTableOne":
		if len(args) < 1 {
			return nil, errors.New("getRowTableOne failed. Must include 1 key value")
		}

		col1Val := args[0]
		var columns []shim.Column
		col1 := shim.Column{Value: &shim.Column_String_{String_: col1Val}}
		columns = append(columns, col1)

		row, err := stub.GetRow("tableOne", columns)
		if err != nil {
			return nil, fmt.Errorf("getRowTableOne operation failed. %s", err)
		}

		rowString := fmt.Sprintf("%s", row)
		return []byte(rowString), nil

	case "getRowTableTwo":
		if len(args) < 3 {
			return nil, errors.New("getRowTableTwo failed. Must include 3 key values")
		}

		col1Val := args[0]
		col2Int, err := strconv.ParseInt(args[1], 10, 32)
		if err != nil {
			return nil, errors.New("getRowTableTwo failed. arg[1] must be convertable to int32")
		}
		col2Val := int32(col2Int)
		col3Val := args[2]
		var columns []shim.Column
		col1 := shim.Column{Value: &shim.Column_String_{String_: col1Val}}
		col2 := shim.Column{Value: &shim.Column_Int32{Int32: col2Val}}
		col3 := shim.Column{Value: &shim.Column_String_{String_: col3Val}}
		columns = append(columns, col1)
		columns = append(columns, col2)
		columns = append(columns, col3)

		row, err := stub.GetRow("tableTwo", columns)
		if err != nil {
			return nil, fmt.Errorf("getRowTableTwo operation failed. %s", err)
		}

		rowString := fmt.Sprintf("%s", row)
		return []byte(rowString), nil

	case "getRowTableThree":
		if len(args) < 1 {
			return nil, errors.New("getRowTableThree failed. Must include 1 key value")
		}

		col1Val := args[0]

		var columns []shim.Column
		col1 := shim.Column{Value: &shim.Column_String_{String_: col1Val}}
		columns = append(columns, col1)

		row, err := stub.GetRow("tableThree", columns)
		if err != nil {
			return nil, fmt.Errorf("getRowTableThree operation failed. %s", err)
		}

		rowString := fmt.Sprintf("%s", row)
		return []byte(rowString), nil

	case "getRowsTableTwo":
		if len(args) < 1 {
			return nil, errors.New("getRowsTableTwo failed. Must include at least key values")
		}

		var columns []shim.Column

		col1Val := args[0]
		col1 := shim.Column{Value: &shim.Column_String_{String_: col1Val}}
		columns = append(columns, col1)

		if len(args) > 1 {
			col2Int, err := strconv.ParseInt(args[1], 10, 32)
			if err != nil {
				return nil, errors.New("getRowsTableTwo failed. arg[1] must be convertable to int32")
			}
			col2Val := int32(col2Int)
			col2 := shim.Column{Value: &shim.Column_Int32{Int32: col2Val}}
			columns = append(columns, col2)
		}

		rowChannel, err := stub.GetRows("tableTwo", columns)
		if err != nil {
			return nil, fmt.Errorf("getRowsTableTwo operation failed. %s", err)
		}

		var rows []shim.Row
		for {
			select {
			case row, ok := <-rowChannel:
				if !ok {
					rowChannel = nil
				} else {
					rows = append(rows, row)
				}
			}
			if rowChannel == nil {
				break
			}
		}

		jsonRows, err := json.Marshal(rows)
		if err != nil {
			return nil, fmt.Errorf("getRowsTableTwo operation failed. Error marshaling JSON: %s", err)
		}

		return jsonRows, nil

	case "getRowTableFour":
		if len(args) < 1 {
			return nil, errors.New("getRowTableFour failed. Must include 1 key")
		}

		col1Val := args[0]
		var columns []shim.Column
		col1 := shim.Column{Value: &shim.Column_String_{String_: col1Val}}
		columns = append(columns, col1)

		row, err := stub.GetRow("tableFour", columns)
		if err != nil {
			return nil, fmt.Errorf("getRowTableFour operation failed. %s", err)
		}

		rowString := fmt.Sprintf("%s", row)
		return []byte(rowString), nil

	case "getRowsTableFour":
		if len(args) < 1 {
			return nil, errors.New("getRowsTableFour failed. Must include 1 key value")
		}

		var columns []shim.Column

		col1Val := args[0]
		col1 := shim.Column{Value: &shim.Column_String_{String_: col1Val}}
		columns = append(columns, col1)

		rowChannel, err := stub.GetRows("tableFour", columns)
		if err != nil {
			return nil, fmt.Errorf("getRowsTableFour operation failed. %s", err)
		}

		var rows []shim.Row
		for {
			select {
			case row, ok := <-rowChannel:
				if !ok {
					rowChannel = nil
				} else {
					rows = append(rows, row)
				}
			}
			if rowChannel == nil {
				break
			}
		}

		jsonRows, err := json.Marshal(rows)
		if err != nil {
			return nil, fmt.Errorf("getRowsTableFour operation failed. Error marshaling JSON: %s", err)
		}

		return jsonRows, nil

	default:
		return nil, errors.New("Unsupported operation")
	}
}