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

目录

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

    以下为相关算法和代码。

    智能合约代码

    溯源信息的存储

      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!"))
    }

    删除方法调用执行


    评论

    发表回复

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