当前位置: 首页 > news >正文

Solidity开发智能合约

05-Solidity开发智能合约

0 Solidity和智能合约

Solidity开发可运行的智能合约步骤:

  1. 源代码通过编译成字节码(Bytecode),同时会产生二进制接口规范(ABI)
  2. 通过交易将字节码部署到以太坊网络,部署成功会产生一个智能合约账户
  3. 通过web3.js+ABI去调用智能合约中的函数来实现数据的读取和修改

下面开始简单例子入手Solidity。

1 以太坊的前端 API

1.1 Web3.js

地址:

alt

安装:

npm install web3

使用方法:

// In Node.js
const Web3 = require('web3');
const web3 = new Web3('ws://localhost:8546');
console.log(web3);
// Output
{
    eth: ...,
    shh: ...,
    utils: ...,
}

也可像以下方法使用:

import Web3 from 'web3';
import { BlockHeader, Block } from 'web3-eth' // ex. package types
const web3 = new Web3('ws://localhost:8546');

使用举例:

web3.eth.getAccounts().then(console.log);

1.2 Ethereumjs

以太坊的实用程序功能集合,如ethereumjs-util和ethereumjs-tx,github:

alt

安装:

npm install ethereumjs-util

使用方法:

import assert from 'assert'
import { isValidChecksumAddress, unpadBuffer, BN } from 'ethereumjs-util'

const address = '0x2F015CG60E0be116B1f0CD534704Dd9c92118FB6A'
assert.ok(isValidChecksumAddress(address))

assert.equal(unpadBuffer(Buffer.from('000000006600''hex'), Buffer.from('6600''hex'))
             
assert.equal(new BN('dead'16).add(new BN('101010'2)), 57047)
Ethereumjs-API

Account class:私钥/公钥和地址相关功能 (创建、验证、转换)

举例: Const generateAddress2

generateAddress2(from: Buffer, salt: Buffer, initCode: Buffer): Buffer

NameTypeDescription
fromBuffer谁开始创建新地址
saltBuffer加盐
initCodeBuffer创建合约的初始代码
ethereumjs-wallet

ethereumjs-wallet: 轻量级钱包实现:

alt

目前,它支持密钥创建和各种格式之间的转换。

使用方法:

import Wallet from 'ethereumjs-wallet' Thirdparty API: import { thirdparty } from 'ethereumjs-wallet' HD Wallet API: import { hdkey } from 'ethereumjs-wallet'

其他常用接口
  • light.js - 为轻客户端优化的高级反式JS库
  • flex-contract 和 flex-ether - 零配置的高级库,用于与智能合约进行交互并进行交易
  • ez-ens - ens-简单的零配置以太坊域名服务地址解析器
  • web3x - web3.js的TypeScript端口。好处包括小巧的构造和全类型的安全性,包括与合同进行交互时的安全性
  • Nethereum - 跨平台的以太坊开发框架
  • Tasit SDK - 一个React Native库,使用在移动端与以太坊进行交互
  • Delphereum - 以太坊区块链的Delphi接口,允许开发适用于Windows,macOS,iOS和Android的dApp开发
  • Fortmatic - 一种易于使用的SDK,无需扩展或下载即可构建web3 dApp
  • Portis - 具有SDK的非托管钱包,可轻松与DApp进行交互而无需安装任何东西

2 以太坊的后端 API

2.1 Web3.py - Python Web3

需要Python 3.7.2+

安装:

pip install web3

测试Provider:

>>> from web3 import Web3, EthereumTesterProvider
>>> w3 = Web3(EthereumTesterProvider())
>>> w3.isConnected()
True

local Provider:

>>> from web3 import Web3
# IPCProvider:
>>> w3 = Web3(Web3.IPCProvider('/path/to/geth.ipc'))
# HTTPProvider:
>>> w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545'))
# WebsocketProvider:
>>> w3 = Web3(Web3.WebsocketProvider('wss://127.0.0.1:8546'))
>>> w3.isConnected()
True

获取最后的区块

web3.eth.get_block("latest")

获取区块number

web3.eth.block_number

检查账户余额

# 输入钱包地址
web3.eth.get_balance('0x742d35Cc6634C0532925a3b844Bc454e4438f44e')

2.2 Web3j:Java Ethereum Dapp API

轻量级、高度模块化、反应式、类型安全的Java和Android库,用于处理智能合约并与以太坊网络上的客户端(节点)集成。

运行时的依赖:

  • RxJava:反应式扩展的Java-VM实现,一个库,用于使用可观察序列组合异步和基于事件的程序
  • OKHttp:默认情况下高效的HTTP客户端
  • Jackson Core : 快速J将SON序列化/反序列化
  • Bouncy Castle : (Android上的Spongy Castle )用于加密
  • Jnr-unixsocket:类Unix系统的IPC(Android上不可用)
  • Java-WebSocket:该存储库包含一个纯Java编写的基本WebSocket服务器和客户端实现。底层类是用java实现的。它允许非阻塞事件驱动模型(类似于web浏览器的WebSocket API)。

Java:

<dependency>
    <groupId>org.web3j</groupId>
    <artifactId>core</artifactId>
    <version>4.8.7</version>
    </dependency>

Android:

<dependency>
    <groupId>org.web3j</groupId>
    <artifactId>core</artifactId>
    <version>4.8.7-android</version>
    </dependency>

2.3 Ethereum-php

Ethereum JSON-RPC API的类型,支持PHP-7.1+。

在composer.json文件中添加类库

{
    "minimum-stability""dev",
    "autoload": {
        "psr-4": {
            "Ethereum\\\": "src/"
        }
    },
    "
repositories": [
        {
            "
type": "git",
            "
url": "https://github.com/digitaldonkey/ethereum-php.git"
        }
    ],
    "require": {
        "digitaldonkey/ethereum-php""dev-master"
    }
}

用法:composer require digitaldonkey/ethereum-php

require __DIR__.'/vendor/autoload.php';
use Ethereum\Ethereum;
try {
    // Connect to Ganache
    $eth = new Ethereum('http://127.0.0.1:7545');
    // Should return Int 63
    echo $eth->eth_protocolVersion() ->val();
}
catch (\Exception $exception) {
    die("Unable to connect.");
}

其它

  • Nethereum - .Net Web3
  • Ethereum.rb - Ruby Web3
  • Eventeum - 由Kauri用Java编写的以太坊智能合约事件和后端微服务之间的桥梁
  • Ethereum-jsonrpc-gateway - 一个网关,允许您运行多个以太坊节点以实现冗余和负载平衡。可以作为Infura的替代品(或在其之上)运行。用Golang写的
  • Ethereum Contract Service - 一种MESG服务,可根据其地址和ABI与任何以太坊合约进行交互
  • Ethereum Service - 一种MESG服务,用于与以太坊中的事件进行交互并与其进行交互
  • Marmo - Python, JS和Java SDK,以简化与以太坊的交互。使用中继器将交易成本分担给中继器

3 开发环境部署

3.1 npm

Node Package Manager,一个软件包管理系统,专管理用 js 编写的软件包。可免费下载别人写好的js软件包,并用到项目中,当然也可以上传共享自己写的js软件包。

Node.js内置npm,只要安装node.js,就可直接使用npm。

node官网: https://nodejs.org/en/

安装完 node.js 后,把npm更新到最新版本:

npm install npm@latest -g
项目使用npm
  1. 初始化:根据提示填写信息,即可产生package.json文件 cd <项目根目录> npm init
  2. 使用npm下载安装包

安装需要使用的包

npm install lodash

安装完成后,package.json中会添加版本信息,如下:

{
    "dependencies": {
        "lodash""^1.0.0"
    }
}

使用安装的包:

var lodash = require('lodash');
var output = lodash.without([1,2,3],1);
console.log(output);

更新包

法一:根据版本号更新

npm install lodash@版本号

法二:更新最新版本

- npm install lodash
- npm install lodash@latest

法三:修改package.json中包的版本号,下次npm install会自动更新会修改后的版本。

npm常用命令
#全局安装 lodash
npm install -g lodash

#本地安装 lodash(默认安装最新版本)
npm install lodash
npm install lodash@latest

#安装指定版本
npm install lodash@1.0.0

#卸载
npm uninstall lodash

#查看已安装
npm ls

#更新 lodash 到最新版本
npm update lodash

#搜索 lodash
npm search lodash
常见错误

Error: Cannot find moduel

packages 没有被安装

解决方法:

# 无作用域包安装
npm install <package_name>

# 有作用域包安装
npm install <@scope/package_name>

安装出错,错误提示:npm resource busy or locked...

可先清除再重新安装

npm cache clean

npm install
版本控制符

版本号由三位数字组成(例如:1.2.3):

  • 第一位表示主版本
  • 第二位表示次要版本
  • 第三位表示补丁版本
^表示用于确定主版本号,~用于确定主版本号+次要版本号

^1:等同于1.xx,以1开头所有版本

~2.2:等同于2.2.x,以2.2开头所有版本

~2.2.1:以2.2开头,且最后一位补丁号≥1的所有版本,即2.2.1与2.2.9之间版本,包括头尾

如:

"dependencies": {
  "my_dep""^1.0.0",
  "another_dep""~2.2.0"
},

3.2 Ganache(过时)

运行在PC上的以太坊开发者的个人区块链。

Ganache,Truffle Suite的一部分,通过把合约和交易放到前面来简化dapp的开发。

用Ganache可快速看到你的应用咋影响区块链的。细节如:你的账户、余额、合约及Gas成本。也可调整Ganache的采矿控制来更好的适用你的应用。

Ganache为那些不在GUI工作的人提供一个命令行工具。非常适合自动化测试和持续集成的环境。

sodu npm install -g ganache-cli

安装完成后命令行输入

$ ganache-cli

查看是否安装成功

启动ganache-cli指令:

ganache-cli

图形界面的版本,下载地址:https://github.com/trufflesuite/ganache/releases

Ganache常见命令参数

调整挖矿时间(Ganache默认是在交易产生时进行挖矿):

//10秒产生一个区块
ganache-cli -b 10

指定主机端口与网络ID:

//指定IP,端口及网络ID
ganache-cli -h 127.0.0.1 -p 8545 -i 8888

设置gas价格和gas上限:

ganache-cli -g 20000000
ganache-cli -l 10000000

输出RPC调用请求体:

ganache-cli -v

-v不是version缩写,而是verbose的意思,RPC调用默认只输出方法名,如eth_getBlockByNumber,而使用-v则会输出请求体

常见命令参数

指定默认生成账户的以太币:

ganache-cli -e 1000

指定默认生成的账户数量:

ganache-cli -a 50

助记词相关:

ganache-cli -d
ganache-cli -m "boil razor arrest first space chicken social explain leader soon unique upset"
ganache-cli -s "hello"


-d: 让Ganache启动节点时使用固定的预定义助记词,这样其他连接Ganache的轻钱包不用每次重新导入助记词。
-m: 可指定助记词,使用相同的助记词会生成一个相同的HD钱包;
-s: 指定一个种子用来生成助记词,然后使用助记词生成HD钱包,相同的种子会产生相同的助记词从而生成相同的HD钱包。

锁定和解锁账户:

# 使用--secure --unlock
ganache-cli --secure --unlock "0x67a3119994ffc7b384e086e443bf7a73a96a45c06ae3d1b163586ebc8e6f22"
--unlock "0xac0603889ceee85ff0075de364d4fc92d383cecc57c2a2c3465404c8296feab15"

# 或用-n -u
ganache-cli -n -u 0 -u 1

指定账户:

ganache-cli --account="<privatekey>",balance" [--account="<privatekey>",balance"]
在工程中启动Ganache的server

Ganache除了可以直接提供Provider之外,还可以作为一个HTTP Server,这样其他的一些服务或者应用就可以通过HTTP的方式调用对应的接口。使用非常简单,我们使用上面建立的工程,不过要添加一个依赖CircularJSON,执行下面的命令安装

npm i circular-json -S

在工程中启动Ganache的server,然后在工程目录下面创建一个server.js文件:

// 读写文件
const fs = require('fs');
// 提供测试服务
const ganache = require("ganache-cli");
// 格式化输对像
const CircularJSON = require('circular-json');
var server = ganache.server();
// 监听8545端口
server.listen(8545function(err, blockchain){
    console.log(err);
    console.log(blockchain)
    // fs.writeFileSync('blockchain.txt', CircularJSON.stringify(blockchain));
    // 输出ganache-cli中区块链数据结构及内容到blockchain文件中
    fs.writeFileSync('blockchain.txt', CircularJSON.stringify(blockchain, null'\t')
    // 打印钱包助记词
    console.log(blockchain.mnemonic);
});

启动服务器不需要web3.js,但是需要文件,所以引入Node.js的ts模块和circular-json将对象转换为字符串,因为对象中有循环引用,所以不能直接使用JSON,而是使用了CircularJSON。

上面设置监听端口8545,回调函数中我们打印了一下blockchain的助记词,当然也可以打印其他blockchain中的数据。blockchain的数据比较多,所以没有直接使用console输出,而是写入blockchain.txt文件中,多看这个文件有助于理解以太坊区块链数据结构。

因为数据比较多,这里就不一一给出blockchain的数据了,感兴趣可以自己动手试一试,然后看一下blockchain文件中的数据。

配置工程中依赖的Ganache

Ganache作为工程依赖的配置和命令行使用命令参数基本一致,以下为Ganache工程依赖常用的配置

参数说明
accounts和命令行的--accounts相同
logger实现了log方法的对象,例如console,用于输出日志
mnemonic字符串,设置助记词
port整数,设置端口
seed字符串,设置种子
total_accounts数字类型,账号数量
default_balance_ether每一个生成账户,默认的以太坊数量
network_id整数,网络ID
blockedboolean值,是否锁定账户
unlocked_accounts数组,不确定账户、地址或者索引值
db_path区块数据存放位置

Geth

又名Go Ethereum,是以太坊协议的三种实现之一,由Go语言开发,完全开源的项目。Geth可以被安装在很多操作系统上,包括Windows、Linux、Mac的OSX、Android或者IOS系统. Geth官网: https://geth.ethereum.org/:

alt

Geth的Github地址: https://github.com/ethereum/go-ethereum:

alt

作者: DeeLThink https://www.bilibili.com/read/cv16165148

输入 geth version,检查是否安装成功

Geth常用命令

USAGE

geth [options] command [command options] [arguments...]:geth [选项] 命令 [命令选项][参数...]

COMMANDS

account  Manage accounts
//管理账户
attach    Start an interactive JavaScript environment (connect to node)
//启动交互式JavaScript环境(连接到节点)
bug       opens a window to report a bug on the geth repo
//给github源代码仓库提issue,提交bug
console   Start an interactive JavaScript environment
//启动交互式JavaScript环境
copydbCreate a local chain from a target chaindata folder //从文件夹创建本地链
dumpDump a specific block from storage //Dump(分析)一个特定的块存储
dumpconfigShow configuration values
exportExport blockchain into file
importImport a blockchain file
initBootstrap and initialize a new genesis block
jsExecute the specified JavaScript files //执行指定的JavaScript文件(多个)
license   Display license information    //显示许可信息
makecache Generate ethash verification cache (for testing)   //生成ethash验证缓存(用于测试)
makedag Generate ethash mining DAG (for testing)   //生成ethash挖矿DAG(用于测试)
monitor Monitor and visualize node metrics    //监控和可视化节点指标
removedb Remove blockchain and state databases   //删除区块链和状态数据库
version Print version numbers    //打印版本号
wallet Manage Ulam presale wallets   //管理Ethereum预售钱包
help, h Shows a list of commands or help for one command   //显示一个命令或帮助一个命令列表

4 投票的例子

以下是一个简单的Solidity合约示例,它实现了电子投票的功能。这个合约的主要目标是确保投票权被正确分配,并防止被操纵。 首先,我们创建了一个委托投票机制,允许选民将他们的投票权委托给他们信任的人。为了做到这一点,我们需要为每个选民(即“表决”)创建一个独立的地址,并赋予他们投票权。然后,作为合约的创造者——即“主席”,我们将为每个选项提供一个简称为“winningProposal()”的函数,用于返回获得最多投票的提案。 在投票时间结束时,“winningProposal()”函数会返回获得最多投票的提案,从而实现电子投票的功能。

pragma solidity ^0.4.22
//@title 委托投票contract Ballot{  //这里声明了一个新的复合类型用于稍后的变量  //它用来表示一个选民  struct Voter {  uint weight; //计票的权重  bool voted; //若为真,代表该人已投票  address delegate; //被委托人  uint vote; //投票提案的索引  }  //提案的类型  struct Proposal {  bytes32 name; //简称(最长32个字节)  uint voteCount; //得票数  }address public chairperson;// 这声明了一个状态变量,为每个可能的地址存储一个 `Voter`。mapping(address => Voter) public voters;// 一个 `Proposal` 结构类型的动态数组Proposal[] public proposals;// 为 `proposalNames` 中的每个提案,创建一个新的(投票)表决constructor(bytes32[][] proposalNames) public {chairperson = msg.sender;voters[chairperson].weight = 1;//对于提供的每个提案名称,//创建一个新的 Proposal 对象并把它添加到数组的末尾。for (uint i = 0; i < proposalNames.length; i++) {// `Proposal({...})` 创建一个临时 Proposal 对象,// `proposals.push({...})` 将其添加到 `proposals` 的末尾proposals.push(Proposal({name: proposalNames[i],voteCount: 0}));}}// 授权 `voter` 对这个(投票)表决进行投票// 只有 `chairperson` 可以调用该函数function giveRightToVote(address voter) public {// 若 `require` 的第一个参数的计算结果为 `false`,// 则终止执行,撤销所有对状态和以太币余额的改动。// 在旧版的 EVM 中这曾经会消耗所有 gas,但现在不会了。// 使用 require 来检查函数是否被正确地调用,是一个好习惯。// 你也可以在 require 的第二个参数中提供一个对错误情况的解释。require(msg.sender == chairperson,"Only chairperson can give right to vote.");require(!voters[voter].voted,"The voter already voted.");require(voters[voter].weight == 0);voters[voter].weight = 1;}//把你的投票委托到投票者 `to`。function delegate(address to) public {//传引用Voter storage sender = voters[msg.sender];require(!sender.voted, "You already voted.");require(to != msg.sender, "Self-delegation is disallowed.");//委托是可以传递的,只要被委托者 `to` 也设置了委托。//一般来说,这种循环委托是危险的。因为,如果传递的链条太长,则可能需消耗的gas要多于区块中剩余的(大于区块设置的gasLimit),这种情况,委托不会被执行。//而在另一些情况下,如果形成闭环,则会让合约完全卡住。while (voters[to].delegate != address(0)) {to = voters[to].delegate;}//不允许闭环委托require(to != msg.sender, "Found loop in delegation.");// `sender` 是一个引用,相当于对 `voters[msg.sender].voted` 进行修改sender.voted = true;sender.delegate = to;Voter storage delegate_ = voters[to];if (delegate_.voted) {// 若被委托者已经投过票了,直接增加得票数proposals[delegate_.vote].voteCount += sender.weight;} else {// 若被委托者还没投票,增加委托者的权重delegate_.weight += sender.weight;}}//把你的票(包括委托给你的票),  //投给提案 `proposals[proposal].name`.  function vote(uint proposal) public {  Voter storage sender = voters[msg.sender];  require(!sender.voted, "Already voted.");  sender.voted = true;  sender.vote = proposal;//如果 `proposal` 超过了数组的范围,则会自动抛出异常,并恢复所有的改动  proposals[proposal].voteCount += sender.weight;  }//@dev 结合之前所有的投票,计算出最终胜出的提案  function winningProposal() public view  returns (uint winningProposal_)  {  uint winningVoteCount = 0;  for (uint p = 0; p < proposals.length; p++) {  if (proposals[p].voteCount > winningVoteCount) {  winningVoteCount = proposals[p].voteCount;  winningProposal_ = p;  }  }}//调用winningProposal()函数以获取提案数组中获胜者的索引,并以此返回获胜者的名称function winnerName() public viewreturns (bytes32 winnerName_){winnerName_ = proposals[winningProposal()].name;}
}

参考:

  • https://github.com/MetaMask

获取更多干货内容,记得关注我哦。

本文由 mdnice 多平台发布

相关文章:

Solidity开发智能合约

05-Solidity开发智能合约 0 Solidity和智能合约 Solidity开发可运行的智能合约步骤&#xff1a; 源代码通过编译成字节码&#xff08;Bytecode&#xff09;&#xff0c;同时会产生二进制接口规范&#xff08;ABI&#xff09; 通过交易将字节码部署到以太坊网络&#xff0c;部署…...

bind实验

服务端 查看域名 [rootclient yum.repos.d]# hostname client 设置域名 [rootclient yum.repos.d]# hostnamectl set-hostname dns1.openlab.edu [rootclient yum.repos.d]# cd [rootclient ~]# hostname dns1.openlab.edu 安装bind包 [rootclient ~]# yum install bind -y…...

ARM架构下安装新版docker及docker-compose

一、常见CPU 架构&#xff1a; 二、环境信息 CPU架构操作系统配置HUAWEI Kunpeng 920 5220 aarch64openEuler 22.03 (LTS-SP3)64C128g15T 三、安装docker 3.1 二进制包下载 docker-ce 社区下载地址&#xff1a; wget https://mirrors.nju.edu.cn/docker-ce/linux/static/s…...

自锁/非自锁开关原理笔记

前言&#xff1a;编写不易&#xff0c;请勿搬运&#xff0c;感谢理解&#xff0c;仅供学习。 开关介绍 6指针开关&#xff0c;这种开关分为自锁和非自锁开关&#xff0c;自锁开关有两种状态&#xff0c;按下和松开的状态&#xff0c;非自锁开关在按下过后&#xff0c;按键会复…...

基于SpringBoot+Vue的论坛网站-无偿分享 (附源码+LW+调试)

目录 1. 项目技术 2. 功能菜单 3. 部分功能截图 4. 研究背景 5. 研究目的 6. 可行性分析 6.1 技术可行性 6.2 经济可行性 6.3 操作可行性 7. 系统设计 7.1 概述 7.2 系统流程和逻辑 7.3 系统结构 8. 数据库设计 8.1 数据库ER图 &#xff08;1&#xff09;问题反…...

基于SSM的博客系统+LW参考示例

1项目介绍 系统角色&#xff1a;管理员、普通用户功能模块&#xff1a;管理员&#xff08;用户管理&#xff0c;博文分类管理&#xff0c;博文信息管理&#xff0c;话题分类管理&#xff0c;热议话题管理&#xff0c;私信管理&#xff0c;敏感词管理&#xff0c;系统管理等&am…...

[241129] Docker Desktop 4.36 发布:企业级管理功能、WSL 2 增强 | Smile v4.0.0 发布

目录 Docker Desktop 4.36 发布&#xff1a;企业级管理功能、WSL 2 和 ECI 增强Smile v4.0.0 发布&#xff01;Java 机器学习库迎来重大升级 Docker Desktop 4.36 发布&#xff1a;企业级管理功能、WSL 2 和 ECI 增强 Docker Desktop 4.36 带来了强大的更新&#xff0c;简化了…...

webpack5开发环境、生产环境配置 (三)

开发环境&#xff1a;就是我们开发代码时使用的模式。 这个模式我们做两件事情&#xff1a; 1、编译代码&#xff0c;使浏览器能识别运行 2、代码质量检查&#xff0c;树立代码规范 生产环境&#xff1a;开发完成代码后&#xff0c;我们需要得到代码将来部署上线。 这个模式…...

一次Kafka启动失败引出的问题

背景 Some time&#xff0c;有个现场童鞋说咱的Kafka实例有个broker一直crash&#xff0c;还截图给我看了&#xff0c;大致是Kafka启动加载topic分区日志文件的时候&#xff0c;然后就没了&#xff0c;连个WARN都没有。当然&#xff0c;光看这个截图咱啥都不知道&#xff0c;因…...

[Linux] 进程间通信——匿名管道命名管道

标题&#xff1a;[Linux] 进程间通信——匿名管道&&命名管道 水墨不写bug &#xff08;图片来源于网络&#xff09; 目录 一、进程间通信 二、进程间通信的方案——匿名管道 &#xff08;1&#xff09;匿名管道的原理 &#xff08;2&#xff09;使用匿名管道 三、进…...

人机交互中的状态交互、趋势交互

在人机交互中&#xff0c; 状态交互 和 趋势交互 是两种重要的交互方式&#xff0c;它们分别涉及到用户与系统之间不同的交互模型和机制。 1. 状态交互 状态交互主要聚焦于用户与系统之间的状态转换及其反馈机制。在这种交互模式下&#xff0c;系统会根据用户的输入或行为发生状…...

基于Java Springboot房屋租赁App且微信小程序

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 微信…...

golang的wails框架在macos下的问题

1、前言 之前练手写了格调用ollama api的web应用&#xff0c;想找个容器打包下&#xff0c;于是找到wails来打包&#xff0c;windows下都是很正常的&#xff0c;因为就是普通的http调用&#xff0c;也没遇到cors跨域问题&#xff0c;但是到了macos下使用wails dev命令启动的客户…...

编程设计模式助记顺口溜

1、顺口溜 创建型&#xff0c;工厂多&#xff0c;单例建对象&#xff0c;抽象工厂做。建造者分步做&#xff0c;原型克隆最不愁。 结构型&#xff0c;适配器&#xff0c;桥接组合都不错&#xff0c;装饰外观飞享元&#xff0c;代理再添一把火。 行为型&#xff0c;责任链&…...

java网络通信(三):TCP通信、实现客户端-服务端消息通信

目录 1、什么是 TCP协议&#xff1f; 2、代码实现TCP协议的一发一收 2.1、客户端 2.2、服务端 2.3 结果演示 3、代码实现TCP协议的多发多收 3.1 客户端 3.2 服务端 3.3 结果演示 简介&#xff1a;本文章主要是演示如何用java代码以及TCP协议实现网络通信&#xff0c;实…...

mybatis-plus 对于属性为null字段不更新

MyBatis-Plus 默认情况下会根据字段的值是否为 null 来决定是否生成对应的 UPDATE 语句。这是由 更新策略 决定的&#xff0c;默认的行为是 忽略 null 值&#xff0c;即如果字段值为 null&#xff0c;该字段将不会出现在 UPDATE 语句中。 默认行为分析 MyBatis-Plus 默认的 Fi…...

GAGAvatar: Generalizable and Animatable Gaussian Head Avatar 学习笔记

1 Overall GAGAvatar&#xff08;Generalizable and Animatable Gaussian Avatar&#xff09;&#xff0c;一种面向单张图片驱动的可动画化头部头像重建的方法&#xff0c;解决了现有方法在渲染效率和泛化能力上的局限。 旋转参数 现有方法的局限性&#xff1a; 基于NeRF的方…...

《数据挖掘:概念、模型、方法与算法(第三版)》

嘿&#xff0c;数据挖掘的小伙伴们&#xff01;今天我要给你们介绍一本超级实用的书——《数据挖掘&#xff1a;概念、模型、方法与算法》第三版。这本书是数据挖掘领域的经典之作&#xff0c;由该领域的知名专家编写&#xff0c;系统性地介绍了在高维数据空间中分析和提取大量…...

springboot vue 开源 会员收银系统 (12)购物车关联服务人员 订单计算提成

前言 完整版演示 http://120.26.95.195/ 开发版演示 http://120.26.95.195:8889/ 在之前的开发进程中&#xff0c;我们完成订单的挂单和取单功能&#xff0c;今天我们完成购物车关联服务人员&#xff0c;用户计算门店服务人员的提成。 1.商品关联服务人员 服务人员可以选择 一…...

lua闭包Upvalue

闭包 lua任何函数都是闭包&#xff0c;闭包至少带1个upValue&#xff1b; CClosure是使用Lua提供的lua_pushcclosure这个C-Api加入到虚拟栈中的C函数&#xff0c;它是对LClosure的一种C模拟 如string.gmatch就是cclosure 定义&#xff1a; #define ClosureHeader \CommonH…...

下载maven 3.6.3并校验文件做md5或SHA512校验

一、下载Apache Maven 3.6.3 Apache Maven 3.6.3 官方下载链接&#xff1a; 二进制压缩包&#xff08;推荐&#xff09;: ZIP格式: https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.zipTAR.GZ格式: https://archive.apache.org/dist/…...

深入探索Flax:一个用于构建神经网络的灵活和高效库

深入探索Flax&#xff1a;一个用于构建神经网络的灵活和高效库 在深度学习领域&#xff0c;TensorFlow 和 PyTorch 作为主流的框架&#xff0c;已被广泛使用。不过&#xff0c;Flax 作为一个较新的库&#xff0c;近年来得到了越来越多的关注。Flax 是一个由Google Research团队…...

vue项目中单独文件的js不存在this.$store?.state怎么办

在Vue项目中&#xff0c;如果你在单独的文件&#xff08;比如插件、工具函数等&#xff09;中遇到this.$store不存在的情况&#xff0c;这通常是因为this上下文不指向Vue实例&#xff0c;或者Vuex store没有被正确地注入到Vue实例中。以下是几种可能的解决方案&#xff1a; 确保…...

物联网客户端在线服务中心(客服功能/私聊/群聊/下发指令等功能)

一、界面 私聊功能&#xff08;下发通知类&#xff0c;一对多&#xff09;群聊&#xff08;点对点&#xff09;发送指令&#xff08;配合使用客户端&#xff0c;基于cefsharp做的物联网浏览器客户端&#xff09;修改远程参数配置&#xff08;直接保存到本地&#xff09;&#…...

AI开发:逻辑回归 - 实战演练- 垃圾邮件的识别(二)

接上一篇AI开发&#xff1a;逻辑回归 - 实战演练- 垃圾邮件的识别&#xff08;一&#xff09; new_email 无论为什么文本&#xff0c;识别结果几乎都是垃圾邮件,因此我们需要对源码的逻辑进行梳理一下&#xff1a; 在代码中&#xff0c;new_email 无论赋值为何内容都被识别为…...

hint: Updates were rejected because the tip of your current branch is behind!

问题 本地仓库往远段仓库推代码时候提示&#xff1a; error: failed to push some refs to 192.168.2.1:java-base/java-cloud.git hint: Updates were rejected because the tip of your current branch is behind! refs/heads/master:refs/heads/master [rejected] (…...

Vue的数据驱动原理

文章目录 什么是数据驱动那么vuejs是如何实现这种数据驱动的呢?对getter/setter的理解?一个简单的演示例子vue数据驱动原理是:采用数据劫持结合发布者和订阅者模式,通过“object.defineproperty()”来劫持各个属性的setter、getter,在数据变动时发布消息给订阅者,触发相应…...

【Db First】.NET开源 ORM 框架 SqlSugar 系列

.NET开源 ORM 框架 SqlSugar 系列 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列【数据事务…...

数据分析-52-时间序列分解之变分模态分解VMD

文章目录 1 时间序列模态分解1.1 模态分解的概念1.2 模态分解的作用1.3 常用的模态分解方法1.4 模态分解的常用库2 变分模态分解VMD2.1 VMD的流程2.2 加载数据集2.2.1 数据重采样2.2.2 原始数据可视化2.3 VMD变分模态分解3 参考附录1 时间序列模态分解 1.1 模态分解的概念 时…...

做异端中的异端 -- Emacs裸奔之路4: 你不需要IDE

确切地说&#xff0c;你不需要在IDE里面编写或者阅读代码。 IDE用于Render资源文件比较合适&#xff0c;但处理文本&#xff0c;并不划算。 这的文本文件&#xff0c;包括源代码&#xff0c;配置文件&#xff0c;文档等非二进制文件。 先说说IDE带的便利: 函数或者变量的自动…...

redhat 7.9配置阿里云yum源

1、mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/ 2、添加dns vim/etc/resolv.conf nameserver 8.8.8.8 nameserver 8.8.4.4 nameserver 114.114.114.114 #配置完先检查下通不通 3、vi /etc/yum/pluginconf.d/subscription-manager.conf # 将 “enabled1” 改为 “ena…...

简单快速的上手python

前言 python是一门可以快速上手的语言&#xff0c;原因是它语法简单&#xff0c;api容易使用自由灵活 当我们需要安装任何的三方库时&#xff0c;只需要执行 pip install XX 之后在代码里面import xxx就可以使用python啦。 并且python的代码自由灵活&#xff0c;使用缩进区…...

PHP和GD如何给图片添加模糊边缘效果

在PHP中&#xff0c;使用GD库给图片添加模糊边缘效果通常涉及几个步骤&#xff0c;包括加载图片、创建模糊效果、应用边缘处理以及保存结果图片。然而&#xff0c;GD库本身并不直接提供边缘模糊的函数&#xff0c;但你可以通过一些技巧来实现类似的效果。 以下是一个简化的步骤…...

PowerShell:查找并关闭打开的文件

Get-SmbOpenFile 打开 Windows PowerShell 并运行 Get-SmbOpenFile | Format-List 若要仅显示特定文件共享的连接&#xff0c;请使用 Where-Object 运行 Get-SmbOpenFile。 Get-SmbOpenFile | Where-Object Path -eq "C:\Data\" | Format-List Get-SmbSession 显…...

SQL进阶技巧:非等值连接--单向近距离匹配

目录 0 场景描述 1 数据准备 2 问题分析 ​编辑 ​编辑 3 小结 数字化建设通关指南 0 场景描述 表 t_1 和表 t_2 通过 a 和 b 关联时,有相等的取相等的值匹配,不相等时每一 个 a 的值在 b 中找差值最小的来匹。 表 t_1:a 中无重复值 表 t_1:a 中无重复值 a 1 2 4 …...

【golang】单元测试,以及出现undefined时的解决方案

单元测试 要对某一方法进行测试时&#xff0c;例如如下这一简单减法函数&#xff0c;选中函数名后右键->转到->测试 1&#xff09;Empty test file 就是一个空文件&#xff0c;我们可以自己写测试的逻辑 但是直接点绿色箭头运行会出问题&#xff1a; 找不到包。我们要在…...

代理IP地址的含义与设置指南‌

在数字化时代&#xff0c;互联网已经成为我们日常生活不可或缺的一部分。然而&#xff0c;在享受互联网带来的便利的同时&#xff0c;我们也面临着隐私泄露、访问限制等问题。代理IP地址作为一种有效的网络工具&#xff0c;能够帮助我们解决这些问题。本文将详细介绍代理IP地址…...

Qt 2D绘图之三:绘制文字、路径、图像、复合模式

参考文章链接: Qt 2D绘图之三:绘制文字、路径、图像、复合模式 绘制文字 除了绘制图形以外,还可以使用QPainter::darwText()函数来绘制文字,也可以使用QPainter::setFont()设置文字所使用的字体,使用QPainter::fontInfo()函数可以获取字体的信息,它返回QFontInfo类对象…...

el-table 纵向 横向 多级表头

<el-table :data"tableData" class"diaTable":span-method"handleSpanMethod"border:header-cell-style"{background:#292929,color:#fff}"><!-- 纵向表头 --><el-table-column label"纵向表头" width"…...

linux perf安装问题解决

WARNING: perf not found for kernel 4.15.0-39 perf安装问题 perf是一个功能强大的linux性能分析工具&#xff0c;其功能依赖于内核&#xff0c;安装perf工具的版本必须与内核版本保持一致。 perf安装问题 使用apt 安装 perf包&#xff0c;运行时提示要安装与内核版本相一致…...

嵌入式Linux无窗口系统下搭建 Qt 开发环境

嵌入式Linux无窗口系统下搭建 Qt 开发环境 本文将介绍如何在树莓派的嵌入式 Linux 环境下&#xff0c;搭建 Qt 开发环境&#xff0c;实现无窗口系统模式&#xff08;framebuffer&#xff09;下的图形程序开发。 1. 安装 Qt 环境 接下来&#xff0c;安装核心 Qt 开发库以及与 …...

JSON vs 表单格式:两种常见请求格式的区别与应用

搞iOS UI 自动化的同时涉及到了给后端发送请求&#xff0c;请求数据的格式常用的有json格式和表单格式&#xff0c;这两种格式如何区分&#xff0c;如何使用&#xff0c;特此总结了一下。 表单格式&#xff08;Form Data&#xff09; 传统的 HTML 表单使用的请求体格式&#…...

通过torch.utils.data.DataLoader可提高深度学习的10倍运行的速度?

引言 在深度学习的训练过程中&#xff0c;数据加载是一个关键步骤&#xff0c;它直接影响到模型训练的效率。为了提高运行速度&#xff0c;我们通常会采用多种方法&#xff0c;比如数据预处理、多线程加载、缓存策略等。然而&#xff0c;有一个经常被忽视的优化点——调整torc…...

【QT】背景,安装和介绍

TOC 目录 背景 GUI技术 QT的安装 使用流程 QT程序介绍 main.cpp​编辑 Wiget.h Widget.cpp form file .pro文件 临时文件 C作为一门比较古老的语言&#xff0c;在人们的认知里始终是以底层&#xff0c;复杂和高性能著称&#xff0c;所以在很多高性能需求的场景之下…...

计算机网络:IP协议详细讲解

目录 前言 一、IP网段划分 二、IP报头 三、解决IP地址不足-->NAT技术 前言 在之前&#xff0c;我们学习了传输层中的TCP和UDP&#xff0c;重点是TCP协议&#xff0c;他帮我们解决具体到主机的哪个应用&#xff08;端口&#xff09;、传输的可靠&#xff08;序列号、校验和…...

Python中使用pip换源的详细指南

在Python开发过程中&#xff0c;我们经常需要安装各种第三方库。pip是Python的包管理工具&#xff0c;用于安装和管理Python库。然而&#xff0c;由于网络原因&#xff0c;有时访问默认的Python包索引&#xff08;PyPI&#xff09;可能会比较慢。这时&#xff0c;我们可以通过更…...

【Unity】WebGL全屏问题

1 前言 WebGL项目打包时不可避免的需要面对全屏化问题&#xff0c;或者说是占满网页的问题。这里讨论一下此问题。 2 全屏化 2.1 打包模板 WebGL在打包时可以选择不同的打包模板&#xff0c;其会影响最终打包好的项目在网页中的展现形式。可以在“Project Setting/Player/Set…...

基于大数据python 电商数据分析及推荐可视化系统(源码+LW+部署讲解+数据库+ppt)

&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 很对人不知道选题怎么选 不清楚自己适合做哪块内容 都可以免费来问我 避免后期給自己答辩找麻烦 增加难度&#xff08;部分学校只有一次答辩机会 没弄好就延迟…...

基于大数据python 热门微博数据分析可视化系统(源码+LW+部署讲解+数据库+ppt)

&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 很对人不知道选题怎么选 不清楚自己适合做哪块内容 都可以免费来问我 避免后期給自己答辩找麻烦 增加难度&#xff08;部分学校只有一次答辩机会 没弄好就延迟…...

MATLAB R2024b软件下载安装教程

软件版本: MATLAB R2024b 软件大小&#xff1a;24G 安装环境&#xff1a;Windows 10/11&#xff08;64位&#xff09; 界面语言&#xff1a;简体中文 软件下载&#xff1a;https://pan.xunlei.com/s/VOCut9-UJcX7k3AO7IGXobAiA1?pwdkqkr# 软件参考安装教程 1、使用网盘…...