基于区块链的数据溯源系统

本项目基于区块链溯源技术,构建了数据溯源系统。

以下为相关算法和代码。

智能合约代码

溯源信息的存储

  func (f *FactContract) save() protogo.Response {
	params := sdk.Instance.GetArgs()
	organizationStr := string(params["organization"])
	addressStr := string(params["address"])
	activityStr := string(params["activity"])
	activityStart := string(params["activity_start"])
	activityEnd := string(params["activity_end"])
	activityaddr := string(params["activity_addr"])
	fileid := string(params["file_id"])
	fileHash := string(params["file_hash"])
	fileName := string(params["file_name"])
	fileUrl := string(params["file_url"])
	timeStr := string(params["Established_time"])
	uac := string(params["u_a_c"])
	filekeyword := string(params["file_keyword"])
	if fileHash == "" || fileName == "" || timeStr == "" || addressStr == "" || organizationStr == "" || activityStr == "" || activityStart == "" || activityStart == "" || activityEnd == "" || activityaddr == "" || fileid == "" || fileUrl == "" || filekeyword == "" {
	 	return sdk.Error("请完整填写必要的信息")
	}
	exists, _ := f.FactExists(fileHash)

	if exists {
		return sdk.Error("the fact already exists")
	}
	fact := NewFact(organizationStr, timeStr, addressStr, activityStr, activityStart, activityEnd, activityaddr, fileHash, fileName, fileid, fileUrl, uac, filekeyword)
	factBytes, err := json.Marshal(fact)
	if err != nil {
		return sdk.Error(fmt.Sprintf("marshal fact failed, err: %s", err))
	}
	sdk.Instance.EmitEvent("topic_vx", []string{fact.FileHash, fact.FileName})
	err = sdk.Instance.PutStateByte("fact_bytes", fact.FileHash, factBytes)
	if err != nil {
		return sdk.Error("fail to save fact bytes")
	}
	sdk.Instance.Infof("[save] fileHash=" + fact.FileHash)
	sdk.Instance.Infof("[save] fileName=" + fact.FileName)
	return sdk.Success([]byte(fact.FileName + fact.FileHash))

}

存储功能调用执行

溯源信息的更新

func (f *FactContract) UpdateByFileHash() protogo.Response {
	params := sdk.Instance.GetArgs()

	// 获取参数
	fileHash := string(params["file_hash"])
	exists, _ := f.FactExists(fileHash)

	if !exists {
		return sdk.Error("the fact is not exists")
	}
	result, err := sdk.Instance.GetStateByte("fact_bytes", fileHash)
	if err != nil {
		return sdk.Error("failed to call get_state")
	}

	// 反序列化
	var fact Fact
	if err = json.Unmarshal(result, &fact); err != nil {
		return sdk.Error(fmt.Sprintf("unmarshal fact failed, err: %s", err))
	}
	// 修改结构体
	if string(params["organization"]) != "" {
		fact.Organization = string(params["organization"])
	}
	if string(params["Established_time"]) != "" {
		fact.Address = string(params["Established_time"])
	}
	if string(params["activity"]) != "" {
		fact.Activity = string(params["activity"])
	}
	if string(params["activity_start"]) != "" {
		fact.ActivityStart = string(params["activity_start"])
	}
	if string(params["activity_end"]) != "" {
		fact.ActivityEnd = string(params["activity_end"])
	}
	if string(params["address"]) != "" {
		fact.ActivityAddr = string(params["address"])
	}
	if string(params["file_id"]) != "" {
		fact.FileID = string(params["file_id"])
	}
	if string(params["file_name"]) != "" {
		fact.FileName = string(params["file_name"])
	}
	if string(params["file_url"]) != "" {
		fact.FileUrl = string(params["file_url"])
	}
	if string(params["Established_time"]) != "" {
		fact.Time = string(params["Established_time"])
	}
	if string(params["u_a_c"]) != "" {
		fact.UAC = string(params["u_a_c"])
	}
	if string(params["file_keyword"]) != "" {
		fact.FileKeyword = string(params["file_keyword"])
	}
	// 序列化
	factBytes, err := json.Marshal(fact)
	if err != nil {
		return sdk.Error(fmt.Sprintf("marshal fact failed, err: %s", err))
	}
	// 发送事件
	sdk.Instance.EmitEvent("topic_vx", []string{fact.FileHash, fact.FileName})

更新方法调用执行

溯源信息的查询

全生命周期精确溯源

func (f *FactContract) findByFileHash() protogo.Response {
	fileHash := string(sdk.Instance.GetArgs()["file_hash"])
	var arr []Fact
	for {
		result, err := sdk.Instance.GetStateByte("fact_bytes", fileHash)
		if err != nil {
			return sdk.Error("failed to call get_state")
		}
		var fact Fact
		if err = json.Unmarshal(result, &fact); err != nil {
			return sdk.Error(fmt.Sprintf("unmarshal fact failed, err: %s", err))
		}
		sdk.Instance.Infof("[find_by_file_hash] fileHash=" + fact.FileHash)
		sdk.Instance.Infof("[find_by_file_hash] fileName=" + fact.FileName)
		sdk.Instance.Infof("[find_by_file_hash] file name:" + fact.UAC)
		arr = append(arr, fact)
		fileHash = fact.UAC
		if fact.UAC == "" {
			break
		}
	}
	arrBytes, err := json.Marshal(arr)
	if err != nil {
		msg := "marshal data fail"
		sdk.Instance.Infof(msg + err.Error())
		return sdk.Error(msg)
	}

精确查找方法调用执行

精确溯源功能执行结果

模糊溯源

type TrieNode struct {
  
Children map[rune]*TrieNode
    Results  []Item
}

func insert(node *TrieNode, key string, value Item) {
    for _, char := range key {
        child, exists := node.Children[char]
        if !exists {
            child = &TrieNode{Children: make(map[rune]*TrieNode)}
            node.Children[char] = child
        }
        node = child
    }
    node.Results = append(node.Results, value)
}
func search(node *TrieNode, prefix string) []Item {
    var results []Item
    for _, char := range prefix {
        child, exists := node.Children[char]
        if !exists {
            continue
        }
        results = append(results, child.Results...)
        results = append(results, search(child, prefix)...)
    }
    return results
}
root := &TrieNode{Children: make(map[rune]*TrieNode)}
    for _, item := range items {
        keywords := strings.Split(item.FileKeyword, "")
        for _, keyword := range keywords {
            insert(root, strings.ToLower(keyword), item)
        }
    }

    for {
        var inputs []string
        fmt.Println("☆☆☆☆☆ 输入关键词进行搜索 ☆☆☆☆☆")
        for i := 1; i <= 5; i++ {
            fmt.Printf("输入第 %d 个关键词(回车直接搜索/输入'ESC' 退出): ", i)
            var input string
            fmt.Scanln(&input)
            if strings.EqualFold(input, "ESC") {
                fmt.Println("已退出。")
                return
            }
            if input == "" {
                break
            }
            inputs = append(inputs, input)
        }
     if len(inputs) == 0 {
            fmt.Println("没有输入关键词,已退出。")
            return
        }

模糊溯源方法调用执行

模糊溯源执行结果

溯源信息的删除

func (f *FactContract) deleteByFileHash() protogo.Response {
	fileHash := string(sdk.Instance.GetArgs()["file_hash"])
	err := sdk.Instance.DelStateFromKey(fileHash)
	if err != nil {
		msg := "failed to call Del_state"
		return sdk.Error(msg)
	}
	return sdk.Success([]byte("aleady delete!"))
}

删除方法调用执行


评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注