金融供应链智能合约 -- 智能合约实例

前提

Ownable:监管者合约,有一个函数能转让监管者。

SupplyChainFin:供应链金融合约,银行、公司信息上链,公司和银行之间的转账。

发票:记录者交易双方和交易金额等的一种记录数据。如:我在超市买了一瓶水,超市给我开了一张发票。

Ownable

javascript 复制代码
// 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

javascript 复制代码
// 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;

    // 银行map
    mapping (address =>Bank) bankMap;

    // 发票的map
    mapping (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
        );
        // 发票索引 + 1
        receiptIndex += 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;
    }







}
相关推荐
兰亭妙微14 小时前
ui设计公司审美积累 | 金融人工智能与用户体验 用户界面仪表盘设计
人工智能·金融·ux
许强0xq18 小时前
Gas优化大师目录
web3·区块链·智能合约·solidity·foundry·ethernaut·gas优化
B站_计算机毕业设计之家1 天前
python股票交易数据管理系统 金融数据 分析可视化 Django框架 爬虫技术 大数据技术 Hadoop spark(源码)✅
大数据·hadoop·python·金融·spark·股票·推荐算法
B站_计算机毕业设计之家1 天前
基于大数据股票数据分析与预测系统 LSTM神经网络算法 股票价格预测 Tensorflow深度学习 机器学习 Flask框架 东方财富(全套资料)✅
深度学习·神经网络·机器学习·金融·股票·预测·股价
B站_计算机毕业设计之家1 天前
机器学习:基于大数据的基金数据分析可视化系统 股票数据 金融数据 股价 Django框架 大数据技术(源码) ✅
大数据·python·金融·数据分析·股票·etf·基金
mtactor2 天前
投资理财学习笔记
笔记·学习·金融
没有bug.的程序员2 天前
金融支付分布式架构实战:从理论到生产级实现
java·分布式·微服务·金融·架构·分布式调度系统
luoganttcc3 天前
除了有效市场假说,还有哪些理论能更好的解释经济或者金融活动
金融
AWS官方合作商3 天前
赋能金融科技:基于AWS的云上量化交易解决方案,让策略研发与部署效率倍增
科技·金融·aws
Joy T3 天前
Solidity智能合约开发入门攻略
web3·区块链·智能合约·solidity·以太坊·共识算法