金融供应链智能合约 -- 智能合约实例
前提
Ownable:监管者合约,有一个函数能转让监管者。
SupplyChainFin:供应链金融合约,银行、公司信息上链,公司和银行之间的转账。
发票:记录者交易双方和交易金额等的一种记录数据。如:我在超市买了一瓶水,超市给我开了一张发票。
Ownable
// SPDX-License-Identifier: MIT
pragma solidity >=0.4 <=0.9;/*
*@title Ownable
*@dev
*/
contract Ownable{address public owner; // 监管者event OwnershipTransferred( // 监管者转让结构体address indexed priviousOwner, // indexed表名可以被索引address indexed newOwner);constructor() {owner = msg.sender;}// 判断用户是否是监管者modifier onlyOwner(){require(msg.sender == owner,"You cannot owner!");_;}// 转让所有权,必须是原先监管者转让function transferOwnership(address newOwner) public onlyOwner{require(newOwner != owner && newOwner != address(0),"newOwner cannot be empty and equal to the priviousOwner");emit OwnershipTransferred(owner, newOwner);owner = newOwner;}}
SupplyChainFin
// SPDX-License-Identifier: MIT
pragma solidity >=0.4 <=0.9;
import "./Ownable.sol";/**
*@title SuppluChainFin
*@dev
*/
contract SupplyChainFin is Ownable{// 监管者信息结构体struct Supervisor{string supervisorName; address supervisorAddress;}// 公司信息结构体struct Company{string companyName;address companyAddress;uint creditAsset;uint[] acceptReceiptIndex;uint[] sendReceiptIndex;}// 银行信息结构体struct Bank{string bankName;address bankAddress;uint creditAsset;uint[] acceptReceiptIndex;uint[] sendReceiptIndex;}// 数字发票收据信息struct Receipt {address senderAddress; address accepterAddress;uint8 receiptType; // 发票类型uint8 transferType; // 转账类型uint amount; // 交易额}// 公司的map ,用于快速搜索mapping(address => Company) companyMap;// 银行mapmapping (address =>Bank) bankMap;// 发票的mapmapping (uint => Receipt) receiptMap;//监管者实体Supervisor public supervisor;// 公司地址的数组address[] public companies;// 银行地址的数组address[] public banks;//数组发票索引uint public receiptIndex;constructor(string memory name){supervisor = Supervisor(name,msg.sender); // 初始化监管者信息}// 将公司信息添加到智能合约中function addCompany(string memory name,address companyAddress)public payable returns(bool){// 初始化公司结构体// 添加到公司map// 添加到公司数组Company memory newCompany = Company(name,companyAddress,msg.value,new uint[](0),new uint[](0));companyMap[companyAddress] = newCompany;companies.push(companyAddress);return true;}// 获取公司信息function getCompany(address companyAddress) public view returns(string memory,address,uint,uint[] memory,uint[] memory){// 用地址拿出公司结构体// 将需要的数据一起返回Company memory company = companyMap[companyAddress];return (company.companyName,company.companyAddress,company.creditAsset,company.acceptReceiptIndex,company.sendReceiptIndex);}// 添加银行信息上链function addBank(string memory bankName,address bankAddress) public payable returns(bool){Bank memory newBank;newBank.bankName = bankName;newBank.bankAddress = bankAddress;newBank.creditAsset = msg.value;bankMap[bankAddress] = newBank;banks.push(bankAddress);return true;}// 获取银行信息function getBank(address bankAddress) public view returns(string memory,address,uint,uint[] memory,uint[] memory){Bank memory bank = bankMap[bankAddress];return (bank.bankName,bank.bankAddress,bank.creditAsset,bank.acceptReceiptIndex,bank.sendReceiptIndex);}// 获取公司全部地址function getAllCompanyAddress() public view returns(address[] memory){return companies;}// 获取银行全部地址function getAllBankAddress() public view returns(address[] memory){return banks;}// 获取凭证function getRecipt(uint index)public view returns(address,address,uint8,uint8,uint){Receipt memory receipt = receiptMap[index];return (receipt.senderAddress,receipt.accepterAddress,receipt.receiptType,receipt.transferType,receipt.amount);}//存证交易// receiptType: 发票类型(存证、现金)//1: 交易类型为存证//2:交易类型为现金// transferType: 交易类型//1: 银行转账给公司//2: 公司与公司间转账//3: 公司转账给银行// 银行向公司交易(公司颁布凭证):function bankToCompanyReceipt(address senderAddress, // 凭证发送方address accepterAddress, // 凭证接受方uint amount, // 交易额uint8 receiptType // 凭证类型) public returns(uint){// 银行转账给公司,银行是发票接受者,只有银行同意要发票,这笔交易才能执行require(msg.sender == accepterAddress,"The function caller must be accper");// 拿出银行、公司结构体Company memory company = companyMap[senderAddress];Bank memory bank = bankMap[accepterAddress];// 判断公司银行是否存在if(keccak256(bytes(bank.bankName)) == keccak256(bytes(""))){return 404001;}if(keccak256(bytes(company.companyName)) == keccak256(bytes(""))){return 404002;}// 判断银行资产是否小于转账额if(bank.creditAsset < amount){return 500001;}// 初始化凭证Receipt memory newReceipt = Receipt(senderAddress,accepterAddress,receiptType,1,amount);// 发票索引 + 1receiptIndex += 1;// 根据转账额,相互的 +-companyMap[accepterAddress].creditAsset += amount;bankMap[senderAddress].creditAsset -= amount;// 存凭证索引,这样我们拿到公司或银行信息,拿到发票索引,在拿到发票结构体receiptMap[receiptIndex] = newReceipt;companyMap[accepterAddress].sendReceiptIndex.push(receiptIndex);bankMap[senderAddress].acceptReceiptIndex.push(receiptIndex);return 200;}//公司向公司交易(接受钱的公司需要颁布凭证)function companyToCompanyReceipt(address senderAddress,address accepterAddress,uint amount,uint8 receiptType) public returns(uint){require(msg.sender == accepterAddress);Company memory senderCompany = companyMap[senderAddress];Company memory accepterCompany = companyMap[accepterAddress];if (keccak256(bytes(senderCompany.companyName)) == keccak256(bytes(""))) {return 404001;}//确认接收公司存在if (keccak256(bytes(accepterCompany.companyName)) == keccak256(bytes(""))) {return 404002;}//如果存证接收的公司资产小于存证数额,那么就不能交易发送存证if (accepterCompany.creditAsset < amount) {return 500001;}//创建存证Receipt memory newReceipt = Receipt(senderAddress,accepterAddress,receiptType,2,amount);receiptIndex += 1;//记录存证(存证Map,公司Map对应地址的发送和接收存证列表)receiptMap[receiptIndex] = newReceipt;companyMap[senderAddress].sendReceiptIndex.push(receiptIndex);companyMap[accepterAddress].acceptReceiptIndex.push(receiptIndex);companyMap[senderAddress].creditAsset += amount;companyMap[accepterAddress].creditAsset -= amount;return 200;}//公司与银行交易(银行颁布凭证)function companyToBankReceipt(address senderAddress,address accepterAddress,uint amount,uint8 receiptType) public returns (uint) {require(msg.sender == accepterAddress);Bank memory bank = bankMap[senderAddress];Company memory accepterCompany = companyMap[accepterAddress];//确认发送公司存在if (keccak256(bytes(bank.bankName)) == keccak256(bytes(""))) {return 404001;}//确认接收公司存在if (keccak256(bytes(accepterCompany.companyName)) == keccak256(bytes(""))) {return 404002;} //如果存证接收的公司资产小于存证数额,那么就不能交易发送存证if (accepterCompany.creditAsset < amount) {return 500001;}//创建存证Receipt memory newReceipt = Receipt(senderAddress,accepterAddress,receiptType,3,amount);receiptIndex += 1;//记录存证(存证Map,公司Map对应地址的发送和接收存证列表)receiptMap[receiptIndex] = newReceipt;bankMap[senderAddress].sendReceiptIndex.push(receiptIndex);companyMap[accepterAddress].acceptReceiptIndex.push(receiptIndex);bankMap[senderAddress].creditAsset += amount;companyMap[accepterAddress].creditAsset -= amount;return 200;}}
相关文章:
金融供应链智能合约 -- 智能合约实例
前提 Ownable:监管者合约,有一个函数能转让监管者。 SupplyChainFin:供应链金融合约,银行、公司信息上链,公司和银行之间的转账。 发票:记录者交易双方和交易金额等的一种记录数据。如:我在超市买了一瓶水,超市给我开了一张发票。 Ownable // SPDX-…...

论文《Contrastive Meta Learning with Behavior Multiplicity for Recommendation》阅读
论文《Contrastive Meta Learning with Behavior Multiplicity for Recommendation》阅读 论文概况论文主要贡献Background & Motivation方法论单行为图神经网络(Behavior-aware GNN)多行为对比学习元对比编码模型训练 实验部分论文总结 论文概况 今…...

K8S 部署 RocketMQ
文章目录 添加模板部署本地访问 集群使用 kubesphere 作为工具 添加模板 添加 helm 模板 helm repo add rocketmq-repo https://helm-charts.itboon.top/rocketmq helm repo update rocketmq-repo编写 value.yaml 文件 配置主从节点的个数,例子为单节点 broker:…...

[Docker]入门之docker-compose
一,Docker-compose简介 1,Docker-compose简介 Docker-Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。 Docker-Compose将所管理的容器分为三层,分别是工程(project),…...
SAP ABAP中使用函数ALSM_EXCEL_TO_INTERNAL_TABLE读取EXCEL中不同的SHEET数据
SAP提供了标准的读取EXCEL的函数(ALSM_EXCEL_TO_INTERNAL_TABLE),但是此标准函数无法满足对同一EXCEL 进行不同SHEET的数据读取,一下方法就是教你如何通过修改程序来实现ALSM_EXCEL_TO_INTERNAL_TABLE读取多个SHEET; …...

Rust 编程小技巧摘选(6)
目录 Rust 编程小技巧(6) 1. 打印字符串 2. 重复打印字串 3. 自定义函数 4. 遍历动态数组 5. 遍历二维数组 6. 同时遍历索引和值 7. 迭代器方法的区别 8. for_each() 用法 9. 分离奇数和偶数 10. 判断素数(质数) Rust 编程小技巧(6) 1. 打印…...
如何保证Redis缓存和数据库的一致性问题
熟练掌握Redis缓存技术? 那么请问Redis缓存中有几种读写策略,又是如何保证与数据库的一致性问题 今天来聊一聊常用的三种缓存读写策略 Cache Aside Pattern Cache Aside Pattern 是我们平时使用比较多的一个缓存读写模式,比较适合读请求比…...

【数据分析入门】人工智能、数据分析和深度学习是什么关系?如何快速入门 Python Pandas?
目录 一、前言二、数据分析和深度学习的区别三、人工智能四、深度学习五、Pandas六、Pandas数据结构6.1 Series - 序列6.2 DataFrame - 数据框 七、输入、输出7.1 读取/写入CSV7.2 读取/写入Excel7.3 读取和写入 SQL 查询及数据库表 八、调用帮助九、选择(这里可以参考上一篇文…...
JavaScript 里三个点 ... 的用法
// table表头数据let tableHeadData deepClone(data);let tableCacheData [];//表格缓存对比if (!parent && isCacheHeadData) {// 缓存数据keylet tableCacheKey ${window.location.pathname}-${$self.attr(id)}if (localStorage.getItem(tableCacheKey)) {//根据缓…...

Linux修改系统语言
sudo dpkg-reconfigure locales 按pagedown键,移动红色光标到 zh_CN.UTF-8 UTF-8,空格标记*号(没标记下一页没有这一项),回车。 下一页选择 zh_CN.UTF-8。 如果找不到 dpkg-reconfigure whereis dpkg-reconfigure …...

Spring注解开发
目录 1、简介 2、原始注解 2.1、注解种类 2.2、组件扫描 2.3、具体使用 2.3.1、xml配置 2.3.2、注解配置 3、⭐新注解 3.1、新注解种类 3.2、实践 3.3、运行结果 3.4、警告信息 1、简介 Spring框架提供了许多注解,用于在Java类中进行配置和标记…...

图像处理库(Opencv, Matplotlib, PIL)以及三者之间的转换
文章目录 1. Opencv2. Matplotlib3. PIL4. 三者的区别和相互转换5. Torchvision 中的相关转换库5.1 ToPILImage([mode])5.2 ToTensor5.3 PILToTensor 1. Opencv opencv的基本图像类型可以和numpy数组相互转化,因此可以直接调用torch.from_numpy(img) 将图像转换成t…...
html+Vue+封装axios实现发送请求
在html中使用Vue和Axios时,可以在HTML中引入Vue库和Axios库,然后使用Vue的语法和指令来创建Vue组件和模板。在Vue组件中,你可以使用Axios发送HTTP请求来获取数据,并将数据绑定到Vue模板中进行展示。 <template><div>&…...
GoogLeNet卷积神经网络输出数据形参分析-笔记
GoogLeNet卷积神经网络输出数据形参分析-笔记 分析结果为: 输入数据形状:[10, 3, 224, 224] 最后输出结果:linear_0 [10, 1] [1024, 1] [1] 子空间执行逻辑 def forward_old(self, x):# 支路1只包含一个1x1卷积p1 F.relu(self.p1_1(x))# 支路2包含 1…...

【docker】dockerfile发布springboot项目
目录 一、实现步骤二、示例 一、实现步骤 1.定义父镜像:FROM java:8 2.定义作者信息:MAINTAINER:learn_docker<https://www.docker.com> 3.将jar包添加到容器:ADD jar包名称.jar app.jar 4.定义容器启动执行命令:…...
利用docker run -v 命令实现使用宿主机中没有的命令
利用docker run -v 命令实现使用宿主机中没有的命令 使用容器中的jar命令解压jar包,并将解压内容输出到挂载在宿主机中的目录里 使用容器中的jar命令解压jar包,并将解压内容输出到挂载在宿主机中的目录里 docker run -it --name java -v /www/temp/java…...

【小沐学NLP】在线AI绘画网站(百度:文心一格)
文章目录 1、简介2、文心一格2.1 功能简介2.2 操作步骤2.3 使用费用2.4 若干示例2.4.1 女孩2.4.2 昙花2.4.3 山水画2.4.4 夜晚2.4.5 古诗2.4.6 二次元2.4.7 帅哥 结语 1、简介 当下,越来越多AI领域前沿技术争相落地,逐步释放出极大的产业价值࿰…...
react经验5:访问子组件内容
应用场景 父级需要调用子组件的某函数 实现步骤 案例:创建自定义按钮 button.tsx import { Ref, forwardRef, useImperativeHandle,ReactNode} from "react" declare type ButtonProps {/**按钮文字 */children?: ReactNode,onClick?: () > voi…...

【LeetCode】647. 回文子串
题目链接 文章目录 1. 思路讲解1.1 方法选择1.2 dp表的创建1.3 状态转移方程1.4 填表顺序 2. 代码实现 1. 思路讲解 1.1 方法选择 这道题我们采用动态规划的解法,倒不是动态规划的解法对于这道题有多好,它并不是最优解。但是,这道题的动态…...
Open3D(C++) 角度制与弧度制的相互转换
目录 一、弧度转角度1、计算公式2、主要函数3、示例代码4、结果展示二、角度转弧度1、计算公式2、主要函数3、示例代码4、结果展示三、归一化到(-PI,PI)1、主要函数<...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...