长安链使用Golang编写智能合约教程(三)
本篇主要介绍长安链Go SDK写智能合约的一些常见方法的使用方法或介绍
资料来源:
- 官方文档
- 官方示例合约库
官方SDK接口文档
教程一:智能合约编写1
教程二:智能合约编写2
一、获取参数、获取状态、获取历史记录的方法解析
注意!
这些查询链上数据的方法:只能是查询本合约之前上链的数据,别的合约上链的数据就算key相同你也是不能查的,其他查询方法也一样
// GetArgs get arg from transaction parameters// @return: 参数map GetArgs() map[string][]byte (常用,获取参数的方法,之前的示例基本上都用到)
// GetState get [key, field] from chain// @param key: 获取的参数名// @param field: 获取的参数名// @return1: 获取结果,格式为string// @return2: 获取错误信息 // Deprecated: 无法通过返回值来判断state是否存在,建议使用GetStateWithExists GetState(key, field string) (string, error)(通过空间域名+key 查询值)官方说废弃了建议用GetStateWithExists
// GetStateWithExists get [key, field] from chain// @param key: 获取的参数名// @param field: 获取的参数名// @return1: 获取结果,格式为string// @return2: 是否存在,bool, 字符串长度为0不代表不存在// @return3: 获取错误信息GetStateWithExists(key, field string) (string, bool, error)
(通过空间域名+key 查询值) 返回值,是否存在,错误参数
其中如果不存在返回空和false
// GetBatchState get [BatchKeys] from chain// @param batchKey: 获取的参数名// @return1: 获取结果// @return2: 获取错误信息GetBatchState(batchKeys []*vmPb.BatchKey) ([]*vmPb.BatchKey, error)
没看懂怎么用,像是批量查询,但是BatchKey很多参数
// GetStateByte get [key, field] from chain// @param key: 获取的参数名// @param field: 获取的参数名// @return1: 获取结果,格式为[]byte, nil表示不存在// @return2: 获取错误信息GetStateByte(key, field string) ([]byte, error)
(通过空间域名+key 查询值) 返回值[]byte,错误参数
// GetStateFromKey get [key] from chain// @param key: 获取的参数名// @return1: 获取结果,格式为string// @return2: 获取错误信息 // Deprecated: 无法通过返回值来判断state是否存在,建议使用GetStateFromKeyWithExistsGetStateFromKey(key string) (string, error)
注意!
通过key去查值,如果前面你存值是用 field 、key 两个参数存的,那么你用一个key值是取不到任何值的
// GetStateFromKeyWithExists get [key] from chain// @param key: 获取的参数名// @return1: 获取结果,格式为string// @return2: 是否存在,bool, 字符串长度为0不代表不存在// @return3: 获取错误信息GetStateFromKeyWithExists(key string) (string, bool, error)
同上
// GetStateFromKeyByte get [key] from chain// @param key: 获取的参数名// @return1: 获取结果,格式为[]byte, nil表示不存在// @return2: 获取错误信息GetStateFromKeyByte(key string) ([]byte, error)
同上
二、存数据、删除数据的一些方法
// PutState put [key, field, value] to chain// @param1 key: 参数名// @param1 field: 参数名// @param2 value: 参数值,类型为string// @return1: 上传参数错误信息PutState(key, field string, value string) error
存数据方法: 参数依次是 key值、空间域名、要存的数据 (string)
官方的一些示例是:空间域名、 key值、要存的数据 (string)
// PutStateByte put [key, field, value] to chain// @param1 key: 参数名// @param1 field: 参数名// @param2 value: 参数值,类型为[]byte// @return1: 上传参数错误信息PutStateByte(key, field string, value []byte) error存数据方法: 参数依次是 key值、空间域名、要存的数据 []byte
官方的一些示例是:空间域名、 key值、要存的数据 []byte
// PutStateFromKey put [key, value] to chain// @param1 key: 参数名// @param2 value: 参数值,类型为string// @return1: 上传参数错误信息 PutStateFromKey(key string, value string) error
存数据方法: 参数依次是 key值、要存的数据 string
注意 ,不带空间域名去存,取值的时候也要不带空间域名
// PutStateFromKeyByte put [key, value] to chain// @param1 key: 参数名// @param2 value: 参数值,类型为[]byte// @return1: 上传参数错误信息 PutStateFromKeyByte(key string, value []byte) error
存数据方法: 参数依次是 key值、要存的数据 []byte
// DelState delete [key, field] to chain// @param1 key: 删除的参数名// @param1 field: 删除的参数名// @return1:删除参数的错误信息 DelState(key, field string) error
删除数据方法: 参数依次是 key值、空间域名
注意:删除不是真的删除数据,会新增一条交易,交易内容是 key 、field 的字段isdelete变成 true , 并且如果区块链上没有 key、field的数据同样也能删除、也会新增一条数据
// DelStateFromKey delete [key] to chain// @param1 key: 删除的参数名// @return1:删除参数的错误信息 DelStateFromKey(key string) error
删除数据的方法通过key
三、获取其他值的一些方法
// GetCreatorOrgId get tx creator org id// @return1: 合约创建者的组织ID// @return2: 获取错误信息GetCreatorOrgId() (string, error)
获取合约创建者的组织ID
// GetCreatorRole get tx creator role// @return1: 合约创建者的角色// @return2: 获取错误信息GetCreatorRole() (string, error)
获取合约创建者的角色
// GetCreatorPk get tx creator pk// @return1: 合约创建者的公钥// @return2: 获取错误信息GetCreatorPk() (string, error)
获取合约创建者的公钥
在IDE可以获取,在使用证书+私钥的链,还没测过
// GetSenderOrgId get tx sender org id// @return1: 交易发起者的组织ID// @return2: 获取错误信息 GetSenderOrgId() (string, error) 获取交易发起者的组织ID
// GetSenderRole get tx sender role// @return1: 交易发起者的角色// @return2: 获取错误信息GetSenderRole() (string, error)
获取交易发起者的角色
// GetSenderPk get tx sender pk// @return1: 交易发起者的公钥// @return2: 获取错误信息GetSenderPk() (string, error)
获取 交易发起者的公钥
// GetBlockHeight get tx block height// @return1: 当前块高度// @return2: 获取错误信息GetBlockHeight() (int, error)
获取当前块高度
// GetTxId get current tx id// @return1: 交易ID// @return2: 获取错误信息GetTxId() (string, error)
获取 交易ID
// GetTxInfo get tx info// @param txId :合约交易IDGetTxInfo(txId string) protogo.Response
获取合约交易ID
// GetTxTimeStamp get tx timestamp// @return1: 交易timestamp// @return2: 获取错误信息GetTxTimeStamp() (string, error)
获取交易timestamp
// EmitEvent emit event, you can subscribe to the event using the SDK// @param1 topic: 合约事件的主题// @param2 data: 合约事件的数据,参数数量不可大于16EmitEvent(topic string, data []string)
发布合约事件,发布了的化,主题和参数,会被订阅者收到
// Log record log to chain server// @param message: 事情日志的信息//DeprecatedLog(message string)
日记记录,会写进节点日志
// Debugf record log to chain server// @param format: 日志格式化模板// @param a: 模板参数Debugf(format string, a ...interface{})
同上
// Infof record log to chain server// @param format: 日志格式化模板// @param a: 模板参数Infof(format string, a ...interface{})
同上
// Warnf record log to chain server// @param format: 日志格式化模板// @param a: 模板参数Warnf(format string, a ...interface{})
同上
// Errorf record log to chain server// @param format: 日志格式化模板// @param a: 模板参数Errorf(format string, a ...interface{})
同上
// CallContract invoke another contract and get response// @param1: 合约名称// @param2: 合约方法// @param3: 合约合约参数// @return1: 合约结果 CallContract(contractName, method string, args map[string][]byte) protogo.Response
合约里面调用别的合约?不知道是干嘛的
官方解释:跨合约调用,用于调用已经安装的其他合约的
四、获取历史数据的一些方法
// NewIterator range of [startKey, limitKey), front closed back open// @param1: 范围查询起始key// @param2: 范围查询结束key// @return1: 根据起始key生成的迭代器// @return2: 获取错误信息NewIterator(startKey string, limitKey string) (ResultSetKV, error)不清出这个起始key、结束key是什么意思,如果key是一些字母也有起始和结束吗?
难以理解,懂得朋友辛苦留言指导一下
// NewIteratorWithField range of [key+"#"+startField, key+"#"+limitField), front closed back open// @param1: 分别与param2, param3 构成查询起始和结束的key// @param2: [param1 + "#" + param2] 来获取查询起始的key// @param3: [param1 + "#" + param3] 来获取查询结束的key// @return1: 根据起始位置生成的迭代器// @return2: 获取错误信息 NewIteratorWithField(key string, startField string, limitField string) (ResultSetKV, error)同上
// NewIteratorPrefixWithKeyField range of [key+"#"+field, key+"#"+field], front closed back closed// @param1: [ param1 + "#" +param2 ] 构成前缀范围查询的key// @param2: [ param1 + "#" +param2 ] 构成前缀范围查询的key// @return1: 根据起始位置生成的迭代器// @return2: 获取错误信息NewIteratorPrefixWithKeyField(key string, field string) (ResultSetKV, error)同上
// NewIteratorPrefixWithKey range of [key, key], front closed back closed// @param1: 前缀范围查询起始key// @return1: 根据起始位置生成的迭代器// @return2: 获取错误信息NewIteratorPrefixWithKey(key string) (ResultSetKV, error)
查询key相同的所有数据,使用方法可以参考教程二
只能是查询本合约之前上链的数据,别的合约上链的数据就算key相同你也是不能查的,其他查询方法也一样
// NewHistoryKvIterForKey query all historical data of key, field// @param1: 查询历史的key// @param2: 查询历史的field// @return1: 根据key, field 生成的历史迭代器// @return2: 获取错误信息 NewHistoryKvIterForKey(key, field string) (KeyHistoryKvIter, error)
查询 field 、key相同的所有数据,使用方法可以参考教程二
只能是查询本合约之前上链的数据,别的合约上链的数据就算key相同你也是不能查的,其他查询方法也一样
// GetSenderAddr Get the address of the origin caller address, same with Origin()// @return1: origin caller address// @return2: 获取错误信息// DeprecatedGetSenderAddr() (string, error)被弃用了,别学
// Sender Get the address of the sender address, if the contract is called by another contract, the result will be// the caller contract's address.// Sender will return system contract address when executing the init or upgrade method (If you need to return the// user address, we recommend using Origin method here), because the init and upgrade methods are cross-contract// txs (system contract -> common contract).// @return1: sender address// @return2: 获取错误信息Sender() (string, error)获取发送者的地址。如果合约是由另一个合约调用的,结果将是调用者合约的地址。
// Origin Get the address of the tx origin caller address// @return1: origin caller address// @return2: 获取错误信息Origin() (string, error)获取交易原始调用者的地址
五、示例合约
以下合约是我在写这个教程测试用的,只写了部分接口测试
/*
Copyright (C) BABEC. All rights reserved.
Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.SPDX-License-Identifier: Apache-2.0
*/package mainimport ("chainmaker/pb/protogo""chainmaker/sandbox""chainmaker/sdk""encoding/json""fmt""log""strconv"
)type FactContract struct {
}// 存证对象
type Fact struct {FileHash stringFileName stringTime int
}// 新建存证对象
func NewFact(fileHash string, fileName string, time int) *Fact {fact := &Fact{FileHash: fileHash,FileName: fileName,Time: time,}return fact
}func (f *FactContract) InitContract() protogo.Response {return sdk.Success([]byte("Init contract success"))
}func (f *FactContract) UpgradeContract() protogo.Response {return sdk.Success([]byte("Upgrade contract success"))
}func (f *FactContract) InvokeContract(method string) protogo.Response {switch method {case "save":return f.Save()case "findByFileHash":return f.FindByFileHash()case "deltedByFileHash":return f.DeleteByFileHash()case "getHistoryByFileHash":return f.GetHistoryByFileHash()case "getStateFromKey":return f.GetStateFromKey()case "getStateByte":return f.GetStateByte()case "getStateWithExists":return f.GetStateWithExists()case "getCreatorOrgId":return f.GetCreatorOrgId()case "getCreatorPk":return f.GetCreatorPk()case "GetSenderOrgId":return f.GetSenderOrgId()case "GetSenderRole":return f.GetSenderRole()case "GetSenderPk":return f.GetSenderPk()case "GetBlockHeight":return f.GetBlockHeight()case "GetTxId":return f.GetTxId()case "GetTxTimeStamp":return f.GetTxTimeStamp()default:return sdk.Error("invalid method")}
}func (f *FactContract) Save() protogo.Response {params := sdk.Instance.GetArgs()// 获取参数fileHash := string(params["file_hash"])fileName := string(params["file_name"])timeStr := string(params["time"])time, err := strconv.Atoi(timeStr)if err != nil {msg := "time is [" + timeStr + "] not int"sdk.Instance.Errorf(msg)return sdk.Error(msg)}// 构建结构体fact := NewFact(fileHash, fileName, time)// 序列化factBytes, err := json.Marshal(fact)if err != nil {return sdk.Error(fmt.Sprintf("传过来的参数序列化失败, 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)createUser, _ := sdk.Instance.GetSenderRole()sdk.Instance.Infof("[saveUser] create=" + createUser)// 返回结果return sdk.Success([]byte(fact.FileName + fact.FileHash))}func (f *FactContract) FindByFileHash() protogo.Response {// 获取参数fileHash := string(sdk.Instance.GetArgs()["file_hash"])// 查询结果result, err := sdk.Instance.GetStateByte("fact_bytes", fileHash)if err != nil {return sdk.Error("failed to call get_state")}// 反序列化var fact Factif 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)// 返回结果return sdk.Success(result)
}func (f *FactContract) DeleteByFileHash() protogo.Response {// 获取参数fileHash := string(sdk.Instance.GetArgs()["file_hash"])// 查询结果err := sdk.Instance.DelState("fact_bytes", fileHash)if err != nil {return sdk.Error("failed to delere get_state")}// 返回结果return sdk.Success(nil)
}func (f *FactContract) GetHistoryByFileHash() protogo.Response {// 获取参数fileHash := string(sdk.Instance.GetArgs()["file_hash"])// 查询结果iter, err := sdk.Instance.NewHistoryKvIterForKey("fact_bytes", fileHash)if err != nil {return sdk.Error("failed to delere get_state")}defer iter.Close()var keyModifications []*sdk.KeyModification// 遍历结果for {if !iter.HasNext() {break}keyModification, err := iter.Next()if err != nil {sdk.Instance.Infof("Error iterating: %v", err)}if keyModification == nil {break}keyModifications = append(keyModifications, keyModification)sdk.Instance.Infof("Key: %s, Field: %s, Value: %s, TxId: %s, BlockHeight: %d, IsDelete: %t, Timestamp: %s, \n",keyModification.Key, keyModification.Field, keyModification.Value, keyModification.TxId, keyModification.BlockHeight, keyModification.IsDelete, keyModification.Timestamp)}jsonBytes, err := json.Marshal(keyModifications)if err != nil {return sdk.Error(fmt.Sprintf("Error marshaling keyModifications: %v", err))}// 返回结果return sdk.Success(jsonBytes)
}func (f *FactContract) GetStateFromKey() protogo.Response {// 获取参数fileHash := string(sdk.Instance.GetArgs()["file_hash"])// 查询结果result, err := sdk.Instance.GetStateFromKey(fileHash)if err != nil {return sdk.Error("failed to call get_state")}sdk.Instance.Infof("[GetStateFromKey] result=" + result)byteSlice := []byte(result)// 返回结果return sdk.Success(byteSlice)
}func (f *FactContract) GetStateByte() protogo.Response {// 获取参数fileHash := string(sdk.Instance.GetArgs()["file_hash"])// 查询结果result, err := sdk.Instance.GetStateByte("fact_bytes", fileHash)if err != nil {return sdk.Error("failed to call get_state")}sdk.Instance.Infof("[GetStateByte] result=" + string(result))// 返回结果return sdk.Success(result)
}func (f *FactContract) GetStateWithExists() protogo.Response {// 获取参数fileHash := string(sdk.Instance.GetArgs()["file_hash"])// 查询结果result, exit, err := sdk.Instance.GetStateWithExists("fact_bytes", fileHash)if err != nil {return sdk.Error("failed to call get_state")}exitStr := fmt.Sprintf("%v", exit)sdk.Instance.Infof("[GetStateByte] result=" + result + "bool:" + string(exitStr))// 返回结果return sdk.Success([]byte(result))
}func (f *FactContract) GetCreatorOrgId() protogo.Response {// 查询结果result, err := sdk.Instance.GetCreatorOrgId()if err != nil {return sdk.Error("failed to call get_state")}sdk.Instance.Infof("[GetCreatorOrgId] GetCreatorOrgId=" + result)// 返回结果return sdk.Success([]byte(result))
}func (f *FactContract) GetCreatorPk() protogo.Response {// 查询结果result, err := sdk.Instance.GetCreatorPk()if err != nil {return sdk.Error("failed to call get_state")}sdk.Instance.Infof("[GetCreatorPk] GetCreatorPk=" + result)// 返回结果return sdk.Success([]byte(result))
}func (f *FactContract) GetSenderOrgId() protogo.Response {// 查询结果result, err := sdk.Instance.GetSenderOrgId()if err != nil {return sdk.Error("failed to call get_state")}sdk.Instance.Infof("[GetSenderOrgId] GetSenderOrgId=" + result)// 返回结果return sdk.Success([]byte(result))
}func (f *FactContract) GetSenderRole() protogo.Response {// 查询结果result, err := sdk.Instance.GetSenderRole()if err != nil {return sdk.Error("failed to call get_state")}sdk.Instance.Infof("[GetSenderRole] GetSenderRole=" + result)// 返回结果return sdk.Success([]byte(result))
}func (f *FactContract) GetSenderPk() protogo.Response {// 查询结果result, err := sdk.Instance.GetSenderPk()if err != nil {return sdk.Error("failed to call get_state")}sdk.Instance.Infof("[GetSenderPk] GetSenderPk=" + result)// 返回结果return sdk.Success([]byte(result))
}
func (f *FactContract) GetBlockHeight() protogo.Response {// 查询结果result, err := sdk.Instance.GetBlockHeight()if err != nil {return sdk.Error("failed to call get_state")}str := strconv.Itoa(result) // 将int转换为字符串bytes := []byte(str) // 将字符串转换为[]byte// 返回结果return sdk.Success(bytes)
}func (f *FactContract) GetTxId() protogo.Response {// 查询结果result, err := sdk.Instance.GetTxId()if err != nil {return sdk.Error("failed to call get_state")}sdk.Instance.Infof("[GetTxId] GetTxId=" + result)// 返回结果return sdk.Success([]byte(result))
}func (f *FactContract) GetTxTimeStamp() protogo.Response {// 查询结果result, err := sdk.Instance.GetTxTimeStamp()if err != nil {return sdk.Error("failed to call get_state")}sdk.Instance.Infof("[GetTxTimeStamp] GetTxTimeStamp=" + result)// 返回结果return sdk.Success([]byte(result))
}func main() {err := sandbox.Start(new(FactContract))if err != nil {log.Fatal(err)}
}
相关文章:

长安链使用Golang编写智能合约教程(三)
本篇主要介绍长安链Go SDK写智能合约的一些常见方法的使用方法或介绍 资料来源: 官方文档官方示例合约库 官方SDK接口文档 教程一:智能合约编写1 教程二:智能合约编写2 一、获取参数、获取状态、获取历史记录的方法解析 注意! …...

Vercel deploy- Nextjs project error-URL link-env variable
Vercel deploy- Nextjs project error-URL link-env variable Error Check Database URL Check next-auth URL NEXTAUTH_URLhttps://yourappname.vercel.app/ 依次排查可能性 Application error: a server-side exception has occurred (see the server logs for more in…...

Java | Leetcode Java题解之第123题买卖股票的最佳时机III
题目: 题解: class Solution {public int maxProfit(int[] prices) {int n prices.length;int buy1 -prices[0], sell1 0;int buy2 -prices[0], sell2 0;for (int i 1; i < n; i) {buy1 Math.max(buy1, -prices[i]);sell1 Math.max(sell1, b…...

Ubuntu22.04之扩展并挂载4T硬盘(二百三十三)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…...

Redis实现延迟队列
最近用到一个延迟消息的功能,第一时间想到使用MQ或者MQ的插件,因为数据量不大,所以尝试使用Redis来实现了,毕竟Redis也天生支持类似MQ的队列消费,所以,在这里总结了一下Redis实现延迟消息队列的方式。 一、…...

如何准确查找论文数据库?
在学术研究过程中,查找相关论文是获取最新研究成果、支持自己研究的重要途径。准确查找论文数据库不仅可以节省时间,还能确保找到高质量的学术资源。本文将介绍一些有效的方法和策略,帮助您准确查找论文数据库。 1. 选择合适的数据库 不同的…...

翻译《The Old New Thing》- What a drag: Dragging a virtual file (IStream edition)
What a drag: Dragging a virtual file (IStream edition) - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20080319-00/?p23073 Raymond Chen 2008年03月19日 拖拽虚拟文件(IStream 版本) 上一次,我们看…...

【FPGA】Verilog语言从零到精通
接触fpga一段时间,也能写点跑点吧……试试系统地康康呢~这个需要耐心但是回报巨大的工作。正原子&&小梅哥 15_语法篇:Verilog高级知识点_哔哩哔哩_bilibili 1Verilog基础 Verilog程序框架:模块的结构 类比:c语言的基础…...

unity打包的WebGL部署到IIS问题
部署之后会出错,我遇到的有以下几种; 进度条卡住不动 明明已经部署到了IIS上,为什么浏览网页的时候还是过不去或者直接报错。 进度条卡住不动的问题其实就是wasm和data的错误。 此时在浏览器上按F12进入开发者模式查看错误(下图…...

GPT-4o:人工智能的新里程碑
GPT-4o,作为OpenAI最新推出的人工智能技术,无疑在人工智能领域掀起了新一轮的浪潮。这款新型的语言模型不仅继承了GPT系列的核心优势,更在多个方面实现了突破性的进展。以下,我们将从版本间的对比分析、GPT-4o的技术能力以及个人整…...

发现一个ai工具网站
网址 https://17yongai.com/ 大概看了下,这个网站收集的数据还挺有用的,有很多实用的ai教程。 懂ai工具的可以在这上面找找灵感。...

第二十五章新增H5基础(以及视频~兼容)
1.HTML5中新增布局标签 HTML5新增了页眉,页脚,内容块等文档结构相关标签,可以使文档结构更加清晰明了。 1.新增的结构标签 1、<header>标签 定义文档或者文档中内容块的页眉。通常可以包含整个页面或一个内容区域的标题,…...

[英语单词] production quality
Our goal is to implement a production quality switch platform that supports standard management interfaces and opens the forwarding functions to programmatic extension and control. 说在openswitch的文档里有说这两词,含义是产品质量。是production修…...

windows安装nodeJs,以及常用操作
1. 官网(Node.js — Run JavaScript Everywhere (nodejs.org))下载想要安装的node版本 的安装包完成安装 2.环境变量设置: 系统变量: Path新增:D:\Program Files\nodejs (node安装目录) 3.设置淘宝源: npm config set registr…...

MySql part1 安装和介绍
MySql part1 安装和介绍 数据 介绍 什么是数据库,数据很好理解,一般来说数据通常是我们所认识的 描述事物的符号记录, 可以是数字、 文字、图形、图像、声音、语言等,数据有多种形式,它们都以经过数字化后存入计算机…...

SpringBoot打war包并配置外部Tomcat运行
简介 由于其他原因,我们需要使用SpringBoot打成war包放在外部的Tomcat中运行,本文就以一个案例来说明从SpringBoot打war包到Tomcat配置并运行的全流程经过 环境 SpringBoot 2.6.15 Tomcat 8.5.100 JDK 1.8.0_281 Windows 正文 一、SpringBoot配置打war包 第一步&a…...

2024.5.31每日一题
LeetCode 找出缺失的重复数字 题目链接:2965. 找出缺失和重复的数字 - 力扣(LeetCode) 题目描述 给你一个下标从 0 开始的二维整数矩阵 grid,大小为 n * n ,其中的值在 [1, n2] 范围内。除了 a 出现 两次ÿ…...

Oracle 数据库 varchar2 从 4000 扩展到 32k
Oracle 数据库 varchar2 从 4000 扩展到 32k 0. 引言1. 扩展 varchar2 支持长度2. 测试 0. 引言 今天来个项目需求,有1个字段的存储内容大概1万字。 当然其中1个方法是将这个字段的内容切分成几个字段,还有1个方法就是将 varchar2 默认支持 4000 的能力…...

postgressql——事务提交会通过delayChkpt阻塞checkpoint(9)
事务提交会通过delayChkpt阻塞checkpoint Postgresql事务在事务提交时(执行commit的最后阶段)会通过加锁阻塞checkpoint的执行,尽管时间非常短,分析为什么需要这样做: 首先看提交堆栈 #1 0x0000000000539175 in Co…...

开发者工具-sources(源代码选项)
一、概要说明 源代码面板从视觉效果上分为三个区域:菜单区、内容区、监听区。 菜单区里面有5个子分类: 网页(Page):指页面源,包含了该页面中所有的文件,即使多个域名下的文件也都会展示出来,包括iframe…...

没有 rr 头的 kamailio 路由脚本
分享下笔者最近编写的 kamailio 路由脚本 不用 rr 模块,因为有些 sip 协议栈不支持 rr 头处理 sip 注册直接回 200 OK,这部分目前不是重点更换 contact 头,换成 kamailio 自己目前只支持 sip transport 为 udp,以后可能支持 tcp&…...

mysql 分区
目标 给一个表(半年有800万)增加分区以增加查询速度 约束 分区不能有外键否则会报错 https://blog.csdn.net/yabingshi_tech/article/details/52241034 主键 按照时间列进行分区 https://blog.csdn.net/winerpro/article/details/135736454 参看以…...

在龙芯安装docker compose
安装过程报错:pynacl无法安装 原因:未知 解决尝试:单独安装pynacl 执行:pip install pynacl 报错: 再次执行dockerscompose撒谎啥 少了头文件 dev,表示c编译器有问题 python是c编写的 喵的 搞了半天是我…...

纯C++做多项式拟合
一、多项式拟合用途 当前有一组对应的x、y数据,希望通过这些数据点做出近似的多项式曲线:YnX^2mXc 其中多项式最高次数可调,返回各个参数及曲线的拟合度R^2 二、函数实现 参数中的order为设置的多项式最高次次数,coefficients为…...

vulnhub靶场之FunBox-9
一.环境搭建 1.靶场描述 Its a box for beginners, but not easy. Gather careful !!! Hint: Dont waste your time ! Every BruteForce-Attack at all ports can be stopped after 1500 trys per account. Enjoy the game and WYSIWYG ! This works better with VirtualBox…...

C# 变量与参数详解
在C#编程中,变量和参数是构建程序逻辑的基础。本篇博客将深入探讨C#中的变量作用域、参数传递方式、以及一些高级特性,如in、ref、out参数,params修饰符,可选参数和命名参数等。 变量作用域 在C#中,变量的作用域分为…...

CentOS7.9部署安装OpenGauss 5.0.2企业版
1、更新系统: yum update -y 2、更改主机名: hostnamectl set-hostname opendb01 3、关闭透明页: echo never > /sys/kernel/mm/transparent_hugepage/enabled echo never > /sys/kernel/mm/transparent_hugepage/defrag# 加入开机自启动 echo …...

java基础-chapter15(io流)
io流:存储和读取数据的解决方案 I:input O:output io流的作用:用于读写数据(本地文件,网络) io流按照流向可以分为: 输出流:程序->文件 输入流:文件->程序 io流按照操作文件…...

mysql去除重复数据
需求描述 doc表有很多重复的title,想去除掉重复的记录 表结构 CREATE TABLE doc (id INT PRIMARY KEY,title VARCHAR(255),content TEXT );去重SQL -- 创建临时表 CREATE TEMPORARY TABLE temp_doc AS SELECT * FROM doc WHERE 10;-- 插入唯一的记录(每个title最…...

MySQL基础索引知识【索引创建删除 | MyISAM InnoDB引擎原理认识】
博客主页:花果山~程序猿-CSDN博客 文章分栏:MySQL之旅_花果山~程序猿的博客-CSDN博客 关注我一起学习,一起进步,一起探索编程的无限可能吧!让我们一起努力,一起成长! 目录 一,索引用…...